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