Factor out the session-terminate handler
This commit is contained in:
parent
642dac9aa0
commit
94794666d7
|
@ -102,16 +102,20 @@ ContentNode get_single_content_node(StanzaNode jingle) throws IqError {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This module can only be attached to one stream at a time.
|
||||||
public class Module : XmppStreamModule, Iq.Handler {
|
public class Module : XmppStreamModule, Iq.Handler {
|
||||||
public static Xmpp.ModuleIdentity<Module> IDENTITY = new Xmpp.ModuleIdentity<Module>(NS_URI, "0166_jingle");
|
public static Xmpp.ModuleIdentity<Module> IDENTITY = new Xmpp.ModuleIdentity<Module>(NS_URI, "0166_jingle");
|
||||||
|
|
||||||
private HashMap<string, ContentType> content_types = new HashMap<string, ContentType>();
|
private HashMap<string, ContentType> content_types = new HashMap<string, ContentType>();
|
||||||
private HashMap<string, Transport> transports = new HashMap<string, Transport>();
|
private HashMap<string, Transport> transports = new HashMap<string, Transport>();
|
||||||
|
|
||||||
|
private XmppStream? current_stream = null;
|
||||||
|
|
||||||
public override void attach(XmppStream stream) {
|
public override void attach(XmppStream stream) {
|
||||||
stream.add_flag(new Flag());
|
stream.add_flag(new Flag());
|
||||||
stream.get_module(ServiceDiscovery.Module.IDENTITY).add_feature(stream, NS_URI);
|
stream.get_module(ServiceDiscovery.Module.IDENTITY).add_feature(stream, NS_URI);
|
||||||
stream.get_module(Iq.Module.IDENTITY).register_for_namespace(NS_URI, this);
|
stream.get_module(Iq.Module.IDENTITY).register_for_namespace(NS_URI, this);
|
||||||
|
current_stream = stream;
|
||||||
}
|
}
|
||||||
public override void detach(XmppStream stream) { }
|
public override void detach(XmppStream stream) { }
|
||||||
|
|
||||||
|
@ -173,7 +177,7 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
throw new Error.GENERAL("Couldn't determine own JID");
|
throw new Error.GENERAL("Couldn't determine own JID");
|
||||||
}
|
}
|
||||||
TransportParameters transport_params = transport.create_transport_parameters(stream, my_jid, receiver_full_jid);
|
TransportParameters transport_params = transport.create_transport_parameters(stream, my_jid, receiver_full_jid);
|
||||||
Session session = new Session.initiate_sent(random_uuid(), type, transport_params, my_jid, receiver_full_jid, content_name, stream);
|
Session session = new Session.initiate_sent(random_uuid(), type, transport_params, my_jid, receiver_full_jid, content_name, send_terminate_and_remove_session);
|
||||||
StanzaNode content = new StanzaNode.build("content", NS_URI)
|
StanzaNode content = new StanzaNode.build("content", NS_URI)
|
||||||
.put_attribute("creator", "initiator")
|
.put_attribute("creator", "initiator")
|
||||||
.put_attribute("name", content_name)
|
.put_attribute("name", content_name)
|
||||||
|
@ -221,20 +225,34 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
ContentParameters content_params = content_type.parse_content_parameters(content.description);
|
ContentParameters content_params = content_type.parse_content_parameters(content.description);
|
||||||
|
|
||||||
TransportType type = content_type.content_type_transport_type();
|
TransportType type = content_type.content_type_transport_type();
|
||||||
Session session = new Session.initiate_received(sid, type, transport_params, my_jid, iq.from, content.name, stream);
|
Session session = new Session.initiate_received(sid, type, transport_params, my_jid, iq.from, content.name, send_terminate_and_remove_session);
|
||||||
stream.get_flag(Flag.IDENTITY).add_session(session);
|
stream.get_flag(Flag.IDENTITY).add_session(session);
|
||||||
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, new Iq.Stanza.result(iq));
|
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, new Iq.Stanza.result(iq));
|
||||||
|
|
||||||
if (transport == null || transport.transport_type() != type) {
|
if (transport == null || transport.transport_type() != type) {
|
||||||
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
||||||
.put_node(new StanzaNode.build("unsupported-transports", NS_URI));
|
.put_node(new StanzaNode.build("unsupported-transports", NS_URI));
|
||||||
session.terminate(stream, reason, "unsupported transports");
|
session.terminate(reason, "unsupported transports");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
content_params.on_session_initiate(stream, session);
|
content_params.on_session_initiate(stream, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void send_terminate_and_remove_session(Jid to, string sid, StanzaNode reason) {
|
||||||
|
StanzaNode jingle = new StanzaNode.build("jingle", NS_URI)
|
||||||
|
.add_self_xmlns()
|
||||||
|
.put_attribute("action", "session-terminate")
|
||||||
|
.put_attribute("sid", sid)
|
||||||
|
.put_node(reason);
|
||||||
|
Iq.Stanza iq = new Iq.Stanza.set(jingle) { to=to };
|
||||||
|
current_stream.get_module(Iq.Module.IDENTITY).send_iq(current_stream, iq);
|
||||||
|
|
||||||
|
// Immediately remove the session from the open sessions as per the
|
||||||
|
// XEP, don't wait for confirmation.
|
||||||
|
current_stream.get_flag(Flag.IDENTITY).remove_session(sid);
|
||||||
|
}
|
||||||
|
|
||||||
public void on_iq_set(XmppStream stream, Iq.Stanza iq) {
|
public void on_iq_set(XmppStream stream, Iq.Stanza iq) {
|
||||||
try {
|
try {
|
||||||
handle_iq_set(stream, iq);
|
handle_iq_set(stream, iq);
|
||||||
|
@ -294,6 +312,8 @@ public enum Senders {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate void SessionTerminate(Jid to, string sid, StanzaNode reason);
|
||||||
|
|
||||||
public interface Transport : Object {
|
public interface Transport : Object {
|
||||||
public abstract string transport_ns_uri();
|
public abstract string transport_ns_uri();
|
||||||
public abstract bool is_transport_available(XmppStream stream, Jid full_jid);
|
public abstract bool is_transport_available(XmppStream stream, Jid full_jid);
|
||||||
|
@ -372,9 +392,9 @@ public class Session {
|
||||||
// INITIATE_SENT | INITIATE_RECEIVED | CONNECTING
|
// INITIATE_SENT | INITIATE_RECEIVED | CONNECTING
|
||||||
TransportParameters? transport = null;
|
TransportParameters? transport = null;
|
||||||
|
|
||||||
XmppStream hack;
|
SessionTerminate session_terminate_handler;
|
||||||
|
|
||||||
public Session.initiate_sent(string sid, Type type, TransportParameters transport, Jid local_full_jid, Jid peer_full_jid, string content_name, XmppStream hack) {
|
public Session.initiate_sent(string sid, Type type, TransportParameters transport, Jid local_full_jid, Jid peer_full_jid, string content_name, owned SessionTerminate session_terminate_handler) {
|
||||||
this.state = State.INITIATE_SENT;
|
this.state = State.INITIATE_SENT;
|
||||||
this.sid = sid;
|
this.sid = sid;
|
||||||
this.type_ = type;
|
this.type_ = type;
|
||||||
|
@ -384,10 +404,10 @@ public class Session {
|
||||||
this.content_name = content_name;
|
this.content_name = content_name;
|
||||||
this.transport = transport;
|
this.transport = transport;
|
||||||
this.connection = new Connection(this);
|
this.connection = new Connection(this);
|
||||||
this.hack = hack;
|
this.session_terminate_handler = (owned)session_terminate_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Session.initiate_received(string sid, Type type, TransportParameters? transport, Jid local_full_jid, Jid peer_full_jid, string content_name, XmppStream hack) {
|
public Session.initiate_received(string sid, Type type, TransportParameters? transport, Jid local_full_jid, Jid peer_full_jid, string content_name, owned SessionTerminate session_terminate_handler) {
|
||||||
this.state = State.INITIATE_RECEIVED;
|
this.state = State.INITIATE_RECEIVED;
|
||||||
this.sid = sid;
|
this.sid = sid;
|
||||||
this.type_ = type;
|
this.type_ = type;
|
||||||
|
@ -397,7 +417,7 @@ public class Session {
|
||||||
this.content_name = content_name;
|
this.content_name = content_name;
|
||||||
this.transport = transport;
|
this.transport = transport;
|
||||||
this.connection = new Connection(this);
|
this.connection = new Connection(this);
|
||||||
this.hack = hack;
|
this.session_terminate_handler = (owned)session_terminate_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle_iq_set(XmppStream stream, string action, StanzaNode jingle, Iq.Stanza iq) throws IqError {
|
public void handle_iq_set(XmppStream stream, string action, StanzaNode jingle, Iq.Stanza iq) throws IqError {
|
||||||
|
@ -466,7 +486,7 @@ public class Session {
|
||||||
// TODO(hrxi): try negotiating other transports…
|
// TODO(hrxi): try negotiating other transports…
|
||||||
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
||||||
.put_node(new StanzaNode.build("failed-transport", NS_URI));
|
.put_node(new StanzaNode.build("failed-transport", NS_URI));
|
||||||
terminate(stream, reason, "failed transport");
|
terminate(reason, "failed transport");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void handle_session_terminate(XmppStream stream, StanzaNode jingle, Iq.Stanza iq) throws IqError {
|
void handle_session_terminate(XmppStream stream, StanzaNode jingle, Iq.Stanza iq) throws IqError {
|
||||||
|
@ -544,7 +564,7 @@ public class Session {
|
||||||
}
|
}
|
||||||
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
||||||
.put_node(new StanzaNode.build("decline", NS_URI));
|
.put_node(new StanzaNode.build("decline", NS_URI));
|
||||||
terminate(stream, reason, "declined");
|
terminate(reason, "declined");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_application_error(XmppStream stream, StanzaNode? application_reason = null) {
|
public void set_application_error(XmppStream stream, StanzaNode? application_reason = null) {
|
||||||
|
@ -553,7 +573,7 @@ public class Session {
|
||||||
if (application_reason != null) {
|
if (application_reason != null) {
|
||||||
reason.put_node(application_reason);
|
reason.put_node(application_reason);
|
||||||
}
|
}
|
||||||
terminate(stream, reason, "application error");
|
terminate(reason, "application error");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void on_connection_error(IOError error) {
|
public void on_connection_error(IOError error) {
|
||||||
|
@ -563,15 +583,15 @@ public class Session {
|
||||||
.put_node(new StanzaNode.build("text", NS_URI)
|
.put_node(new StanzaNode.build("text", NS_URI)
|
||||||
.put_node(new StanzaNode.text(error.message))
|
.put_node(new StanzaNode.text(error.message))
|
||||||
);
|
);
|
||||||
terminate(hack, reason, "transport error: $(error.message)");
|
terminate(reason, "transport error: $(error.message)");
|
||||||
}
|
}
|
||||||
public void on_connection_close() {
|
public void on_connection_close() {
|
||||||
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
StanzaNode reason = new StanzaNode.build("reason", NS_URI)
|
||||||
.put_node(new StanzaNode.build("success", NS_URI));
|
.put_node(new StanzaNode.build("success", NS_URI));
|
||||||
terminate(hack, reason, "success");
|
terminate(reason, "success");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terminate(XmppStream stream, StanzaNode reason, string? local_reason) {
|
public void terminate(StanzaNode reason, string? local_reason) {
|
||||||
if (state == State.ENDED) {
|
if (state == State.ENDED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -583,18 +603,8 @@ public class Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StanzaNode jingle = new StanzaNode.build("jingle", NS_URI)
|
session_terminate_handler(peer_full_jid, sid, reason);
|
||||||
.add_self_xmlns()
|
|
||||||
.put_attribute("action", "session-terminate")
|
|
||||||
.put_attribute("sid", sid)
|
|
||||||
.put_node(reason);
|
|
||||||
Iq.Stanza iq = new Iq.Stanza.set(jingle) { to=peer_full_jid };
|
|
||||||
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq);
|
|
||||||
|
|
||||||
state = State.ENDED;
|
state = State.ENDED;
|
||||||
// Immediately remove the session from the open sessions as per the
|
|
||||||
// XEP, don't wait for confirmation.
|
|
||||||
stream.get_flag(Flag.IDENTITY).remove_session(sid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue