u8-mqtt 0.6.2 → 0.6.4
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 +247 -368
- package/cjs/basic-v5.cjs.map +1 -1
- package/cjs/full-v4.cjs +342 -384
- package/cjs/full-v4.cjs.map +1 -1
- package/cjs/full-v5.cjs +395 -507
- package/cjs/full-v5.cjs.map +1 -1
- package/cjs/index.cjs +292 -399
- package/cjs/index.cjs.map +1 -1
- package/cjs/v4.cjs +239 -274
- package/cjs/v4.cjs.map +1 -1
- package/cjs/v5.cjs +292 -399
- package/cjs/v5.cjs.map +1 -1
- package/code/router_path.jsy +39 -28
- package/code/with_topic_router.jsy +4 -1
- package/esm/basic-v4.js +194 -243
- package/esm/basic-v4.js.map +1 -1
- package/esm/basic-v5.js +247 -368
- 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 +247 -368
- package/esm/deno/basic-v5.js.map +1 -1
- package/esm/deno/full-v4.js +342 -384
- package/esm/deno/full-v4.js.map +1 -1
- package/esm/deno/full-v5.js +395 -507
- package/esm/deno/full-v5.js.map +1 -1
- package/esm/deno/index.js +292 -399
- package/esm/deno/index.js.map +1 -1
- package/esm/deno/v4.js +239 -274
- package/esm/deno/v4.js.map +1 -1
- package/esm/deno/v5.js +292 -399
- package/esm/deno/v5.js.map +1 -1
- package/esm/full-v4.js +342 -384
- package/esm/full-v4.js.map +1 -1
- package/esm/full-v5.js +395 -507
- package/esm/full-v5.js.map +1 -1
- package/esm/index.js +292 -399
- 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 +247 -368
- package/esm/node/basic-v5.js.map +1 -1
- package/esm/node/basic-v5.mjs +247 -368
- package/esm/node/basic-v5.mjs.map +1 -1
- package/esm/node/full-v4.js +342 -384
- package/esm/node/full-v4.js.map +1 -1
- package/esm/node/full-v4.mjs +342 -384
- package/esm/node/full-v4.mjs.map +1 -1
- package/esm/node/full-v5.js +395 -507
- package/esm/node/full-v5.js.map +1 -1
- package/esm/node/full-v5.mjs +395 -507
- package/esm/node/full-v5.mjs.map +1 -1
- package/esm/node/index.js +292 -399
- package/esm/node/index.js.map +1 -1
- package/esm/node/index.mjs +292 -399
- package/esm/node/index.mjs.map +1 -1
- package/esm/node/v4.js +239 -274
- package/esm/node/v4.js.map +1 -1
- package/esm/node/v4.mjs +239 -274
- package/esm/node/v4.mjs.map +1 -1
- package/esm/node/v5.js +292 -399
- package/esm/node/v5.js.map +1 -1
- package/esm/node/v5.mjs +292 -399
- package/esm/node/v5.mjs.map +1 -1
- package/esm/v4.js +239 -274
- package/esm/v4.js.map +1 -1
- package/esm/v5.js +292 -399
- 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 +247 -368
- 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 +342 -384
- 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 +395 -507
- 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 +292 -399
- 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 +239 -274
- 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 +292 -399
- 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 +5 -5
package/esm/web/full-v5.js
CHANGED
|
@@ -1,39 +1,18 @@
|
|
|
1
1
|
function encode_varint(n, a=[]) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
n
|
|
5
|
-
a.push( ni | (0===n ? 0 : 0x80) );
|
|
6
|
-
} while (n > 0)
|
|
2
|
+
a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
|
|
3
|
+
for(; ( n>>>=7 ) > 0 ;)
|
|
4
|
+
a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
|
|
7
5
|
return a
|
|
8
6
|
}
|
|
9
7
|
|
|
8
|
+
function decode_varint$1(u8, i0=0, invalid) {
|
|
9
|
+
let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
|
|
10
|
+
for(; b & 0x80;)
|
|
11
|
+
n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
let shift = 0, n = (u8[i] & 0x7f)
|
|
15
|
-
while ( 0x80 & u8[i++] )
|
|
16
|
-
n |= (u8[i] & 0x7f) << (shift += 7)
|
|
17
|
-
|
|
18
|
-
return [n, i, i0]
|
|
19
|
-
}
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function decode_varint$1(u8, i=0) {
|
|
24
|
-
let i0 = i;
|
|
25
|
-
// unrolled for a max of 4 chains
|
|
26
|
-
let n = (u8[i] & 0x7f) << 0;
|
|
27
|
-
if ( 0x80 & u8[i++] ) {
|
|
28
|
-
n |= (u8[i] & 0x7f) << 7;
|
|
29
|
-
if ( 0x80 & u8[i++] ) {
|
|
30
|
-
n |= (u8[i] & 0x7f) << 14;
|
|
31
|
-
if ( 0x80 & u8[i++] ) {
|
|
32
|
-
n |= (u8[i] & 0x7f) << 21;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return [n, i, i0]
|
|
13
|
+
return (u8.length < i)
|
|
14
|
+
? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
|
|
15
|
+
: [n, i, i0] // successful value
|
|
37
16
|
}
|
|
38
17
|
|
|
39
18
|
function add_mqtt_props(mqtt_props, entries) {
|
|
@@ -80,19 +59,18 @@ const init_mqtt_props = () =>
|
|
|
80
59
|
const mqtt_props = /* #__PURE__ */
|
|
81
60
|
init_mqtt_props();
|
|
82
61
|
|
|
83
|
-
class
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return self
|
|
62
|
+
class mqtt_reason extends Number {
|
|
63
|
+
constructor(v, reason) {
|
|
64
|
+
super(v);
|
|
65
|
+
this.reason = `:${(this.ok = v<0x80) ? 'ok' : 'fail'}:${reason}`;
|
|
88
66
|
}
|
|
89
67
|
}
|
|
90
68
|
|
|
91
69
|
class mqtt_reader_v4 {
|
|
92
|
-
static
|
|
93
|
-
of(buf) {
|
|
70
|
+
static for(pkt, u8_body) { return new this().of(u8_body, {pkt}) }
|
|
71
|
+
of(buf, opt) {
|
|
94
72
|
let step = (width, k) => (k=0|step.k, step.k=k+width, k);
|
|
95
|
-
return {__proto__: this, buf, step}
|
|
73
|
+
return {__proto__: this, buf, step, ...opt}
|
|
96
74
|
}
|
|
97
75
|
|
|
98
76
|
has_more() {
|
|
@@ -135,7 +113,7 @@ class mqtt_reader_v4 {
|
|
|
135
113
|
reason(pkt_kind) {
|
|
136
114
|
let v = this.buf[this.step(1)];
|
|
137
115
|
if (null != v)
|
|
138
|
-
return
|
|
116
|
+
return new mqtt_reason(v, this._reason_for?.(v, pkt_kind))
|
|
139
117
|
}
|
|
140
118
|
|
|
141
119
|
flush() {
|
|
@@ -149,7 +127,7 @@ class mqtt_reader_v4 {
|
|
|
149
127
|
let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
|
|
150
128
|
props() {
|
|
151
129
|
let {buf, step} = this;
|
|
152
|
-
let [n, vi, vi0] = decode_varint$1(buf, step.k|0);
|
|
130
|
+
let [n, vi, vi0] = decode_varint$1(buf, step.k|0, 0);
|
|
153
131
|
step(n + vi - vi0);
|
|
154
132
|
if (0 === n) return null
|
|
155
133
|
|
|
@@ -158,7 +136,7 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
|
|
|
158
136
|
let v, pk = fork.u8(), pt = mqtt_props.get( pk );
|
|
159
137
|
if (!pt) {
|
|
160
138
|
res._unknown_ = pk;
|
|
161
|
-
this.warn(`unknown property: ${pk}`);
|
|
139
|
+
this.warn?.(`unknown property: ${pk}`);
|
|
162
140
|
break
|
|
163
141
|
}
|
|
164
142
|
|
|
@@ -178,8 +156,6 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
|
|
|
178
156
|
return vec
|
|
179
157
|
}
|
|
180
158
|
|
|
181
|
-
warn(msg) { console.warn('[u8-mqtt-packet] '+msg); }
|
|
182
|
-
|
|
183
159
|
/*
|
|
184
160
|
vbuf() {
|
|
185
161
|
let {buf, step} = this
|
|
@@ -191,28 +167,99 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
|
|
|
191
167
|
*/
|
|
192
168
|
};
|
|
193
169
|
|
|
194
|
-
function
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
let proto = this.prototype;
|
|
198
|
-
proto._reasons_by = {... proto._reasons_by};
|
|
170
|
+
function with_reasons(mqtt_reader, by_kind) {
|
|
171
|
+
for (let [k,lut] of Object.entries(by_kind))
|
|
172
|
+
by_kind[k] = new Map(lut);
|
|
199
173
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
174
|
+
return class extends mqtt_reader {
|
|
175
|
+
_reason_for(v, pkt_kind) {
|
|
176
|
+
return by_kind[pkt_kind]?.get(v) || by_kind.all.get(v)
|
|
177
|
+
}
|
|
178
|
+
warn(msg) {
|
|
179
|
+
let pkt = this.pkt;
|
|
180
|
+
pkt.warn ? pkt.warn(msg, pkt)
|
|
181
|
+
: console.warn('[u8-mqtt-packet] '+msg);
|
|
205
182
|
}
|
|
206
|
-
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
207
185
|
|
|
208
|
-
for (let fn_info of info_fn_list)
|
|
209
|
-
fn_info(mqtt_reader);
|
|
210
186
|
|
|
211
|
-
|
|
212
|
-
|
|
187
|
+
const reasons_v4 = {
|
|
188
|
+
connack: [
|
|
189
|
+
[ 0x01, 'conn refused: unacceptable protocol version'],
|
|
190
|
+
[ 0x02, 'conn refused: identifier rejected'],
|
|
191
|
+
[ 0x03, 'conn refused: server unavailable'],
|
|
192
|
+
[ 0x04, 'conn refused: bad user name or password'],
|
|
193
|
+
[ 0x05, 'conn refused: not authorized'],
|
|
194
|
+
],
|
|
195
|
+
suback: [
|
|
196
|
+
[ 0x00, 'qos=0'],
|
|
197
|
+
[ 0x01, 'qos=1'],
|
|
198
|
+
[ 0x02, 'qos=2'],
|
|
199
|
+
],
|
|
200
|
+
unsuback: [
|
|
201
|
+
[ 0x11, 'no subscription existed'],
|
|
202
|
+
],
|
|
203
|
+
puback: [
|
|
204
|
+
[ 0x10, 'no matching subscribers'],
|
|
205
|
+
],
|
|
206
|
+
all: [
|
|
207
|
+
[ 0, ''], // Success
|
|
208
|
+
[ 0x80, 'unspecified error'], // disconnect puback suback unsuback
|
|
209
|
+
[ 0x83, 'implementation specific error'], // connack disconnect puback suback unsuback
|
|
210
|
+
[ 0x87, 'not authorized'], // connack disconnect puback suback unsuback
|
|
211
|
+
[ 0x8F, 'topic filter invalid'], // disconnect suback unsuback
|
|
212
|
+
[ 0x91, 'packet identifier in use'], // puback suback unsuback
|
|
213
|
+
[ 0x92, 'packet identifier not found' ], // pubxxx
|
|
214
|
+
]};
|
|
215
|
+
|
|
216
|
+
const reasons_v5 = {
|
|
217
|
+
... reasons_v4,
|
|
218
|
+
auth: [
|
|
219
|
+
[ 0x18, 'continue authentication' ],
|
|
220
|
+
[ 0x19, 're-authenticate' ],
|
|
221
|
+
],
|
|
222
|
+
disconnect: [
|
|
223
|
+
[ 0x04, 'disconnect with will message'],
|
|
224
|
+
],
|
|
225
|
+
all: [
|
|
226
|
+
... reasons_v4.all,
|
|
227
|
+
[ 0x81, 'malformed packet'], // connack disconnect
|
|
228
|
+
[ 0x82, 'protocol error'], // connack disconnect
|
|
229
|
+
[ 0x84, 'unsupported protocol version'], // connack
|
|
230
|
+
[ 0x85, 'client identifier not valid'], // connack
|
|
231
|
+
[ 0x86, 'bad user name or password'], // connack
|
|
232
|
+
[ 0x88, 'server unavailable'], // connack
|
|
233
|
+
[ 0x89, 'server busy'], // connack disconnect
|
|
234
|
+
[ 0x8A, 'banned'], // connack
|
|
235
|
+
[ 0x8B, 'server shutting down'], // disconnect
|
|
236
|
+
[ 0x8C, 'bad authentication method'], // connack
|
|
237
|
+
[ 0x8D, 'keep alive timeout'], // disconnect
|
|
238
|
+
[ 0x8E, 'session taken over'], // disconnect
|
|
239
|
+
[ 0x90, 'topic name invalid'], // connack disconnect puback
|
|
240
|
+
[ 0x93, 'receive maximum exceeded'], // disconnect
|
|
241
|
+
[ 0x94, 'topic alias invalid'], // disconnect
|
|
242
|
+
[ 0x95, 'packet too large'], // connack disconnect
|
|
243
|
+
[ 0x96, 'message rate too high'], // disconnect
|
|
244
|
+
[ 0x97, 'quota exceeded'], // connack disconnect puback suback
|
|
245
|
+
[ 0x98, 'administrative action'], // disconnect
|
|
246
|
+
[ 0x99, 'payload format invalid'], // connack disconnect puback
|
|
247
|
+
[ 0x9A, 'retain not supported'], // connack disconnect
|
|
248
|
+
[ 0x9B, 'qoS not supported'], // connack disconnect
|
|
249
|
+
[ 0x9C, 'use another server'], // connack disconnect
|
|
250
|
+
[ 0x9D, 'server moved'], // connack disconnect
|
|
251
|
+
[ 0x9E, 'shared subscriptions not supported'], // disconnect suback
|
|
252
|
+
[ 0x9F, 'connection rate exceeded'], // connack disconnect
|
|
253
|
+
[ 0xA0, 'maximum connect time'], // disconnect
|
|
254
|
+
[ 0xA1, 'subscription identifiers not supported'], // disconnect suback
|
|
255
|
+
[ 0xA2, 'wildcard subscriptions not supported'], // disconnect suback
|
|
256
|
+
]};
|
|
257
|
+
|
|
258
|
+
const mqtt_reader_v5 = /* #__PURE__ */
|
|
259
|
+
with_reasons(mqtt_reader_v5$1, reasons_v5);
|
|
213
260
|
|
|
214
261
|
class mqtt_writer_v4 {
|
|
215
|
-
static
|
|
262
|
+
static for(pkt) { return new this().of() }
|
|
216
263
|
of() { return {__proto__: this, $:[]} }
|
|
217
264
|
|
|
218
265
|
static init() { return this }
|
|
@@ -326,351 +373,6 @@ class mqtt_writer_v5 extends mqtt_writer_v4 {
|
|
|
326
373
|
}
|
|
327
374
|
}
|
|
328
375
|
|
|
329
|
-
function mqtt_decode_connect(ns, mqtt_reader) {
|
|
330
|
-
class _connect_flags_ extends Number {
|
|
331
|
-
get reserved() { return this & 0x01 !== 0 }
|
|
332
|
-
get clean_start() { return this & 0x02 !== 0 }
|
|
333
|
-
get will_flag() { return this & 0x04 !== 0 }
|
|
334
|
-
get will_qos() { return (this >>> 3) & 0x3 }
|
|
335
|
-
get will_retain() { return this & 0x20 !== 0 }
|
|
336
|
-
get password() { return this & 0x40 !== 0 }
|
|
337
|
-
get username() { return this & 0x80 !== 0 }
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
return ns[0x1] = (pkt, u8_body) => {
|
|
341
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
342
|
-
if ('MQTT' !== rdr.utf8())
|
|
343
|
-
throw new Error('Invalid mqtt_connect packet')
|
|
344
|
-
|
|
345
|
-
pkt._base_.mqtt_level = pkt.mqtt_level = rdr.u8();
|
|
346
|
-
|
|
347
|
-
let flags = pkt.flags =
|
|
348
|
-
rdr.flags(_connect_flags_);
|
|
349
|
-
|
|
350
|
-
pkt.keep_alive = rdr.u16();
|
|
351
|
-
|
|
352
|
-
if (5 <= pkt.mqtt_level)
|
|
353
|
-
pkt.props = rdr.props();
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
pkt.client_id = rdr.utf8();
|
|
358
|
-
if (flags.will_flag) {
|
|
359
|
-
let will = pkt.will = {};
|
|
360
|
-
if (5 <= pkt.mqtt_level)
|
|
361
|
-
will.props = rdr.props();
|
|
362
|
-
|
|
363
|
-
will.topic = rdr.utf8();
|
|
364
|
-
will.payload = rdr.bin();
|
|
365
|
-
will.qos = flags.will_qos;
|
|
366
|
-
will.retain = flags.will_retain;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (flags.username)
|
|
370
|
-
pkt.username = rdr.utf8();
|
|
371
|
-
|
|
372
|
-
if (flags.password)
|
|
373
|
-
pkt.password = rdr.bin();
|
|
374
|
-
return pkt }
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function mqtt_decode_connack(ns, mqtt_reader) {
|
|
378
|
-
class _connack_flags_ extends Number {
|
|
379
|
-
get session_present() { return this & 0x01 !== 0 }
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return ns[0x2] = (pkt, u8_body) => {
|
|
383
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
384
|
-
|
|
385
|
-
pkt.flags =
|
|
386
|
-
rdr.flags(_connack_flags_);
|
|
387
|
-
|
|
388
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
389
|
-
if (5 <= pkt.mqtt_level)
|
|
390
|
-
pkt.props = rdr.props();
|
|
391
|
-
return pkt }
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
function _connack_v4(mqtt_reader) {
|
|
396
|
-
mqtt_reader.reasons('connack',
|
|
397
|
-
// MQTT 3.1.1
|
|
398
|
-
[ 0x00, 'Success'],
|
|
399
|
-
[ 0x01, 'Connection refused, unacceptable protocol version'],
|
|
400
|
-
[ 0x02, 'Connection refused, identifier rejected'],
|
|
401
|
-
[ 0x03, 'Connection refused, server unavailable'],
|
|
402
|
-
[ 0x04, 'Connection refused, bad user name or password'],
|
|
403
|
-
[ 0x05, 'Connection refused, not authorized'],
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
function _connack_v5(mqtt_reader) {
|
|
408
|
-
_connack_v4(mqtt_reader);
|
|
409
|
-
|
|
410
|
-
mqtt_reader.reasons('connack',
|
|
411
|
-
// MQTT 5.0
|
|
412
|
-
[ 0x81, 'Malformed Packet'],
|
|
413
|
-
[ 0x82, 'Protocol Error'],
|
|
414
|
-
[ 0x83, 'Implementation specific error'],
|
|
415
|
-
[ 0x84, 'Unsupported Protocol Version'],
|
|
416
|
-
[ 0x85, 'Client Identifier not valid'],
|
|
417
|
-
[ 0x86, 'Bad User Name or Password'],
|
|
418
|
-
[ 0x87, 'Not authorized'],
|
|
419
|
-
[ 0x88, 'Server unavailable'],
|
|
420
|
-
[ 0x89, 'Server busy'],
|
|
421
|
-
[ 0x8A, 'Banned'],
|
|
422
|
-
[ 0x8C, 'Bad authentication method'],
|
|
423
|
-
[ 0x90, 'Topic Name invalid'],
|
|
424
|
-
[ 0x95, 'Packet too large'],
|
|
425
|
-
[ 0x97, 'Quota exceeded'],
|
|
426
|
-
[ 0x99, 'Payload format invalid'],
|
|
427
|
-
[ 0x9A, 'Retain not supported'],
|
|
428
|
-
[ 0x9B, 'QoS not supported'],
|
|
429
|
-
[ 0x9C, 'Use another server'],
|
|
430
|
-
[ 0x9D, 'Server moved'],
|
|
431
|
-
[ 0x9F, 'Connection rate exceeded'],
|
|
432
|
-
);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
function mqtt_decode_publish(ns, mqtt_reader) {
|
|
436
|
-
return ns[0x3] = (pkt, u8_body) => {
|
|
437
|
-
let {hdr} = pkt;
|
|
438
|
-
pkt.dup = Boolean(hdr & 0x8);
|
|
439
|
-
pkt.retain = Boolean(hdr & 0x1);
|
|
440
|
-
let qos = pkt.qos = (hdr>>1) & 0x3;
|
|
441
|
-
|
|
442
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
443
|
-
pkt.topic = rdr.utf8();
|
|
444
|
-
if (0 !== qos)
|
|
445
|
-
pkt.pkt_id = rdr.u16();
|
|
446
|
-
|
|
447
|
-
if (5 <= pkt.mqtt_level)
|
|
448
|
-
pkt.props = rdr.props();
|
|
449
|
-
|
|
450
|
-
pkt.payload = rdr.flush();
|
|
451
|
-
return pkt }
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
function mqtt_decode_puback(ns, mqtt_reader) {
|
|
455
|
-
return ns[0x4] = (pkt, u8_body) => {
|
|
456
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
457
|
-
|
|
458
|
-
pkt.pkt_id = rdr.u16();
|
|
459
|
-
if (5 <= pkt.mqtt_level) {
|
|
460
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
461
|
-
pkt.props = rdr.props();
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
return pkt }
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
function _puback_v5(mqtt_reader) {
|
|
469
|
-
mqtt_reader.reasons('puback',
|
|
470
|
-
// MQTT 5.0
|
|
471
|
-
[ 0x00, 'Success'],
|
|
472
|
-
[ 0x10, 'No matching subscribers'],
|
|
473
|
-
[ 0x80, 'Unspecified error'],
|
|
474
|
-
[ 0x83, 'Implementation specific error'],
|
|
475
|
-
[ 0x87, 'Not authorized'],
|
|
476
|
-
[ 0x90, 'Topic Name invalid'],
|
|
477
|
-
[ 0x91, 'Packet identifier in use'],
|
|
478
|
-
[ 0x97, 'Quota exceeded'],
|
|
479
|
-
[ 0x99, 'Payload format invalid'],
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
function mqtt_decode_pubxxx(ns, mqtt_reader) {
|
|
484
|
-
return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
|
|
485
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
486
|
-
|
|
487
|
-
pkt.pkt_id = rdr.u16();
|
|
488
|
-
pkt.reason = rdr.reason('pubxxx', mqtt_reader);
|
|
489
|
-
if (5 <= pkt.mqtt_level)
|
|
490
|
-
pkt.props = rdr.props();
|
|
491
|
-
return pkt }
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
function _pubxxx_v4(mqtt_reader) {
|
|
495
|
-
mqtt_reader.reasons('pubxxx',
|
|
496
|
-
// MQTT 3.1.1
|
|
497
|
-
[ 0x00, 'Success' ],
|
|
498
|
-
[ 0x92, 'Packet Identifier not found' ],
|
|
499
|
-
);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
function mqtt_decode_subscribe(ns, mqtt_reader) {
|
|
503
|
-
class _subscription_options_ extends Number {
|
|
504
|
-
get qos() { return this & 0x3 }
|
|
505
|
-
get retain() { return this & 0x4 !== 0 }
|
|
506
|
-
get retain_handling() { return (this >> 2) & 0x3 }
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
return ns[0x8] = (pkt, u8_body) => {
|
|
510
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
511
|
-
|
|
512
|
-
pkt.pkt_id = rdr.u16();
|
|
513
|
-
if (5 <= pkt.mqtt_level)
|
|
514
|
-
pkt.props = rdr.props();
|
|
515
|
-
|
|
516
|
-
let topic, opts, topic_list = pkt.topics = [];
|
|
517
|
-
while (rdr.has_more()) {
|
|
518
|
-
topic = rdr.utf8();
|
|
519
|
-
opts = rdr.flags(_subscription_options_);
|
|
520
|
-
topic_list.push({topic, opts});
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
return pkt }
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
function _mqtt_decode_suback(mqtt_reader) {
|
|
527
|
-
return (pkt, u8_body) => {
|
|
528
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
529
|
-
|
|
530
|
-
pkt.pkt_id = rdr.u16();
|
|
531
|
-
if (5 <= pkt.mqtt_level)
|
|
532
|
-
pkt.props = rdr.props();
|
|
533
|
-
|
|
534
|
-
let answers = pkt.answers = [];
|
|
535
|
-
while (rdr.has_more())
|
|
536
|
-
answers.push(
|
|
537
|
-
rdr.reason(pkt.type) );
|
|
538
|
-
|
|
539
|
-
return pkt }
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
function mqtt_decode_suback(ns, mqtt_reader) {
|
|
543
|
-
return ns[0x9] = _mqtt_decode_suback(mqtt_reader)
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
function _suback_v4(mqtt_reader) {
|
|
547
|
-
mqtt_reader.reasons('suback',
|
|
548
|
-
// MQTT 3.1.1
|
|
549
|
-
[ 0x00, 'Granted QoS 0'],
|
|
550
|
-
[ 0x01, 'Granted QoS 1'],
|
|
551
|
-
[ 0x02, 'Granted QoS 2'],
|
|
552
|
-
);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
function _suback_v5(mqtt_reader) {
|
|
556
|
-
_suback_v4(mqtt_reader);
|
|
557
|
-
|
|
558
|
-
mqtt_reader.reasons('suback',
|
|
559
|
-
// MQTT 5.0
|
|
560
|
-
[ 0x80, 'Unspecified error'],
|
|
561
|
-
[ 0x83, 'Implementation specific error'],
|
|
562
|
-
[ 0x87, 'Not authorized'],
|
|
563
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
564
|
-
[ 0x91, 'Packet Identifier in use'],
|
|
565
|
-
[ 0x97, 'Quota exceeded'],
|
|
566
|
-
[ 0x9E, 'Shared Subscriptions not supported'],
|
|
567
|
-
[ 0xA1, 'Subscription Identifiers not supported'],
|
|
568
|
-
[ 0xA2, 'Wildcard Subscriptions not supported'],
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
function mqtt_decode_unsubscribe(ns, mqtt_reader) {
|
|
573
|
-
return ns[0xa] = (pkt, u8_body) => {
|
|
574
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
575
|
-
|
|
576
|
-
pkt.pkt_id = rdr.u16();
|
|
577
|
-
if (5 <= pkt.mqtt_level)
|
|
578
|
-
pkt.props = rdr.props();
|
|
579
|
-
|
|
580
|
-
let topic_list = pkt.topics = [];
|
|
581
|
-
while (rdr.has_more())
|
|
582
|
-
topic_list.push(rdr.utf8());
|
|
583
|
-
|
|
584
|
-
return pkt }
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
function mqtt_decode_unsuback(ns, mqtt_reader) {
|
|
588
|
-
return ns[0xb] = _mqtt_decode_suback(mqtt_reader)
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
function _unsuback_v4(mqtt_reader) {
|
|
592
|
-
mqtt_reader.reasons('unsuback',
|
|
593
|
-
// MQTT 3.1.1
|
|
594
|
-
[ 0x00, 'Success'],
|
|
595
|
-
[ 0x11, 'No subscription existed'],
|
|
596
|
-
[ 0x80, 'Unspecified error'],
|
|
597
|
-
[ 0x83, 'Implementation specific error'],
|
|
598
|
-
[ 0x87, 'Not authorized'],
|
|
599
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
600
|
-
[ 0x91, 'Packet Identifier in use'],
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
function mqtt_decode_pingxxx(ns) {
|
|
605
|
-
return ns[0xc] = ns[0xd] = pkt => pkt
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
function mqtt_decode_disconnect(ns, mqtt_reader) {
|
|
609
|
-
return ns[0xe] = (pkt, u8_body) => {
|
|
610
|
-
if (u8_body && 5 <= pkt.mqtt_level) {
|
|
611
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
612
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
613
|
-
pkt.props = rdr.props();
|
|
614
|
-
}
|
|
615
|
-
return pkt }
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
function _disconnect_v5(mqtt_reader) {
|
|
620
|
-
mqtt_reader.reasons('disconnect',
|
|
621
|
-
// MQTT 5.0
|
|
622
|
-
[ 0x00, 'Normal disconnection'],
|
|
623
|
-
[ 0x04, 'Disconnect with Will Message'],
|
|
624
|
-
[ 0x80, 'Unspecified error'],
|
|
625
|
-
[ 0x81, 'Malformed Packet'],
|
|
626
|
-
[ 0x82, 'Protocol Error'],
|
|
627
|
-
[ 0x83, 'Implementation specific error'],
|
|
628
|
-
[ 0x87, 'Not authorized'],
|
|
629
|
-
[ 0x89, 'Server busy'],
|
|
630
|
-
[ 0x8B, 'Server shutting down'],
|
|
631
|
-
[ 0x8D, 'Keep Alive timeout'],
|
|
632
|
-
[ 0x8E, 'Session taken over'],
|
|
633
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
634
|
-
[ 0x90, 'Topic Name invalid'],
|
|
635
|
-
[ 0x93, 'Receive Maximum exceeded'],
|
|
636
|
-
[ 0x94, 'Topic Alias invalid'],
|
|
637
|
-
[ 0x95, 'Packet too large'],
|
|
638
|
-
[ 0x96, 'Message rate too high'],
|
|
639
|
-
[ 0x97, 'Quota exceeded'],
|
|
640
|
-
[ 0x98, 'Administrative action'],
|
|
641
|
-
[ 0x99, 'Payload format invalid'],
|
|
642
|
-
[ 0x9A, 'Retain not supported'],
|
|
643
|
-
[ 0x9B, 'QoS not supported'],
|
|
644
|
-
[ 0x9C, 'Use another server'],
|
|
645
|
-
[ 0x9D, 'Server moved'],
|
|
646
|
-
[ 0x9E, 'Shared Subscriptions not supported'],
|
|
647
|
-
[ 0x9F, 'Connection rate exceeded'],
|
|
648
|
-
[ 0xA0, 'Maximum connect time'],
|
|
649
|
-
[ 0xA1, 'Subscription Identifiers not supported'],
|
|
650
|
-
[ 0xA2, 'Wildcard Subscriptions not supported'],
|
|
651
|
-
);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
function mqtt_decode_auth(ns, mqtt_reader) {
|
|
655
|
-
return ns[0xf] = (pkt, u8_body) => {
|
|
656
|
-
if ( 5 <= pkt.mqtt_level ) {
|
|
657
|
-
let rdr = mqtt_reader.of(u8_body);
|
|
658
|
-
pkt.reason = rdr.reason(pkt.type);
|
|
659
|
-
pkt.props = rdr.props();
|
|
660
|
-
}
|
|
661
|
-
return pkt }
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
function _auth_v5(mqtt_reader) {
|
|
666
|
-
mqtt_reader.reasons('auth',
|
|
667
|
-
// MQTT 5.0
|
|
668
|
-
[ 0x00, 'Success' ],
|
|
669
|
-
[ 0x18, 'Continue authentication' ],
|
|
670
|
-
[ 0x19, 'Re-authenticate' ],
|
|
671
|
-
);
|
|
672
|
-
}
|
|
673
|
-
|
|
674
376
|
function mqtt_encode_connect(ns, mqtt_writer) {
|
|
675
377
|
const _c_mqtt_proto = new Uint8Array([
|
|
676
378
|
0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
|
|
@@ -689,7 +391,7 @@ function mqtt_encode_connect(ns, mqtt_writer) {
|
|
|
689
391
|
| ( will.retain ? 0x20 : 0 );
|
|
690
392
|
|
|
691
393
|
return ns.connect = ( mqtt_level, pkt ) => {
|
|
692
|
-
let wrt = mqtt_writer.
|
|
394
|
+
let wrt = mqtt_writer.for(pkt);
|
|
693
395
|
|
|
694
396
|
wrt.push(_c_mqtt_proto);
|
|
695
397
|
wrt.u8( mqtt_level );
|
|
@@ -727,12 +429,61 @@ function mqtt_encode_connect(ns, mqtt_writer) {
|
|
|
727
429
|
}
|
|
728
430
|
}
|
|
729
431
|
|
|
432
|
+
function mqtt_decode_connect(ns, mqtt_reader) {
|
|
433
|
+
class _connect_flags_ extends Number {
|
|
434
|
+
get reserved() { return this & 0x01 !== 0 }
|
|
435
|
+
get clean_start() { return this & 0x02 !== 0 }
|
|
436
|
+
get will_flag() { return this & 0x04 !== 0 }
|
|
437
|
+
get will_qos() { return (this >>> 3) & 0x3 }
|
|
438
|
+
get will_retain() { return this & 0x20 !== 0 }
|
|
439
|
+
get password() { return this & 0x40 !== 0 }
|
|
440
|
+
get username() { return this & 0x80 !== 0 }
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return ns[0x1] = (pkt, u8_body) => {
|
|
444
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
445
|
+
if ('MQTT' !== rdr.utf8())
|
|
446
|
+
throw new Error('Invalid mqtt_connect packet')
|
|
447
|
+
|
|
448
|
+
pkt.__proto__.mqtt_level =
|
|
449
|
+
pkt.mqtt_level = rdr.u8();
|
|
450
|
+
|
|
451
|
+
let flags = pkt.flags =
|
|
452
|
+
rdr.flags(_connect_flags_);
|
|
453
|
+
|
|
454
|
+
pkt.keep_alive = rdr.u16();
|
|
455
|
+
|
|
456
|
+
if (5 <= pkt.mqtt_level)
|
|
457
|
+
pkt.props = rdr.props();
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
pkt.client_id = rdr.utf8();
|
|
462
|
+
if (flags.will_flag) {
|
|
463
|
+
let will = pkt.will = {};
|
|
464
|
+
if (5 <= pkt.mqtt_level)
|
|
465
|
+
will.props = rdr.props();
|
|
466
|
+
|
|
467
|
+
will.topic = rdr.utf8();
|
|
468
|
+
will.payload = rdr.bin();
|
|
469
|
+
will.qos = flags.will_qos;
|
|
470
|
+
will.retain = flags.will_retain;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (flags.username)
|
|
474
|
+
pkt.username = rdr.utf8();
|
|
475
|
+
|
|
476
|
+
if (flags.password)
|
|
477
|
+
pkt.password = rdr.bin();
|
|
478
|
+
return pkt }
|
|
479
|
+
}
|
|
480
|
+
|
|
730
481
|
function mqtt_encode_connack(ns, mqtt_writer) {
|
|
731
482
|
const _enc_flags_connack = flags =>
|
|
732
483
|
flags.session_present ? 1 : 0;
|
|
733
484
|
|
|
734
485
|
return ns.connack = (mqtt_level, pkt) => {
|
|
735
|
-
let wrt = mqtt_writer.
|
|
486
|
+
let wrt = mqtt_writer.for(pkt);
|
|
736
487
|
|
|
737
488
|
wrt.flags( pkt.flags, _enc_flags_connack );
|
|
738
489
|
|
|
@@ -748,10 +499,28 @@ function mqtt_encode_connack(ns, mqtt_writer) {
|
|
|
748
499
|
}
|
|
749
500
|
}
|
|
750
501
|
|
|
502
|
+
|
|
503
|
+
function mqtt_decode_connack(ns, mqtt_reader) {
|
|
504
|
+
class _connack_flags_ extends Number {
|
|
505
|
+
get session_present() { return this & 0x01 !== 0 }
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
return ns[0x2] = (pkt, u8_body) => {
|
|
509
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
510
|
+
|
|
511
|
+
pkt.flags =
|
|
512
|
+
rdr.flags(_connack_flags_);
|
|
513
|
+
|
|
514
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
515
|
+
if (5 <= pkt.mqtt_level)
|
|
516
|
+
pkt.props = rdr.props();
|
|
517
|
+
return pkt }
|
|
518
|
+
}
|
|
519
|
+
|
|
751
520
|
function mqtt_encode_publish(ns, mqtt_writer) {
|
|
752
521
|
return ns.publish = ( mqtt_level, pkt ) => {
|
|
753
522
|
let qos = (pkt.qos & 0x3) << 1;
|
|
754
|
-
let wrt = mqtt_writer.
|
|
523
|
+
let wrt = mqtt_writer.for(pkt);
|
|
755
524
|
|
|
756
525
|
wrt.utf8(pkt.topic);
|
|
757
526
|
if (0 !== qos)
|
|
@@ -769,9 +538,28 @@ function mqtt_encode_publish(ns, mqtt_writer) {
|
|
|
769
538
|
}
|
|
770
539
|
}
|
|
771
540
|
|
|
541
|
+
function mqtt_decode_publish(ns, mqtt_reader) {
|
|
542
|
+
return ns[0x3] = (pkt, u8_body) => {
|
|
543
|
+
let {hdr} = pkt;
|
|
544
|
+
pkt.dup = Boolean(hdr & 0x8);
|
|
545
|
+
pkt.retain = Boolean(hdr & 0x1);
|
|
546
|
+
let qos = pkt.qos = (hdr>>1) & 0x3;
|
|
547
|
+
|
|
548
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
549
|
+
pkt.topic = rdr.utf8();
|
|
550
|
+
if (0 !== qos)
|
|
551
|
+
pkt.pkt_id = rdr.u16();
|
|
552
|
+
|
|
553
|
+
if (5 <= pkt.mqtt_level)
|
|
554
|
+
pkt.props = rdr.props();
|
|
555
|
+
|
|
556
|
+
pkt.payload = rdr.flush();
|
|
557
|
+
return pkt }
|
|
558
|
+
}
|
|
559
|
+
|
|
772
560
|
function mqtt_encode_puback(ns, mqtt_writer) {
|
|
773
561
|
return ns.puback = ( mqtt_level, pkt ) => {
|
|
774
|
-
let wrt = mqtt_writer.
|
|
562
|
+
let wrt = mqtt_writer.for(pkt);
|
|
775
563
|
|
|
776
564
|
wrt.u16(pkt.pkt_id);
|
|
777
565
|
if (5 <= mqtt_level) {
|
|
@@ -783,6 +571,20 @@ function mqtt_encode_puback(ns, mqtt_writer) {
|
|
|
783
571
|
}
|
|
784
572
|
}
|
|
785
573
|
|
|
574
|
+
|
|
575
|
+
function mqtt_decode_puback(ns, mqtt_reader) {
|
|
576
|
+
return ns[0x4] = (pkt, u8_body) => {
|
|
577
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
578
|
+
|
|
579
|
+
pkt.pkt_id = rdr.u16();
|
|
580
|
+
if (5 <= pkt.mqtt_level) {
|
|
581
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
582
|
+
pkt.props = rdr.props();
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return pkt }
|
|
586
|
+
}
|
|
587
|
+
|
|
786
588
|
function mqtt_encode_pubxxx(ns, mqtt_writer) {
|
|
787
589
|
ns.pubrec = _enc_pubxxx(0x50);
|
|
788
590
|
ns.pubrel = _enc_pubxxx(0x62);
|
|
@@ -791,7 +593,7 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
|
|
|
791
593
|
|
|
792
594
|
function _enc_pubxxx(hdr) {
|
|
793
595
|
return ( mqtt_level, pkt ) => {
|
|
794
|
-
let wrt = mqtt_writer.
|
|
596
|
+
let wrt = mqtt_writer.for(pkt);
|
|
795
597
|
|
|
796
598
|
wrt.u16(pkt.pkt_id);
|
|
797
599
|
if (5 <= mqtt_level) {
|
|
@@ -807,6 +609,17 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
|
|
|
807
609
|
}
|
|
808
610
|
}
|
|
809
611
|
|
|
612
|
+
function mqtt_decode_pubxxx(ns, mqtt_reader) {
|
|
613
|
+
return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
|
|
614
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
615
|
+
|
|
616
|
+
pkt.pkt_id = rdr.u16();
|
|
617
|
+
pkt.reason = rdr.reason('pubxxx', mqtt_reader);
|
|
618
|
+
if (5 <= pkt.mqtt_level)
|
|
619
|
+
pkt.props = rdr.props();
|
|
620
|
+
return pkt }
|
|
621
|
+
}
|
|
622
|
+
|
|
810
623
|
function mqtt_encode_subscribe(ns, mqtt_writer) {
|
|
811
624
|
const _enc_subscribe_flags = opts => 0
|
|
812
625
|
| ( opts.qos & 0x3 )
|
|
@@ -814,7 +627,7 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
|
|
|
814
627
|
| ( (opts.retain_handling & 0x3) << 2 );
|
|
815
628
|
|
|
816
629
|
return ns.subscribe = ( mqtt_level, pkt ) => {
|
|
817
|
-
let wrt = mqtt_writer.
|
|
630
|
+
let wrt = mqtt_writer.for(pkt);
|
|
818
631
|
|
|
819
632
|
wrt.u16(pkt.pkt_id);
|
|
820
633
|
if (5 <= mqtt_level)
|
|
@@ -840,6 +653,30 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
|
|
|
840
653
|
}
|
|
841
654
|
}
|
|
842
655
|
|
|
656
|
+
function mqtt_decode_subscribe(ns, mqtt_reader) {
|
|
657
|
+
class _subscription_options_ extends Number {
|
|
658
|
+
get qos() { return this & 0x3 }
|
|
659
|
+
get retain() { return this & 0x4 !== 0 }
|
|
660
|
+
get retain_handling() { return (this >> 2) & 0x3 }
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return ns[0x8] = (pkt, u8_body) => {
|
|
664
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
665
|
+
|
|
666
|
+
pkt.pkt_id = rdr.u16();
|
|
667
|
+
if (5 <= pkt.mqtt_level)
|
|
668
|
+
pkt.props = rdr.props();
|
|
669
|
+
|
|
670
|
+
let topic, opts, topic_list = pkt.topics = [];
|
|
671
|
+
while (rdr.has_more()) {
|
|
672
|
+
topic = rdr.utf8();
|
|
673
|
+
opts = rdr.flags(_subscription_options_);
|
|
674
|
+
topic_list.push({topic, opts});
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
return pkt }
|
|
678
|
+
}
|
|
679
|
+
|
|
843
680
|
function mqtt_encode_xxsuback(ns, mqtt_writer) {
|
|
844
681
|
ns.suback = _enc_xxsuback(0x90);
|
|
845
682
|
ns.unsuback = _enc_xxsuback(0xb0);
|
|
@@ -847,7 +684,7 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
|
|
|
847
684
|
|
|
848
685
|
function _enc_xxsuback(hdr) {
|
|
849
686
|
return ( mqtt_level, pkt ) => {
|
|
850
|
-
let wrt = mqtt_writer.
|
|
687
|
+
let wrt = mqtt_writer.for(pkt);
|
|
851
688
|
|
|
852
689
|
wrt.u16(pkt.pkt_id);
|
|
853
690
|
if (5 <= mqtt_level)
|
|
@@ -861,9 +698,26 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
|
|
|
861
698
|
}
|
|
862
699
|
}
|
|
863
700
|
|
|
701
|
+
|
|
702
|
+
function mqtt_decode_xxsuback(ns, mqtt_reader) {
|
|
703
|
+
return ns[0x9] = ns[0xb] = (pkt, u8_body) => {
|
|
704
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
705
|
+
|
|
706
|
+
pkt.pkt_id = rdr.u16();
|
|
707
|
+
if (5 <= pkt.mqtt_level)
|
|
708
|
+
pkt.props = rdr.props();
|
|
709
|
+
|
|
710
|
+
let answers = pkt.answers = [];
|
|
711
|
+
while (rdr.has_more())
|
|
712
|
+
answers.push(
|
|
713
|
+
rdr.reason(pkt.type) );
|
|
714
|
+
|
|
715
|
+
return pkt }
|
|
716
|
+
}
|
|
717
|
+
|
|
864
718
|
function mqtt_encode_unsubscribe(ns, mqtt_writer) {
|
|
865
719
|
return ns.unsubscribe = ( mqtt_level, pkt ) => {
|
|
866
|
-
let wrt = mqtt_writer.
|
|
720
|
+
let wrt = mqtt_writer.for(pkt);
|
|
867
721
|
|
|
868
722
|
wrt.u16(pkt.pkt_id);
|
|
869
723
|
if (5 <= mqtt_level)
|
|
@@ -876,14 +730,34 @@ function mqtt_encode_unsubscribe(ns, mqtt_writer) {
|
|
|
876
730
|
}
|
|
877
731
|
}
|
|
878
732
|
|
|
733
|
+
function mqtt_decode_unsubscribe(ns, mqtt_reader) {
|
|
734
|
+
return ns[0xa] = (pkt, u8_body) => {
|
|
735
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
736
|
+
|
|
737
|
+
pkt.pkt_id = rdr.u16();
|
|
738
|
+
if (5 <= pkt.mqtt_level)
|
|
739
|
+
pkt.props = rdr.props();
|
|
740
|
+
|
|
741
|
+
let topic_list = pkt.topics = [];
|
|
742
|
+
while (rdr.has_more())
|
|
743
|
+
topic_list.push(rdr.utf8());
|
|
744
|
+
|
|
745
|
+
return pkt }
|
|
746
|
+
}
|
|
747
|
+
|
|
879
748
|
function mqtt_encode_pingxxx(ns) {
|
|
880
749
|
ns.pingreq = () => new Uint8Array([ 0xc0, 0 ]);
|
|
881
750
|
ns.pingresp = () => new Uint8Array([ 0xd0, 0 ]);
|
|
882
751
|
}
|
|
883
752
|
|
|
753
|
+
|
|
754
|
+
function mqtt_decode_pingxxx(ns) {
|
|
755
|
+
return ns[0xc] = ns[0xd] = pkt => pkt
|
|
756
|
+
}
|
|
757
|
+
|
|
884
758
|
function mqtt_encode_disconnect(ns, mqtt_writer) {
|
|
885
759
|
return ns.disconnect = ( mqtt_level, pkt ) => {
|
|
886
|
-
let wrt = mqtt_writer.
|
|
760
|
+
let wrt = mqtt_writer.for(pkt);
|
|
887
761
|
|
|
888
762
|
if (pkt && 5 <= mqtt_level) {
|
|
889
763
|
if (pkt.reason || pkt.props) {
|
|
@@ -896,6 +770,17 @@ function mqtt_encode_disconnect(ns, mqtt_writer) {
|
|
|
896
770
|
}
|
|
897
771
|
}
|
|
898
772
|
|
|
773
|
+
|
|
774
|
+
function mqtt_decode_disconnect(ns, mqtt_reader) {
|
|
775
|
+
return ns[0xe] = (pkt, u8_body) => {
|
|
776
|
+
if (u8_body && 5 <= pkt.mqtt_level) {
|
|
777
|
+
let rdr = mqtt_reader.for(pkt, u8_body);
|
|
778
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
779
|
+
pkt.props = rdr.props();
|
|
780
|
+
}
|
|
781
|
+
return pkt }
|
|
782
|
+
}
|
|
783
|
+
|
|
899
784
|
function mqtt_encode_auth(ns, mqtt_writer) {
|
|
900
785
|
return ns.auth = ( mqtt_level, pkt ) => {
|
|
901
786
|
if (5 > mqtt_level)
|
|
@@ -910,17 +795,15 @@ function mqtt_encode_auth(ns, mqtt_writer) {
|
|
|
910
795
|
}
|
|
911
796
|
}
|
|
912
797
|
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
_auth_v5,
|
|
923
|
-
);
|
|
798
|
+
function mqtt_decode_auth(ns, mqtt_reader) {
|
|
799
|
+
return ns[0xf] = (pkt, u8_body) => {
|
|
800
|
+
if ( 5 <= pkt.mqtt_level ) {
|
|
801
|
+
let rdr = mqtt_reader.of(u8_body);
|
|
802
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
803
|
+
pkt.props = rdr.props();
|
|
804
|
+
}
|
|
805
|
+
return pkt }
|
|
806
|
+
}
|
|
924
807
|
|
|
925
808
|
const mqtt_decode_v5 = [
|
|
926
809
|
mqtt_decode_connect,
|
|
@@ -929,9 +812,8 @@ const mqtt_decode_v5 = [
|
|
|
929
812
|
mqtt_decode_puback,
|
|
930
813
|
mqtt_decode_pubxxx,
|
|
931
814
|
mqtt_decode_subscribe,
|
|
932
|
-
|
|
815
|
+
mqtt_decode_xxsuback,
|
|
933
816
|
mqtt_decode_unsubscribe,
|
|
934
|
-
mqtt_decode_unsuback,
|
|
935
817
|
mqtt_decode_pingxxx,
|
|
936
818
|
mqtt_decode_disconnect,
|
|
937
819
|
mqtt_decode_auth,
|
|
@@ -1044,7 +926,10 @@ const with_topic_router = mqtt_topic_router =>
|
|
|
1044
926
|
// alias: unsub_topic
|
|
1045
927
|
unsubscribe_topic(topic_route, ...args) {
|
|
1046
928
|
let router = this.router;
|
|
1047
|
-
|
|
929
|
+
|
|
930
|
+
let fn = args.at(-1)?.call ? args.pop() : null;
|
|
931
|
+
router.remove(topic_route, true, fn);
|
|
932
|
+
|
|
1048
933
|
let topic = router.mqtt_topic(topic_route);
|
|
1049
934
|
return this.unsubscribe(topic, ...args ) }// topic_prefix
|
|
1050
935
|
|
|
@@ -1097,34 +982,38 @@ function mqtt_topic_path_router() {
|
|
|
1097
982
|
if (fn) {throw new TypeError()}
|
|
1098
983
|
fn = _ignore;}
|
|
1099
984
|
|
|
1100
|
-
let
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
pri_lsts[priority ? 0 : 1].push(rte);
|
|
985
|
+
let route = parse(as_topic_path(topic_route));
|
|
986
|
+
route.topic = topic_route;
|
|
987
|
+
route.tgt = fn;
|
|
988
|
+
pri_lsts[priority ? 0 : 1].push(route);
|
|
1105
989
|
return this}
|
|
1106
990
|
|
|
1107
|
-
, remove(
|
|
1108
|
-
let lst = pri_lsts
|
|
1109
|
-
|
|
991
|
+
, remove(query, ...args) {
|
|
992
|
+
let lst = pri_lsts;
|
|
993
|
+
if ('boolean' === typeof args[0]) {
|
|
994
|
+
lst = [pri_lsts[args.shift() ? 0 : 1]];}
|
|
995
|
+
|
|
996
|
+
if ('string' === typeof query) {
|
|
997
|
+
query ={topic: query, tgt: args.pop()}; }
|
|
998
|
+
return _route_remove(lst, query)}
|
|
1110
999
|
|
|
1111
1000
|
, clear(priority) {
|
|
1112
|
-
pri_lsts[priority ? 0 : 1] = [];
|
|
1113
1001
|
if (null == priority) {
|
|
1114
|
-
pri_lsts
|
|
1002
|
+
pri_lsts = [[],[]]; }// null clears both lists
|
|
1003
|
+
else {
|
|
1004
|
+
pri_lsts[priority ? 0 : 1] = [];} }
|
|
1115
1005
|
|
|
1116
1006
|
, async invoke(pkt, ctx) {
|
|
1117
1007
|
ctx.idx = 0;
|
|
1118
1008
|
ctx.rm = rm;
|
|
1119
1009
|
|
|
1120
|
-
for (let [fn, params] of find(pkt.topic)) {
|
|
1010
|
+
for (let [fn, params, route] of find(pkt.topic)) {
|
|
1121
1011
|
let res = await fn(pkt, params, ctx);
|
|
1122
1012
|
|
|
1123
1013
|
if (rm === res) {
|
|
1124
|
-
_route_remove(pri_lsts,
|
|
1014
|
+
_route_remove(pri_lsts, route);}
|
|
1125
1015
|
|
|
1126
|
-
if (ctx.done) {
|
|
1127
|
-
break}
|
|
1016
|
+
if (ctx.done) {break}
|
|
1128
1017
|
else ctx.idx++;}
|
|
1129
1018
|
|
|
1130
1019
|
if (1 === pkt.qos) {
|
|
@@ -1134,70 +1023,68 @@ function mqtt_topic_path_router() {
|
|
|
1134
1023
|
function * _routes_iter(all_route_lists, topic) {
|
|
1135
1024
|
topic = topic.replace(/^[\/]*/, '/'); // ensure '/' prefix for regexparam library
|
|
1136
1025
|
for (let route_list of all_route_lists) {
|
|
1137
|
-
for (let
|
|
1138
|
-
let match = pattern.exec(topic);
|
|
1026
|
+
for (let route of route_list) {
|
|
1027
|
+
let match = route.pattern.exec(topic);
|
|
1139
1028
|
if (match) {
|
|
1140
|
-
let params = keys
|
|
1141
|
-
? keys.reduce(
|
|
1029
|
+
let params = route.keys
|
|
1030
|
+
? route.keys.reduce(
|
|
1142
1031
|
(o, k, i) => (o[k] = match[1+i], o)
|
|
1143
1032
|
, {})
|
|
1144
1033
|
: match.groups ?? match;
|
|
1145
|
-
yield [tgt, params];} } } }
|
|
1034
|
+
yield [route.tgt, params, route];} } } }
|
|
1146
1035
|
|
|
1147
1036
|
|
|
1148
1037
|
function _route_remove(all_route_lists, query) {
|
|
1149
|
-
let
|
|
1150
|
-
route===query
|
|
1151
|
-
|| route.tgt===query
|
|
1152
|
-
|| route.key===query);
|
|
1038
|
+
let ans = false;
|
|
1153
1039
|
for (let lst of all_route_lists) {
|
|
1154
|
-
let
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
n
|
|
1178
|
-
if ( 0x80 & u8[i++] ) {
|
|
1179
|
-
n |= (u8[i] & 0x7f) << 14;
|
|
1180
|
-
if ( 0x80 & u8[i++] ) {
|
|
1181
|
-
n |= (u8[i] & 0x7f) << 21;
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
return [n, i, i0]
|
|
1040
|
+
let idx_tip = 0;
|
|
1041
|
+
for (let route of lst) {
|
|
1042
|
+
// skip matching routes to remove from compacted list
|
|
1043
|
+
if (route === query) continue
|
|
1044
|
+
if (route.topic === query.topic) {
|
|
1045
|
+
if (null == query.tgt) continue
|
|
1046
|
+
if (route.tgt === query.tgt) continue}
|
|
1047
|
+
|
|
1048
|
+
lst[idx_tip++] = route;}
|
|
1049
|
+
|
|
1050
|
+
// truncate remaining list
|
|
1051
|
+
if (lst.splice(idx_tip).length)
|
|
1052
|
+
ans = true;}
|
|
1053
|
+
|
|
1054
|
+
return ans}
|
|
1055
|
+
|
|
1056
|
+
function decode_varint(u8, i0=0, invalid) {
|
|
1057
|
+
let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
|
|
1058
|
+
for(; b & 0x80;)
|
|
1059
|
+
n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
|
|
1060
|
+
|
|
1061
|
+
return (u8.length < i)
|
|
1062
|
+
? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
|
|
1063
|
+
: [n, i, i0] // successful value
|
|
1186
1064
|
}
|
|
1187
1065
|
|
|
1188
1066
|
function mqtt_raw_dispatch(opt) {
|
|
1189
|
-
let u8 = new Uint8Array(0);
|
|
1067
|
+
let u8 = new Uint8Array(0), len_tip=0;
|
|
1190
1068
|
return u8_buf => {
|
|
1191
1069
|
u8 = 0 === u8.byteLength
|
|
1192
1070
|
? u8_buf : _u8_join(u8, u8_buf);
|
|
1193
1071
|
|
|
1194
1072
|
let res = [];
|
|
1195
|
-
while (1) {
|
|
1196
|
-
let [len_body, len_vh] = decode_varint(u8, 1);
|
|
1197
|
-
let len_pkt = len_body + len_vh;
|
|
1198
1073
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1074
|
+
// wait for at least len_tip bytes for next (tip) message
|
|
1075
|
+
while ( u8.byteLength >= len_tip ) {
|
|
1076
|
+
|
|
1077
|
+
// if varint is incomplete, return len_body=NaN
|
|
1078
|
+
let [len_body, len_vh] = decode_varint(u8, 1, NaN);
|
|
1079
|
+
let len_pkt = len_body + len_vh; // may be NaN
|
|
1080
|
+
|
|
1081
|
+
if (!( len_pkt <= u8.byteLength )) {
|
|
1082
|
+
// incomplete packet cases:
|
|
1083
|
+
// - len_pkt is less than available bytes
|
|
1084
|
+
// - len_pkt is NaN from decode_varint() due to lack of data
|
|
1085
|
+
len_tip = len_pkt || 0; // 0 when NaN
|
|
1086
|
+
break
|
|
1087
|
+
}
|
|
1201
1088
|
|
|
1202
1089
|
let b0 = u8[0];
|
|
1203
1090
|
let u8_body = 0 === len_body ? null
|
|
@@ -1209,6 +1096,8 @@ function mqtt_raw_dispatch(opt) {
|
|
|
1209
1096
|
if (null != pkt)
|
|
1210
1097
|
res.push( pkt );
|
|
1211
1098
|
}
|
|
1099
|
+
|
|
1100
|
+
return res
|
|
1212
1101
|
}
|
|
1213
1102
|
}
|
|
1214
1103
|
|
|
@@ -1219,16 +1108,17 @@ function _u8_join(a, b) {
|
|
|
1219
1108
|
return r
|
|
1220
1109
|
}
|
|
1221
1110
|
|
|
1222
|
-
const _pkt_types =
|
|
1111
|
+
const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
function mqtt_pkt_ctx(mqtt_level, opts, pkt_api=opts.pkt_ctx) {
|
|
1115
|
+
let _as_pkt_ctx = pkt_api => ({
|
|
1116
|
+
__proto__: pkt_api,
|
|
1117
|
+
get hdr() { return this.b0 & 0xf },
|
|
1118
|
+
get id() { return this.b0 >>> 4 },
|
|
1119
|
+
get type() { return _pkt_types[this.b0 >>> 4] },
|
|
1120
|
+
mqtt_level });
|
|
1223
1121
|
|
|
1224
|
-
function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
1225
|
-
pkt_ctx = {
|
|
1226
|
-
__proto__: pkt_ctx || opts.pkt_ctx,
|
|
1227
|
-
mqtt_level,
|
|
1228
|
-
get hdr() { return this.b0 & 0xf },
|
|
1229
|
-
get id() { return this.b0 >>> 4 },
|
|
1230
|
-
get type() { return _pkt_types[this.b0 >>> 4] },
|
|
1231
|
-
};
|
|
1232
1122
|
|
|
1233
1123
|
let op, _decode_by_id=[], _encode_by_type={};
|
|
1234
1124
|
for (op of opts.encode_fns)
|
|
@@ -1237,10 +1127,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
|
1237
1127
|
op(_decode_by_id, opts.mqtt_reader);
|
|
1238
1128
|
|
|
1239
1129
|
return {
|
|
1240
|
-
pkt_ctx,
|
|
1130
|
+
pkt_api, pkt_ctx: _as_pkt_ctx(pkt_api),
|
|
1241
1131
|
|
|
1242
|
-
encode_pkt(type, pkt)
|
|
1243
|
-
|
|
1132
|
+
encode_pkt: (type, pkt) =>
|
|
1133
|
+
_encode_by_type[type]( mqtt_level, pkt ),
|
|
1244
1134
|
|
|
1245
1135
|
decode_pkt(b0, u8_body) {
|
|
1246
1136
|
if (b0.map) // Uint8Array in first arg
|
|
@@ -1249,12 +1139,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
|
1249
1139
|
let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
|
|
1250
1140
|
return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
|
|
1251
1141
|
|
|
1252
|
-
mqtt_stream() {
|
|
1253
|
-
let self = { __proto__: this, pkt_ctx:
|
|
1254
|
-
self.pkt_ctx._base_ = self.pkt_ctx;
|
|
1142
|
+
mqtt_stream(pkt_api=this.pkt_api) {
|
|
1143
|
+
let self = { __proto__: this, pkt_ctx: _as_pkt_ctx(pkt_api) };
|
|
1255
1144
|
self.decode = mqtt_raw_dispatch(self);
|
|
1256
|
-
return self
|
|
1257
|
-
},
|
|
1145
|
+
return self },
|
|
1258
1146
|
}
|
|
1259
1147
|
}
|
|
1260
1148
|
|
|
@@ -1778,7 +1666,7 @@ class MQTTCore extends MQTTBase {
|
|
|
1778
1666
|
|
|
1779
1667
|
return this} }
|
|
1780
1668
|
|
|
1781
|
-
const version = '0.6.
|
|
1669
|
+
const version = '0.6.4-web';
|
|
1782
1670
|
|
|
1783
1671
|
const MQTTClient_v4 = /* #__PURE__ */
|
|
1784
1672
|
with_topic_path_router(
|