@seriousme/opifex 1.9.3 → 1.10.1
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/README.md +37 -26
- package/bin/conformanceServer.ts +3 -2
- package/bin/demoServer.ts +3 -2
- package/bin/mqtt.ts +126 -117
- package/client/client.ts +35 -15
- package/client/context.ts +42 -22
- package/client/deps.ts +5 -0
- package/client/handlers/handleConnack.ts +17 -5
- package/client/handlers/handlePublish.ts +4 -1
- package/client/handlers/handlePubrec.ts +3 -1
- package/client/handlers/handlePubrel.ts +3 -1
- package/client/handlers/handleSuback.ts +3 -1
- package/client/mod.ts +8 -1
- package/client/store/memoryStore.ts +2 -1
- package/dev_utils/dummyConn.ts +17 -2
- package/dist/bin/conformanceServer.js +3 -2
- package/dist/bin/conformanceServer.js.map +1 -1
- package/dist/bin/demoServer.js +3 -2
- package/dist/bin/demoServer.js.map +1 -1
- package/dist/bin/mqtt.d.ts +29 -0
- package/dist/bin/mqtt.d.ts.map +1 -1
- package/dist/bin/mqtt.js +101 -96
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/client.d.ts +7 -4
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +17 -9
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +3 -1
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/context.js +27 -13
- package/dist/client/context.js.map +1 -1
- package/dist/client/deps.d.ts +3 -2
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js +2 -1
- package/dist/client/deps.js.map +1 -1
- package/dist/client/handlers/handleConnack.d.ts +1 -1
- package/dist/client/handlers/handleConnack.d.ts.map +1 -1
- package/dist/client/handlers/handleConnack.js +14 -5
- package/dist/client/handlers/handleConnack.js.map +1 -1
- package/dist/client/handlers/handlePublish.d.ts +1 -1
- package/dist/client/handlers/handlePublish.d.ts.map +1 -1
- package/dist/client/handlers/handlePublish.js +2 -0
- package/dist/client/handlers/handlePublish.js.map +1 -1
- package/dist/client/handlers/handlePubrec.d.ts +1 -1
- package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/client/handlers/handlePubrec.js +1 -0
- package/dist/client/handlers/handlePubrec.js.map +1 -1
- package/dist/client/handlers/handlePubrel.d.ts +1 -1
- package/dist/client/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/client/handlers/handlePubrel.js +1 -0
- package/dist/client/handlers/handlePubrel.js.map +1 -1
- package/dist/client/handlers/handleSuback.d.ts.map +1 -1
- package/dist/client/handlers/handleSuback.js +3 -1
- package/dist/client/handlers/handleSuback.js.map +1 -1
- package/dist/client/mod.d.ts +3 -1
- package/dist/client/mod.d.ts.map +1 -1
- package/dist/client/mod.js +2 -1
- package/dist/client/mod.js.map +1 -1
- package/dist/client/store/memoryStore.d.ts +1 -1
- package/dist/client/store/memoryStore.d.ts.map +1 -1
- package/dist/client/store/memoryStore.js.map +1 -1
- package/dist/mqttConn/mqttConn.d.ts +13 -8
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +27 -12
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts +1 -0
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/PacketType.js +1 -0
- package/dist/mqttPacket/PacketType.js.map +1 -1
- package/dist/mqttPacket/Properties.d.ts +157 -0
- package/dist/mqttPacket/Properties.d.ts.map +1 -0
- package/dist/mqttPacket/Properties.js +177 -0
- package/dist/mqttPacket/Properties.js.map +1 -0
- package/dist/mqttPacket/ReasonCode.d.ts +74 -0
- package/dist/mqttPacket/ReasonCode.d.ts.map +1 -0
- package/dist/mqttPacket/ReasonCode.js +230 -0
- package/dist/mqttPacket/ReasonCode.js.map +1 -0
- package/dist/mqttPacket/RetainHandling.d.ts +12 -0
- package/dist/mqttPacket/RetainHandling.d.ts.map +1 -0
- package/dist/mqttPacket/RetainHandling.js +12 -0
- package/dist/mqttPacket/RetainHandling.js.map +1 -0
- package/dist/mqttPacket/auth.d.ts +21 -0
- package/dist/mqttPacket/auth.d.ts.map +1 -0
- package/dist/mqttPacket/auth.js +34 -0
- package/dist/mqttPacket/auth.js.map +1 -0
- package/dist/mqttPacket/connack.d.ts +15 -7
- package/dist/mqttPacket/connack.d.ts.map +1 -1
- package/dist/mqttPacket/connack.js +43 -15
- package/dist/mqttPacket/connack.js.map +1 -1
- package/dist/mqttPacket/connect.d.ts +27 -8
- package/dist/mqttPacket/connect.d.ts.map +1 -1
- package/dist/mqttPacket/connect.js +106 -30
- package/dist/mqttPacket/connect.js.map +1 -1
- package/dist/mqttPacket/decoder.d.ts +42 -3
- package/dist/mqttPacket/decoder.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +135 -4
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/disconnect.d.ts +13 -7
- package/dist/mqttPacket/disconnect.d.ts.map +1 -1
- package/dist/mqttPacket/disconnect.js +45 -6
- package/dist/mqttPacket/disconnect.js.map +1 -1
- package/dist/mqttPacket/encoder.d.ts +57 -8
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +185 -13
- package/dist/mqttPacket/encoder.js.map +1 -1
- package/dist/mqttPacket/length.d.ts.map +1 -1
- package/dist/mqttPacket/length.js +3 -2
- package/dist/mqttPacket/length.js.map +1 -1
- package/dist/mqttPacket/mod.d.ts +56 -91
- package/dist/mqttPacket/mod.d.ts.map +1 -1
- package/dist/mqttPacket/mod.js +22 -22
- package/dist/mqttPacket/mod.js.map +1 -1
- package/dist/mqttPacket/pingreq.d.ts +4 -6
- package/dist/mqttPacket/pingreq.d.ts.map +1 -1
- package/dist/mqttPacket/pingreq.js +5 -4
- package/dist/mqttPacket/pingreq.js.map +1 -1
- package/dist/mqttPacket/pingres.d.ts +4 -6
- package/dist/mqttPacket/pingres.d.ts.map +1 -1
- package/dist/mqttPacket/pingres.js +7 -5
- package/dist/mqttPacket/pingres.js.map +1 -1
- package/dist/mqttPacket/protocolLevels.d.ts +11 -0
- package/dist/mqttPacket/protocolLevels.d.ts.map +1 -0
- package/dist/mqttPacket/protocolLevels.js +11 -0
- package/dist/mqttPacket/protocolLevels.js.map +1 -0
- package/dist/mqttPacket/pubblishAcks.d.ts +35 -0
- package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -0
- package/dist/mqttPacket/pubblishAcks.js +56 -0
- package/dist/mqttPacket/pubblishAcks.js.map +1 -0
- package/dist/mqttPacket/publish.d.ts +19 -8
- package/dist/mqttPacket/publish.d.ts.map +1 -1
- package/dist/mqttPacket/publish.js +26 -7
- package/dist/mqttPacket/publish.js.map +1 -1
- package/dist/mqttPacket/suback.d.ts +14 -7
- package/dist/mqttPacket/suback.d.ts.map +1 -1
- package/dist/mqttPacket/suback.js +41 -20
- package/dist/mqttPacket/suback.js.map +1 -1
- package/dist/mqttPacket/subscribe.d.ts +24 -9
- package/dist/mqttPacket/subscribe.d.ts.map +1 -1
- package/dist/mqttPacket/subscribe.js +71 -15
- package/dist/mqttPacket/subscribe.js.map +1 -1
- package/dist/mqttPacket/types.d.ts +33 -0
- package/dist/mqttPacket/types.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.d.ts +14 -7
- package/dist/mqttPacket/unsuback.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.js +29 -6
- package/dist/mqttPacket/unsuback.js.map +1 -1
- package/dist/mqttPacket/unsubscribe.d.ts +14 -7
- package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
- package/dist/mqttPacket/unsubscribe.js +24 -8
- package/dist/mqttPacket/unsubscribe.js.map +1 -1
- package/dist/node/wrapNodeSocket.d.ts.map +1 -1
- package/dist/node/wrapNodeSocket.js.map +1 -1
- package/dist/persistence/deps.d.ts +1 -1
- package/dist/persistence/deps.d.ts.map +1 -1
- package/dist/persistence/deps.js +1 -1
- package/dist/persistence/deps.js.map +1 -1
- package/dist/server/context.d.ts +3 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +8 -2
- package/dist/server/context.js.map +1 -1
- package/dist/server/deps.d.ts +2 -2
- package/dist/server/deps.d.ts.map +1 -1
- package/dist/server/deps.js +1 -1
- package/dist/server/deps.js.map +1 -1
- package/dist/server/handlers/handleConnect.d.ts +1 -1
- package/dist/server/handlers/handleConnect.d.ts.map +1 -1
- package/dist/server/handlers/handleConnect.js +9 -1
- package/dist/server/handlers/handleConnect.js.map +1 -1
- package/dist/server/handlers/handlePacket.d.ts +1 -1
- package/dist/server/handlers/handlePacket.d.ts.map +1 -1
- package/dist/server/handlers/handlePacket.js +1 -1
- package/dist/server/handlers/handlePacket.js.map +1 -1
- package/dist/server/handlers/handlePingreq.d.ts.map +1 -1
- package/dist/server/handlers/handlePingreq.js +1 -0
- package/dist/server/handlers/handlePingreq.js.map +1 -1
- package/dist/server/handlers/handlePublish.d.ts +2 -2
- package/dist/server/handlers/handlePublish.d.ts.map +1 -1
- package/dist/server/handlers/handlePublish.js +2 -0
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/server/handlers/handlePubrec.d.ts +1 -1
- package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrec.js +1 -0
- package/dist/server/handlers/handlePubrec.js.map +1 -1
- package/dist/server/handlers/handlePubrel.d.ts +1 -1
- package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrel.js +1 -0
- package/dist/server/handlers/handlePubrel.js.map +1 -1
- package/dist/server/handlers/handleSubscribe.d.ts +1 -1
- package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleSubscribe.js +2 -1
- package/dist/server/handlers/handleSubscribe.js.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.d.ts +1 -1
- package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.js +1 -0
- package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
- package/dist/server/server.d.ts +2 -2
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +5 -3
- package/dist/server/server.js.map +1 -1
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +6 -1
- package/dist/socket/socket.js.map +1 -1
- package/dist/utils/assert.d.ts +0 -3
- package/dist/utils/assert.d.ts.map +1 -1
- package/dist/utils/assert.js +0 -7
- package/dist/utils/assert.js.map +1 -1
- package/dist/utils/mod.d.ts +0 -3
- package/dist/utils/mod.d.ts.map +1 -1
- package/dist/utils/mod.js +0 -2
- package/dist/utils/mod.js.map +1 -1
- package/mqttConn/mqttConn.test.ts +27 -12
- package/mqttConn/mqttConn.ts +45 -14
- package/mqttPacket/PacketType.ts +1 -0
- package/mqttPacket/Properties.ts +276 -0
- package/mqttPacket/ReasonCode.test.ts +22 -0
- package/mqttPacket/ReasonCode.ts +256 -0
- package/mqttPacket/RetainHandling.ts +11 -0
- package/mqttPacket/auth.test.ts +112 -0
- package/mqttPacket/auth.ts +72 -0
- package/mqttPacket/connack.test.ts +84 -64
- package/mqttPacket/connack.ts +84 -20
- package/mqttPacket/connect.test.ts +497 -18
- package/mqttPacket/connect.ts +167 -36
- package/mqttPacket/decoder.test.ts +33 -16
- package/mqttPacket/decoder.ts +173 -5
- package/mqttPacket/disconnect.test.ts +97 -18
- package/mqttPacket/disconnect.ts +82 -10
- package/mqttPacket/encoder.test.ts +32 -8
- package/mqttPacket/encoder.ts +236 -11
- package/mqttPacket/length.ts +3 -2
- package/mqttPacket/mod.ts +75 -32
- package/mqttPacket/pingreq.test.ts +52 -4
- package/mqttPacket/pingreq.ts +20 -7
- package/mqttPacket/pingres.test.ts +52 -4
- package/mqttPacket/pingres.ts +22 -8
- package/mqttPacket/properties.test.ts +193 -0
- package/mqttPacket/protocolLevels.ts +13 -0
- package/mqttPacket/pubblishAcks.ts +117 -0
- package/mqttPacket/publish.test.ts +212 -133
- package/mqttPacket/publish.ts +69 -14
- package/mqttPacket/publishAcks.test.ts +128 -0
- package/mqttPacket/suback.test.ts +71 -27
- package/mqttPacket/suback.ts +78 -26
- package/mqttPacket/subscribe.test.ts +132 -43
- package/mqttPacket/subscribe.ts +125 -22
- package/mqttPacket/types.ts +40 -0
- package/mqttPacket/unsuback.test.ts +80 -30
- package/mqttPacket/unsuback.ts +65 -10
- package/mqttPacket/unsubscribe.test.ts +59 -34
- package/mqttPacket/unsubscribe.ts +61 -14
- package/node/wrapNodeSocket.ts +2 -1
- package/package.json +2 -2
- package/persistence/deps.ts +1 -1
- package/persistence/memory/memoryPersistence.test.ts +5 -1
- package/server/context.ts +23 -10
- package/server/deps.ts +2 -0
- package/server/handlers/handleConnect.ts +12 -9
- package/server/handlers/handlePacket.ts +10 -11
- package/server/handlers/handlePingreq.ts +1 -0
- package/server/handlers/handlePublish.ts +6 -2
- package/server/handlers/handlePubrec.ts +3 -1
- package/server/handlers/handlePubrel.ts +3 -1
- package/server/handlers/handleSubscribe.ts +3 -6
- package/server/handlers/handleUnsubscribe.ts +3 -1
- package/server/server.ts +8 -12
- package/server/test/handleConnect.test.ts +2 -1
- package/server/test/test-handlers.ts +2 -1
- package/socket/socket.ts +5 -1
- package/utils/assert.ts +0 -18
- package/utils/mod.ts +0 -3
- package/dist/mqttPacket/puback.d.ts +0 -16
- package/dist/mqttPacket/puback.d.ts.map +0 -1
- package/dist/mqttPacket/puback.js +0 -21
- package/dist/mqttPacket/puback.js.map +0 -1
- package/dist/mqttPacket/pubcomp.d.ts +0 -17
- package/dist/mqttPacket/pubcomp.d.ts.map +0 -1
- package/dist/mqttPacket/pubcomp.js +0 -21
- package/dist/mqttPacket/pubcomp.js.map +0 -1
- package/dist/mqttPacket/pubrec.d.ts +0 -17
- package/dist/mqttPacket/pubrec.d.ts.map +0 -1
- package/dist/mqttPacket/pubrec.js +0 -21
- package/dist/mqttPacket/pubrec.js.map +0 -1
- package/dist/mqttPacket/pubrel.d.ts +0 -17
- package/dist/mqttPacket/pubrel.d.ts.map +0 -1
- package/dist/mqttPacket/pubrel.js +0 -21
- package/dist/mqttPacket/pubrel.js.map +0 -1
- package/dist/utils/args.d.ts +0 -28
- package/dist/utils/args.d.ts.map +0 -1
- package/dist/utils/args.js +0 -76
- package/dist/utils/args.js.map +0 -1
- package/dist/utils/platform.d.ts +0 -5
- package/dist/utils/platform.d.ts.map +0 -1
- package/dist/utils/platform.js +0 -8
- package/dist/utils/platform.js.map +0 -1
- package/mqttPacket/puback.test.ts +0 -55
- package/mqttPacket/puback.ts +0 -34
- package/mqttPacket/pubcomp.test.ts +0 -55
- package/mqttPacket/pubcomp.ts +0 -35
- package/mqttPacket/pubrec.test.ts +0 -55
- package/mqttPacket/pubrec.ts +0 -35
- package/mqttPacket/pubrel.test.ts +0 -55
- package/mqttPacket/pubrel.ts +0 -35
- package/utils/args.ts +0 -103
- package/utils/platform.ts +0 -8
package/mqttConn/mqttConn.ts
CHANGED
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
* @module mqttConn
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type {
|
|
6
|
+
AnyPacket,
|
|
7
|
+
CodecOpts,
|
|
8
|
+
LengthDecoderResult,
|
|
9
|
+
ProtocolLevel,
|
|
10
|
+
} from "../mqttPacket/mod.ts";
|
|
11
|
+
|
|
5
12
|
import {
|
|
6
|
-
type AnyPacket,
|
|
7
13
|
decodePayload,
|
|
8
14
|
encode,
|
|
9
15
|
getLengthDecoder,
|
|
10
|
-
|
|
16
|
+
MQTTLevel,
|
|
11
17
|
} from "../mqttPacket/mod.ts";
|
|
12
18
|
|
|
13
19
|
import { assert } from "../utils/mod.ts";
|
|
@@ -23,6 +29,8 @@ export const MqttConnError = {
|
|
|
23
29
|
UnexpectedEof: "Unexpected EOF",
|
|
24
30
|
} as const;
|
|
25
31
|
|
|
32
|
+
const DEFAULT_MAX_PACKETSIZE = 2 * 1024 * 1024; // 2MB
|
|
33
|
+
|
|
26
34
|
/**
|
|
27
35
|
* Interface for MQTT connection handling
|
|
28
36
|
*/
|
|
@@ -74,13 +82,13 @@ async function readFull(conn: Conn, buf: Uint8Array): Promise<void> {
|
|
|
74
82
|
/**
|
|
75
83
|
* Read a complete MQTT packet from the connection
|
|
76
84
|
* @param conn Connection to read from
|
|
77
|
-
* @param
|
|
85
|
+
* @param maxIncomingPacketSize Maximum allowed packet size
|
|
78
86
|
* @returns Decoded MQTT packet
|
|
79
87
|
* @throws Error if packet is invalid or too large
|
|
80
88
|
*/
|
|
81
89
|
export async function readPacket(
|
|
82
90
|
conn: Conn,
|
|
83
|
-
|
|
91
|
+
codecOpts: CodecOpts,
|
|
84
92
|
): Promise<AnyPacket> {
|
|
85
93
|
// fixed header is 1 byte of type + flags
|
|
86
94
|
// + a maximum of 4 bytes to encode the remaining length
|
|
@@ -93,11 +101,15 @@ export async function readPacket(
|
|
|
93
101
|
} while (!result.done);
|
|
94
102
|
|
|
95
103
|
const remainingLength = result.length;
|
|
96
|
-
|
|
104
|
+
const maxIncomingPacketSize = codecOpts.maxIncomingPacketSize;
|
|
105
|
+
assert(
|
|
106
|
+
remainingLength < maxIncomingPacketSize - 1,
|
|
107
|
+
MqttConnError.packetTooLarge,
|
|
108
|
+
);
|
|
97
109
|
const packetBuf = new Uint8Array(remainingLength);
|
|
98
110
|
// read the rest of the packet
|
|
99
111
|
await readFull(conn, packetBuf);
|
|
100
|
-
const packet = decodePayload(firstByte, packetBuf);
|
|
112
|
+
const packet = decodePayload(firstByte, packetBuf, codecOpts);
|
|
101
113
|
assert(packet !== null, MqttConnError.UnexpectedEof);
|
|
102
114
|
return packet;
|
|
103
115
|
}
|
|
@@ -108,8 +120,8 @@ export async function readPacket(
|
|
|
108
120
|
export class MqttConn implements IMqttConn {
|
|
109
121
|
/** Underlying connection */
|
|
110
122
|
readonly conn: Conn;
|
|
111
|
-
/**
|
|
112
|
-
|
|
123
|
+
/** codecOpts */
|
|
124
|
+
codecOpts: CodecOpts;
|
|
113
125
|
/** Reason for connection closure if any */
|
|
114
126
|
private _reason: string | undefined = undefined;
|
|
115
127
|
/** Whether connection is closed */
|
|
@@ -119,17 +131,25 @@ export class MqttConn implements IMqttConn {
|
|
|
119
131
|
* Create new MQTT connection
|
|
120
132
|
* @param options Connection options
|
|
121
133
|
* @param options.conn Underlying socket connection
|
|
122
|
-
* @param options.
|
|
134
|
+
* @param options.maxIncomingPacketSize Maximum allowed incoming packet size (default 2MB)
|
|
135
|
+
* @param options.maxOutGoingPacketSize Maximum allowed outgoing packet size (default 2MB)
|
|
136
|
+
* @param options.protocolLevel Supported protocolLevel
|
|
123
137
|
*/
|
|
124
138
|
constructor({
|
|
125
139
|
conn,
|
|
126
|
-
|
|
140
|
+
maxIncomingPacketSize = DEFAULT_MAX_PACKETSIZE,
|
|
141
|
+
protocolLevel = MQTTLevel.unknown,
|
|
127
142
|
}: {
|
|
128
143
|
conn: SockConn;
|
|
129
|
-
|
|
144
|
+
maxIncomingPacketSize?: number;
|
|
145
|
+
protocolLevel?: ProtocolLevel;
|
|
130
146
|
}) {
|
|
131
147
|
this.conn = new Conn(conn);
|
|
132
|
-
this.
|
|
148
|
+
this.codecOpts = {
|
|
149
|
+
maxIncomingPacketSize,
|
|
150
|
+
maxOutgoingPacketSize: maxIncomingPacketSize,
|
|
151
|
+
protocolLevel,
|
|
152
|
+
};
|
|
133
153
|
}
|
|
134
154
|
|
|
135
155
|
/** Get reason for connection closure */
|
|
@@ -137,6 +157,14 @@ export class MqttConn implements IMqttConn {
|
|
|
137
157
|
return this._reason;
|
|
138
158
|
}
|
|
139
159
|
|
|
160
|
+
/** Get remoteAdress */
|
|
161
|
+
get remoteAddress(): string {
|
|
162
|
+
if (this.conn.remoteAddr?.transport === "tcp") {
|
|
163
|
+
return this.conn.remoteAddr.hostname;
|
|
164
|
+
}
|
|
165
|
+
return "unknown";
|
|
166
|
+
}
|
|
167
|
+
|
|
140
168
|
/**
|
|
141
169
|
* Async iterator for receiving packets
|
|
142
170
|
* @yields MQTT packets
|
|
@@ -144,7 +172,10 @@ export class MqttConn implements IMqttConn {
|
|
|
144
172
|
async *[Symbol.asyncIterator](): AsyncIterableIterator<AnyPacket> {
|
|
145
173
|
while (!this._isClosed) {
|
|
146
174
|
try {
|
|
147
|
-
yield await readPacket(
|
|
175
|
+
yield await readPacket(
|
|
176
|
+
this.conn,
|
|
177
|
+
this.codecOpts,
|
|
178
|
+
);
|
|
148
179
|
} catch (err) {
|
|
149
180
|
if (err instanceof Error) {
|
|
150
181
|
if (err.name === "PartialReadError") {
|
|
@@ -165,7 +196,7 @@ export class MqttConn implements IMqttConn {
|
|
|
165
196
|
*/
|
|
166
197
|
async send(data: AnyPacket): Promise<void> {
|
|
167
198
|
try {
|
|
168
|
-
await this.conn.write(encode(data));
|
|
199
|
+
await this.conn.write(encode(data, this.codecOpts));
|
|
169
200
|
} catch (err) {
|
|
170
201
|
if (err instanceof Error) {
|
|
171
202
|
this._reason = err.message;
|
package/mqttPacket/PacketType.ts
CHANGED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { PacketType } from "./PacketType.ts";
|
|
2
|
+
import type { InvertRecord, UTF8StringPair } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
export const PropertySetType = {
|
|
5
|
+
...PacketType,
|
|
6
|
+
will: 100,
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export type TPropertySetType =
|
|
10
|
+
typeof PropertySetType[keyof typeof PropertySetType];
|
|
11
|
+
|
|
12
|
+
export const propertyKind = {
|
|
13
|
+
boolean: 0, // its a byte in the MQTT standard, but for convenience we convert to boolean
|
|
14
|
+
byte: 1,
|
|
15
|
+
int16: 2,
|
|
16
|
+
int32: 3,
|
|
17
|
+
varInt: 4,
|
|
18
|
+
byteArray: 5,
|
|
19
|
+
utf8string: 6,
|
|
20
|
+
utf8StringPairs: 7,
|
|
21
|
+
varIntArray: 8,
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
export const propertyToId = {
|
|
25
|
+
payloadFormatIndicator: 0x01,
|
|
26
|
+
messageExpiryInterval: 0x02,
|
|
27
|
+
contentType: 0x03,
|
|
28
|
+
responseTopic: 0x08,
|
|
29
|
+
correlationData: 0x09,
|
|
30
|
+
subscriptionIdentifier: 0x0b,
|
|
31
|
+
// special case,placeholder to encode decode multiple subscription identifiers
|
|
32
|
+
subscriptionIdentifiers: 0xff,
|
|
33
|
+
sessionExpiryInterval: 0x11,
|
|
34
|
+
assignedClientIdentifier: 0x12,
|
|
35
|
+
serverKeepAlive: 0x13,
|
|
36
|
+
authenticationMethod: 0x15,
|
|
37
|
+
authenticationData: 0x16,
|
|
38
|
+
requestProblemInformation: 0x17,
|
|
39
|
+
willDelayInterval: 0x18,
|
|
40
|
+
requestResponseInformation: 0x19,
|
|
41
|
+
responseInformation: 0x1a,
|
|
42
|
+
serverReference: 0x1c,
|
|
43
|
+
reasonString: 0x1f,
|
|
44
|
+
receiveMaximum: 0x21,
|
|
45
|
+
topicAliasMaximum: 0x22,
|
|
46
|
+
topicAlias: 0x23,
|
|
47
|
+
maximumQos: 0x24,
|
|
48
|
+
retainAvailable: 0x25,
|
|
49
|
+
userProperty: 0x26,
|
|
50
|
+
maximumPacketSize: 0x27,
|
|
51
|
+
wildcardSubscriptionAvailable: 0x28,
|
|
52
|
+
subscriptionIdentifierAvailable: 0x29,
|
|
53
|
+
sharedSubscriptionAvailable: 0x2a,
|
|
54
|
+
} as const;
|
|
55
|
+
|
|
56
|
+
type PropertyNames = keyof typeof propertyToId;
|
|
57
|
+
// A helper type to convert a tuple of numbers to a union of strings
|
|
58
|
+
|
|
59
|
+
export const propertyToKind = {
|
|
60
|
+
[propertyToId.payloadFormatIndicator]: propertyKind.boolean,
|
|
61
|
+
[propertyToId.messageExpiryInterval]: propertyKind.int32,
|
|
62
|
+
[propertyToId.contentType]: propertyKind.utf8string,
|
|
63
|
+
[propertyToId.responseTopic]: propertyKind.utf8string,
|
|
64
|
+
[propertyToId.correlationData]: propertyKind.byteArray,
|
|
65
|
+
[propertyToId.subscriptionIdentifier]: propertyKind.varInt,
|
|
66
|
+
[propertyToId.subscriptionIdentifiers]: propertyKind.varIntArray,
|
|
67
|
+
[propertyToId.sessionExpiryInterval]: propertyKind.int32,
|
|
68
|
+
[propertyToId.assignedClientIdentifier]: propertyKind.utf8string,
|
|
69
|
+
[propertyToId.serverKeepAlive]: propertyKind.int16,
|
|
70
|
+
[propertyToId.authenticationMethod]: propertyKind.utf8string,
|
|
71
|
+
[propertyToId.authenticationData]: propertyKind.byteArray,
|
|
72
|
+
[propertyToId.requestProblemInformation]: propertyKind.boolean,
|
|
73
|
+
[propertyToId.willDelayInterval]: propertyKind.int32,
|
|
74
|
+
[propertyToId.requestResponseInformation]: propertyKind.boolean,
|
|
75
|
+
[propertyToId.responseInformation]: propertyKind.utf8string,
|
|
76
|
+
[propertyToId.serverReference]: propertyKind.utf8string,
|
|
77
|
+
[propertyToId.reasonString]: propertyKind.utf8string,
|
|
78
|
+
[propertyToId.receiveMaximum]: propertyKind.int16,
|
|
79
|
+
[propertyToId.topicAliasMaximum]: propertyKind.int16,
|
|
80
|
+
[propertyToId.topicAlias]: propertyKind.int16,
|
|
81
|
+
[propertyToId.maximumQos]: propertyKind.byte,
|
|
82
|
+
[propertyToId.retainAvailable]: propertyKind.boolean,
|
|
83
|
+
[propertyToId.userProperty]: propertyKind.utf8StringPairs,
|
|
84
|
+
[propertyToId.maximumPacketSize]: propertyKind.int32,
|
|
85
|
+
[propertyToId.wildcardSubscriptionAvailable]: propertyKind.boolean,
|
|
86
|
+
[propertyToId.subscriptionIdentifierAvailable]: propertyKind.boolean,
|
|
87
|
+
[propertyToId.sharedSubscriptionAvailable]: propertyKind.boolean,
|
|
88
|
+
} as const;
|
|
89
|
+
|
|
90
|
+
export type UserPropertyType = Array<UTF8StringPair>;
|
|
91
|
+
export type SubscriptionIdentifiersType = Array<number>;
|
|
92
|
+
|
|
93
|
+
type PropertyKindMap = {
|
|
94
|
+
[propertyKind.boolean]: boolean;
|
|
95
|
+
[propertyKind.byte]: number;
|
|
96
|
+
[propertyKind.int16]: number;
|
|
97
|
+
[propertyKind.int32]: number;
|
|
98
|
+
[propertyKind.varInt]: number;
|
|
99
|
+
[propertyKind.byteArray]: Uint8Array;
|
|
100
|
+
[propertyKind.utf8string]: string;
|
|
101
|
+
[propertyKind.utf8StringPairs]: UserPropertyType;
|
|
102
|
+
[propertyKind.varIntArray]: SubscriptionIdentifiersType;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
type Mqttv5PropertyType<K extends number> = K extends keyof PropertyKindMap
|
|
106
|
+
? PropertyKindMap[K]
|
|
107
|
+
: never;
|
|
108
|
+
|
|
109
|
+
export type Mqttv5PropertyTypes = PropertyKindMap[keyof PropertyKindMap];
|
|
110
|
+
export type Mqttv5PropertyTypesNoUser = Exclude<
|
|
111
|
+
Mqttv5PropertyTypes,
|
|
112
|
+
UserPropertyType
|
|
113
|
+
>;
|
|
114
|
+
|
|
115
|
+
// First, create a type for all valid property numbers
|
|
116
|
+
export type ValidPropertyNumber =
|
|
117
|
+
(typeof propertyToId)[keyof typeof propertyToId];
|
|
118
|
+
// Then, create a mapped type that iterates over the property names
|
|
119
|
+
// and uses propertyToKind to look up the correct TypeScript type.
|
|
120
|
+
|
|
121
|
+
type AllMqttv5Properties = {
|
|
122
|
+
[K in PropertyNames]?: Mqttv5PropertyType<
|
|
123
|
+
typeof propertyToKind[typeof propertyToId[K]]
|
|
124
|
+
>;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
type PropertyByNumberType = InvertRecord<typeof propertyToId>;
|
|
128
|
+
|
|
129
|
+
export const propertyByNumber = Object.fromEntries(
|
|
130
|
+
Object.entries(propertyToId).map(
|
|
131
|
+
([k, v]) => [v, k],
|
|
132
|
+
),
|
|
133
|
+
) as PropertyByNumberType;
|
|
134
|
+
|
|
135
|
+
export const PropertyByPropertySetType = {
|
|
136
|
+
[PropertySetType.reserved]: [],
|
|
137
|
+
[PropertySetType.connect]: [
|
|
138
|
+
propertyToId.sessionExpiryInterval,
|
|
139
|
+
propertyToId.authenticationMethod,
|
|
140
|
+
propertyToId.authenticationData,
|
|
141
|
+
propertyToId.requestProblemInformation,
|
|
142
|
+
propertyToId.requestResponseInformation,
|
|
143
|
+
propertyToId.receiveMaximum,
|
|
144
|
+
propertyToId.topicAliasMaximum,
|
|
145
|
+
propertyToId.userProperty,
|
|
146
|
+
propertyToId.maximumPacketSize,
|
|
147
|
+
],
|
|
148
|
+
[PropertySetType.connack]: [
|
|
149
|
+
propertyToId.sessionExpiryInterval,
|
|
150
|
+
propertyToId.assignedClientIdentifier,
|
|
151
|
+
propertyToId.serverKeepAlive,
|
|
152
|
+
propertyToId.authenticationMethod,
|
|
153
|
+
propertyToId.authenticationData,
|
|
154
|
+
propertyToId.responseInformation,
|
|
155
|
+
propertyToId.serverReference,
|
|
156
|
+
propertyToId.reasonString,
|
|
157
|
+
propertyToId.receiveMaximum,
|
|
158
|
+
propertyToId.topicAliasMaximum,
|
|
159
|
+
propertyToId.maximumQos,
|
|
160
|
+
propertyToId.retainAvailable,
|
|
161
|
+
propertyToId.userProperty,
|
|
162
|
+
propertyToId.maximumPacketSize,
|
|
163
|
+
propertyToId.wildcardSubscriptionAvailable,
|
|
164
|
+
propertyToId.subscriptionIdentifierAvailable,
|
|
165
|
+
propertyToId.sharedSubscriptionAvailable,
|
|
166
|
+
],
|
|
167
|
+
[PropertySetType.publish]: [
|
|
168
|
+
propertyToId.payloadFormatIndicator,
|
|
169
|
+
propertyToId.messageExpiryInterval,
|
|
170
|
+
propertyToId.contentType,
|
|
171
|
+
propertyToId.responseTopic,
|
|
172
|
+
propertyToId.correlationData,
|
|
173
|
+
propertyToId.subscriptionIdentifiers,
|
|
174
|
+
propertyToId.topicAlias,
|
|
175
|
+
propertyToId.userProperty,
|
|
176
|
+
],
|
|
177
|
+
[PropertySetType.subscribe]: [
|
|
178
|
+
propertyToId.subscriptionIdentifier,
|
|
179
|
+
propertyToId.userProperty,
|
|
180
|
+
],
|
|
181
|
+
[PropertySetType.unsubscribe]: [
|
|
182
|
+
propertyToId.userProperty,
|
|
183
|
+
],
|
|
184
|
+
|
|
185
|
+
[PropertySetType.disconnect]: [
|
|
186
|
+
propertyToId.sessionExpiryInterval,
|
|
187
|
+
propertyToId.serverReference,
|
|
188
|
+
propertyToId.reasonString,
|
|
189
|
+
propertyToId.userProperty,
|
|
190
|
+
],
|
|
191
|
+
[PropertySetType.auth]: [
|
|
192
|
+
propertyToId.authenticationMethod,
|
|
193
|
+
propertyToId.authenticationData,
|
|
194
|
+
propertyToId.reasonString,
|
|
195
|
+
propertyToId.userProperty,
|
|
196
|
+
],
|
|
197
|
+
[PropertySetType.puback]: [
|
|
198
|
+
propertyToId.reasonString,
|
|
199
|
+
propertyToId.userProperty,
|
|
200
|
+
],
|
|
201
|
+
[PropertySetType.pubrec]: [
|
|
202
|
+
propertyToId.reasonString,
|
|
203
|
+
propertyToId.userProperty,
|
|
204
|
+
],
|
|
205
|
+
[PropertySetType.pubrel]: [
|
|
206
|
+
propertyToId.reasonString,
|
|
207
|
+
propertyToId.userProperty,
|
|
208
|
+
],
|
|
209
|
+
[PropertySetType.pubcomp]: [
|
|
210
|
+
propertyToId.reasonString,
|
|
211
|
+
propertyToId.userProperty,
|
|
212
|
+
],
|
|
213
|
+
[PropertySetType.suback]: [
|
|
214
|
+
propertyToId.reasonString,
|
|
215
|
+
propertyToId.userProperty,
|
|
216
|
+
],
|
|
217
|
+
[PropertySetType.unsuback]: [
|
|
218
|
+
propertyToId.reasonString,
|
|
219
|
+
propertyToId.userProperty,
|
|
220
|
+
],
|
|
221
|
+
[PropertySetType.pingreq]: [],
|
|
222
|
+
[PropertySetType.pingres]: [],
|
|
223
|
+
|
|
224
|
+
[PropertySetType.will]: [
|
|
225
|
+
propertyToId.payloadFormatIndicator,
|
|
226
|
+
propertyToId.messageExpiryInterval,
|
|
227
|
+
propertyToId.contentType,
|
|
228
|
+
propertyToId.responseTopic,
|
|
229
|
+
propertyToId.correlationData,
|
|
230
|
+
propertyToId.willDelayInterval,
|
|
231
|
+
propertyToId.userProperty,
|
|
232
|
+
],
|
|
233
|
+
} as const;
|
|
234
|
+
|
|
235
|
+
// helper types
|
|
236
|
+
type PropertyIdsToKeys<T extends readonly ValidPropertyNumber[]> = {
|
|
237
|
+
[K in T[number]]: (typeof propertyByNumber)[K];
|
|
238
|
+
}[T[number]];
|
|
239
|
+
|
|
240
|
+
// from AllMqttv5Properties pick the ones returned by PropertyIdsToKeys for this type
|
|
241
|
+
type GeneratePacketTypeProperties<T extends readonly ValidPropertyNumber[]> =
|
|
242
|
+
Pick<AllMqttv5Properties, PropertyIdsToKeys<T>>;
|
|
243
|
+
|
|
244
|
+
export type PropsByPacketSetType = {
|
|
245
|
+
[K in TPropertySetType]: GeneratePacketTypeProperties<
|
|
246
|
+
typeof PropertyByPropertySetType[K]
|
|
247
|
+
>;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// props per PacketType
|
|
251
|
+
export type ConnectProperties =
|
|
252
|
+
PropsByPacketSetType[typeof PropertySetType.connect];
|
|
253
|
+
export type ConnackProperties =
|
|
254
|
+
PropsByPacketSetType[typeof PropertySetType.connack];
|
|
255
|
+
export type PublishProperties =
|
|
256
|
+
PropsByPacketSetType[typeof PropertySetType.publish];
|
|
257
|
+
export type PubackProperties =
|
|
258
|
+
PropsByPacketSetType[typeof PropertySetType.puback];
|
|
259
|
+
export type PubrecProperties =
|
|
260
|
+
PropsByPacketSetType[typeof PropertySetType.pubrec];
|
|
261
|
+
export type PubrelProperties =
|
|
262
|
+
PropsByPacketSetType[typeof PropertySetType.pubrel];
|
|
263
|
+
export type PubcompProperties =
|
|
264
|
+
PropsByPacketSetType[typeof PropertySetType.pubcomp];
|
|
265
|
+
export type SubscribeProperties =
|
|
266
|
+
PropsByPacketSetType[typeof PropertySetType.subscribe];
|
|
267
|
+
export type SubackProperties =
|
|
268
|
+
PropsByPacketSetType[typeof PropertySetType.suback];
|
|
269
|
+
export type UnsubscribeProperties =
|
|
270
|
+
PropsByPacketSetType[typeof PropertySetType.unsubscribe];
|
|
271
|
+
export type UnsubackProperties =
|
|
272
|
+
PropsByPacketSetType[typeof PropertySetType.unsuback];
|
|
273
|
+
export type DisconnectProperties =
|
|
274
|
+
PropsByPacketSetType[typeof PropertySetType.disconnect];
|
|
275
|
+
export type AuthProperties = PropsByPacketSetType[typeof PropertySetType.auth];
|
|
276
|
+
export type WillProperties = PropsByPacketSetType[typeof PropertySetType.will];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { ReasonCode, reasonCodeToString } from "./ReasonCode.ts";
|
|
4
|
+
import { PacketType } from "./mod.ts";
|
|
5
|
+
|
|
6
|
+
test("lookup of reason codes works", () => {
|
|
7
|
+
assert.equal(
|
|
8
|
+
reasonCodeToString(PacketType.connect, ReasonCode.success),
|
|
9
|
+
"Success",
|
|
10
|
+
"Succes on Connect works",
|
|
11
|
+
);
|
|
12
|
+
assert.equal(
|
|
13
|
+
reasonCodeToString(PacketType.suback, ReasonCode.success),
|
|
14
|
+
"Granted QoS 0",
|
|
15
|
+
"Granted QoS 0 on Suback works",
|
|
16
|
+
);
|
|
17
|
+
assert.equal(
|
|
18
|
+
reasonCodeToString(PacketType.disconnect, ReasonCode.success),
|
|
19
|
+
"Normal disconnection",
|
|
20
|
+
"Normal disconnection on Disconnect works",
|
|
21
|
+
);
|
|
22
|
+
});
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Possible MQTT V5 reason codes
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { PacketType } from "./PacketType.ts";
|
|
6
|
+
import type { InvertRecord } from "./types.ts";
|
|
7
|
+
|
|
8
|
+
export const ReasonCode = {
|
|
9
|
+
success: 0x00,
|
|
10
|
+
normalDisconnection: 0x00,
|
|
11
|
+
grantedQos0: 0x00,
|
|
12
|
+
grantedQos1: 0x01,
|
|
13
|
+
grantedQos2: 0x02,
|
|
14
|
+
disconnectWithWillMessage: 0x04,
|
|
15
|
+
noMatchingSubscribers: 0x10,
|
|
16
|
+
noSubscriptionExisted: 0x11,
|
|
17
|
+
continueAuthentication: 0x18,
|
|
18
|
+
reAuthenticate: 0x19,
|
|
19
|
+
unspecifiedError: 0x80,
|
|
20
|
+
malformedPacket: 0x81,
|
|
21
|
+
protocolError: 0x82,
|
|
22
|
+
implementationSpecificError: 0x83,
|
|
23
|
+
unsupportedProtocolVersion: 0x84,
|
|
24
|
+
clientIdentifierNotValid: 0x85,
|
|
25
|
+
badUserNameOrPassword: 0x86,
|
|
26
|
+
notAuthorized: 0x87,
|
|
27
|
+
serverUnavailable: 0x88,
|
|
28
|
+
serverBusy: 0x89,
|
|
29
|
+
banned: 0x8a,
|
|
30
|
+
serverShuttingDown: 0x8b,
|
|
31
|
+
badAuthenticationMethod: 0x8c,
|
|
32
|
+
keepAliveTimeout: 0x8d,
|
|
33
|
+
sessionTakenOver: 0x8e,
|
|
34
|
+
topicFilterInvalid: 0x8f,
|
|
35
|
+
topicNameInvalid: 0x90,
|
|
36
|
+
packetIdentifierInUse: 0x91,
|
|
37
|
+
packetIdentifierNotFound: 0x92,
|
|
38
|
+
receiveMaximumExceeded: 0x93,
|
|
39
|
+
topicAliasInvalid: 0x94,
|
|
40
|
+
packetTooLarge: 0x95,
|
|
41
|
+
messageRateTooHigh: 0x96,
|
|
42
|
+
quotaExceeded: 0x97,
|
|
43
|
+
administrativeAction: 0x98,
|
|
44
|
+
payloadFormatInvalid: 0x99,
|
|
45
|
+
retainNotSupported: 0x9a,
|
|
46
|
+
qosNotSupported: 0x9b,
|
|
47
|
+
useAnotherServer: 0x9c,
|
|
48
|
+
serverMoved: 0x9d,
|
|
49
|
+
sharedSubscriptionsNotSupported: 0x9e,
|
|
50
|
+
connectionRateExceeded: 0x9f,
|
|
51
|
+
maximumConnectTime: 0xa0,
|
|
52
|
+
subscriptionIdentifiersNotSupported: 0xa1,
|
|
53
|
+
wildcardSubscriptionsNotSupported: 0xa2,
|
|
54
|
+
} as const;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Reverse lookup for ReasonCode
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
export type ReasonCodeByNumberType = InvertRecord<typeof ReasonCode>;
|
|
61
|
+
export const ReasonCodeByNumber = Object
|
|
62
|
+
.fromEntries(
|
|
63
|
+
Object.entries(ReasonCode).map(([k, v]) => [v, k]),
|
|
64
|
+
) as ReasonCodeByNumberType;
|
|
65
|
+
|
|
66
|
+
export const ReasonCodebyPacket = {
|
|
67
|
+
[PacketType.connack]: [
|
|
68
|
+
ReasonCode.success,
|
|
69
|
+
ReasonCode.unspecifiedError,
|
|
70
|
+
ReasonCode.malformedPacket,
|
|
71
|
+
ReasonCode.protocolError,
|
|
72
|
+
ReasonCode.implementationSpecificError,
|
|
73
|
+
ReasonCode.unsupportedProtocolVersion,
|
|
74
|
+
ReasonCode.clientIdentifierNotValid,
|
|
75
|
+
ReasonCode.badUserNameOrPassword,
|
|
76
|
+
ReasonCode.notAuthorized,
|
|
77
|
+
ReasonCode.serverUnavailable,
|
|
78
|
+
ReasonCode.serverBusy,
|
|
79
|
+
ReasonCode.banned,
|
|
80
|
+
ReasonCode.badAuthenticationMethod,
|
|
81
|
+
ReasonCode.topicNameInvalid,
|
|
82
|
+
ReasonCode.packetTooLarge,
|
|
83
|
+
ReasonCode.quotaExceeded,
|
|
84
|
+
ReasonCode.payloadFormatInvalid,
|
|
85
|
+
ReasonCode.retainNotSupported,
|
|
86
|
+
ReasonCode.qosNotSupported,
|
|
87
|
+
ReasonCode.useAnotherServer,
|
|
88
|
+
ReasonCode.serverMoved,
|
|
89
|
+
ReasonCode.connectionRateExceeded,
|
|
90
|
+
],
|
|
91
|
+
[PacketType.puback]: [
|
|
92
|
+
ReasonCode.success,
|
|
93
|
+
ReasonCode.noMatchingSubscribers,
|
|
94
|
+
ReasonCode.unspecifiedError,
|
|
95
|
+
ReasonCode.implementationSpecificError,
|
|
96
|
+
ReasonCode.notAuthorized,
|
|
97
|
+
ReasonCode.topicNameInvalid,
|
|
98
|
+
ReasonCode.packetIdentifierInUse,
|
|
99
|
+
ReasonCode.quotaExceeded,
|
|
100
|
+
ReasonCode.payloadFormatInvalid,
|
|
101
|
+
],
|
|
102
|
+
[PacketType.pubrec]: [
|
|
103
|
+
ReasonCode.success,
|
|
104
|
+
ReasonCode.noMatchingSubscribers,
|
|
105
|
+
ReasonCode.unspecifiedError,
|
|
106
|
+
ReasonCode.implementationSpecificError,
|
|
107
|
+
ReasonCode.notAuthorized,
|
|
108
|
+
ReasonCode.topicNameInvalid,
|
|
109
|
+
ReasonCode.packetIdentifierInUse,
|
|
110
|
+
ReasonCode.quotaExceeded,
|
|
111
|
+
ReasonCode.payloadFormatInvalid,
|
|
112
|
+
],
|
|
113
|
+
[PacketType.pubrel]: [
|
|
114
|
+
ReasonCode.success,
|
|
115
|
+
ReasonCode.packetIdentifierNotFound,
|
|
116
|
+
],
|
|
117
|
+
[PacketType.pubcomp]: [
|
|
118
|
+
ReasonCode.success,
|
|
119
|
+
ReasonCode.packetIdentifierNotFound,
|
|
120
|
+
],
|
|
121
|
+
[PacketType.unsuback]: [
|
|
122
|
+
ReasonCode.success,
|
|
123
|
+
ReasonCode.noSubscriptionExisted,
|
|
124
|
+
ReasonCode.unspecifiedError,
|
|
125
|
+
ReasonCode.implementationSpecificError,
|
|
126
|
+
ReasonCode.notAuthorized,
|
|
127
|
+
ReasonCode.topicFilterInvalid,
|
|
128
|
+
ReasonCode.packetIdentifierInUse,
|
|
129
|
+
],
|
|
130
|
+
[PacketType.auth]: [
|
|
131
|
+
ReasonCode.success,
|
|
132
|
+
ReasonCode.continueAuthentication,
|
|
133
|
+
ReasonCode.reAuthenticate,
|
|
134
|
+
],
|
|
135
|
+
[PacketType.disconnect]: [
|
|
136
|
+
ReasonCode.normalDisconnection,
|
|
137
|
+
ReasonCode.disconnectWithWillMessage,
|
|
138
|
+
ReasonCode.unspecifiedError,
|
|
139
|
+
ReasonCode.malformedPacket,
|
|
140
|
+
ReasonCode.protocolError,
|
|
141
|
+
ReasonCode.implementationSpecificError,
|
|
142
|
+
ReasonCode.notAuthorized,
|
|
143
|
+
ReasonCode.serverBusy,
|
|
144
|
+
ReasonCode.serverShuttingDown,
|
|
145
|
+
ReasonCode.badAuthenticationMethod,
|
|
146
|
+
ReasonCode.keepAliveTimeout,
|
|
147
|
+
ReasonCode.sessionTakenOver,
|
|
148
|
+
ReasonCode.topicFilterInvalid,
|
|
149
|
+
ReasonCode.topicNameInvalid,
|
|
150
|
+
ReasonCode.receiveMaximumExceeded,
|
|
151
|
+
ReasonCode.topicAliasInvalid,
|
|
152
|
+
ReasonCode.packetTooLarge,
|
|
153
|
+
ReasonCode.messageRateTooHigh,
|
|
154
|
+
ReasonCode.quotaExceeded,
|
|
155
|
+
ReasonCode.administrativeAction,
|
|
156
|
+
ReasonCode.payloadFormatInvalid,
|
|
157
|
+
ReasonCode.retainNotSupported,
|
|
158
|
+
ReasonCode.qosNotSupported,
|
|
159
|
+
ReasonCode.useAnotherServer,
|
|
160
|
+
ReasonCode.serverMoved,
|
|
161
|
+
ReasonCode.sharedSubscriptionsNotSupported,
|
|
162
|
+
ReasonCode.connectionRateExceeded,
|
|
163
|
+
ReasonCode.maximumConnectTime,
|
|
164
|
+
ReasonCode.subscriptionIdentifiersNotSupported,
|
|
165
|
+
ReasonCode.wildcardSubscriptionsNotSupported,
|
|
166
|
+
],
|
|
167
|
+
[PacketType.suback]: [
|
|
168
|
+
ReasonCode.grantedQos0,
|
|
169
|
+
ReasonCode.grantedQos1,
|
|
170
|
+
ReasonCode.grantedQos2,
|
|
171
|
+
ReasonCode.unspecifiedError,
|
|
172
|
+
ReasonCode.implementationSpecificError,
|
|
173
|
+
ReasonCode.notAuthorized,
|
|
174
|
+
ReasonCode.topicFilterInvalid,
|
|
175
|
+
ReasonCode.packetIdentifierInUse,
|
|
176
|
+
ReasonCode.quotaExceeded,
|
|
177
|
+
ReasonCode.sharedSubscriptionsNotSupported,
|
|
178
|
+
ReasonCode.subscriptionIdentifiersNotSupported,
|
|
179
|
+
ReasonCode.wildcardSubscriptionsNotSupported,
|
|
180
|
+
],
|
|
181
|
+
} as const;
|
|
182
|
+
|
|
183
|
+
const reasonCodesToString = {
|
|
184
|
+
[0x00]: "Success",
|
|
185
|
+
[0x01]: "Granted QoS 1",
|
|
186
|
+
[0x02]: "Granted QoS 2",
|
|
187
|
+
[0x04]: "Disconnect with Will Message",
|
|
188
|
+
[0x10]: "No matching subscribers",
|
|
189
|
+
[0x11]: "No subscription existed",
|
|
190
|
+
[0x18]: "Continue authentication",
|
|
191
|
+
[0x19]: "Re-authenticate",
|
|
192
|
+
[0x80]: "Unspecified error",
|
|
193
|
+
[0x81]: "Malformed Packet",
|
|
194
|
+
[0x82]: "Protocol Error",
|
|
195
|
+
[0x83]: "Implementation specific error",
|
|
196
|
+
[0x84]: "Unsupported Protocol Version",
|
|
197
|
+
[0x85]: "Client Identifier not valid",
|
|
198
|
+
[0x86]: "Bad User Name or Password",
|
|
199
|
+
[0x87]: "Not authorized",
|
|
200
|
+
[0x88]: "Server unavailable",
|
|
201
|
+
[0x89]: "Server busy",
|
|
202
|
+
[0x8a]: "Banned",
|
|
203
|
+
[0x8b]: "Server shutting down",
|
|
204
|
+
[0x8c]: "Bad authentication method",
|
|
205
|
+
[0x8d]: "Keep Alive timeout",
|
|
206
|
+
[0x8e]: "Session taken over",
|
|
207
|
+
[0x8f]: "Topic Filter invalid",
|
|
208
|
+
[0x90]: "Topic Name invalid",
|
|
209
|
+
[0x91]: "Packet Identifier in use",
|
|
210
|
+
[0x92]: "Packet Identifier not found",
|
|
211
|
+
[0x93]: "Receive Maximum exceeded",
|
|
212
|
+
[0x94]: "Topic Alias invalid",
|
|
213
|
+
[0x95]: "Packet too large",
|
|
214
|
+
[0x96]: "Message rate too high",
|
|
215
|
+
[0x97]: "Quota exceeded",
|
|
216
|
+
[0x98]: "Administrative action",
|
|
217
|
+
[0x99]: "Payload format invalid",
|
|
218
|
+
[0x9a]: "Retain not supported",
|
|
219
|
+
[0x9b]: "QoS not supported",
|
|
220
|
+
[0x9c]: "Use another server",
|
|
221
|
+
[0x9d]: "Server moved",
|
|
222
|
+
[0x9e]: "Shared Subscriptions not supported",
|
|
223
|
+
[0x9f]: "Connection rate exceeded",
|
|
224
|
+
[0xa0]: "Maximum connect time",
|
|
225
|
+
[0xa1]: "Subscription Identifiers not supported",
|
|
226
|
+
[0xa2]: "Wildcard Subscriptions not supported",
|
|
227
|
+
} as const;
|
|
228
|
+
|
|
229
|
+
// Can't import this from types as this would create an import loop
|
|
230
|
+
type TPacketType = typeof PacketType[keyof typeof PacketType];
|
|
231
|
+
export type TReasonCode = typeof ReasonCode[keyof typeof ReasonCode];
|
|
232
|
+
type TReasonCodeByPacket = keyof typeof ReasonCodebyPacket;
|
|
233
|
+
|
|
234
|
+
export function reasonCodeToString(
|
|
235
|
+
packetType: TPacketType,
|
|
236
|
+
code: TReasonCode,
|
|
237
|
+
): string {
|
|
238
|
+
if (code === 0) {
|
|
239
|
+
if (packetType === PacketType.disconnect) {
|
|
240
|
+
return "Normal disconnection";
|
|
241
|
+
}
|
|
242
|
+
if (packetType === PacketType.suback) {
|
|
243
|
+
return "Granted QoS 0";
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return reasonCodesToString[code];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export function isValidReasonCode(
|
|
250
|
+
packetType: TPacketType,
|
|
251
|
+
code: number,
|
|
252
|
+
): boolean {
|
|
253
|
+
const validReasonCodes =
|
|
254
|
+
ReasonCodebyPacket[packetType as TReasonCodeByPacket] as readonly number[];
|
|
255
|
+
return validReasonCodes.includes(code);
|
|
256
|
+
}
|