@seriousme/opifex
Version:
MQTT client & server for Deno & NodeJS
55 lines (48 loc) • 1.73 kB
text/typescript
import type { PacketId, Topic, TopicFilter, TPacketType } from "./types.ts";
import { PacketType } from "./PacketType.ts";
import { BitMask } from "./BitMask.ts";
import { Encoder } from "./encoder.ts";
import { booleanFlag, Decoder, DecoderError } from "./decoder.ts";
/**
* UnsubscribePacket is sent from client to server to unsubscribe from topics
*/
export type UnsubscribePacket = {
type: TPacketType;
id: PacketId;
topicFilters: TopicFilter[];
};
export const unsubscribe: {
encode(packet: UnsubscribePacket): { flags: number; bytes: number[] };
decode(buffer: Uint8Array, flags: number): UnsubscribePacket;
} = {
encode(packet: UnsubscribePacket): { flags: number; bytes: number[] } {
// Bits 3,2,1 and 0 of the fixed header of the UNSUBSCRIBE Control Packet are reserved and
// MUST be set to 0,0,1 and 0 respectively. The Server MUST treat any other value as
// malformed and close the Network Connection [MQTT-3.10.1-1].
const flags = 0b0010;
const encoder = new Encoder();
encoder.setInt16(packet.id);
for (const topicFilter of packet.topicFilters) {
encoder.setTopicFilter(topicFilter);
}
return { flags, bytes: encoder.done() };
},
decode(buffer: Uint8Array, flags: number): UnsubscribePacket {
if (!booleanFlag(flags, BitMask.bit1)) {
throw new DecoderError("Invalid header");
}
const decoder = new Decoder(buffer);
const id = decoder.getInt16();
const topicFilters: Topic[] = [];
do {
const topicFilter = decoder.getTopicFilter();
topicFilters.push(topicFilter);
} while (!decoder.atEnd());
decoder.done();
return {
type: PacketType.unsubscribe,
id,
topicFilters,
};
},
};