u8-mqtt 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/basic-v4.cjs +194 -243
- package/cjs/basic-v4.cjs.map +1 -1
- package/cjs/basic-v5.cjs +264 -385
- package/cjs/basic-v5.cjs.map +1 -1
- package/cjs/full-v4.cjs +297 -353
- package/cjs/full-v4.cjs.map +1 -1
- package/cjs/full-v5.cjs +366 -492
- package/cjs/full-v5.cjs.map +1 -1
- package/cjs/index.cjs +263 -384
- package/cjs/index.cjs.map +1 -1
- package/cjs/v4.cjs +194 -243
- package/cjs/v4.cjs.map +1 -1
- package/cjs/v5.cjs +263 -384
- package/cjs/v5.cjs.map +1 -1
- package/esm/basic-v4.js +194 -243
- package/esm/basic-v4.js.map +1 -1
- package/esm/basic-v5.js +264 -385
- package/esm/basic-v5.js.map +1 -1
- package/esm/deno/basic-v4.js +194 -243
- package/esm/deno/basic-v4.js.map +1 -1
- package/esm/deno/basic-v5.js +264 -385
- package/esm/deno/basic-v5.js.map +1 -1
- package/esm/deno/full-v4.js +297 -353
- package/esm/deno/full-v4.js.map +1 -1
- package/esm/deno/full-v5.js +366 -492
- package/esm/deno/full-v5.js.map +1 -1
- package/esm/deno/index.js +263 -384
- package/esm/deno/index.js.map +1 -1
- package/esm/deno/v4.js +194 -243
- package/esm/deno/v4.js.map +1 -1
- package/esm/deno/v5.js +263 -384
- package/esm/deno/v5.js.map +1 -1
- package/esm/full-v4.js +297 -353
- package/esm/full-v4.js.map +1 -1
- package/esm/full-v5.js +366 -492
- package/esm/full-v5.js.map +1 -1
- package/esm/index.js +263 -384
- package/esm/index.js.map +1 -1
- package/esm/node/basic-v4.js +194 -243
- package/esm/node/basic-v4.js.map +1 -1
- package/esm/node/basic-v4.mjs +194 -243
- package/esm/node/basic-v4.mjs.map +1 -1
- package/esm/node/basic-v5.js +264 -385
- package/esm/node/basic-v5.js.map +1 -1
- package/esm/node/basic-v5.mjs +264 -385
- package/esm/node/basic-v5.mjs.map +1 -1
- package/esm/node/full-v4.js +297 -353
- package/esm/node/full-v4.js.map +1 -1
- package/esm/node/full-v4.mjs +297 -353
- package/esm/node/full-v4.mjs.map +1 -1
- package/esm/node/full-v5.js +366 -492
- package/esm/node/full-v5.js.map +1 -1
- package/esm/node/full-v5.mjs +366 -492
- package/esm/node/full-v5.mjs.map +1 -1
- package/esm/node/index.js +263 -384
- package/esm/node/index.js.map +1 -1
- package/esm/node/index.mjs +263 -384
- package/esm/node/index.mjs.map +1 -1
- package/esm/node/v4.js +194 -243
- package/esm/node/v4.js.map +1 -1
- package/esm/node/v4.mjs +194 -243
- package/esm/node/v4.mjs.map +1 -1
- package/esm/node/v5.js +263 -384
- package/esm/node/v5.js.map +1 -1
- package/esm/node/v5.mjs +263 -384
- package/esm/node/v5.mjs.map +1 -1
- package/esm/v4.js +194 -243
- package/esm/v4.js.map +1 -1
- package/esm/v5.js +263 -384
- package/esm/v5.js.map +1 -1
- package/esm/web/basic-v4.js +194 -243
- package/esm/web/basic-v4.js.map +1 -1
- package/esm/web/basic-v4.min.js +1 -1
- package/esm/web/basic-v4.min.js.br +0 -0
- package/esm/web/basic-v4.min.js.gz +0 -0
- package/esm/web/basic-v5.js +264 -385
- package/esm/web/basic-v5.js.map +1 -1
- package/esm/web/basic-v5.min.js +1 -1
- package/esm/web/basic-v5.min.js.br +0 -0
- package/esm/web/basic-v5.min.js.gz +0 -0
- package/esm/web/full-v4.js +297 -353
- package/esm/web/full-v4.js.map +1 -1
- package/esm/web/full-v4.min.js +1 -1
- package/esm/web/full-v4.min.js.br +0 -0
- package/esm/web/full-v4.min.js.gz +0 -0
- package/esm/web/full-v5.js +366 -492
- package/esm/web/full-v5.js.map +1 -1
- package/esm/web/full-v5.min.js +1 -1
- package/esm/web/full-v5.min.js.br +0 -0
- package/esm/web/full-v5.min.js.gz +0 -0
- package/esm/web/index.js +263 -384
- package/esm/web/index.js.map +1 -1
- package/esm/web/index.min.js +1 -1
- package/esm/web/index.min.js.br +0 -0
- package/esm/web/index.min.js.gz +0 -0
- package/esm/web/v4.js +194 -243
- package/esm/web/v4.js.map +1 -1
- package/esm/web/v4.min.js +1 -1
- package/esm/web/v4.min.js.br +0 -0
- package/esm/web/v4.min.js.gz +0 -0
- package/esm/web/v5.js +263 -384
- package/esm/web/v5.js.map +1 -1
- package/esm/web/v5.min.js +1 -1
- package/esm/web/v5.min.js.br +0 -0
- package/esm/web/v5.min.js.gz +0 -0
- package/package.json +2 -2
package/cjs/full-v5.cjs
CHANGED
|
@@ -6,50 +6,33 @@ var node_net = require('node:net');
|
|
|
6
6
|
var node_tls = require('node:tls');
|
|
7
7
|
|
|
8
8
|
function encode_varint(n, a=[]) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
n
|
|
12
|
-
a.push( ni | (0===n ? 0 : 0x80) );
|
|
13
|
-
} while (n > 0)
|
|
9
|
+
a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
|
|
10
|
+
for(; ( n>>>=7 ) > 0 ;)
|
|
11
|
+
a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
|
|
14
12
|
return a
|
|
15
13
|
}
|
|
16
14
|
|
|
15
|
+
function decode_varint$1(u8, i0=0, invalid) {
|
|
16
|
+
let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
|
|
17
|
+
for(; b & 0x80;)
|
|
18
|
+
n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
let shift = 0, n = (u8[i] & 0x7f)
|
|
22
|
-
while ( 0x80 & u8[i++] )
|
|
23
|
-
n |= (u8[i] & 0x7f) << (shift += 7)
|
|
24
|
-
|
|
25
|
-
return [n, i, i0]
|
|
20
|
+
return (u8.length < i)
|
|
21
|
+
? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
|
|
22
|
+
: [n, i, i0] // successful value
|
|
26
23
|
}
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
24
|
|
|
30
|
-
function
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if ( 0x80 & u8[i++] ) {
|
|
35
|
-
n |= (u8[i] & 0x7f) << 7;
|
|
36
|
-
if ( 0x80 & u8[i++] ) {
|
|
37
|
-
n |= (u8[i] & 0x7f) << 14;
|
|
38
|
-
if ( 0x80 & u8[i++] ) {
|
|
39
|
-
n |= (u8[i] & 0x7f) << 21;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
25
|
+
function add_mqtt_props(mqtt_props, entries) {
|
|
26
|
+
for (let [id, type, name, obj] of entries) {
|
|
27
|
+
obj = {id, type, name, ...obj};
|
|
28
|
+
mqtt_props.set(id, obj).set(name, obj);
|
|
42
29
|
}
|
|
43
|
-
return
|
|
30
|
+
return mqtt_props
|
|
44
31
|
}
|
|
45
32
|
|
|
46
|
-
const mqtt_props = /* #__PURE__ */
|
|
47
|
-
init_mqtt_props();
|
|
48
33
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let entries = [
|
|
34
|
+
const init_mqtt_props = () =>
|
|
35
|
+
add_mqtt_props(new Map(), [
|
|
53
36
|
[ 0x01, 'u8', 'payload_format_indicator'],
|
|
54
37
|
[ 0x02, 'u32', 'message_expiry_interval'],
|
|
55
38
|
[ 0x03, 'utf8', 'content_type'],
|
|
@@ -77,30 +60,24 @@ function init_mqtt_props() {
|
|
|
77
60
|
[ 0x28, 'u8', 'wildcard_subscription_available'],
|
|
78
61
|
[ 0x29, 'u8', 'subscription_identifiers_available', {op: 'u8_vec'}],
|
|
79
62
|
[ 0x2A, 'u8', 'shared_subscription_available'],
|
|
80
|
-
];
|
|
63
|
+
]);
|
|
81
64
|
|
|
82
|
-
for (let [id, type, name, extra] of entries) {
|
|
83
|
-
let prop_obj = {id, type, name, ...extra};
|
|
84
|
-
mqtt_props.set(prop_obj.id, prop_obj);
|
|
85
|
-
mqtt_props.set(prop_obj.name, prop_obj);
|
|
86
|
-
}
|
|
87
65
|
|
|
88
|
-
|
|
89
|
-
|
|
66
|
+
const mqtt_props = /* #__PURE__ */
|
|
67
|
+
init_mqtt_props();
|
|
90
68
|
|
|
91
|
-
class
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return self
|
|
69
|
+
class mqtt_reason extends Number {
|
|
70
|
+
constructor(v, reason) {
|
|
71
|
+
super(v);
|
|
72
|
+
this.reason = `:${(this.ok = v<0x80) ? 'ok' : 'fail'}:${reason}`;
|
|
96
73
|
}
|
|
97
74
|
}
|
|
98
75
|
|
|
99
76
|
class mqtt_reader_v4 {
|
|
100
|
-
static
|
|
101
|
-
of(buf) {
|
|
77
|
+
static for(pkt, u8_body) { return new this().of(u8_body, {pkt}) }
|
|
78
|
+
of(buf, opt) {
|
|
102
79
|
let step = (width, k) => (k=0|step.k, step.k=k+width, k);
|
|
103
|
-
return {__proto__: this, buf, step}
|
|
80
|
+
return {__proto__: this, buf, step, ...opt}
|
|
104
81
|
}
|
|
105
82
|
|
|
106
83
|
has_more() {
|
|
@@ -143,7 +120,7 @@ class mqtt_reader_v4 {
|
|
|
143
120
|
reason(pkt_kind) {
|
|
144
121
|
let v = this.buf[this.step(1)];
|
|
145
122
|
if (null != v)
|
|
146
|
-
return
|
|
123
|
+
return new mqtt_reason(v, this._reason_for?.(v, pkt_kind))
|
|
147
124
|
}
|
|
148
125
|
|
|
149
126
|
flush() {
|
|
@@ -157,24 +134,22 @@ class mqtt_reader_v4 {
|
|
|
157
134
|
let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
|
|
158
135
|
props() {
|
|
159
136
|
let {buf, step} = this;
|
|
160
|
-
let [n, vi, vi0] = decode_varint$1(buf, step.k|0);
|
|
137
|
+
let [n, vi, vi0] = decode_varint$1(buf, step.k|0, 0);
|
|
161
138
|
step(n + vi - vi0);
|
|
162
139
|
if (0 === n) return null
|
|
163
140
|
|
|
164
141
|
let res={}, fork = this.of(buf.subarray(vi, step.k|0));
|
|
165
142
|
while (fork.has_more()) {
|
|
166
143
|
let v, pk = fork.u8(), pt = mqtt_props.get( pk );
|
|
167
|
-
|
|
168
144
|
if (!pt) {
|
|
169
|
-
res.
|
|
170
|
-
|
|
145
|
+
res._unknown_ = pk;
|
|
146
|
+
this.warn?.(`unknown property: ${pk}`);
|
|
147
|
+
break
|
|
171
148
|
}
|
|
172
149
|
|
|
173
150
|
v = fork[pt.type]();
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
res[pt.name] = v;
|
|
151
|
+
res[pt.name] = !pt.op ? v
|
|
152
|
+
: fork[pt.op](res[pt.name], v); // accumulate operation
|
|
178
153
|
}
|
|
179
154
|
return res
|
|
180
155
|
}
|
|
@@ -199,28 +174,99 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
|
|
|
199
174
|
*/
|
|
200
175
|
};
|
|
201
176
|
|
|
202
|
-
function
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
let proto = this.prototype;
|
|
206
|
-
proto._reasons_by = {... proto._reasons_by};
|
|
177
|
+
function with_reasons(mqtt_reader, by_kind) {
|
|
178
|
+
for (let [k,lut] of Object.entries(by_kind))
|
|
179
|
+
by_kind[k] = new Map(lut);
|
|
207
180
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
181
|
+
return class extends mqtt_reader {
|
|
182
|
+
_reason_for(v, pkt_kind) {
|
|
183
|
+
return by_kind[pkt_kind]?.get(v) || by_kind.all.get(v)
|
|
184
|
+
}
|
|
185
|
+
warn(msg) {
|
|
186
|
+
let pkt = this.pkt;
|
|
187
|
+
pkt.warn ? pkt.warn(msg, pkt)
|
|
188
|
+
: console.warn('[u8-mqtt-packet] '+msg);
|
|
213
189
|
}
|
|
214
|
-
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
215
192
|
|
|
216
|
-
for (let fn_info of info_fn_list)
|
|
217
|
-
fn_info(mqtt_reader);
|
|
218
193
|
|
|
219
|
-
|
|
220
|
-
|
|
194
|
+
const reasons_v4 = {
|
|
195
|
+
connack: [
|
|
196
|
+
[ 0x01, 'conn refused: unacceptable protocol version'],
|
|
197
|
+
[ 0x02, 'conn refused: identifier rejected'],
|
|
198
|
+
[ 0x03, 'conn refused: server unavailable'],
|
|
199
|
+
[ 0x04, 'conn refused: bad user name or password'],
|
|
200
|
+
[ 0x05, 'conn refused: not authorized'],
|
|
201
|
+
],
|
|
202
|
+
suback: [
|
|
203
|
+
[ 0x00, 'qos=0'],
|
|
204
|
+
[ 0x01, 'qos=1'],
|
|
205
|
+
[ 0x02, 'qos=2'],
|
|
206
|
+
],
|
|
207
|
+
unsuback: [
|
|
208
|
+
[ 0x11, 'no subscription existed'],
|
|
209
|
+
],
|
|
210
|
+
puback: [
|
|
211
|
+
[ 0x10, 'no matching subscribers'],
|
|
212
|
+
],
|
|
213
|
+
all: [
|
|
214
|
+
[ 0, ''], // Success
|
|
215
|
+
[ 0x80, 'unspecified error'], // disconnect puback suback unsuback
|
|
216
|
+
[ 0x83, 'implementation specific error'], // connack disconnect puback suback unsuback
|
|
217
|
+
[ 0x87, 'not authorized'], // connack disconnect puback suback unsuback
|
|
218
|
+
[ 0x8F, 'topic filter invalid'], // disconnect suback unsuback
|
|
219
|
+
[ 0x91, 'packet identifier in use'], // puback suback unsuback
|
|
220
|
+
[ 0x92, 'packet identifier not found' ], // pubxxx
|
|
221
|
+
]};
|
|
222
|
+
|
|
223
|
+
const reasons_v5 = {
|
|
224
|
+
... reasons_v4,
|
|
225
|
+
auth: [
|
|
226
|
+
[ 0x18, 'continue authentication' ],
|
|
227
|
+
[ 0x19, 're-authenticate' ],
|
|
228
|
+
],
|
|
229
|
+
disconnect: [
|
|
230
|
+
[ 0x04, 'disconnect with will message'],
|
|
231
|
+
],
|
|
232
|
+
all: [
|
|
233
|
+
... reasons_v4.all,
|
|
234
|
+
[ 0x81, 'malformed packet'], // connack disconnect
|
|
235
|
+
[ 0x82, 'protocol error'], // connack disconnect
|
|
236
|
+
[ 0x84, 'unsupported protocol version'], // connack
|
|
237
|
+
[ 0x85, 'client identifier not valid'], // connack
|
|
238
|
+
[ 0x86, 'bad user name or password'], // connack
|
|
239
|
+
[ 0x88, 'server unavailable'], // connack
|
|
240
|
+
[ 0x89, 'server busy'], // connack disconnect
|
|
241
|
+
[ 0x8A, 'banned'], // connack
|
|
242
|
+
[ 0x8B, 'server shutting down'], // disconnect
|
|
243
|
+
[ 0x8C, 'bad authentication method'], // connack
|
|
244
|
+
[ 0x8D, 'keep alive timeout'], // disconnect
|
|
245
|
+
[ 0x8E, 'session taken over'], // disconnect
|
|
246
|
+
[ 0x90, 'topic name invalid'], // connack disconnect puback
|
|
247
|
+
[ 0x93, 'receive maximum exceeded'], // disconnect
|
|
248
|
+
[ 0x94, 'topic alias invalid'], // disconnect
|
|
249
|
+
[ 0x95, 'packet too large'], // connack disconnect
|
|
250
|
+
[ 0x96, 'message rate too high'], // disconnect
|
|
251
|
+
[ 0x97, 'quota exceeded'], // connack disconnect puback suback
|
|
252
|
+
[ 0x98, 'administrative action'], // disconnect
|
|
253
|
+
[ 0x99, 'payload format invalid'], // connack disconnect puback
|
|
254
|
+
[ 0x9A, 'retain not supported'], // connack disconnect
|
|
255
|
+
[ 0x9B, 'qoS not supported'], // connack disconnect
|
|
256
|
+
[ 0x9C, 'use another server'], // connack disconnect
|
|
257
|
+
[ 0x9D, 'server moved'], // connack disconnect
|
|
258
|
+
[ 0x9E, 'shared subscriptions not supported'], // disconnect suback
|
|
259
|
+
[ 0x9F, 'connection rate exceeded'], // connack disconnect
|
|
260
|
+
[ 0xA0, 'maximum connect time'], // disconnect
|
|
261
|
+
[ 0xA1, 'subscription identifiers not supported'], // disconnect suback
|
|
262
|
+
[ 0xA2, 'wildcard subscriptions not supported'], // disconnect suback
|
|
263
|
+
]};
|
|
264
|
+
|
|
265
|
+
const mqtt_reader_v5 = /* #__PURE__ */
|
|
266
|
+
with_reasons(mqtt_reader_v5$1, reasons_v5);
|
|
221
267
|
|
|
222
268
|
class mqtt_writer_v4 {
|
|
223
|
-
static
|
|
269
|
+
static for(pkt) { return new this().of() }
|
|
224
270
|
of() { return {__proto__: this, $:[]} }
|
|
225
271
|
|
|
226
272
|
static init() { return this }
|
|
@@ -309,7 +355,8 @@ class mqtt_writer_v5 extends mqtt_writer_v4 {
|
|
|
309
355
|
for (let [name, value] of props) {
|
|
310
356
|
let pt = mqtt_props.get(name);
|
|
311
357
|
if (!pt)
|
|
312
|
-
throw new Error(`
|
|
358
|
+
throw new Error(`MQTT unknown property "${name}"`)
|
|
359
|
+
|
|
313
360
|
fork[pt.op || 'one'](value, pt);
|
|
314
361
|
}
|
|
315
362
|
this.push(fork.pack());
|
|
@@ -333,351 +380,6 @@ class mqtt_writer_v5 extends mqtt_writer_v4 {
|
|
|
333
380
|
}
|
|
334
381
|
}
|
|
335
382
|
|
|
336
|
-
function mqtt_decode_connect(ns, mqtt_reader) {
|
|
337
|
-
class _connect_flags_ extends Number {
|
|
338
|
-
get reserved() { return this & 0x01 !== 0 }
|
|
339
|
-
get clean_start() { return this & 0x02 !== 0 }
|
|
340
|
-
get will_flag() { return this & 0x04 !== 0 }
|
|
341
|
-
get will_qos() { return (this >>> 3) & 0x3 }
|
|
342
|
-
get will_retain() { return this & 0x20 !== 0 }
|
|
343
|
-
get password() { return this & 0x40 !== 0 }
|
|
344
|
-
get username() { return this & 0x80 !== 0 }
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return ns[0x1] = (pkt, u8_body) => {
|
|
348
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
349
|
-
if ('MQTT' !== rdr.utf8())
|
|
350
|
-
throw new Error('Invalid mqtt_connect packet')
|
|
351
|
-
|
|
352
|
-
pkt._base_.mqtt_level = pkt.mqtt_level = rdr.u8();
|
|
353
|
-
|
|
354
|
-
let flags = pkt.flags =
|
|
355
|
-
rdr.flags(_connect_flags_);
|
|
356
|
-
|
|
357
|
-
pkt.keep_alive = rdr.u16();
|
|
358
|
-
|
|
359
|
-
if (5 <= pkt.mqtt_level)
|
|
360
|
-
pkt.props = rdr.props();
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
pkt.client_id = rdr.utf8();
|
|
365
|
-
if (flags.will_flag) {
|
|
366
|
-
let will = pkt.will = {};
|
|
367
|
-
if (5 <= pkt.mqtt_level)
|
|
368
|
-
will.props = rdr.props();
|
|
369
|
-
|
|
370
|
-
will.topic = rdr.utf8();
|
|
371
|
-
will.payload = rdr.bin();
|
|
372
|
-
will.qos = flags.will_qos;
|
|
373
|
-
will.retain = flags.will_retain;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
if (flags.username)
|
|
377
|
-
pkt.username = rdr.utf8();
|
|
378
|
-
|
|
379
|
-
if (flags.password)
|
|
380
|
-
pkt.password = rdr.bin();
|
|
381
|
-
return pkt }
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
function mqtt_decode_connack(ns, mqtt_reader) {
|
|
385
|
-
class _connack_flags_ extends Number {
|
|
386
|
-
get session_present() { return this & 0x01 !== 0 }
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return ns[0x2] = (pkt, u8_body) => {
|
|
390
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
391
|
-
|
|
392
|
-
pkt.flags =
|
|
393
|
-
rdr.flags(_connack_flags_);
|
|
394
|
-
|
|
395
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
396
|
-
if (5 <= pkt.mqtt_level)
|
|
397
|
-
pkt.props = rdr.props();
|
|
398
|
-
return pkt }
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
function _connack_v4(mqtt_reader) {
|
|
403
|
-
mqtt_reader.reasons('connack',
|
|
404
|
-
// MQTT 3.1.1
|
|
405
|
-
[ 0x00, 'Success'],
|
|
406
|
-
[ 0x01, 'Connection refused, unacceptable protocol version'],
|
|
407
|
-
[ 0x02, 'Connection refused, identifier rejected'],
|
|
408
|
-
[ 0x03, 'Connection refused, server unavailable'],
|
|
409
|
-
[ 0x04, 'Connection refused, bad user name or password'],
|
|
410
|
-
[ 0x05, 'Connection refused, not authorized'],
|
|
411
|
-
);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
function _connack_v5(mqtt_reader) {
|
|
415
|
-
_connack_v4(mqtt_reader);
|
|
416
|
-
|
|
417
|
-
mqtt_reader.reasons('connack',
|
|
418
|
-
// MQTT 5.0
|
|
419
|
-
[ 0x81, 'Malformed Packet'],
|
|
420
|
-
[ 0x82, 'Protocol Error'],
|
|
421
|
-
[ 0x83, 'Implementation specific error'],
|
|
422
|
-
[ 0x84, 'Unsupported Protocol Version'],
|
|
423
|
-
[ 0x85, 'Client Identifier not valid'],
|
|
424
|
-
[ 0x86, 'Bad User Name or Password'],
|
|
425
|
-
[ 0x87, 'Not authorized'],
|
|
426
|
-
[ 0x88, 'Server unavailable'],
|
|
427
|
-
[ 0x89, 'Server busy'],
|
|
428
|
-
[ 0x8A, 'Banned'],
|
|
429
|
-
[ 0x8C, 'Bad authentication method'],
|
|
430
|
-
[ 0x90, 'Topic Name invalid'],
|
|
431
|
-
[ 0x95, 'Packet too large'],
|
|
432
|
-
[ 0x97, 'Quota exceeded'],
|
|
433
|
-
[ 0x99, 'Payload format invalid'],
|
|
434
|
-
[ 0x9A, 'Retain not supported'],
|
|
435
|
-
[ 0x9B, 'QoS not supported'],
|
|
436
|
-
[ 0x9C, 'Use another server'],
|
|
437
|
-
[ 0x9D, 'Server moved'],
|
|
438
|
-
[ 0x9F, 'Connection rate exceeded'],
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
function mqtt_decode_publish(ns, mqtt_reader) {
|
|
443
|
-
return ns[0x3] = (pkt, u8_body) => {
|
|
444
|
-
let {hdr} = pkt;
|
|
445
|
-
pkt.dup = Boolean(hdr & 0x8);
|
|
446
|
-
pkt.retain = Boolean(hdr & 0x1);
|
|
447
|
-
let qos = pkt.qos = (hdr>>1) & 0x3;
|
|
448
|
-
|
|
449
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
450
|
-
pkt.topic = rdr.utf8();
|
|
451
|
-
if (0 !== qos)
|
|
452
|
-
pkt.pkt_id = rdr.u16();
|
|
453
|
-
|
|
454
|
-
if (5 <= pkt.mqtt_level)
|
|
455
|
-
pkt.props = rdr.props();
|
|
456
|
-
|
|
457
|
-
pkt.payload = rdr.flush();
|
|
458
|
-
return pkt }
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
function mqtt_decode_puback(ns, mqtt_reader) {
|
|
462
|
-
return ns[0x4] = (pkt, u8_body) => {
|
|
463
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
464
|
-
|
|
465
|
-
pkt.pkt_id = rdr.u16();
|
|
466
|
-
if (5 <= pkt.mqtt_level) {
|
|
467
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
468
|
-
pkt.props = rdr.props();
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
return pkt }
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
function _puback_v5(mqtt_reader) {
|
|
476
|
-
mqtt_reader.reasons('puback',
|
|
477
|
-
// MQTT 5.0
|
|
478
|
-
[ 0x00, 'Success'],
|
|
479
|
-
[ 0x10, 'No matching subscribers'],
|
|
480
|
-
[ 0x80, 'Unspecified error'],
|
|
481
|
-
[ 0x83, 'Implementation specific error'],
|
|
482
|
-
[ 0x87, 'Not authorized'],
|
|
483
|
-
[ 0x90, 'Topic Name invalid'],
|
|
484
|
-
[ 0x91, 'Packet identifier in use'],
|
|
485
|
-
[ 0x97, 'Quota exceeded'],
|
|
486
|
-
[ 0x99, 'Payload format invalid'],
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
function mqtt_decode_pubxxx(ns, mqtt_reader) {
|
|
491
|
-
return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
|
|
492
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
493
|
-
|
|
494
|
-
pkt.pkt_id = rdr.u16();
|
|
495
|
-
pkt.reason = rdr.reason('pubxxx', mqtt_reader);
|
|
496
|
-
if (5 <= pkt.mqtt_level)
|
|
497
|
-
pkt.props = rdr.props();
|
|
498
|
-
return pkt }
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
function _pubxxx_v4(mqtt_reader) {
|
|
502
|
-
mqtt_reader.reasons('pubxxx',
|
|
503
|
-
// MQTT 3.1.1
|
|
504
|
-
[ 0x00, 'Success' ],
|
|
505
|
-
[ 0x92, 'Packet Identifier not found' ],
|
|
506
|
-
);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
function mqtt_decode_subscribe(ns, mqtt_reader) {
|
|
510
|
-
class _subscription_options_ extends Number {
|
|
511
|
-
get qos() { return this & 0x3 }
|
|
512
|
-
get retain() { return this & 0x4 !== 0 }
|
|
513
|
-
get retain_handling() { return (this >> 2) & 0x3 }
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
return ns[0x8] = (pkt, u8_body) => {
|
|
517
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
518
|
-
|
|
519
|
-
pkt.pkt_id = rdr.u16();
|
|
520
|
-
if (5 <= pkt.mqtt_level)
|
|
521
|
-
pkt.props = rdr.props();
|
|
522
|
-
|
|
523
|
-
let topic, opts, topic_list = pkt.topics = [];
|
|
524
|
-
while (rdr.has_more()) {
|
|
525
|
-
topic = rdr.utf8();
|
|
526
|
-
opts = rdr.flags(_subscription_options_);
|
|
527
|
-
topic_list.push({topic, opts});
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
return pkt }
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
function _mqtt_decode_suback(mqtt_reader) {
|
|
534
|
-
return (pkt, u8_body) => {
|
|
535
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
536
|
-
|
|
537
|
-
pkt.pkt_id = rdr.u16();
|
|
538
|
-
if (5 <= pkt.mqtt_level)
|
|
539
|
-
pkt.props = rdr.props();
|
|
540
|
-
|
|
541
|
-
let answers = pkt.answers = [];
|
|
542
|
-
while (rdr.has_more())
|
|
543
|
-
answers.push(
|
|
544
|
-
rdr.reason(pkt.type) );
|
|
545
|
-
|
|
546
|
-
return pkt }
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
function mqtt_decode_suback(ns, mqtt_reader) {
|
|
550
|
-
return ns[0x9] = _mqtt_decode_suback(mqtt_reader)
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
function _suback_v4(mqtt_reader) {
|
|
554
|
-
mqtt_reader.reasons('suback',
|
|
555
|
-
// MQTT 3.1.1
|
|
556
|
-
[ 0x00, 'Granted QoS 0'],
|
|
557
|
-
[ 0x01, 'Granted QoS 1'],
|
|
558
|
-
[ 0x02, 'Granted QoS 2'],
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
function _suback_v5(mqtt_reader) {
|
|
563
|
-
_suback_v4(mqtt_reader);
|
|
564
|
-
|
|
565
|
-
mqtt_reader.reasons('suback',
|
|
566
|
-
// MQTT 5.0
|
|
567
|
-
[ 0x80, 'Unspecified error'],
|
|
568
|
-
[ 0x83, 'Implementation specific error'],
|
|
569
|
-
[ 0x87, 'Not authorized'],
|
|
570
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
571
|
-
[ 0x91, 'Packet Identifier in use'],
|
|
572
|
-
[ 0x97, 'Quota exceeded'],
|
|
573
|
-
[ 0x9E, 'Shared Subscriptions not supported'],
|
|
574
|
-
[ 0xA1, 'Subscription Identifiers not supported'],
|
|
575
|
-
[ 0xA2, 'Wildcard Subscriptions not supported'],
|
|
576
|
-
);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
function mqtt_decode_unsubscribe(ns, mqtt_reader) {
|
|
580
|
-
return ns[0xa] = (pkt, u8_body) => {
|
|
581
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
582
|
-
|
|
583
|
-
pkt.pkt_id = rdr.u16();
|
|
584
|
-
if (5 <= pkt.mqtt_level)
|
|
585
|
-
pkt.props = rdr.props();
|
|
586
|
-
|
|
587
|
-
let topic_list = pkt.topics = [];
|
|
588
|
-
while (rdr.has_more())
|
|
589
|
-
topic_list.push(rdr.utf8());
|
|
590
|
-
|
|
591
|
-
return pkt }
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
function mqtt_decode_unsuback(ns, mqtt_reader) {
|
|
595
|
-
return ns[0xb] = _mqtt_decode_suback(mqtt_reader)
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
function _unsuback_v4(mqtt_reader) {
|
|
599
|
-
mqtt_reader.reasons('unsuback',
|
|
600
|
-
// MQTT 3.1.1
|
|
601
|
-
[ 0x00, 'Success'],
|
|
602
|
-
[ 0x11, 'No subscription existed'],
|
|
603
|
-
[ 0x80, 'Unspecified error'],
|
|
604
|
-
[ 0x83, 'Implementation specific error'],
|
|
605
|
-
[ 0x87, 'Not authorized'],
|
|
606
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
607
|
-
[ 0x91, 'Packet Identifier in use'],
|
|
608
|
-
);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
function mqtt_decode_pingxxx(ns) {
|
|
612
|
-
return ns[0xc] = ns[0xd] = pkt => pkt
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
function mqtt_decode_disconnect(ns, mqtt_reader) {
|
|
616
|
-
return ns[0xe] = (pkt, u8_body) => {
|
|
617
|
-
if (u8_body && 5 <= pkt.mqtt_level) {
|
|
618
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
619
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
620
|
-
pkt.props = rdr.props();
|
|
621
|
-
}
|
|
622
|
-
return pkt }
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
function _disconnect_v5(mqtt_reader) {
|
|
627
|
-
mqtt_reader.reasons('disconnect',
|
|
628
|
-
// MQTT 5.0
|
|
629
|
-
[ 0x00, 'Normal disconnection'],
|
|
630
|
-
[ 0x04, 'Disconnect with Will Message'],
|
|
631
|
-
[ 0x80, 'Unspecified error'],
|
|
632
|
-
[ 0x81, 'Malformed Packet'],
|
|
633
|
-
[ 0x82, 'Protocol Error'],
|
|
634
|
-
[ 0x83, 'Implementation specific error'],
|
|
635
|
-
[ 0x87, 'Not authorized'],
|
|
636
|
-
[ 0x89, 'Server busy'],
|
|
637
|
-
[ 0x8B, 'Server shutting down'],
|
|
638
|
-
[ 0x8D, 'Keep Alive timeout'],
|
|
639
|
-
[ 0x8E, 'Session taken over'],
|
|
640
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
641
|
-
[ 0x90, 'Topic Name invalid'],
|
|
642
|
-
[ 0x93, 'Receive Maximum exceeded'],
|
|
643
|
-
[ 0x94, 'Topic Alias invalid'],
|
|
644
|
-
[ 0x95, 'Packet too large'],
|
|
645
|
-
[ 0x96, 'Message rate too high'],
|
|
646
|
-
[ 0x97, 'Quota exceeded'],
|
|
647
|
-
[ 0x98, 'Administrative action'],
|
|
648
|
-
[ 0x99, 'Payload format invalid'],
|
|
649
|
-
[ 0x9A, 'Retain not supported'],
|
|
650
|
-
[ 0x9B, 'QoS not supported'],
|
|
651
|
-
[ 0x9C, 'Use another server'],
|
|
652
|
-
[ 0x9D, 'Server moved'],
|
|
653
|
-
[ 0x9E, 'Shared Subscriptions not supported'],
|
|
654
|
-
[ 0x9F, 'Connection rate exceeded'],
|
|
655
|
-
[ 0xA0, 'Maximum connect time'],
|
|
656
|
-
[ 0xA1, 'Subscription Identifiers not supported'],
|
|
657
|
-
[ 0xA2, 'Wildcard Subscriptions not supported'],
|
|
658
|
-
);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
function mqtt_decode_auth(ns, mqtt_reader) {
|
|
662
|
-
return ns[0xf] = (pkt, u8_body) => {
|
|
663
|
-
if ( 5 <= pkt.mqtt_level ) {
|
|
664
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
665
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
666
|
-
pkt.props = rdr.props();
|
|
667
|
-
}
|
|
668
|
-
return pkt }
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
function _auth_v5(mqtt_reader) {
|
|
673
|
-
mqtt_reader.reasons('auth',
|
|
674
|
-
// MQTT 5.0
|
|
675
|
-
[ 0x00, 'Success' ],
|
|
676
|
-
[ 0x18, 'Continue authentication' ],
|
|
677
|
-
[ 0x19, 'Re-authenticate' ],
|
|
678
|
-
);
|
|
679
|
-
}
|
|
680
|
-
|
|
681
383
|
function mqtt_encode_connect(ns, mqtt_writer) {
|
|
682
384
|
const _c_mqtt_proto = new Uint8Array([
|
|
683
385
|
0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
|
|
@@ -696,7 +398,7 @@ function mqtt_encode_connect(ns, mqtt_writer) {
|
|
|
696
398
|
| ( will.retain ? 0x20 : 0 );
|
|
697
399
|
|
|
698
400
|
return ns.connect = ( mqtt_level, pkt ) => {
|
|
699
|
-
let wrt = mqtt_writer.
|
|
401
|
+
let wrt = mqtt_writer.for(pkt);
|
|
700
402
|
|
|
701
403
|
wrt.push(_c_mqtt_proto);
|
|
702
404
|
wrt.u8( mqtt_level );
|
|
@@ -734,12 +436,61 @@ function mqtt_encode_connect(ns, mqtt_writer) {
|
|
|
734
436
|
}
|
|
735
437
|
}
|
|
736
438
|
|
|
439
|
+
function mqtt_decode_connect(ns, mqtt_reader) {
|
|
440
|
+
class _connect_flags_ extends Number {
|
|
441
|
+
get reserved() { return this & 0x01 !== 0 }
|
|
442
|
+
get clean_start() { return this & 0x02 !== 0 }
|
|
443
|
+
get will_flag() { return this & 0x04 !== 0 }
|
|
444
|
+
get will_qos() { return (this >>> 3) & 0x3 }
|
|
445
|
+
get will_retain() { return this & 0x20 !== 0 }
|
|
446
|
+
get password() { return this & 0x40 !== 0 }
|
|
447
|
+
get username() { return this & 0x80 !== 0 }
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return ns[0x1] = (pkt, u8_body) => {
|
|
451
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
452
|
+
if ('MQTT' !== rdr.utf8())
|
|
453
|
+
throw new Error('Invalid mqtt_connect packet')
|
|
454
|
+
|
|
455
|
+
pkt.__proto__.mqtt_level =
|
|
456
|
+
pkt.mqtt_level = rdr.u8();
|
|
457
|
+
|
|
458
|
+
let flags = pkt.flags =
|
|
459
|
+
rdr.flags(_connect_flags_);
|
|
460
|
+
|
|
461
|
+
pkt.keep_alive = rdr.u16();
|
|
462
|
+
|
|
463
|
+
if (5 <= pkt.mqtt_level)
|
|
464
|
+
pkt.props = rdr.props();
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
pkt.client_id = rdr.utf8();
|
|
469
|
+
if (flags.will_flag) {
|
|
470
|
+
let will = pkt.will = {};
|
|
471
|
+
if (5 <= pkt.mqtt_level)
|
|
472
|
+
will.props = rdr.props();
|
|
473
|
+
|
|
474
|
+
will.topic = rdr.utf8();
|
|
475
|
+
will.payload = rdr.bin();
|
|
476
|
+
will.qos = flags.will_qos;
|
|
477
|
+
will.retain = flags.will_retain;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (flags.username)
|
|
481
|
+
pkt.username = rdr.utf8();
|
|
482
|
+
|
|
483
|
+
if (flags.password)
|
|
484
|
+
pkt.password = rdr.bin();
|
|
485
|
+
return pkt }
|
|
486
|
+
}
|
|
487
|
+
|
|
737
488
|
function mqtt_encode_connack(ns, mqtt_writer) {
|
|
738
489
|
const _enc_flags_connack = flags =>
|
|
739
490
|
flags.session_present ? 1 : 0;
|
|
740
491
|
|
|
741
492
|
return ns.connack = (mqtt_level, pkt) => {
|
|
742
|
-
let wrt = mqtt_writer.
|
|
493
|
+
let wrt = mqtt_writer.for(pkt);
|
|
743
494
|
|
|
744
495
|
wrt.flags( pkt.flags, _enc_flags_connack );
|
|
745
496
|
|
|
@@ -755,10 +506,28 @@ function mqtt_encode_connack(ns, mqtt_writer) {
|
|
|
755
506
|
}
|
|
756
507
|
}
|
|
757
508
|
|
|
509
|
+
|
|
510
|
+
function mqtt_decode_connack(ns, mqtt_reader) {
|
|
511
|
+
class _connack_flags_ extends Number {
|
|
512
|
+
get session_present() { return this & 0x01 !== 0 }
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
return ns[0x2] = (pkt, u8_body) => {
|
|
516
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
517
|
+
|
|
518
|
+
pkt.flags =
|
|
519
|
+
rdr.flags(_connack_flags_);
|
|
520
|
+
|
|
521
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
522
|
+
if (5 <= pkt.mqtt_level)
|
|
523
|
+
pkt.props = rdr.props();
|
|
524
|
+
return pkt }
|
|
525
|
+
}
|
|
526
|
+
|
|
758
527
|
function mqtt_encode_publish(ns, mqtt_writer) {
|
|
759
528
|
return ns.publish = ( mqtt_level, pkt ) => {
|
|
760
529
|
let qos = (pkt.qos & 0x3) << 1;
|
|
761
|
-
let wrt = mqtt_writer.
|
|
530
|
+
let wrt = mqtt_writer.for(pkt);
|
|
762
531
|
|
|
763
532
|
wrt.utf8(pkt.topic);
|
|
764
533
|
if (0 !== qos)
|
|
@@ -776,9 +545,28 @@ function mqtt_encode_publish(ns, mqtt_writer) {
|
|
|
776
545
|
}
|
|
777
546
|
}
|
|
778
547
|
|
|
548
|
+
function mqtt_decode_publish(ns, mqtt_reader) {
|
|
549
|
+
return ns[0x3] = (pkt, u8_body) => {
|
|
550
|
+
let {hdr} = pkt;
|
|
551
|
+
pkt.dup = Boolean(hdr & 0x8);
|
|
552
|
+
pkt.retain = Boolean(hdr & 0x1);
|
|
553
|
+
let qos = pkt.qos = (hdr>>1) & 0x3;
|
|
554
|
+
|
|
555
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
556
|
+
pkt.topic = rdr.utf8();
|
|
557
|
+
if (0 !== qos)
|
|
558
|
+
pkt.pkt_id = rdr.u16();
|
|
559
|
+
|
|
560
|
+
if (5 <= pkt.mqtt_level)
|
|
561
|
+
pkt.props = rdr.props();
|
|
562
|
+
|
|
563
|
+
pkt.payload = rdr.flush();
|
|
564
|
+
return pkt }
|
|
565
|
+
}
|
|
566
|
+
|
|
779
567
|
function mqtt_encode_puback(ns, mqtt_writer) {
|
|
780
568
|
return ns.puback = ( mqtt_level, pkt ) => {
|
|
781
|
-
let wrt = mqtt_writer.
|
|
569
|
+
let wrt = mqtt_writer.for(pkt);
|
|
782
570
|
|
|
783
571
|
wrt.u16(pkt.pkt_id);
|
|
784
572
|
if (5 <= mqtt_level) {
|
|
@@ -790,6 +578,20 @@ function mqtt_encode_puback(ns, mqtt_writer) {
|
|
|
790
578
|
}
|
|
791
579
|
}
|
|
792
580
|
|
|
581
|
+
|
|
582
|
+
function mqtt_decode_puback(ns, mqtt_reader) {
|
|
583
|
+
return ns[0x4] = (pkt, u8_body) => {
|
|
584
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
585
|
+
|
|
586
|
+
pkt.pkt_id = rdr.u16();
|
|
587
|
+
if (5 <= pkt.mqtt_level) {
|
|
588
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
589
|
+
pkt.props = rdr.props();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return pkt }
|
|
593
|
+
}
|
|
594
|
+
|
|
793
595
|
function mqtt_encode_pubxxx(ns, mqtt_writer) {
|
|
794
596
|
ns.pubrec = _enc_pubxxx(0x50);
|
|
795
597
|
ns.pubrel = _enc_pubxxx(0x62);
|
|
@@ -798,7 +600,7 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
|
|
|
798
600
|
|
|
799
601
|
function _enc_pubxxx(hdr) {
|
|
800
602
|
return ( mqtt_level, pkt ) => {
|
|
801
|
-
let wrt = mqtt_writer.
|
|
603
|
+
let wrt = mqtt_writer.for(pkt);
|
|
802
604
|
|
|
803
605
|
wrt.u16(pkt.pkt_id);
|
|
804
606
|
if (5 <= mqtt_level) {
|
|
@@ -814,6 +616,17 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
|
|
|
814
616
|
}
|
|
815
617
|
}
|
|
816
618
|
|
|
619
|
+
function mqtt_decode_pubxxx(ns, mqtt_reader) {
|
|
620
|
+
return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
|
|
621
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
622
|
+
|
|
623
|
+
pkt.pkt_id = rdr.u16();
|
|
624
|
+
pkt.reason = rdr.reason('pubxxx', mqtt_reader);
|
|
625
|
+
if (5 <= pkt.mqtt_level)
|
|
626
|
+
pkt.props = rdr.props();
|
|
627
|
+
return pkt }
|
|
628
|
+
}
|
|
629
|
+
|
|
817
630
|
function mqtt_encode_subscribe(ns, mqtt_writer) {
|
|
818
631
|
const _enc_subscribe_flags = opts => 0
|
|
819
632
|
| ( opts.qos & 0x3 )
|
|
@@ -821,7 +634,7 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
|
|
|
821
634
|
| ( (opts.retain_handling & 0x3) << 2 );
|
|
822
635
|
|
|
823
636
|
return ns.subscribe = ( mqtt_level, pkt ) => {
|
|
824
|
-
let wrt = mqtt_writer.
|
|
637
|
+
let wrt = mqtt_writer.for(pkt);
|
|
825
638
|
|
|
826
639
|
wrt.u16(pkt.pkt_id);
|
|
827
640
|
if (5 <= mqtt_level)
|
|
@@ -847,6 +660,30 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
|
|
|
847
660
|
}
|
|
848
661
|
}
|
|
849
662
|
|
|
663
|
+
function mqtt_decode_subscribe(ns, mqtt_reader) {
|
|
664
|
+
class _subscription_options_ extends Number {
|
|
665
|
+
get qos() { return this & 0x3 }
|
|
666
|
+
get retain() { return this & 0x4 !== 0 }
|
|
667
|
+
get retain_handling() { return (this >> 2) & 0x3 }
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
return ns[0x8] = (pkt, u8_body) => {
|
|
671
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
672
|
+
|
|
673
|
+
pkt.pkt_id = rdr.u16();
|
|
674
|
+
if (5 <= pkt.mqtt_level)
|
|
675
|
+
pkt.props = rdr.props();
|
|
676
|
+
|
|
677
|
+
let topic, opts, topic_list = pkt.topics = [];
|
|
678
|
+
while (rdr.has_more()) {
|
|
679
|
+
topic = rdr.utf8();
|
|
680
|
+
opts = rdr.flags(_subscription_options_);
|
|
681
|
+
topic_list.push({topic, opts});
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
return pkt }
|
|
685
|
+
}
|
|
686
|
+
|
|
850
687
|
function mqtt_encode_xxsuback(ns, mqtt_writer) {
|
|
851
688
|
ns.suback = _enc_xxsuback(0x90);
|
|
852
689
|
ns.unsuback = _enc_xxsuback(0xb0);
|
|
@@ -854,7 +691,7 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
|
|
|
854
691
|
|
|
855
692
|
function _enc_xxsuback(hdr) {
|
|
856
693
|
return ( mqtt_level, pkt ) => {
|
|
857
|
-
let wrt = mqtt_writer.
|
|
694
|
+
let wrt = mqtt_writer.for(pkt);
|
|
858
695
|
|
|
859
696
|
wrt.u16(pkt.pkt_id);
|
|
860
697
|
if (5 <= mqtt_level)
|
|
@@ -868,9 +705,26 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
|
|
|
868
705
|
}
|
|
869
706
|
}
|
|
870
707
|
|
|
708
|
+
|
|
709
|
+
function mqtt_decode_xxsuback(ns, mqtt_reader) {
|
|
710
|
+
return ns[0x9] = ns[0xb] = (pkt, u8_body) => {
|
|
711
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
712
|
+
|
|
713
|
+
pkt.pkt_id = rdr.u16();
|
|
714
|
+
if (5 <= pkt.mqtt_level)
|
|
715
|
+
pkt.props = rdr.props();
|
|
716
|
+
|
|
717
|
+
let answers = pkt.answers = [];
|
|
718
|
+
while (rdr.has_more())
|
|
719
|
+
answers.push(
|
|
720
|
+
rdr.reason(pkt.type) );
|
|
721
|
+
|
|
722
|
+
return pkt }
|
|
723
|
+
}
|
|
724
|
+
|
|
871
725
|
function mqtt_encode_unsubscribe(ns, mqtt_writer) {
|
|
872
726
|
return ns.unsubscribe = ( mqtt_level, pkt ) => {
|
|
873
|
-
let wrt = mqtt_writer.
|
|
727
|
+
let wrt = mqtt_writer.for(pkt);
|
|
874
728
|
|
|
875
729
|
wrt.u16(pkt.pkt_id);
|
|
876
730
|
if (5 <= mqtt_level)
|
|
@@ -883,14 +737,34 @@ function mqtt_encode_unsubscribe(ns, mqtt_writer) {
|
|
|
883
737
|
}
|
|
884
738
|
}
|
|
885
739
|
|
|
740
|
+
function mqtt_decode_unsubscribe(ns, mqtt_reader) {
|
|
741
|
+
return ns[0xa] = (pkt, u8_body) => {
|
|
742
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
743
|
+
|
|
744
|
+
pkt.pkt_id = rdr.u16();
|
|
745
|
+
if (5 <= pkt.mqtt_level)
|
|
746
|
+
pkt.props = rdr.props();
|
|
747
|
+
|
|
748
|
+
let topic_list = pkt.topics = [];
|
|
749
|
+
while (rdr.has_more())
|
|
750
|
+
topic_list.push(rdr.utf8());
|
|
751
|
+
|
|
752
|
+
return pkt }
|
|
753
|
+
}
|
|
754
|
+
|
|
886
755
|
function mqtt_encode_pingxxx(ns) {
|
|
887
756
|
ns.pingreq = () => new Uint8Array([ 0xc0, 0 ]);
|
|
888
757
|
ns.pingresp = () => new Uint8Array([ 0xd0, 0 ]);
|
|
889
758
|
}
|
|
890
759
|
|
|
760
|
+
|
|
761
|
+
function mqtt_decode_pingxxx(ns) {
|
|
762
|
+
return ns[0xc] = ns[0xd] = pkt => pkt
|
|
763
|
+
}
|
|
764
|
+
|
|
891
765
|
function mqtt_encode_disconnect(ns, mqtt_writer) {
|
|
892
766
|
return ns.disconnect = ( mqtt_level, pkt ) => {
|
|
893
|
-
let wrt = mqtt_writer.
|
|
767
|
+
let wrt = mqtt_writer.for(pkt);
|
|
894
768
|
|
|
895
769
|
if (pkt && 5 <= mqtt_level) {
|
|
896
770
|
if (pkt.reason || pkt.props) {
|
|
@@ -903,6 +777,17 @@ function mqtt_encode_disconnect(ns, mqtt_writer) {
|
|
|
903
777
|
}
|
|
904
778
|
}
|
|
905
779
|
|
|
780
|
+
|
|
781
|
+
function mqtt_decode_disconnect(ns, mqtt_reader) {
|
|
782
|
+
return ns[0xe] = (pkt, u8_body) => {
|
|
783
|
+
if (u8_body && 5 <= pkt.mqtt_level) {
|
|
784
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
785
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
786
|
+
pkt.props = rdr.props();
|
|
787
|
+
}
|
|
788
|
+
return pkt }
|
|
789
|
+
}
|
|
790
|
+
|
|
906
791
|
function mqtt_encode_auth(ns, mqtt_writer) {
|
|
907
792
|
return ns.auth = ( mqtt_level, pkt ) => {
|
|
908
793
|
if (5 > mqtt_level)
|
|
@@ -917,17 +802,15 @@ function mqtt_encode_auth(ns, mqtt_writer) {
|
|
|
917
802
|
}
|
|
918
803
|
}
|
|
919
804
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
_auth_v5,
|
|
930
|
-
);
|
|
805
|
+
function mqtt_decode_auth(ns, mqtt_reader) {
|
|
806
|
+
return ns[0xf] = (pkt, u8_body) => {
|
|
807
|
+
if ( 5 <= pkt.mqtt_level ) {
|
|
808
|
+
let rdr = mqtt_reader.of(u8_body);
|
|
809
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
810
|
+
pkt.props = rdr.props();
|
|
811
|
+
}
|
|
812
|
+
return pkt }
|
|
813
|
+
}
|
|
931
814
|
|
|
932
815
|
const mqtt_decode_v5 = [
|
|
933
816
|
mqtt_decode_connect,
|
|
@@ -936,9 +819,8 @@ const mqtt_decode_v5 = [
|
|
|
936
819
|
mqtt_decode_puback,
|
|
937
820
|
mqtt_decode_pubxxx,
|
|
938
821
|
mqtt_decode_subscribe,
|
|
939
|
-
|
|
822
|
+
mqtt_decode_xxsuback,
|
|
940
823
|
mqtt_decode_unsubscribe,
|
|
941
|
-
mqtt_decode_unsuback,
|
|
942
824
|
mqtt_decode_pingxxx,
|
|
943
825
|
mqtt_decode_disconnect,
|
|
944
826
|
mqtt_decode_auth,
|
|
@@ -1164,47 +1046,38 @@ function _route_remove(all_route_lists, query) {
|
|
|
1164
1046
|
return true} }
|
|
1165
1047
|
return false}
|
|
1166
1048
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
while ( 0x80 & u8[i++] )
|
|
1172
|
-
n |= (u8[i] & 0x7f) << (shift += 7)
|
|
1173
|
-
|
|
1174
|
-
return [n, i, i0]
|
|
1175
|
-
}
|
|
1176
|
-
*/
|
|
1049
|
+
function decode_varint(u8, i0=0, invalid) {
|
|
1050
|
+
let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
|
|
1051
|
+
for(; b & 0x80;)
|
|
1052
|
+
n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
|
|
1177
1053
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
// unrolled for a max of 4 chains
|
|
1182
|
-
let n = (u8[i] & 0x7f) << 0;
|
|
1183
|
-
if ( 0x80 & u8[i++] ) {
|
|
1184
|
-
n |= (u8[i] & 0x7f) << 7;
|
|
1185
|
-
if ( 0x80 & u8[i++] ) {
|
|
1186
|
-
n |= (u8[i] & 0x7f) << 14;
|
|
1187
|
-
if ( 0x80 & u8[i++] ) {
|
|
1188
|
-
n |= (u8[i] & 0x7f) << 21;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
return [n, i, i0]
|
|
1054
|
+
return (u8.length < i)
|
|
1055
|
+
? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
|
|
1056
|
+
: [n, i, i0] // successful value
|
|
1193
1057
|
}
|
|
1194
1058
|
|
|
1195
1059
|
function mqtt_raw_dispatch(opt) {
|
|
1196
|
-
let u8 = new Uint8Array(0);
|
|
1060
|
+
let u8 = new Uint8Array(0), len_tip=0;
|
|
1197
1061
|
return u8_buf => {
|
|
1198
1062
|
u8 = 0 === u8.byteLength
|
|
1199
1063
|
? u8_buf : _u8_join(u8, u8_buf);
|
|
1200
1064
|
|
|
1201
1065
|
let res = [];
|
|
1202
|
-
while (1) {
|
|
1203
|
-
let [len_body, len_vh] = decode_varint(u8, 1);
|
|
1204
|
-
let len_pkt = len_body + len_vh;
|
|
1205
1066
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1067
|
+
// wait for at least len_tip bytes for next (tip) message
|
|
1068
|
+
while ( u8.byteLength >= len_tip ) {
|
|
1069
|
+
|
|
1070
|
+
// if varint is incomplete, return len_body=NaN
|
|
1071
|
+
let [len_body, len_vh] = decode_varint(u8, 1, NaN);
|
|
1072
|
+
let len_pkt = len_body + len_vh; // may be NaN
|
|
1073
|
+
|
|
1074
|
+
if (!( len_pkt <= u8.byteLength )) {
|
|
1075
|
+
// incomplete packet cases:
|
|
1076
|
+
// - len_pkt is less than available bytes
|
|
1077
|
+
// - len_pkt is NaN from decode_varint() due to lack of data
|
|
1078
|
+
len_tip = len_pkt || 0; // 0 when NaN
|
|
1079
|
+
break
|
|
1080
|
+
}
|
|
1208
1081
|
|
|
1209
1082
|
let b0 = u8[0];
|
|
1210
1083
|
let u8_body = 0 === len_body ? null
|
|
@@ -1216,6 +1089,8 @@ function mqtt_raw_dispatch(opt) {
|
|
|
1216
1089
|
if (null != pkt)
|
|
1217
1090
|
res.push( pkt );
|
|
1218
1091
|
}
|
|
1092
|
+
|
|
1093
|
+
return res
|
|
1219
1094
|
}
|
|
1220
1095
|
}
|
|
1221
1096
|
|
|
@@ -1226,16 +1101,17 @@ function _u8_join(a, b) {
|
|
|
1226
1101
|
return r
|
|
1227
1102
|
}
|
|
1228
1103
|
|
|
1229
|
-
const _pkt_types =
|
|
1104
|
+
const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
function mqtt_pkt_ctx(mqtt_level, opts, pkt_api=opts.pkt_ctx) {
|
|
1108
|
+
let _as_pkt_ctx = pkt_api => ({
|
|
1109
|
+
__proto__: pkt_api,
|
|
1110
|
+
get hdr() { return this.b0 & 0xf },
|
|
1111
|
+
get id() { return this.b0 >>> 4 },
|
|
1112
|
+
get type() { return _pkt_types[this.b0 >>> 4] },
|
|
1113
|
+
mqtt_level });
|
|
1230
1114
|
|
|
1231
|
-
function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
1232
|
-
pkt_ctx = {
|
|
1233
|
-
__proto__: pkt_ctx || opts.pkt_ctx,
|
|
1234
|
-
mqtt_level,
|
|
1235
|
-
get hdr() { return this.b0 & 0xf },
|
|
1236
|
-
get id() { return this.b0 >>> 4 },
|
|
1237
|
-
get type() { return _pkt_types[this.b0 >>> 4] },
|
|
1238
|
-
};
|
|
1239
1115
|
|
|
1240
1116
|
let op, _decode_by_id=[], _encode_by_type={};
|
|
1241
1117
|
for (op of opts.encode_fns)
|
|
@@ -1244,10 +1120,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
|
1244
1120
|
op(_decode_by_id, opts.mqtt_reader);
|
|
1245
1121
|
|
|
1246
1122
|
return {
|
|
1247
|
-
pkt_ctx,
|
|
1123
|
+
pkt_api, pkt_ctx: _as_pkt_ctx(pkt_api),
|
|
1248
1124
|
|
|
1249
|
-
encode_pkt(type, pkt)
|
|
1250
|
-
|
|
1125
|
+
encode_pkt: (type, pkt) =>
|
|
1126
|
+
_encode_by_type[type]( mqtt_level, pkt ),
|
|
1251
1127
|
|
|
1252
1128
|
decode_pkt(b0, u8_body) {
|
|
1253
1129
|
if (b0.map) // Uint8Array in first arg
|
|
@@ -1256,12 +1132,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
|
1256
1132
|
let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
|
|
1257
1133
|
return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
|
|
1258
1134
|
|
|
1259
|
-
mqtt_stream() {
|
|
1260
|
-
let self = { __proto__: this, pkt_ctx:
|
|
1261
|
-
self.pkt_ctx._base_ = self.pkt_ctx;
|
|
1135
|
+
mqtt_stream(pkt_api=this.pkt_api) {
|
|
1136
|
+
let self = { __proto__: this, pkt_ctx: _as_pkt_ctx(pkt_api) };
|
|
1262
1137
|
self.decode = mqtt_raw_dispatch(self);
|
|
1263
|
-
return self
|
|
1264
|
-
},
|
|
1138
|
+
return self },
|
|
1265
1139
|
}
|
|
1266
1140
|
}
|
|
1267
1141
|
|
|
@@ -1785,7 +1659,7 @@ class MQTTCore extends MQTTBase {
|
|
|
1785
1659
|
|
|
1786
1660
|
return this} }
|
|
1787
1661
|
|
|
1788
|
-
const version = '0.6.
|
|
1662
|
+
const version = '0.6.3-node';
|
|
1789
1663
|
|
|
1790
1664
|
const MQTTClient_v4 = /* #__PURE__ */
|
|
1791
1665
|
with_topic_path_router(
|