1using Gee; 2 3namespace Xmpp.Presence { 4 private const string NS_URI = "jabber:client"; 5 6 public class Module : XmppStreamModule { 7 public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "presence_module"); 8 9 public signal void received_presence(XmppStream stream, Presence.Stanza presence); 10 public signal void pre_send_presence_stanza(XmppStream stream, Presence.Stanza presence); 11 public signal void initial_presence_sent(XmppStream stream, Presence.Stanza presence); 12 public signal void received_available(XmppStream stream, Presence.Stanza presence); 13 public signal void received_available_show(XmppStream stream, Jid jid, string show); 14 public signal void received_unavailable(XmppStream stream, Presence.Stanza presence); 15 public signal void received_subscription_request(XmppStream stream, Jid jid); 16 public signal void received_subscription_approval(XmppStream stream, Jid jid); 17 public signal void received_unsubscription(XmppStream stream, Jid jid); 18 19 public bool available_resource = true; 20 21 public void request_subscription(XmppStream stream, Jid bare_jid) { 22 Presence.Stanza presence = new Presence.Stanza(); 23 presence.to = bare_jid; 24 presence.type_ = Presence.Stanza.TYPE_SUBSCRIBE; 25 send_presence(stream, presence); 26 } 27 28 public void approve_subscription(XmppStream stream, Jid bare_jid) { 29 Presence.Stanza presence = new Presence.Stanza(); 30 presence.to = bare_jid; 31 presence.type_ = Presence.Stanza.TYPE_SUBSCRIBED; 32 send_presence(stream, presence); 33 } 34 35 public void deny_subscription(XmppStream stream, Jid bare_jid) { 36 cancel_subscription(stream, bare_jid); 37 } 38 39 public void cancel_subscription(XmppStream stream, Jid bare_jid) { 40 Presence.Stanza presence = new Presence.Stanza(); 41 presence.to = bare_jid; 42 presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBED; 43 send_presence(stream, presence); 44 } 45 46 public void unsubscribe(XmppStream stream, Jid bare_jid) { 47 Presence.Stanza presence = new Presence.Stanza(); 48 presence.to = bare_jid; 49 presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBE; 50 send_presence(stream, presence); 51 } 52 53 public void send_presence(XmppStream stream, Presence.Stanza presence) { 54 pre_send_presence_stanza(stream, presence); 55 stream.write(presence.stanza); 56 } 57 58 public override void attach(XmppStream stream) { 59 stream.add_flag(new Flag()); 60 stream.received_presence_stanza.connect(on_received_presence_stanza); 61 stream.stream_negotiated.connect(on_stream_negotiated); 62 } 63 64 public override void detach(XmppStream stream) { 65 stream.received_presence_stanza.disconnect(on_received_presence_stanza); 66 stream.stream_negotiated.disconnect(on_stream_negotiated); 67 } 68 69 private void on_received_presence_stanza(XmppStream stream, StanzaNode node) { 70 Presence.Stanza presence = new Presence.Stanza.from_stanza(node, stream.get_flag(Bind.Flag.IDENTITY).my_jid); 71 received_presence(stream, presence); 72 switch (presence.type_) { 73 case Presence.Stanza.TYPE_AVAILABLE: 74 stream.get_flag(Flag.IDENTITY).add_presence(presence); 75 received_available(stream, presence); 76 received_available_show(stream, presence.from, presence.show); 77 break; 78 case Presence.Stanza.TYPE_UNAVAILABLE: 79 stream.get_flag(Flag.IDENTITY).remove_presence(presence.from); 80 received_unavailable(stream, presence); 81 break; 82 case Presence.Stanza.TYPE_SUBSCRIBE: 83 received_subscription_request(stream, presence.from); 84 break; 85 case Presence.Stanza.TYPE_SUBSCRIBED: 86 received_subscription_approval(stream, presence.from); 87 break; 88 case Presence.Stanza.TYPE_UNSUBSCRIBE: 89 stream.get_flag(Flag.IDENTITY).remove_presence(presence.from); 90 received_unsubscription(stream, presence.from); 91 break; 92 case Presence.Stanza.TYPE_UNSUBSCRIBED: 93 break; 94 } 95 } 96 97 private void on_stream_negotiated(XmppStream stream) { 98 if (available_resource) { 99 Presence.Stanza presence = new Presence.Stanza(); 100 send_presence(stream, presence); 101 initial_presence_sent(stream, presence); 102 } 103 } 104 105 public override string get_ns() { return NS_URI; } 106 public override string get_id() { return IDENTITY.id; } 107 } 108 109} 110