aboutsummaryrefslogtreecommitdiff
path: root/xmpp-vala/src/module/xep/0030_service_discovery/module.vala
blob: 332e8fc3d49cf27276842b0c629d586f39da7b15 (plain) (blame)
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
using Gee;

namespace Xmpp.Xep.ServiceDiscovery {

private const string NS_URI = "http://jabber.org/protocol/disco";
public const string NS_URI_INFO = NS_URI + "#info";
public const string NS_URI_ITEMS = NS_URI + "#items";

public class Module : XmppStreamModule, Iq.Handler {
    public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0030_service_discovery_module");

    public Identity own_identity;

    public Module.with_identity(string category, string type, string? name = null) {
        own_identity = new Identity(category, type, name);
    }

    public void add_feature(XmppStream stream, string feature) {
        stream.get_flag(Flag.IDENTITY).add_own_feature(feature);
    }

    public void remove_feature(XmppStream stream, string feature) {
        stream.get_flag(Flag.IDENTITY).remove_own_feature(feature);
    }

    public void add_feature_notify(XmppStream stream, string feature) {
        add_feature(stream, feature + "+notify");
    }

    public void remove_feature_notify(XmppStream stream, string feature) {
        remove_feature(stream, feature + "+notify");
    }

    public void add_identity(XmppStream stream, Identity identity) {
        stream.get_flag(Flag.IDENTITY).add_own_identity(identity);
    }

    public void remove_identity(XmppStream stream, Identity identity) {
        stream.get_flag(Flag.IDENTITY).remove_own_identity(identity);
    }

    public delegate void HasEntryCategoryRes(XmppStream stream, Gee.Set<Identity>? identities);
    public void get_entity_categories(XmppStream stream, Jid jid, owned HasEntryCategoryRes listener) {
        Gee.Set<Identity>? res = stream.get_flag(Flag.IDENTITY).get_entity_categories(jid);
        if (res != null) listener(stream, res);
        request_info(stream, jid, (stream, query_result) => {
            listener(stream, query_result != null ? query_result.identities : null);
        });
    }

    public delegate void OnInfoResult(XmppStream stream, InfoResult? query_result);
    public void request_info(XmppStream stream, Jid jid, owned OnInfoResult listener) {
        Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns());
        iq.to = jid;
        stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => {
            InfoResult? result = InfoResult.create_from_iq(iq);
            stream.get_flag(Flag.IDENTITY).set_entity_features(iq.from, result != null ? result.features : null);
            stream.get_flag(Flag.IDENTITY).set_entity_identities(iq.from, result != null ? result.identities : null);
            listener(stream, result);
        });
    }

    public delegate void OnItemsResult(XmppStream stream, ItemsResult query_result);
    public void request_items(XmppStream stream, Jid jid, owned OnItemsResult listener) {
        Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_ITEMS).add_self_xmlns());
        iq.to = jid;
        stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => {
            ItemsResult? result = ItemsResult.create_from_iq(iq);
            stream.get_flag(Flag.IDENTITY).set_entity_items(iq.from, result != null ? result.items : null);
            listener(stream, result);
        });
    }

    public void on_iq_get(XmppStream stream, Iq.Stanza iq) {
        StanzaNode? query_node = iq.stanza.get_subnode("query", NS_URI_INFO);
        if (query_node != null) {
            send_query_result(stream, iq);
        }
    }

    public override void attach(XmppStream stream) {
        stream.add_flag(new Flag());
        add_identity(stream, own_identity);

        stream.get_module(Iq.Module.IDENTITY).register_for_namespace(NS_URI_INFO, this);
        add_feature(stream, NS_URI_INFO);
    }

    public override void detach(XmppStream stream) {
        remove_identity(stream, own_identity);

        stream.get_module(Iq.Module.IDENTITY).unregister_from_namespace(NS_URI_INFO, this);
        remove_feature(stream, NS_URI_INFO);
    }

    public static void require(XmppStream stream) {
        if (stream.get_module(IDENTITY) == null) stream.add_module(new ServiceDiscovery.Module());
    }

    public override string get_ns() { return NS_URI; }
    public override string get_id() { return IDENTITY.id; }

    private void send_query_result(XmppStream stream, Iq.Stanza iq_request) {
        InfoResult query_result = new ServiceDiscovery.InfoResult(iq_request);
        query_result.features = stream.get_flag(Flag.IDENTITY).own_features;
        query_result.identities = stream.get_flag(Flag.IDENTITY).own_identities;
        stream.get_module(Iq.Module.IDENTITY).send_iq(stream, query_result.iq);
    }
}

}