diff options
21 files changed, 352 insertions, 324 deletions
diff --git a/include/m_jabber.h b/include/m_jabber.h index 758dd6bc6c..72a16801bf 100644 --- a/include/m_jabber.h +++ b/include/m_jabber.h @@ -116,8 +116,11 @@ struct IJabberInterface // Returns Jabber module name. DO NOT free the returned string.
virtual char* STDMETHODCALLTYPE GetModuleName() const = 0;
+ // Returns our full JID.
+ virtual char* STDMETHODCALLTYPE GetFullJid() const = 0;
+
// Returns id that can be used for next message sent through SendXmlNode().
- virtual int STDMETHODCALLTYPE SerialNext() = 0;
+ virtual char* STDMETHODCALLTYPE GetSerialNext() = 0;
// Registers incoming <presence/> handler. Returns handler handle on success or NULL on error.
@@ -149,8 +152,8 @@ struct IJabberInterface // Returns features supported by JID in format "feature1\0feature2\0...\0featureN\0\0" (a list of features separated by \0 character and terminated with two \0 characters), or NULL on error. JID may contain resource name to get features of a specific resource. If there's no resource name, GetResourceFeatures() returns features for the same resource as IJabberSysInterface::GetBestResourceName() returns. If a feature you're checking for is not supported by Jabber plugin natively, you must register it with RegisterFeature(), otherwise GetContactFeatures() won't be able to return it. You must free returned string using mir_free().
virtual char* STDMETHODCALLTYPE GetResourceFeatures(LPCSTR jid) = 0;
- // Returns the connection handle
- virtual HNETLIBUSER STDMETHODCALLTYPE GetHandle(void) = 0;
+ // Sends a stanza
+ virtual void STDMETHODCALLTYPE SendXml(const TiXmlElement *pXml) = 0;
};
/*
diff --git a/plugins/Jingle/Jingle.vcxproj b/plugins/Jingle/Jingle.vcxproj index 0f061b8cfe..4e625da708 100644 --- a/plugins/Jingle/Jingle.vcxproj +++ b/plugins/Jingle/Jingle.vcxproj @@ -31,11 +31,13 @@ </ClCompile> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\..\protocols\JabberG\src\jabber_xml.cpp" /> <ClCompile Include="src\account.cpp" /> <ClCompile Include="src\main.cpp" /> <ClCompile Include="src\stdafx.cxx"> <PrecompiledHeader>Create</PrecompiledHeader> </ClCompile> + <ClCompile Include="src\voip.cpp" /> <ClInclude Include="..\ExternalAPI\m_jingle.h" /> <ClInclude Include="src\account.h" /> <ClInclude Include="src\stdafx.h" /> diff --git a/plugins/Jingle/Jingle.vcxproj.filters b/plugins/Jingle/Jingle.vcxproj.filters index 947797218d..edcb62535d 100644 --- a/plugins/Jingle/Jingle.vcxproj.filters +++ b/plugins/Jingle/Jingle.vcxproj.filters @@ -11,6 +11,12 @@ <ClCompile Include="src\account.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="src\voip.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\protocols\JabberG\src\jabber_xml.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="src\stdafx.h"> diff --git a/plugins/Jingle/src/account.cpp b/plugins/Jingle/src/account.cpp index 551f59db00..a6e68b76ec 100644 --- a/plugins/Jingle/src/account.cpp +++ b/plugins/Jingle/src/account.cpp @@ -42,13 +42,250 @@ static int OnAccountCreated(WPARAM reason, LPARAM param) return 0; } +static int OnSettingChanged(WPARAM hContact, LPARAM lParam) +{ + if (!hContact) { + auto *pcws = (DBCONTACTWRITESETTING *)lParam; + if (!mir_strcmp(pcws->szSetting, "EnableVOIP")) { + for (auto &it : g_arJabber) { + if (!mir_strcmp(it->m_szModuleName, pcws->szModule)) { + it->InitVoip(pcws->value.bVal != 0); + break; + } + } + } + } + + return 0; +} + void CJabberAccount::InitHooks() { HookEvent(ME_SYSTEM_MODULESLOADED, &OnModulesLoaded); HookEvent(ME_PROTO_ACCLISTCHANGED, &OnAccountCreated); + HookEvent(ME_DB_CONTACT_SETTINGCHANGED, &OnSettingChanged); } /////////////////////////////////////////////////////////////////////////////// +// Permanent IQ handler + +static BOOL OnProcessJingle(struct IJabberInterface *api, const TiXmlElement *node, void *pUserData) +{ + auto *pThis = (CJabberAccount *)pUserData; + + 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" + api->SendXml(XmlNodeIq("result", idStr, from)); + + const TiXmlElement *descr = XmlGetChildByTag(content, "description", "xmlns", JABBER_FEAT_JINGLE_RTP); + const char *reason = NULL; + if (pThis->m_bEnableVOIP && descr) { + if (pThis->m_voipSession.IsEmpty()) { + pThis->m_voipSession = szSid; + pThis->m_voipPeerJid = from; + pThis->m_isOutgoing = false; + pThis->m_offerNode = child->DeepClone(&pThis->m_offerDoc)->ToElement(); + + //Make call GUI + VOICE_CALL vc = {}; + vc.cbSize = sizeof(VOICE_CALL); + vc.moduleName = pThis->m_szModuleName; + vc.id = szSid; // Protocol specific ID for this call + vc.hContact = api->ContactFromJID(from); // Contact associated with the call (can be NULL) + vc.state = VOICE_STATE_RINGING; + vc.szNumber.a = pThis->m_voipPeerJid; + NotifyEventHooks(pThis->m_hVoiceEvent, WPARAM(&vc), 0); + + // ringing message + XmlNodeIq iq("set", api->GetSerialNext(), 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"); + + api->SendXml(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(api->ContactFromJID(from), &recv); + reason = "busy"; + } + + XmlNodeIq iq("set", api->GetSerialNext(), 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"); + + api->SendXml(iq); + return true; + } + else if (!mir_strcmp(szAction, "session-accept")) { + if (pThis->m_bEnableVOIP && pThis->m_voipSession == szSid) { + api->SendXml(XmlNodeIq("result", idStr, from)); + if (pThis->OnRTPDescription(child)) { + //Make call GUI + VOICE_CALL vc = {}; + vc.cbSize = sizeof(VOICE_CALL); + vc.moduleName = pThis->m_szModuleName; + vc.id = szSid; + vc.hContact = api->ContactFromJID(from); + vc.state = VOICE_STATE_TALKING; + NotifyEventHooks(pThis->m_hVoiceEvent, WPARAM(&vc), 0); + } + return true; + } + } + else if (!mir_strcmp(szAction, "session-terminate")) { + if (pThis->m_bEnableVOIP && pThis->m_voipSession == szSid) { + // EndCall() + api->SendXml(XmlNodeIq("result", idStr, from)); + + VOICE_CALL vc = {}; + vc.cbSize = sizeof(VOICE_CALL); + vc.moduleName = pThis->m_szModuleName; + vc.id = szSid; + vc.hContact = api->ContactFromJID(from); + vc.state = VOICE_STATE_ENDED; + NotifyEventHooks(pThis->m_hVoiceEvent, WPARAM(&vc), 0); + + pThis->VOIPTerminateSession(nullptr); + return true; + } + } + else if (!mir_strcmp(szAction, "transport-info")) { + auto *transport = XmlGetChildByTag(content, "transport", "xmlns", JABBER_FEAT_JINGLE_ICEUDP); + if (pThis->m_bEnableVOIP && pThis->m_voipSession == szSid && transport) { + api->SendXml(XmlNodeIq("result", idStr, from)); + if (const TiXmlElement *candidate = XmlFirstChild(transport, "candidate")) { + pThis->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"); + api->SendXml(iq); + return true; + } + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// Services + +static INT_PTR __cdecl JabberVOIP_call(void *pThis, WPARAM hContact, LPARAM) +{ + auto *pAcc = (CJabberAccount *)pThis; + if (pAcc->VOIPCallIinitiate(hContact)) { + VOICE_CALL vc = {}; + vc.cbSize = sizeof(VOICE_CALL); + vc.moduleName = pAcc->m_szModuleName; + vc.id = pAcc->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 = pAcc->m_voipPeerJid; + NotifyEventHooks(pAcc->m_hVoiceEvent, WPARAM(&vc), 0); + } + + return 0; +} + +static INT_PTR __cdecl JabberVOIP_answercall(void *pThis, WPARAM id, LPARAM) +{ + auto *pAcc = (CJabberAccount *)pThis; + if (strcmp((const char *)id, pAcc->m_voipSession)) + return 0; + + VOICE_CALL vc = {}; + vc.cbSize = sizeof(VOICE_CALL); + vc.moduleName = pAcc->m_szModuleName; + vc.hContact = pAcc->m_api->ContactFromJID(pAcc->m_voipPeerJid);// Contact associated with the call (can be NULL) + vc.szNumber.a = pAcc->m_voipPeerJid; + vc.id = pAcc->m_voipSession; + vc.state = VOICE_STATE_ENDED; + + if (pAcc->VOIPCreatePipeline()) { + if (pAcc->m_isOutgoing) + vc.state = VOICE_STATE_CALLING; + else if (pAcc->OnRTPDescription(pAcc->m_offerNode)) + vc.state = VOICE_STATE_TALKING; + else + pAcc->VOIPTerminateSession(); + } + + NotifyEventHooks(pAcc->m_hVoiceEvent, WPARAM(&vc), 0); + return 0; +} + +static INT_PTR __cdecl JabberVOIP_dropcall(void *pThis, WPARAM id, LPARAM) +{ + auto *pAcc = (CJabberAccount *)pThis; + + VOICE_CALL vc = {}; + vc.cbSize = sizeof(VOICE_CALL); + vc.moduleName = pAcc->m_szModuleName; + vc.id = (char *)id; + vc.state = VOICE_STATE_ENDED; + NotifyEventHooks(pAcc->m_hVoiceEvent, WPARAM(&vc), 0); + + pAcc->VOIPTerminateSession(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// CJabberAccount members + +CJabberAccount::CJabberAccount(IJabberInterface *_1) : + m_api(_1), + m_szModuleName(m_api->GetModuleName()), + m_bEnableVOIP(m_szModuleName, "EnableVOIP", false) +{ + CMStringA tmp(m_szModuleName); + m_hVoiceEvent = CreateHookableEvent(tmp + PE_VOICE_CALL_STATE); + CreateServiceFunctionObj(tmp + PS_VOICE_CALL, &JabberVOIP_call, this); + CreateServiceFunctionObj(tmp + PS_VOICE_ANSWERCALL, &JabberVOIP_answercall, this); + CreateServiceFunctionObj(tmp + PS_VOICE_DROPCALL, &JabberVOIP_dropcall, this); +} + +CJabberAccount::~CJabberAccount() +{ + DestroyHookableEvent(m_hVoiceEvent); + + if (m_bEnableVOIP) + InitVoip(false); +} void CJabberAccount::Init() { @@ -59,4 +296,9 @@ void CJabberAccount::Init() m_api->RegisterFeature(JABBER_FEAT_JINGLE_RTPAUDIO, LPGEN("Jingle RTP Audio")); m_api->AddFeatures(JABBER_FEAT_JINGLE "\0" JABBER_FEAT_JINGLE_ICEUDP "\0" JABBER_FEAT_JINGLE_RTP "\0" JABBER_FEAT_JINGLE_DTLS "\0" JABBER_FEAT_JINGLE_RTPAUDIO "\0\0"); + + m_api->AddIqHandler(&OnProcessJingle, JABBER_IQ_TYPE_ANY, JABBER_FEAT_JINGLE, 0, this); + + if (m_bEnableVOIP) + InitVoip(true); } diff --git a/plugins/Jingle/src/account.h b/plugins/Jingle/src/account.h index 8302f8e3f2..ae974b9363 100644 --- a/plugins/Jingle/src/account.h +++ b/plugins/Jingle/src/account.h @@ -1,16 +1,34 @@ #ifndef _ACCOUNT_H #define _ACCOUNT_H -struct CJabberAccount +struct CJabberAccount : public MZeroedObject { - CJabberAccount(IJabberInterface *_1) : - m_api(_1) - {} + CJabberAccount(IJabberInterface *_1); + ~CJabberAccount(); IJabberInterface *m_api; + CMOption<bool> m_bEnableVOIP; + void Init(); static void InitHooks(); + + 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); + + const char *m_szModuleName; + CMStringA m_voipSession, m_voipPeerJid; + CMStringA m_voipICEPwd, m_voipICEUfrag, m_medianame; + bool m_isOutgoing = false; + TiXmlDocument m_offerDoc; + const TiXmlElement *m_offerNode = 0; + HANDLE m_hVoiceEvent = 0; + struct _GstElement *m_pipe1 = 0; + struct _GstElement *m_webrtc1 = 0; }; extern OBJLIST<CJabberAccount> g_arJabber; diff --git a/plugins/Jingle/src/main.cpp b/plugins/Jingle/src/main.cpp index 016244ad29..bef4e15717 100644 --- a/plugins/Jingle/src/main.cpp +++ b/plugins/Jingle/src/main.cpp @@ -27,23 +27,10 @@ CMPlugin::CMPlugin() : ///////////////////////////////////////////////////////////////////////////////////////// // Load -static INT_PTR FakeService(WPARAM, LPARAM) -{ - g_assertion_message(0, 0, 0, 0, 0); - g_object_unref(0); - gst_bin_add(0, 0); - gst_rtp_header_extension_set_id(0, 0); - gst_sdp_message_as_text(0); - gst_webrtc_session_description_free(0); - return 0; -} - int CMPlugin::Load() { SetEnvironmentVariableW(L"GST_PLUGIN_PATH", VARSW(L"%miranda_path%\\Libs\\gst_plugins")); - CreateServiceFunction("JINGLE/SERVICE", &FakeService); - CJabberAccount::InitHooks(); return 0; } diff --git a/plugins/Jingle/src/stdafx.h b/plugins/Jingle/src/stdafx.h index ff0b86c4b9..4c7a794c1a 100644 --- a/plugins/Jingle/src/stdafx.h +++ b/plugins/Jingle/src/stdafx.h @@ -26,6 +26,8 @@ #include <m_voice.h> #include <m_voiceservice.h> +#include "../../protocols/JabberG/src/jabber_xml.h" + #include "account.h" #include "resource.h" #include "version.h" diff --git a/protocols/JabberG/src/jabber_voip.cpp b/plugins/Jingle/src/voip.cpp index 9c8cb589d9..bd5e541499 100644 --- a/protocols/JabberG/src/jabber_voip.cpp +++ b/plugins/Jingle/src/voip.cpp @@ -9,15 +9,6 @@ #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); @@ -120,7 +111,7 @@ static void on_incoming_stream_cb(GstElement */*webrtc*/, GstPad *pad, GstElemen void on_offer_created_cb(GstPromise *promise, gpointer user_data) { GstWebRTCSessionDescription *offer = NULL; - CJabberProto *jproto = (CJabberProto *)user_data; + CJabberAccount *jproto = (CJabberAccount *)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); @@ -154,15 +145,15 @@ void on_offer_created_cb(GstPromise *promise, gpointer user_data) 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 + // send it all bool outgoing = jproto->m_isOutgoing; - XmlNodeIq iq("set", jproto->SerialNext(), jproto->m_voipPeerJid); + XmlNodeIq iq("set", jproto->m_api->GetSerialNext(), 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); + << XATTR("initiator", outgoing ? jproto->m_api->GetFullJid() : jproto->m_voipPeerJid); if (!outgoing) - rjNode << XATTR("responder", jproto->m_ThreadInfo->fullJID); + rjNode << XATTR("responder", jproto->m_api->GetFullJid()); 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"); @@ -194,14 +185,14 @@ void on_offer_created_cb(GstPromise *promise, gpointer user_data) << XATTR("setup", gst_sdp_media_get_attribute_val(media_audio, "setup")); } - jproto->m_ThreadInfo->send(iq); + jproto->m_api->SendXml(iq); gst_webrtc_session_description_free(offer); } void on_negotiation_needed_cb(GstElement *webrtcbin, gpointer user_data) { - if (((CJabberProto *)user_data)->m_isOutgoing) { + if (((CJabberAccount *)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); @@ -213,13 +204,13 @@ 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); + g_signal_emit_by_name(((CJabberAccount *)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) +void send_ice_candidate_message_cb(G_GNUC_UNUSED GstElement */*webrtcbin*/, guint mline_index, gchar *candidate, CJabberAccount *jproto) { // parse candidate and send - char foundation[11], component[11], protocol[4], priority[11], ip[40], port[6], type[6]; + 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")) @@ -228,7 +219,7 @@ void send_ice_candidate_message_cb(G_GNUC_UNUSED GstElement */*webrtcbin*/, guin 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); + XmlNodeIq iq("set", jproto->m_api->GetSerialNext(), jproto->m_voipPeerJid); TiXmlElement *rjNode = iq << XCHILDNS("jingle", JABBER_FEAT_JINGLE); rjNode << XATTR("action", "transport-info") << XATTR("sid", jproto->m_voipSession); @@ -248,13 +239,13 @@ void send_ice_candidate_message_cb(G_GNUC_UNUSED GstElement */*webrtcbin*/, guin if (GetCandidateProp(attr, 255, candidate, "rport")) candidateNode << XATTR("rel-port", attr); - jproto->m_ThreadInfo->send(iq); + jproto->m_api->SendXml(iq); } static gboolean check_plugins(void) { const gchar *needed[] = { "opus", "nice", "webrtc", "dtls", "srtp", "rtpmanager" - /*"vpx", "videotestsrc", "audiotestsrc",*/ }; + /*"vpx", "videotestsrc", "audiotestsrc",*/ }; GstRegistry *registry = gst_registry_get(); gboolean ret = TRUE; @@ -275,9 +266,9 @@ void dbgprint(const gchar *string) OutputDebugStringA(string); } -bool CJabberProto::VOIPCreatePipeline(void) +bool CJabberAccount::VOIPCreatePipeline(void) { - if (!hasJingle()) + if (!m_bEnableVOIP) goto err; //gstreamer init @@ -347,7 +338,7 @@ err: return false; } -bool CJabberProto::VOIPTerminateSession(const char *reason) +bool CJabberAccount::VOIPTerminateSession(const char *reason) { if (m_pipe1) { gst_element_set_state(GST_ELEMENT(m_pipe1), GST_STATE_NULL); @@ -356,15 +347,15 @@ bool CJabberProto::VOIPTerminateSession(const char *reason) gst_print("Pipeline stopped\n"); } - if (m_ThreadInfo && reason && !m_voipSession.IsEmpty() && !m_voipPeerJid.IsEmpty()) { - XmlNodeIq iq("set", SerialNext(), m_voipPeerJid); + if (reason && !m_voipSession.IsEmpty() && !m_voipPeerJid.IsEmpty()) { + XmlNodeIq iq("set", m_api->GetSerialNext(), 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 << XATTR("initiator", m_isOutgoing ? m_api->GetFullJid() : m_voipPeerJid); jingleNode << XCHILD("reason") << XCHILD(reason); - m_ThreadInfo->send(iq); + m_api->SendXml(iq); } m_voipICEPwd.Empty(); @@ -377,7 +368,7 @@ bool CJabberProto::VOIPTerminateSession(const char *reason) return true; } -bool CJabberProto::OnRTPDescription(const TiXmlElement *jingleNode) +bool CJabberAccount::OnRTPDescription(const TiXmlElement *jingleNode) { if (!jingleNode) return false; @@ -444,9 +435,9 @@ bool CJabberProto::OnRTPDescription(const TiXmlElement *jingleNode) return true; } -bool CJabberProto::OnICECandidate(const TiXmlElement *Node) +bool CJabberAccount::OnICECandidate(const TiXmlElement *Node) { - if (!hasJingle()) + if (!m_bEnableVOIP) return false; CMStringA scandidate; @@ -473,7 +464,7 @@ bool CJabberProto::OnICECandidate(const TiXmlElement *Node) return true; } -bool CJabberProto::VOIPCallIinitiate(MCONTACT hContact) +bool CJabberAccount::VOIPCallIinitiate(MCONTACT hContact) { if (!m_voipSession.IsEmpty()) { VOIPTerminateSession(); @@ -481,26 +472,26 @@ bool CJabberProto::VOIPCallIinitiate(MCONTACT hContact) return false; } - if (!hasJingle()) + if (!m_bEnableVOIP) return false; - CMStringA jid(getMStringA(hContact, "jid")); + CMStringA jid(db_get_sm(hContact, m_szModuleName, "jid")); if (jid.IsEmpty()) return false; - - auto r = ListGetBestResource(jid); - if (r) { + + ptrA szResource(m_api->GetBestResourceName(jid)); + if (szResource) { + jid.AppendFormat("/%s", szResource.get()); bool bFound = false; - if (auto *pFeature = FindFeature(JABBER_FEAT_JINGLE)) - if (!(r->m_pCaps->GetCaps() & pFeature->jcbCap)) + ptrA szFeatures(m_api->GetResourceFeatures(jid)); + for (auto *p = szFeatures.get(); *p; p += mir_strlen(p)) + if (!mir_strcmp(p, JABBER_FEAT_JINGLE)) bFound = true; if (!bFound) { - MsgPopup(hContact, TranslateT("Client's program does not support voice calls"), TranslateT("Error")); + // 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]; @@ -513,77 +504,17 @@ bool CJabberProto::VOIPCallIinitiate(MCONTACT hContact) 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) +void CJabberAccount::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.name = (char*)m_szModuleName; + vsr.icon = g_plugin.getIconHandle(IDI_MAIN); vsr.flags = 3; if (bEnable) CallService(MS_VOICESERVICE_REGISTER, (WPARAM)&vsr, 0); 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_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;
|