annotate mod_pubsub_mqtt/mod_pubsub_mqtt.lua @ 5296:0f5657db1cfc

mod_isolate_host: handle server-generated stanzas The hook for setting the no_host_isolation is only called for c2s sessions. This does not work for stanzas generated by the server, such as PEP notifications or presence probe answers. To handle that, we do per-stanza checks for the case that the origin is local.
author Jonas Schäfer <jonas@wielicki.name>
date Sat, 01 Apr 2023 12:03:08 +0200
parents 85a7304cfea1
children 801f64e6d4e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 module:set_global();
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local mqtt = module:require "mqtt";
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
4 local id = require "util.id";
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local st = require "util.stanza";
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
7 local function tostring_content(item)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
8 return tostring(item[1]);
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
9 end
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
10
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
11 local data_translators = setmetatable({
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
12 utf8 = {
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
13 from_item = function (item)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
14 return item:find("{https://prosody.im/protocol/data}data#");
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
15 end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
16 to_item = function (payload)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
17 return st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = id.medium() })
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
18 :text_tag("data", payload, { xmlns = "https://prosody.im/protocol/data" })
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
19 end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
20 };
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
21 json = {
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
22 from_item = function (item)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
23 return item:find("{urn:xmpp:json:0}json#");
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
24 end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
25 to_item = function (payload)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
26 return st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = id.medium() })
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
27 :text_tag("json", payload, { xmlns = "urn:xmpp:json:0" });
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
28 end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
29 };
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
30 atom_title = {
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
31 from_item = function (item)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
32 return item:find("{http://www.w3.org/2005/Atom}entry/title#");
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
33 end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
34 to_item = function (payload)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
35 return st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = id.medium() })
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
36 :tag("entry", { xmlns = "http://www.w3.org/2005/Atom" })
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
37 :text_tag("title", payload, { type = "text" });
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
38 end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
39 };
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
40 }, {
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
41 __index = function () return { from_item = tostring }; end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
42 });
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
43
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 local pubsub_services = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 local pubsub_subscribers = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 local packet_handlers = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 function handle_packet(session, packet)
5112
9499b88f3453 mod_pubsub_mqtt: Fix some inappropriate log levels
Matthew Wild <mwild1@gmail.com>
parents: 5111
diff changeset
49 module:log("debug", "MQTT packet received! Length: %d", packet.length);
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 for k,v in pairs(packet) do
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 module:log("debug", "MQTT %s: %s", tostring(k), tostring(v));
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 local handler = packet_handlers[packet.type];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 if not handler then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 module:log("warn", "Unhandled command: %s", tostring(packet.type));
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 return;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 handler(session, packet);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 function packet_handlers.connect(session, packet)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 session.conn:write(mqtt.serialize_packet{
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 type = "connack";
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 data = string.char(0x00, 0x00);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 });
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 function packet_handlers.disconnect(session, packet)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 session.conn:close();
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 function packet_handlers.publish(session, packet)
5112
9499b88f3453 mod_pubsub_mqtt: Fix some inappropriate log levels
Matthew Wild <mwild1@gmail.com>
parents: 5111
diff changeset
73 module:log("info", "PUBLISH to %s", packet.topic);
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
74 local host, payload_type, node = packet.topic:match("^([^/]+)/([^/]+)/(.+)$");
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
75 if not host then
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
76 module:log("warn", "Invalid topic format - expected: HOST/TYPE/NODE");
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
77 return;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
78 end
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 local pubsub = pubsub_services[host];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 if not pubsub then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 module:log("warn", "Unable to locate host/node: %s", packet.topic);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 return;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 end
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
84
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
85 local payload_translator = data_translators[payload_type];
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
86 if not payload_translator or not payload_translator.to_item then
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
87 module:log("warn", "Unsupported payload type '%s' on topic '%s'", payload_type, packet.topic);
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
88 return;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
89 end
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
90
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
91 local payload_item = payload_translator.to_item(packet.data);
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
92 local ok, err = pubsub:publish(node, true, payload_item.attr.id, payload_item);
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 if not ok then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 module:log("warn", "Error publishing MQTT data: %s", tostring(err));
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 function packet_handlers.subscribe(session, packet)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 for _, topic in ipairs(packet.topics) do
5112
9499b88f3453 mod_pubsub_mqtt: Fix some inappropriate log levels
Matthew Wild <mwild1@gmail.com>
parents: 5111
diff changeset
100 module:log("info", "SUBSCRIBE to %s", topic);
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
101 local host, payload_type, node = topic:match("^([^/]+)/([^/]+)/(.+)$");
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
102 if not host then
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
103 module:log("warn", "Invalid topic format - expected: HOST/TYPE/NODE");
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
104 return;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
105 end
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 local pubsub = pubsub_subscribers[host];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 if not pubsub then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 module:log("warn", "Unable to locate host/node: %s", topic);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 return;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 local node_subs = pubsub[node];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 if not node_subs then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 node_subs = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 pubsub[node] = node_subs;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 end
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
116 session.subscriptions[topic] = payload_type;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
117 node_subs[session] = payload_type;
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1309
diff changeset
119
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 function packet_handlers.pingreq(session, packet)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 session.conn:write(mqtt.serialize_packet{type = "pingresp"});
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 local sessions = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 local mqtt_listener = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 function mqtt_listener.onconnect(conn)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 sessions[conn] = {
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 conn = conn;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 stream = mqtt.new_stream();
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 subscriptions = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 };
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 function mqtt_listener.onincoming(conn, data)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 local session = sessions[conn];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 if session then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 local packets = session.stream:feed(data);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 for i = 1, #packets do
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 handle_packet(session, packets[i]);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 function mqtt_listener.ondisconnect(conn)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 local session = sessions[conn];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 for topic in pairs(session.subscriptions) do
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 local host, node = topic:match("^([^/]+)/(.+)$");
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 local subs = pubsub_subscribers[host];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 if subs then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 local node_subs = subs[node];
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 if node_subs then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 node_subs[session] = nil;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 sessions[conn] = nil;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 module:log("debug", "MQTT client disconnected");
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 module:provides("net", {
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 default_port = 1883;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 listener = mqtt_listener;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 });
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 function module.add_host(module)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 local pubsub_module = hosts[module.host].modules.pubsub
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 if pubsub_module then
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 module:log("debug", "MQTT enabled for %s", module.host);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 module:depends("pubsub");
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 pubsub_services[module.host] = assert(pubsub_module.service);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 local subscribers = {};
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 pubsub_subscribers[module.host] = subscribers;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 local function handle_publish(event)
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 -- Build MQTT packet
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
179 local packet_types = setmetatable({}, {
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
180 __index = function (self, payload_type)
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
181 local packet = mqtt.serialize_packet{
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
182 type = "publish";
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
183 id = "\000\000";
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
184 topic = module.host.."/"..payload_type.."/"..event.node;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
185 data = data_translators[payload_type].from_item(event.item) or "";
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
186 };
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
187 rawset(self, packet);
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
188 return packet;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
189 end;
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
190 });
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 -- Broadcast to subscribers
5113
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
192 module:log("debug", "Broadcasting PUBLISH to subscribers of %s/*/%s", module.host, event.node);
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
193 for session, payload_type in pairs(subscribers[event.node] or {}) do
85a7304cfea1 mod_pubsub_mqtt: Support atom_title payload type
Matthew Wild <mwild1@gmail.com>
parents: 5112
diff changeset
194 session.conn:write(packet_types[payload_type]);
1240
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 module:log("debug", "Sent to %s", tostring(session));
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 pubsub_services[module.host].events.add_handler("item-published", handle_publish);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 function module.unload()
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 module:log("debug", "MQTT disabled for %s", module.host);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 pubsub_module.service.remove_handler("item-published", handle_publish);
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 pubsub_services[module.host] = nil;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 pubsub_subscribers[module.host] = nil;
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 end
e0d97eb52ab8 mod_pubsub_mqtt: MQTT (a lightweight binary pubsub protocol) interface for mod_pubsub
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 end