Skip to content

Commit 392e49a

Browse files
committed
feat: 🎸 add unsuback
1 parent 495fbaa commit 392e49a

File tree

3 files changed

+89
-3
lines changed

3 files changed

+89
-3
lines changed

‎src/MqttDecoder.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import BufferList from 'bl';
2-
import {DECODER_STATE, PACKET_TYPE} from './enums';
2+
import {DECODER_STATE, ERROR, PACKET_TYPE} from './enums';
33
import {PacketConnack, parseConnack} from './packets/connack';
44
import {PacketConnect, parseConnect} from './packets/connect';
55
import {PacketPublish, parsePublish} from './packets/publish';
@@ -10,6 +10,7 @@ import {PacketPubcomp, parsePubcomp} from './packets/pubcomp';
1010
import {PacketSubscribe, parseSubscribe} from './packets/subscribe';
1111
import {PacketSuback, parseSuback} from './packets/suback';
1212
import {PacketUnsubscribe, parseUnsubscribe} from './packets/unsubscribe';
13+
import {PacketUnsuback, parseUnsuback} from './packets/unsuback';
1314

1415
export class MqttDecoder {
1516
public state: DECODER_STATE = DECODER_STATE.HEADER;
@@ -37,7 +38,19 @@ export class MqttDecoder {
3738
this.list = new BufferList();
3839
}
3940

40-
public parse(): null | PacketConnect | PacketConnack | PacketPublish | PacketPuback | PacketPubrec | PacketPubrel | PacketPubcomp | PacketSubscribe | PacketSuback | PacketUnsubscribe {
41+
public parse():
42+
| null
43+
| PacketConnect
44+
| PacketConnack
45+
| PacketPublish
46+
| PacketPuback
47+
| PacketPubrec
48+
| PacketPubrel
49+
| PacketPubcomp
50+
| PacketSubscribe
51+
| PacketSuback
52+
| PacketUnsubscribe
53+
| PacketUnsuback {
4154
this.parseFixedHeader();
4255
const data = this.parseVariableData();
4356
if (!data) return null;
@@ -84,8 +97,12 @@ export class MqttDecoder {
8497
const packet = parseUnsubscribe(b, l, data, this.version);
8598
return packet;
8699
}
100+
case PACKET_TYPE.UNSUBACK: {
101+
const packet = parseUnsuback(b, l, data, this.version);
102+
return packet;
103+
}
87104
default: {
88-
return null;
105+
throw ERROR.MALFORMED_PACKET;
89106
}
90107
}
91108
}

‎src/__tests__/MqttDecoder.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {PacketPubrec} from '../packets/pubrec';
99
import {PacketSubscribe} from '../packets/subscribe';
1010
import { PacketSuback } from '../packets/suback';
1111
import { PacketUnsubscribe } from '../packets/unsubscribe';
12+
import { PacketUnsuback } from '../packets/unsuback';
1213

1314
it('can instantiate', () => {
1415
const decoder = new MqttDecoder();
@@ -572,3 +573,29 @@ describe('UNSUBSCRIBE', () => {
572573
]);
573574
});
574575
});
576+
577+
describe('UNSUBACK', () => {
578+
it('parses MQTT 5.0 packet', () => {
579+
const decoder = new MqttDecoder();
580+
decoder.version = 5;
581+
decoder.push(Buffer.from([
582+
176, 25, // Header
583+
0, 8, // Message ID
584+
20, // properties length
585+
31, 0, 4, 116, 101, 115, 116, // reasonString
586+
38, 0, 4, 116, 101, 115, 116, 0, 4, 116, 101, 115, 116, // userProperties
587+
0, 128 // success and error
588+
]));
589+
const packet: PacketUnsuback = decoder.parse() as PacketUnsuback;
590+
expect(packet.b).toBe(176);
591+
expect(packet.l).toBe(25);
592+
expect(packet.i).toBe(8);
593+
expect(packet.p).toEqual({
594+
[PROPERTY.ReasonString]: 'test',
595+
[PROPERTY.UserProperty]: [
596+
['test', 'test'],
597+
],
598+
});
599+
expect(packet.s).toEqual([0, 128]);
600+
});
601+
});

‎src/packets/unsuback.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import BufferList from 'bl';
2+
import {Packet, PacketHeaderData} from '../packet';
3+
import {Properties} from '../types';
4+
import {parseProps} from '../util/parse';
5+
6+
export interface PacketUnsubackData extends PacketHeaderData {
7+
/** Packet Identifier. */
8+
i: number;
9+
/** Properties. */
10+
p: Properties;
11+
/** SUBACK Payload. */
12+
s: number[];
13+
}
14+
15+
export class PacketUnsuback extends Packet implements PacketUnsubackData {
16+
constructor(
17+
b: number,
18+
l: number,
19+
public i: number,
20+
public p: Properties,
21+
public s: number[],
22+
) {
23+
super(b, l);
24+
}
25+
}
26+
27+
export const parseUnsuback = (b: number, l: number, data: BufferList, version: number): PacketUnsuback => {
28+
const i = data.readUInt16BE(0);
29+
let offset = 2;
30+
let p: Properties = {};
31+
if (version === 5) {
32+
const [props, size] = parseProps(data, offset);
33+
p = props;
34+
offset += size;
35+
}
36+
const len = data.length;
37+
const s: number[] = [];
38+
while (offset < len) {
39+
s.push(data.readUInt8(offset++));
40+
}
41+
return new PacketUnsuback(b, l, i, p, s);
42+
};

0 commit comments

Comments
 (0)