diff --git a/libdino/src/service/module_manager.vala b/libdino/src/service/module_manager.vala index 9a510662..9f2a05d0 100644 --- a/libdino/src/service/module_manager.vala +++ b/libdino/src/service/module_manager.vala @@ -32,12 +32,13 @@ public class ModuleManager { public ArrayList get_modules(Account account, string? resource = null) { ArrayList modules = new ArrayList(); + + modules.add(new Bind.Module(resource == null ? account.resourcepart : resource)); + modules.add(new PlainSasl.Module(account.bare_jid.to_string(), account.password)); lock (module_map) { if (!module_map.has_key(account)) initialize(account); foreach (Core.XmppStreamModule module in module_map[account]) modules.add(module); } - modules.add(new Bind.Module(resource == null ? account.resourcepart : resource)); - modules.add(new PlainSasl.Module(account.bare_jid.to_string(), account.password)); return modules; } @@ -45,6 +46,7 @@ public class ModuleManager { lock(module_map) { module_map[account] = new ArrayList(); module_map[account].add(new Tls.Module()); + module_map[account].add(new Session.Module()); module_map[account].add(new Roster.Module()); module_map[account].add(new Xep.ServiceDiscovery.Module.with_identity("client", "pc")); module_map[account].add(new Xep.PrivateXmlStorage.Module()); @@ -66,4 +68,4 @@ public class ModuleManager { } } -} \ No newline at end of file +} diff --git a/xmpp-vala/CMakeLists.txt b/xmpp-vala/CMakeLists.txt index 68c4f356..80e665e2 100644 --- a/xmpp-vala/CMakeLists.txt +++ b/xmpp-vala/CMakeLists.txt @@ -28,6 +28,7 @@ SOURCES "src/module/roster/module.vala" "src/module/roster/versioning_module.vala" "src/module/sasl.vala" + "src/module/session.vala" "src/module/stanza.vala" "src/module/stanza_error.vala" "src/module/stream_error.vala" @@ -81,4 +82,4 @@ set_target_properties(xmpp-vala PROPERTIES VERSION 0.1 SOVERSION 0) install(TARGETS xmpp-vala ${TARGET_INSTALL}) install(FILES ${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi ${CMAKE_BINARY_DIR}/exports/xmpp-vala.deps DESTINATION ${VAPI_INSTALL_DIR}) -install(FILES ${CMAKE_BINARY_DIR}/exports/xmpp-vala.h DESTINATION ${INCLUDE_INSTALL_DIR}) \ No newline at end of file +install(FILES ${CMAKE_BINARY_DIR}/exports/xmpp-vala.h DESTINATION ${INCLUDE_INSTALL_DIR}) diff --git a/xmpp-vala/src/module/bind.vala b/xmpp-vala/src/module/bind.vala index 5a611875..7b08e0f7 100644 --- a/xmpp-vala/src/module/bind.vala +++ b/xmpp-vala/src/module/bind.vala @@ -35,7 +35,7 @@ namespace Xmpp.Bind { StanzaNode bind_node = new StanzaNode.build("bind", NS_URI).add_self_xmlns(); bind_node.put_node(new StanzaNode.build("resource", NS_URI).put_node(new StanzaNode.text(requested_resource))); stream.get_module(Iq.Module.IDENTITY).send_iq(stream, new Iq.Stanza.set(bind_node), (stream, iq) => { - stream.get_module(Bind.Module.IDENTITY).iq_response_stanza(stream, iq); + stream.get_module(Module.IDENTITY).iq_response_stanza(stream, iq); }); stream.add_flag(flag); } @@ -51,7 +51,7 @@ namespace Xmpp.Bind { } public static void require(XmppStream stream) { - if (stream.get_module(IDENTITY) == null) stream.add_module(new Bind.Module("")); + if (stream.get_module(IDENTITY) == null) stream.add_module(new Module("")); } public override bool mandatory_outstanding(XmppStream stream) { diff --git a/xmpp-vala/src/module/session.vala b/xmpp-vala/src/module/session.vala new file mode 100644 index 00000000..f37e585f --- /dev/null +++ b/xmpp-vala/src/module/session.vala @@ -0,0 +1,54 @@ +using Xmpp.Core; + +namespace Xmpp.Session { +private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-session"; + +public class Module : XmppStreamNegotiationModule { + public static ModuleIdentity IDENTITY = new ModuleIdentity(NS_URI, "session"); + + public override void attach(XmppStream stream) { + Bind.Module.require(stream); + stream.get_module(Bind.Module.IDENTITY).bound_to_resource.connect(on_bound_resource); + } + + public override void detach(XmppStream stream) { + stream.get_module(Bind.Module.IDENTITY).bound_to_resource.disconnect(on_bound_resource); + } + + public static void require(XmppStream stream) { + if (stream.get_module(IDENTITY) == null) stream.add_module(new Module()); + } + + /* the client MUST establish a session if it desires to engage in instant messaging and presence functionality (RFC 3921 3) */ + public override bool mandatory_outstanding(XmppStream stream) { + return !stream.has_flag(Flag.IDENTITY) || !stream.get_flag(Flag.IDENTITY).finished; + } + + public override bool negotiation_active(XmppStream stream) { + return stream.has_flag(Flag.IDENTITY) && !stream.get_flag(Flag.IDENTITY).finished; + } + + public override string get_ns() { return NS_URI; } + public override string get_id() { return IDENTITY.id; } + + private void on_bound_resource(XmppStream stream, string my_jid) { + if (stream.features.get_subnode("session", NS_URI) != null) { + stream.add_flag(new Flag()); + Iq.Stanza iq = new Iq.Stanza.set(new StanzaNode.build("session", NS_URI).add_self_xmlns()) { to=stream.remote_name }; + stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => { + if (!iq.is_error()) { + stream.get_flag(Flag.IDENTITY).finished = true; + } + }); + } + } +} + +public class Flag : XmppStreamFlag { + public static FlagIdentity IDENTITY = new FlagIdentity(NS_URI, "session"); + public bool finished = false; + + public override string get_ns() { return NS_URI; } + public override string get_id() { return IDENTITY.id; } +} +}