summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-07-09 15:03:09 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-07-09 15:03:09 +0300
commit7c33e4a07ba1f22a58c291018ca99a4f6becb1fe (patch)
tree4a8ef2882a0cc26e2f583b56fab9054d9f5e72f6 /protocols
parent14e09a5f84023ad21a2f494ced01a991966abee4 (diff)
fixes #3351 (Jingle: Separate all VOIP-related code from Jabber to Jingle plugin)
Diffstat (limited to 'protocols')
-rw-r--r--protocols/JabberG/jabber.vcxproj9
-rw-r--r--protocols/JabberG/jabber.vcxproj.filters3
-rw-r--r--protocols/JabberG/src/jabber_api.cpp17
-rw-r--r--protocols/JabberG/src/jabber_opt.cpp2
-rw-r--r--protocols/JabberG/src/jabber_proto.cpp15
-rw-r--r--protocols/JabberG/src/jabber_proto.h30
-rw-r--r--protocols/JabberG/src/jabber_send_manager.cpp2
-rw-r--r--protocols/JabberG/src/jabber_send_manager.h2
-rw-r--r--protocols/JabberG/src/jabber_strm_mgmt.cpp2
-rw-r--r--protocols/JabberG/src/jabber_strm_mgmt.h2
-rw-r--r--protocols/JabberG/src/jabber_thread.cpp139
-rw-r--r--protocols/JabberG/src/jabber_voip.cpp594
-rw-r--r--protocols/JabberG/src/jabber_xml.cpp6
-rw-r--r--protocols/JabberG/src/stdafx.h4
14 files changed, 35 insertions, 792 deletions
diff --git a/protocols/JabberG/jabber.vcxproj b/protocols/JabberG/jabber.vcxproj
index ec58b9f728..1c6f2f6266 100644
--- a/protocols/JabberG/jabber.vcxproj
+++ b/protocols/JabberG/jabber.vcxproj
@@ -25,11 +25,6 @@
<ImportGroup Label="PropertySheets">
<Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" />
</ImportGroup>
- <ItemDefinitionGroup>
- <ClCompile>
- <AdditionalIncludeDirectories>..\..\include\glib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\utils\mir_signal.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
@@ -83,7 +78,6 @@
<ClCompile Include="src\jabber_userinfo.cpp" />
<ClCompile Include="src\jabber_util.cpp" />
<ClCompile Include="src\jabber_vcard.cpp" />
- <ClCompile Include="src\jabber_voip.cpp" />
<ClCompile Include="src\jabber_xml.cpp" />
<ClCompile Include="src\jabber_xstatus.cpp" />
<ClCompile Include="src\jabber_zstream.cpp" />
@@ -117,8 +111,7 @@
</ItemGroup>
<ItemDefinitionGroup>
<Link>
- <AdditionalDependencies>delayimp.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <DelayLoadDLLs>glib-2.0-0.dll;gobject-2.0-0.dll;gstreamer-1.0-0.dll;gstrtp-1.0-0.dll;gstsdp-1.0-0.dll;gstwebrtc-1.0-0.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <AdditionalDependencies>libcrypto.lib;libssl.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/protocols/JabberG/jabber.vcxproj.filters b/protocols/JabberG/jabber.vcxproj.filters
index 17d86404b3..4bed895b71 100644
--- a/protocols/JabberG/jabber.vcxproj.filters
+++ b/protocols/JabberG/jabber.vcxproj.filters
@@ -161,9 +161,6 @@
<ClCompile Include="src\jabber_mam.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="src\jabber_voip.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\utils\mir_signal.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/protocols/JabberG/src/jabber_api.cpp b/protocols/JabberG/src/jabber_api.cpp
index ef2b285f70..cfbbb24083 100644
--- a/protocols/JabberG/src/jabber_api.cpp
+++ b/protocols/JabberG/src/jabber_api.cpp
@@ -103,6 +103,16 @@ char* CJabberProto::GetModuleName() const
return m_szModuleName;
}
+char* CJabberProto::GetFullJid() const
+{
+ return (m_ThreadInfo) ? m_ThreadInfo->fullJID : "";
+}
+
+char* CJabberProto::GetSerialNext()
+{
+ return JabberId2string(SerialNext());
+}
+
typedef struct
{
JABBER_HANDLER_FUNC Func;
@@ -317,7 +327,8 @@ char* CJabberProto::GetResourceFeatures(const char *jid)
return res.Detach();
}
-HNETLIBUSER CJabberProto::GetHandle()
+void CJabberProto::SendXml(const TiXmlElement *pXml)
{
- return m_hNetlibUser;
-}
+ if (m_ThreadInfo)
+ m_ThreadInfo->send(pXml);
+} \ No newline at end of file
diff --git a/protocols/JabberG/src/jabber_opt.cpp b/protocols/JabberG/src/jabber_opt.cpp
index c49f75ba7a..650b564fe5 100644
--- a/protocols/JabberG/src/jabber_opt.cpp
+++ b/protocols/JabberG/src/jabber_opt.cpp
@@ -763,8 +763,6 @@ public:
else
m_proto->m_omemo.deinit();
- m_proto->InitVoip(m_proto->hasJingle());
-
m_proto->UpdateFeatHash();
m_proto->SendPresence(m_proto->m_iStatus, true);
return true;
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp
index b094f85590..bdf00f50e9 100644
--- a/protocols/JabberG/src/jabber_proto.cpp
+++ b/protocols/JabberG/src/jabber_proto.cpp
@@ -178,12 +178,6 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) :
CreateProtoService(JS_GETJABBERAPI, &CJabberProto::JabberGetApi);
- // Voice
- m_hVoiceEvent = CreateProtoEvent(PE_VOICE_CALL_STATE);
- CreateProtoService(PS_VOICE_CALL, &CJabberProto::JabberVOIP_call);
- CreateProtoService(PS_VOICE_ANSWERCALL, &CJabberProto::JabberVOIP_answercall);
- CreateProtoService(PS_VOICE_DROPCALL, &CJabberProto::JabberVOIP_dropcall);
-
// XEP-0224 support (Attention/Nudge)
CreateProtoService(PS_SEND_NUDGE, &CJabberProto::JabberSendNudge);
@@ -261,11 +255,6 @@ CJabberProto::~CJabberProto()
DestroyHookableEvent(m_hEventNudge);
DestroyHookableEvent(m_hEventXStatusIconChanged);
DestroyHookableEvent(m_hEventXStatusChanged);
- DestroyHookableEvent(m_hVoiceEvent);
-
- // Voice
- if (hasJingle())
- InitVoip(false);
// Lists & strings
ListWipe();
@@ -323,10 +312,6 @@ void CJabberProto::OnModulesLoaded()
CheckAllContactsAreTransported();
- // Voip
- if (hasJingle())
- InitVoip(true);
-
// Set all contacts to offline
for (auto &hContact : AccContacts()) {
SetContactOfflineStatus(hContact);
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h
index 10c6e87feb..bc41a58f3c 100644
--- a/protocols/JabberG/src/jabber_proto.h
+++ b/protocols/JabberG/src/jabber_proto.h
@@ -159,10 +159,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
//====| Services |====================================================================
INT_PTR __cdecl GetMyAwayMsg(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl JabberVOIP_call(WPARAM hContact, LPARAM);
- INT_PTR __cdecl JabberVOIP_answercall(WPARAM hContact, LPARAM);
- INT_PTR __cdecl JabberVOIP_dropcall(WPARAM hContact, LPARAM);
-
//====| Events |======================================================================
void __cdecl OnAddContactForever(MCONTACT hContact);
int __cdecl OnDbSettingChanged(WPARAM, LPARAM);
@@ -854,7 +850,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void CheckKeepAlive(void);
- bool OnProcessJingle(const TiXmlElement *node);
void OnProcessIq(const TiXmlElement *node);
void SetRegConfig(CJabberFormDlg *pDlg, void *from);
void CancelRegConfig(CJabberFormDlg *pDlg, void *from);
@@ -878,6 +873,8 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void SendPresenceTo(int status, const char* to, const TiXmlElement *extra = nullptr, const char *msg = nullptr);
void SendPresence(int iStatus, bool bSendToAll);
+ int SerialNext(); // Returns id that can be used for next message sent through SendXmlNode().
+
// returns buf or nullptr on error
char* GetClientJID(MCONTACT hContact, char *dest, size_t destLen);
char* GetClientJID(const char *jid, char *dest, size_t destLen);
@@ -906,21 +903,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
//---- jabber_voip.c -----------------------------------------------------------------
- void InitVoip(bool bEnable);
- bool OnICECandidate(const TiXmlElement *Node);
- bool OnRTPDescription(const TiXmlElement *Node);
- bool VOIPCreatePipeline();
- bool VOIPTerminateSession(const char *reason = "cancel");
- bool VOIPCallIinitiate(MCONTACT hContact);
-
- CMStringA m_voipSession, m_voipPeerJid;
- CMStringA m_voipICEPwd, m_voipICEUfrag, m_medianame;
- bool m_isOutgoing;
- TiXmlDocument m_offerDoc; const TiXmlElement *m_offerNode;
- HANDLE m_hVoiceEvent;
- struct _GstElement *m_pipe1 = NULL;
- struct _GstElement *m_webrtc1 = NULL;
-
__forceinline bool hasJingle()
{ return FindFeature(JABBER_FEAT_JINGLE) != 0 && m_bEnableVOIP;
}
@@ -981,8 +963,8 @@ public:
char* STDMETHODCALLTYPE GetBestResourceName(const char *jid) override; // Returns best resource name for given JID. You must free the result using mir_free().
char* STDMETHODCALLTYPE GetResourceList(const char *jid) override; // Returns all resource names for a given JID in format "resource1\0resource2\0resource3\0\0" (all resources are separated by \0 character and the whole string is terminated with two \0 characters). You must free the string using mir_free().
char* STDMETHODCALLTYPE GetModuleName() const override; // Returns Jabber module name.
-
- int STDMETHODCALLTYPE SerialNext() override; // Returns id that can be used for next message sent through SendXmlNode().
+ char* STDMETHODCALLTYPE GetFullJid() const override; // Returns full JID of the current session
+ char* STDMETHODCALLTYPE GetSerialNext() override;
HJHANDLER STDMETHODCALLTYPE AddPresenceHandler(JABBER_HANDLER_FUNC Func, void *pUserData, int iPriority) override;
HJHANDLER STDMETHODCALLTYPE AddMessageHandler(JABBER_HANDLER_FUNC Func, int iMsgTypes, const char *szXmlns, const char *szTag, void *pUserData, int iPriority) override;
@@ -994,8 +976,8 @@ public:
int STDMETHODCALLTYPE AddFeatures(const char *szFeatures) override; // Adds features to the list of features returned by the client.
int STDMETHODCALLTYPE RemoveFeatures(const char *szFeatures) override; // Removes features from the list of features returned by the client.
char* STDMETHODCALLTYPE GetResourceFeatures(const char *jid) override; // Returns all features supported by JID in format "feature1\0feature2\0...\0featureN\0\0". You must free returned string using mir_free().
-
- HNETLIBUSER STDMETHODCALLTYPE GetHandle() override; // Returns connection handle
+
+ void STDMETHODCALLTYPE SendXml(const TiXmlElement *pXml) override;
};
#endif
diff --git a/protocols/JabberG/src/jabber_send_manager.cpp b/protocols/JabberG/src/jabber_send_manager.cpp
index 67031c0567..05ba3d4248 100644
--- a/protocols/JabberG/src/jabber_send_manager.cpp
+++ b/protocols/JabberG/src/jabber_send_manager.cpp
@@ -60,7 +60,7 @@ bool CJabberSendManager::DeletePermanentHandler(CJabberSendPermanentInfo *pInfo)
return m_arHandlers.remove(pInfo) == 1;
}
-bool CJabberSendManager::HandleSendPermanent(TiXmlElement *node, ThreadData *pThreadData)
+bool CJabberSendManager::HandleSendPermanent(const TiXmlElement *node, ThreadData *pThreadData)
{
for (auto &pInfo : m_arHandlers) {
CJabberSendInfo sendInfo;
diff --git a/protocols/JabberG/src/jabber_send_manager.h b/protocols/JabberG/src/jabber_send_manager.h
index 9b98db0458..393ed8adba 100644
--- a/protocols/JabberG/src/jabber_send_manager.h
+++ b/protocols/JabberG/src/jabber_send_manager.h
@@ -99,7 +99,7 @@ public:
CJabberSendPermanentInfo* AddPermanentHandler(JABBER_SEND_HANDLER pHandler, void *pUserData = nullptr, SEND_USER_DATA_FREE_FUNC pUserDataFree = nullptr, int iPriority = JH_PRIORITY_DEFAULT);
bool DeletePermanentHandler(CJabberSendPermanentInfo *pInfo);
- bool HandleSendPermanent(TiXmlElement *node, ThreadData *pThreadData);
+ bool HandleSendPermanent(const TiXmlElement *node, ThreadData *pThreadData);
};
#endif
diff --git a/protocols/JabberG/src/jabber_strm_mgmt.cpp b/protocols/JabberG/src/jabber_strm_mgmt.cpp
index 4f96076ac7..c660eea476 100644
--- a/protocols/JabberG/src/jabber_strm_mgmt.cpp
+++ b/protocols/JabberG/src/jabber_strm_mgmt.cpp
@@ -163,7 +163,7 @@ void strm_mgmt::CheckState()
EnableStrmMgmt();
}
-void strm_mgmt::HandleOutgoingNode(TiXmlElement *node)
+void strm_mgmt::HandleOutgoingNode(const TiXmlElement *node)
{
if (!m_bHalfEnabled)
return;
diff --git a/protocols/JabberG/src/jabber_strm_mgmt.h b/protocols/JabberG/src/jabber_strm_mgmt.h
index fc4f898af3..5225dfc286 100644
--- a/protocols/JabberG/src/jabber_strm_mgmt.h
+++ b/protocols/JabberG/src/jabber_strm_mgmt.h
@@ -54,7 +54,7 @@ class strm_mgmt
public:
strm_mgmt(CJabberProto *proto);
void EnableStrmMgmt();
- void HandleOutgoingNode(TiXmlElement *node);
+ void HandleOutgoingNode(const TiXmlElement *node);
bool HandleIncommingNode(const TiXmlElement *node);
void HandleConnectionLost();
void OnProcessEnabled(const TiXmlElement *node, ThreadData *info);
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp
index c044ed9998..4ab15f6805 100644
--- a/protocols/JabberG/src/jabber_thread.cpp
+++ b/protocols/JabberG/src/jabber_thread.cpp
@@ -1782,137 +1782,6 @@ void CJabberProto::OnProcessPresence(const TiXmlElement *node, ThreadData *info)
}
}
-bool CJabberProto::OnProcessJingle(const TiXmlElement *node)
-{
- auto *child = XmlGetChildByTag(node, "jingle", "xmlns", JABBER_FEAT_JINGLE);
- if (!child)
- return false;
-
- const char *type = XmlGetAttr(node, "type");
- if (type == nullptr)
- return false;
-
- const char *szAction = XmlGetAttr(child, "action");
- const char *szSid = XmlGetAttr(child, "sid");
-
- if (!mir_strcmp(type, "get") || !mir_strcmp(type, "set")) {
- const char *idStr = XmlGetAttr(node, "id");
- const char *from = XmlGetAttr(node, "from");
- const char *szInitiator = XmlGetAttr(child, "initiator");
- auto *content = XmlGetChildByTag(child, "content", "creator", "initiator");
-
- if (szAction && szSid) {
- if (!mir_strcmp(szAction, "session-initiate")) {
- // if this is a Jingle 'session-initiate' and noone processed it yet, reply with "unsupported-applications"
- m_ThreadInfo->send(XmlNodeIq("result", idStr, from));
-
- const TiXmlElement *descr = XmlGetChildByTag(content, "description", "xmlns", JABBER_FEAT_JINGLE_RTP);
- const char *reason = NULL;
- if (hasJingle() && descr) {
- if (m_voipSession.IsEmpty()) {
- m_voipSession = szSid;
- m_voipPeerJid = from;
- m_isOutgoing = false;
- m_offerNode = child->DeepClone(&m_offerDoc)->ToElement();
-
- //Make call GUI
- VOICE_CALL vc = {};
- vc.cbSize = sizeof(VOICE_CALL);
- vc.moduleName = m_szModuleName;
- vc.id = szSid; // Protocol specific ID for this call
- vc.hContact = HContactFromJID(from); // Contact associated with the call (can be NULL)
- vc.state = VOICE_STATE_RINGING;
- vc.szNumber.a = m_voipPeerJid;
- NotifyEventHooks(m_hVoiceEvent, WPARAM(&vc), 0);
-
- // ringing message
- XmlNodeIq iq("set", SerialNext(), from);
- TiXmlElement *rjNode = iq << XCHILDNS("jingle", JABBER_FEAT_JINGLE);
- rjNode << XATTR("action", "session-info") << XATTR("sid", szSid);
- if (szInitiator)
- rjNode << XATTR("initiator", szInitiator);
- rjNode << XCHILDNS("ringing", "urn:xmpp:jingle:apps:rtp:info:1");
-
- m_ThreadInfo->send(iq);
- return true;
- }
-
- // Save this event to history
- PROTORECVEVENT recv = {};
- recv.timestamp = (uint32_t)time(0);
- recv.szMessage = "** A call while we were busy **";
- ProtoChainRecvMsg(HContactFromJID(from), &recv);
- reason = "busy";
- }
-
- XmlNodeIq iq("set", SerialNext(), from);
- TiXmlElement *jingleNode = iq << XCHILDNS("jingle", JABBER_FEAT_JINGLE);
- jingleNode << XATTR("action", "session-terminate") << XATTR("sid", szSid);
- if (szInitiator)
- jingleNode << XATTR("initiator", szInitiator);
- jingleNode << XCHILD("reason") << XCHILD(reason ? reason : "unsupported-applications");
-
- m_ThreadInfo->send(iq);
- return true;
- }
- else if (!mir_strcmp(szAction, "session-accept")) {
- if (hasJingle() && m_voipSession == szSid) {
- m_ThreadInfo->send(XmlNodeIq("result", idStr, from));
- if (OnRTPDescription(child)) {
- //Make call GUI
- VOICE_CALL vc = {};
- vc.cbSize = sizeof(VOICE_CALL);
- vc.moduleName = m_szModuleName;
- vc.id = szSid;
- vc.hContact = HContactFromJID(from);
- vc.state = VOICE_STATE_TALKING;
- NotifyEventHooks(m_hVoiceEvent, WPARAM(&vc), 0);
- }
- return true;
- }
- }
- else if (!mir_strcmp(szAction, "session-terminate")) {
- if (hasJingle() && m_voipSession == szSid) {
- // EndCall()
- m_ThreadInfo->send(XmlNodeIq("result", idStr, from));
-
- VOICE_CALL vc = {};
- vc.cbSize = sizeof(VOICE_CALL);
- vc.moduleName = m_szModuleName;
- vc.id = szSid;
- vc.hContact = HContactFromJID(from);
- vc.state = VOICE_STATE_ENDED;
- NotifyEventHooks(m_hVoiceEvent, WPARAM(&vc), 0);
-
- VOIPTerminateSession(nullptr);
- return true;
- }
- }
- else if (!mir_strcmp(szAction, "transport-info")) {
- auto *transport = XmlGetChildByTag(content, "transport", "xmlns", JABBER_FEAT_JINGLE_ICEUDP);
- if (hasJingle() && m_voipSession == szSid && transport) {
- m_ThreadInfo->send(XmlNodeIq("result", idStr, from));
- if (const TiXmlElement *candidate = XmlFirstChild(transport, "candidate")) {
- OnICECandidate(candidate);
- return true;
- }
- }
- }
- }
-
- // if it's something else than 'session-initiate' and noone processed it yet, reply with "unknown-session"
- XmlNodeIq iq("error", idStr, from);
- TiXmlElement *errNode = iq << XCHILD("error");
- errNode << XATTR("type", "cancel");
- errNode << XCHILDNS("item-not-found", "urn:ietf:params:xml:ns:xmpp-stanzas");
- errNode << XCHILDNS("unknown-session", "urn:xmpp:jingle:errors:1");
- m_ThreadInfo->send(iq);
- return true;
- }
-
- return false;
-}
-
void CJabberProto::OnProcessIq(const TiXmlElement *node)
{
if (!node->Name() || mir_strcmp(node->Name(), "iq"))
@@ -1932,10 +1801,6 @@ void CJabberProto::OnProcessIq(const TiXmlElement *node)
if (m_iqManager.HandleIqPermanent(node))
return;
- // Jingle support
- if (OnProcessJingle(node))
- return;
-
// RECVED: <iq type='error'> ...
if (!mir_strcmp(type, "error")) {
char tszBuf[20];
@@ -2139,7 +2004,7 @@ int ThreadData::send(char *buf, int bufsize)
}
// Caution: DO NOT use ->send() to send binary (non-string) data
-int ThreadData::send(TiXmlElement *node)
+int ThreadData::send(const TiXmlElement *node)
{
if (this == nullptr || node == nullptr)
return 0;
@@ -2159,7 +2024,7 @@ int ThreadData::send(TiXmlElement *node)
}
// this function required for send <r/>, <a/> and more important, for resend stuck nodes by strm_mgmt (xep-0198)
-int ThreadData::send_no_strm_mgmt(TiXmlElement *node)
+int ThreadData::send_no_strm_mgmt(const TiXmlElement *node)
{
if (proto->m_sendManager.HandleSendPermanent(node, this))
return 0;
diff --git a/protocols/JabberG/src/jabber_voip.cpp b/protocols/JabberG/src/jabber_voip.cpp
deleted file mode 100644
index 9c8cb589d9..0000000000
--- a/protocols/JabberG/src/jabber_voip.cpp
+++ /dev/null
@@ -1,594 +0,0 @@
-#include "stdafx.h"
-
-#include <m_voiceservice.h>
-
-#include <gst/gst.h>
-#include <gst/sdp/sdp.h>
-#include <gst/rtp/rtp.h>
-
-#define GST_USE_UNSTABLE_API
-#include <gst/webrtc/webrtc.h>
-
-#pragma comment(lib, "glib-2.0.lib")
-#pragma comment(lib, "gobject-2.0.lib")
-#pragma comment(lib, "gstreamer-1.0.lib")
-#pragma comment(lib, "gstrtp-1.0.lib")
-#pragma comment(lib, "gstsdp-1.0.lib")
-#pragma comment(lib, "gstwebrtc-1.0.lib")
-
-static std::list<CMStringA> remotecands;
-
-bool GetCandidateProp(char *output, byte maxlen, const char *candidate, const char *prop)
-{
- const char *pprop = strstr(candidate, prop);
- if (!pprop)
- return false;
-
- const char *val = pprop + strlen(prop);
- while (*val == ' ') val++;
- int i = 0;
- while (*val != 0 && *val != ' ' && i < maxlen - 1)
- output[i++] = *val++;
- output[i] = 0;
-
- return i > 0;
-}
-
-static void handle_media_stream(GstPad *pad, GstElement *pipe, const char *convert_name, const char *sink_name)
-{
- GstPad *qpad;
- GstElement *q, *conv, *resample, *sink;
- GstPadLinkReturn ret;
-
- gst_print("Trying to handle stream with %s ! %s", convert_name, sink_name);
-
- q = gst_element_factory_make("queue", NULL);
- g_assert_nonnull(q);
- conv = gst_element_factory_make(convert_name, NULL);
- g_assert_nonnull(conv);
- sink = gst_element_factory_make(sink_name, NULL);
- g_assert_nonnull(sink);
-
- if (g_strcmp0(convert_name, "audioconvert") == 0) {
- /* Might also need to resample, so add it just in case.
- * Will be a no-op if it's not required. */
- resample = gst_element_factory_make("audioresample", NULL);
- g_assert_nonnull(resample);
- gst_bin_add_many(GST_BIN(pipe), q, conv, resample, sink, NULL);
- gst_element_sync_state_with_parent(q);
- gst_element_sync_state_with_parent(conv);
- gst_element_sync_state_with_parent(resample);
- gst_element_sync_state_with_parent(sink);
- gst_element_link_many(q, conv, resample, sink, NULL);
- }
- else {
- gst_bin_add_many(GST_BIN(pipe), q, conv, sink, NULL);
- gst_element_sync_state_with_parent(q);
- gst_element_sync_state_with_parent(conv);
- gst_element_sync_state_with_parent(sink);
- gst_element_link_many(q, conv, sink, NULL);
- }
-
- qpad = gst_element_get_static_pad(q, "sink");
-
- ret = gst_pad_link(pad, qpad);
- g_assert_cmphex(ret, == , GST_PAD_LINK_OK);
-}
-
-static void on_incoming_decodebin_stream(GstElement * /*decodebin*/, GstPad *pad, GstElement *pipe)
-{
- GstCaps *caps;
- const gchar *name;
-
- if (!gst_pad_has_current_caps(pad)) {
- gst_printerr("Pad '%s' has no caps, can't do anything, ignoring\n", GST_PAD_NAME(pad));
- return;
- }
-
- caps = gst_pad_get_current_caps(pad);
- name = gst_structure_get_name(gst_caps_get_structure(caps, 0));
-
- if (g_str_has_prefix(name, "video")) {
- handle_media_stream(pad, pipe, "videoconvert", "autovideosink");
- }
- else if (g_str_has_prefix(name, "audio")) {
- handle_media_stream(pad, pipe, "audioconvert", "autoaudiosink");
- }
- else {
- gst_printerr("Unknown pad %s, ignoring", GST_PAD_NAME(pad));
- }
-}
-
-static void on_incoming_stream_cb(GstElement */*webrtc*/, GstPad *pad, GstElement *pipe)
-{
- GstElement *decodebin;
- GstPad *sinkpad;
-
- if (GST_PAD_DIRECTION(pad) != GST_PAD_SRC)
- return;
-
- decodebin = gst_element_factory_make("decodebin", NULL);
- g_signal_connect(decodebin, "pad-added", G_CALLBACK(on_incoming_decodebin_stream), pipe);
- gst_bin_add(GST_BIN(pipe), decodebin);
- gst_element_sync_state_with_parent(decodebin);
-
- sinkpad = gst_element_get_static_pad(decodebin, "sink");
- gst_pad_link(pad, sinkpad);
- gst_object_unref(sinkpad);
-}
-
-void on_offer_created_cb(GstPromise *promise, gpointer user_data)
-{
- GstWebRTCSessionDescription *offer = NULL;
- CJabberProto *jproto = (CJabberProto *)user_data;
-
- GstStructure const *reply = gst_promise_get_reply(promise);
- gst_structure_get(reply, jproto->m_isOutgoing ? "offer" : "answer", GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &offer, NULL);
- gst_promise_unref(promise);
- if (!offer) {
- gst_print("Cannot process sdp");
- return;
- }
-
- GstPromise *local_desc_promise = gst_promise_new();
- g_signal_emit_by_name(jproto->m_webrtc1, "set-local-description", offer, local_desc_promise);
- gst_promise_interrupt(local_desc_promise);
- gst_promise_unref(local_desc_promise);
-
- gchar *sdp_string = gst_sdp_message_as_text(offer->sdp);
- gst_print("VOIP - Wanna send SDP offer:\r\n%s\r\n", sdp_string);
- g_free(sdp_string);
-
- const GstSDPMedia *media_audio = NULL;
- for (unsigned int i = 0; i < gst_sdp_message_medias_len(offer->sdp); i++) {
- const GstSDPMedia *m = gst_sdp_message_get_media(offer->sdp, i);
- if (!strcmp(m->media, "audio"))
- media_audio = m;
- }
- if (!media_audio) {
- gst_print("No audio media in SDP");
- return;
- }
-
- jproto->m_voipICEPwd = gst_sdp_media_get_attribute_val(media_audio, "ice-pwd");
- jproto->m_voipICEUfrag = gst_sdp_media_get_attribute_val(media_audio, "ice-ufrag");
- jproto->m_medianame = gst_sdp_media_get_attribute_val(media_audio, "mid");
-
- //send it all
- bool outgoing = jproto->m_isOutgoing;
- XmlNodeIq iq("set", jproto->SerialNext(), jproto->m_voipPeerJid);
- TiXmlElement *rjNode = iq << XCHILDNS("jingle", JABBER_FEAT_JINGLE);
- rjNode << XATTR("sid", jproto->m_voipSession)
- << XATTR("action", outgoing ? "session-initiate" : "session-accept")
- << XATTR("initiator", outgoing ? jproto->m_ThreadInfo->fullJID : jproto->m_voipPeerJid);
- if (!outgoing)
- rjNode << XATTR("responder", jproto->m_ThreadInfo->fullJID);
-
- TiXmlElement *content = rjNode << XCHILD("content") << XATTR("creator", "initiator") << XATTR("name", jproto->m_medianame);
- TiXmlElement *description = content << XCHILDNS("description", JABBER_FEAT_JINGLE_RTP) << XATTR("media", "audio");
-
- auto *opuspayload = description << XCHILD("payload-type") << XATTR("id", "111") << XATTR("name", "opus") << XATTR("clockrate", "48000") << XATTR("channels", "2");
-
- opuspayload << XCHILD("parameter") << XATTR("name", "minptime") << XATTR("value", "10");
- opuspayload << XCHILD("parameter") << XATTR("name", "useinbandfec") << XATTR("value", "1");
- opuspayload << XCHILDNS("rtcp-fb", "urn:xmpp:jingle:apps:rtp:rtcp-fb:0") << XATTR("type", "transport-cc");
-
- description << XCHILDNS("rtp-hdrext", "urn:xmpp:jingle:apps:rtp:rtp-hdrext:0") << XATTR("id", "1") << XATTR("uri", "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01");
- /*
- auto* source = description << XCHILDNS("source", "urn:xmpp:jingle:apps:rtp:ssma:0") << XATTR("ssrc", "2165039095");
- source << XCHILD("parameter") << XATTR("name", "cname") << XATTR("value", "8ee+PcGu8BNwq22f");
- source << XCHILD("parameter") << XATTR("name", "msid") << XATTR("value", "my-media-stream2 my-audio-track2");
- source << XCHILD("parameter") << XATTR("name", "mslabel") << XATTR("value", "my-media-stream2");
- source << XCHILD("parameter") << XATTR("name", "label") << XATTR("value", "my-audio-track2");*/
-
- description << XCHILD("rtcp-mux");
-
- //fingerprint
- char hash[100];
- if (sscanf(gst_sdp_media_get_attribute_val(media_audio, "fingerprint"), "sha-256 %95s", hash) == 1) {
- auto *transport = content << XCHILDNS("transport", JABBER_FEAT_JINGLE_ICEUDP);
- transport << XATTR("pwd", jproto->m_voipICEPwd) << XATTR("ufrag", jproto->m_voipICEUfrag);
-
- auto *fingerprint = transport << XCHILD("fingerprint", hash);
- fingerprint << XATTR("xmlns", JABBER_FEAT_JINGLE_DTLS) << XATTR("hash", "sha-256")
- << XATTR("setup", gst_sdp_media_get_attribute_val(media_audio, "setup"));
- }
-
- jproto->m_ThreadInfo->send(iq);
-
- gst_webrtc_session_description_free(offer);
-}
-
-void on_negotiation_needed_cb(GstElement *webrtcbin, gpointer user_data)
-{
- if (((CJabberProto *)user_data)->m_isOutgoing) {
- gst_print("Creating negotiation offer\n");
-
- GstPromise *promise = gst_promise_new_with_change_func(on_offer_created_cb, user_data, NULL);
- g_signal_emit_by_name(G_OBJECT(webrtcbin), "create-offer", NULL, promise);
- }
-}
-
-static void on_offer_set(GstPromise *promise, gpointer user_data)
-{
- gst_promise_unref(promise);
- promise = gst_promise_new_with_change_func(on_offer_created_cb, user_data, NULL);
- g_signal_emit_by_name(((CJabberProto *)user_data)->m_webrtc1, "create-answer", NULL, promise);
-}
-
-void send_ice_candidate_message_cb(G_GNUC_UNUSED GstElement */*webrtcbin*/, guint mline_index, gchar *candidate, CJabberProto *jproto)
-{
- // parse candidate and send
- char foundation[11], component[11], protocol[4], priority[11], ip[40], port[6], type[6];
- int ret = sscanf(candidate, "candidate:%10s %10s %3s %10s %39s %5s typ %5s",
- foundation, component, protocol, priority, ip, port, type);
- if (ret != 7 || strcmp(protocol, "UDP"))
- return;
-
- gst_print("VOIP - Wanna send ice candidate(m-line_index=%d):\r\n%s\r\n", mline_index, candidate);
- for (char *p = protocol; *p; ++p) *p = tolower(*p);
-
- XmlNodeIq iq("set", jproto->SerialNext(), jproto->m_voipPeerJid);
- TiXmlElement *rjNode = iq << XCHILDNS("jingle", JABBER_FEAT_JINGLE);
- rjNode << XATTR("action", "transport-info") << XATTR("sid", jproto->m_voipSession);
-
- TiXmlElement *content = rjNode << XCHILD("content");
- content << XATTR("creator", "initiator") << XATTR("name", jproto->m_medianame);
-
- auto *transport = content << XCHILDNS("transport", JABBER_FEAT_JINGLE_ICEUDP);
- transport << XATTR("pwd", jproto->m_voipICEPwd) << XATTR("ufrag", jproto->m_voipICEUfrag);
-
- auto *candidateNode = transport << XCHILD("candidate");
- candidateNode << XATTR("type", type) << XATTR("protocol", protocol) << XATTR("ip", ip)
- << XATTR("port", port) << XATTR("priority", priority) << XATTR("foundation", foundation) << XATTR("component", component);
-
- char attr[255];
- if (GetCandidateProp(attr, 255, candidate, "raddr"))
- candidateNode << XATTR("rel-addr", attr);
- if (GetCandidateProp(attr, 255, candidate, "rport"))
- candidateNode << XATTR("rel-port", attr);
-
- jproto->m_ThreadInfo->send(iq);
-}
-
-static gboolean check_plugins(void)
-{
- const gchar *needed[] = { "opus", "nice", "webrtc", "dtls", "srtp", "rtpmanager"
- /*"vpx", "videotestsrc", "audiotestsrc",*/ };
-
- GstRegistry *registry = gst_registry_get();
- gboolean ret = TRUE;
- for (auto &it : needed) {
- GstPlugin *plugin = gst_registry_find_plugin(registry, it);
- if (!plugin) {
- gst_print("Required gstreamer plugin '%s' not found\n", it);
- ret = FALSE;
- }
- else gst_object_unref(plugin);
- }
-
- return ret;
-}
-
-void dbgprint(const gchar *string)
-{
- OutputDebugStringA(string);
-}
-
-bool CJabberProto::VOIPCreatePipeline(void)
-{
- if (!hasJingle())
- goto err;
-
- //gstreamer init
- static bool gstinited = 0;
- if (!gstinited) {
- if (!LoadLibrary(L"gstreamer-1.0-0.dll")) {
- MessageBoxA(0, "Cannot load Gstreamer library!", 0, MB_OK | MB_ICONERROR);
- goto err;
- }
- gst_init(NULL, NULL);
- g_set_print_handler(dbgprint);
- gst_print("preved medved");
- if (!check_plugins()) {
- MessageBoxA(0, "Gstreamer plugins not found!", 0, MB_OK | MB_ICONERROR);
- goto err;
- }
- gstinited = 1;
- }
-
- #define STUN_SERVER "stun-server=stun://stun.tng.de:3478 "
- #define RTP_CAPS_OPUS "application/x-rtp,media=audio,encoding-name=OPUS,payload="
- #define RTP_TWCC_URI "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"
-
- GError *error = NULL;
- m_pipe1 = gst_parse_launch(
- "webrtcbin bundle-policy=max-bundle name=sendrecv "
- STUN_SERVER
- "autoaudiosrc ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay name=audiopay ! "
- "queue ! " RTP_CAPS_OPUS "111 ! sendrecv. ", &error);
-
- if (error) {
- MessageBoxA(0, "Failed to parse launch: ", error->message, MB_OK);
- g_error_free(error);
- goto err;
- }
-
- m_webrtc1 = gst_bin_get_by_name(GST_BIN(m_pipe1), "sendrecv");
- g_assert_nonnull(m_webrtc1);
- if (!m_webrtc1)
- goto err;
-
- GstElement *audiopay = gst_bin_get_by_name(GST_BIN(m_pipe1), "audiopay");
- g_assert_nonnull(audiopay);
- GstRTPHeaderExtension *audio_twcc = gst_rtp_header_extension_create_from_uri(RTP_TWCC_URI);
- g_assert_nonnull(audio_twcc);
- gst_rtp_header_extension_set_id(audio_twcc, 1);
- g_signal_emit_by_name(audiopay, "add-extension", audio_twcc);
- g_clear_object(&audio_twcc);
- g_clear_object(&audiopay);
-
- // It will be called when the pipeline goes to PLAYING.
- g_signal_connect(m_webrtc1, "on-negotiation-needed", G_CALLBACK(on_negotiation_needed_cb), this);
- // It will be called when we obtain local ICE candidate
- g_signal_connect(m_webrtc1, "on-ice-candidate", G_CALLBACK(send_ice_candidate_message_cb), this);
- // idk
- g_signal_connect(m_webrtc1, "pad-added", G_CALLBACK(on_incoming_stream_cb), m_pipe1);
-
- // Lifetime is the same as the pipeline itself
- gst_object_unref(m_webrtc1);
-
- gst_print("Starting pipeline\n");
- if (gst_element_set_state(GST_ELEMENT(m_pipe1), GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE)
- return true;
-
-err:
- VOIPTerminateSession();
- return false;
-}
-
-bool CJabberProto::VOIPTerminateSession(const char *reason)
-{
- if (m_pipe1) {
- gst_element_set_state(GST_ELEMENT(m_pipe1), GST_STATE_NULL);
- g_clear_object(&m_pipe1);
- gst_object_unref(m_pipe1);
- gst_print("Pipeline stopped\n");
- }
-
- if (m_ThreadInfo && reason && !m_voipSession.IsEmpty() && !m_voipPeerJid.IsEmpty()) {
- XmlNodeIq iq("set", SerialNext(), m_voipPeerJid);
-
- TiXmlElement *jingleNode = iq << XCHILDNS("jingle", JABBER_FEAT_JINGLE);
- jingleNode << XATTR("action", "session-terminate") << XATTR("sid", m_voipSession);
- jingleNode << XATTR("initiator", m_isOutgoing ? m_ThreadInfo->fullJID : m_voipPeerJid);
- jingleNode << XCHILD("reason") << XCHILD(reason);
-
- m_ThreadInfo->send(iq);
- }
-
- m_voipICEPwd.Empty();
- m_voipICEUfrag.Empty();
- m_medianame.Empty();
-
- m_voipSession.Empty();
- m_voipPeerJid.Empty();
- m_pipe1 = m_webrtc1 = NULL;
- return true;
-}
-
-bool CJabberProto::OnRTPDescription(const TiXmlElement *jingleNode)
-{
- if (!jingleNode)
- return false;
-
- // process remote offer
- auto *content = XmlGetChildByTag(jingleNode, "content", "creator", "initiator");
- auto *transport = XmlGetChildByTag(content, "transport", "xmlns", "urn:xmpp:jingle:transports:ice-udp:1");
- auto *description = XmlGetChildByTag(content, "description", "xmlns", "urn:xmpp:jingle:apps:rtp:1");
- auto *source = XmlGetChildByTag(description, "source", "xmlns", "urn:xmpp:jingle:apps:rtp:ssma:0");
-
- CMStringA sdp_string(FORMAT, "v=0\r\no=- 0 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=ice-options:trickle\r\n"
- "m=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:%s\r\na=ice-pwd:%s\r\na=rtcp-mux\r\na=sendrecv\r\na=rtpmap:111 OPUS/48000/2\r\n"
-
- "a=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\n"
- "a=ssrc:%s msid:%s\r\n"
- "a=ssrc:%s cname:%s\r\n"
-
- "a=mid:%s\r\na=setup:%s\r\na=fingerprint:sha-256 %s\r\na=rtcp-mux-only\r\n",
- XmlGetAttr(transport, "ufrag"),
- XmlGetAttr(transport, "pwd"),
-
- XmlGetAttr(source, "ssrc"),
- XmlGetAttr(XmlGetChildByTag(source, "parameter", "name", "msid"), "value"),
- XmlGetAttr(source, "ssrc"),
- XmlGetAttr(XmlGetChildByTag(source, "parameter", "name", "cname"), "value"),
-
- XmlGetAttr(content, "name"),
- XmlGetAttr(XmlFirstChild(transport, "fingerprint"), "setup"),
- XmlFirstChild(transport, "fingerprint")->GetText());
-
- GstSDPMessage *sdp;
- int ret = gst_sdp_message_new(&sdp);
- g_assert_cmphex(ret, == , GST_SDP_OK);
- ret = gst_sdp_message_parse_buffer((guint8 *)sdp_string.c_str(), sdp_string.GetLength(), sdp);
- if (ret != GST_SDP_OK) {
- g_error("Could not parse SDP string\n");
- return false;
- }
-
- gchar *str = gst_sdp_message_as_text(sdp);
- gst_print("VOIP - Eating remote SDP offer:\r\n%s\r\n", str);
- g_free(str);
-
- if (m_isOutgoing) {
- GstWebRTCSessionDescription *answer = gst_webrtc_session_description_new(GST_WEBRTC_SDP_TYPE_ANSWER, sdp);
- g_assert_nonnull(answer);
-
- GstPromise *promise = gst_promise_new();
- g_signal_emit_by_name(m_webrtc1, "set-remote-description", answer, promise);
- gst_promise_interrupt(promise);
- gst_promise_unref(promise);
- gst_webrtc_session_description_free(answer);
- }
- else {
- // Set remote description on our pipeline
- GstWebRTCSessionDescription *offer = gst_webrtc_session_description_new(GST_WEBRTC_SDP_TYPE_OFFER, sdp);
- g_assert_nonnull(offer);
-
- GstPromise *promise = gst_promise_new_with_change_func(on_offer_set, this, NULL);
- g_signal_emit_by_name(m_webrtc1, "set-remote-description", offer, promise);
- gst_webrtc_session_description_free(offer);
- }
-
- return true;
-}
-
-bool CJabberProto::OnICECandidate(const TiXmlElement *Node)
-{
- if (!hasJingle())
- return false;
-
- CMStringA scandidate;
- CMStringA proto(XmlGetAttr(Node, "protocol"));
- proto.MakeUpper();
-
- scandidate.AppendFormat("candidate:%s ", XmlGetAttr(Node, "foundation")); //FIXME
- scandidate.AppendFormat("%s ", XmlGetAttr(Node, "component"));
- scandidate.AppendFormat("%s ", proto.c_str());
- scandidate.AppendFormat("%s ", XmlGetAttr(Node, "priority"));
- scandidate.AppendFormat("%s ", XmlGetAttr(Node, "ip"));
- scandidate.AppendFormat("%s ", XmlGetAttr(Node, "port"));
- scandidate.AppendFormat("typ %s", XmlGetAttr(Node, "type"));
-
- if (const char *tmp = XmlGetAttr(Node, "rel-addr"))
- scandidate.AppendFormat(" raddr %s", tmp);
- if (const char *tmp = XmlGetAttr(Node, "rel-port"))
- scandidate.AppendFormat(" rport %s", tmp);
- if (const char *generation = XmlGetAttr(Node, "generation"))
- scandidate.AppendFormat(" generation %s", generation);
-
- gst_print("VOIP - Accepting ICE candidate:\r\n%s\r\n", scandidate.c_str());
- g_signal_emit_by_name(m_webrtc1, "add-ice-candidate", 0, scandidate.c_str());
- return true;
-}
-
-bool CJabberProto::VOIPCallIinitiate(MCONTACT hContact)
-{
- if (!m_voipSession.IsEmpty()) {
- VOIPTerminateSession();
- MessageBoxA(0, "Something went wrong\r\nOld session terminated", NULL, 0);
- return false;
- }
-
- if (!hasJingle())
- return false;
-
- CMStringA jid(getMStringA(hContact, "jid"));
- if (jid.IsEmpty())
- return false;
-
- auto r = ListGetBestResource(jid);
- if (r) {
- bool bFound = false;
- if (auto *pFeature = FindFeature(JABBER_FEAT_JINGLE))
- if (!(r->m_pCaps->GetCaps() & pFeature->jcbCap))
- bFound = true;
-
- if (!bFound) {
- MsgPopup(hContact, TranslateT("Client's program does not support voice calls"), TranslateT("Error"));
- return false;
- }
-
- jid = MakeJid(jid, r->m_szResourceName);
- }
-
- unsigned char tmp[16];
- Utils_GetRandom(tmp, sizeof(tmp));
-
- m_isOutgoing = true;
- m_voipSession = ptrA(mir_base64_encode(tmp, sizeof(tmp)));
- m_voipPeerJid = jid.c_str();
-
- return true;
-}
-
-INT_PTR CJabberProto::JabberVOIP_call(WPARAM hContact, LPARAM)
-{
- if (VOIPCallIinitiate(hContact)) {
- VOICE_CALL vc = {};
- vc.cbSize = sizeof(VOICE_CALL);
- vc.moduleName = m_szModuleName;
- vc.id = m_voipSession; // Protocol especific ID for this call
- vc.hContact = hContact; // Contact associated with the call (can be NULL)
- vc.state = VOICE_STATE_READY;
- vc.szNumber.a = m_voipPeerJid;
- NotifyEventHooks(m_hVoiceEvent, WPARAM(&vc), 0);
- }
-
- return 0;
-}
-
-INT_PTR CJabberProto::JabberVOIP_answercall(WPARAM id, LPARAM)
-{
- if(strcmp((const char *)id, m_voipSession))
- return 0;
-
-/* CMStringA question(FORMAT, "Proceed call with %s?\r\n"
- "It will disclose IP address to the peer and his server", m_voipPeerJid.c_str());
- if (MessageBoxA(0, question.c_str(), "Outgoing call", MB_YESNO | MB_ICONQUESTION) != IDYES)
- return 0;*/
-
- VOICE_CALL vc = {};
- vc.cbSize = sizeof(VOICE_CALL);
- vc.moduleName = m_szModuleName;
- vc.hContact = HContactFromJID(m_voipPeerJid);// Contact associated with the call (can be NULL)
- vc.szNumber.a = m_voipPeerJid;
- vc.id = m_voipSession;
- vc.state = VOICE_STATE_ENDED;
-
- if (VOIPCreatePipeline()) {
- if (m_isOutgoing)
- vc.state = VOICE_STATE_CALLING;
- else if (OnRTPDescription(m_offerNode))
- vc.state = VOICE_STATE_TALKING;
- else
- VOIPTerminateSession();
- }
- NotifyEventHooks(m_hVoiceEvent, WPARAM(&vc), 0);
-
- return 0;
-}
-
-INT_PTR CJabberProto::JabberVOIP_dropcall(WPARAM id, LPARAM)
-{
- VOICE_CALL vc = {};
- vc.cbSize = sizeof(VOICE_CALL);
- vc.moduleName = m_szModuleName;
- vc.id = (char*)id;
- vc.state = VOICE_STATE_ENDED;
- NotifyEventHooks(m_hVoiceEvent, WPARAM(&vc), 0);
-
- VOIPTerminateSession();
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// module entry point
-
-void CJabberProto::InitVoip(bool bEnable)
-{
- // Voip
- VOICE_MODULE vsr = {};
- vsr.cbSize = sizeof(VOICE_MODULE);
- vsr.description = L"XMPP/DTLS-SRTP";
- vsr.name = m_szModuleName;
- vsr.icon = g_plugin.getIconHandle(IDI_NOTES);
- vsr.flags = 3;
- if (bEnable)
- CallService(MS_VOICESERVICE_REGISTER, (WPARAM)&vsr, 0);
- else {
- VOIPTerminateSession();
- CallService(MS_VOICESERVICE_UNREGISTER, (WPARAM)&vsr, 0);
- }
-}
diff --git a/protocols/JabberG/src/jabber_xml.cpp b/protocols/JabberG/src/jabber_xml.cpp
index c3a166017a..00e80eeeaa 100644
--- a/protocols/JabberG/src/jabber_xml.cpp
+++ b/protocols/JabberG/src/jabber_xml.cpp
@@ -69,6 +69,7 @@ CMStringA XmlNodeHash::getResult()
/////////////////////////////////////////////////////////////////////////////////////////
// XmlNodeIq class members
+#ifdef _JABBER_H_
XmlNodeIq::XmlNodeIq(const char *type, int id, const char *to) :
XmlNode("iq")
{
@@ -79,6 +80,7 @@ XmlNodeIq::XmlNodeIq(const char *type, int id, const char *to) :
if (id != -1)
XmlAddAttrID(*this, id);
}
+#endif
XmlNodeIq::XmlNodeIq(const char *type, const char *idStr, const char *to) :
XmlNode("iq")
@@ -105,6 +107,7 @@ XmlNodeIq::XmlNodeIq(const char *type, TiXmlElement *node, const char *to) :
}
}
+#ifdef _JABBER_H_
XmlNodeIq::XmlNodeIq(CJabberIqInfo *pInfo) :
XmlNode("iq")
{
@@ -131,6 +134,7 @@ XmlNodeIq::XmlNodeIq(const char *type, CJabberIqInfo *pInfo) :
m_hXml->SetAttribute("id", pInfo->GetIdStr());
}
}
+#endif
/////////////////////////////////////////////////////////////////////////////////////////
// XmlNode class members
@@ -165,7 +169,9 @@ TiXmlElement* __fastcall operator<<(TiXmlElement *node, const XQUERY &child)
/////////////////////////////////////////////////////////////////////////////////////////
+#ifdef _JABBER_H_
void XmlAddAttrID(TiXmlElement *hXml, int id)
{
hXml->SetAttribute("id", ptrA(JabberId2string(id)).get());
}
+#endif
diff --git a/protocols/JabberG/src/stdafx.h b/protocols/JabberG/src/stdafx.h
index 82b719af32..a96311c6f0 100644
--- a/protocols/JabberG/src/stdafx.h
+++ b/protocols/JabberG/src/stdafx.h
@@ -389,8 +389,8 @@ struct ThreadData
void shutdown(void);
int recv(char* buf, size_t len);
int send(char* buffer, int bufsize = -1);
- int send(TiXmlElement *node);
- int send_no_strm_mgmt(TiXmlElement *node);
+ int send(const TiXmlElement *node);
+ int send_no_strm_mgmt(const TiXmlElement *node);
private:
bool bShutdown;