Move raw packet processing to the base class

This commit is contained in:
MultiMote 2025-01-08 11:56:25 +03:00
parent 2b671a6d96
commit 2659b824ed
4 changed files with 47 additions and 77 deletions

@ -19,6 +19,7 @@ import {
HeartbeatEvent, HeartbeatEvent,
HeartbeatFailedEvent, HeartbeatFailedEvent,
PacketReceivedEvent, PacketReceivedEvent,
RawPacketReceivedEvent,
} from "../events"; } from "../events";
import { findPrintTask, PrintTaskName } from "../print_tasks"; import { findPrintTask, PrintTaskName } from "../print_tasks";
import { Utils, Validators } from "../utils"; import { Utils, Validators } from "../utils";
@ -65,6 +66,7 @@ export abstract class NiimbotAbstractClient extends EventEmitter<ClientEventMap>
private heartbeatIntervalMs: number = 2_000; private heartbeatIntervalMs: number = 2_000;
protected mutex: Mutex = new Mutex(); protected mutex: Mutex = new Mutex();
protected debug: boolean = false; protected debug: boolean = false;
private packetBuf = new Uint8Array();
/** @see https://github.com/MultiMote/niimblue/issues/5 */ /** @see https://github.com/MultiMote/niimblue/issues/5 */
protected packetIntervalMs: number = 10; protected packetIntervalMs: number = 10;
@ -145,6 +147,42 @@ export abstract class NiimbotAbstractClient extends EventEmitter<ClientEventMap>
}); });
} }
/**
* Convert raw bytes to packet objects and fire events. Defragmentation included.
* @param data Bytes to process.
*/
protected processRawPacket(data: DataView | Uint8Array) {
if (data.byteLength === 0) {
return;
}
console.log("processRawPacket")
if (data instanceof DataView) {
data = new Uint8Array(data.buffer);
}
this.packetBuf = Utils.u8ArrayAppend(this.packetBuf, data);
try {
const packets: NiimbotPacket[] = NiimbotPacket.fromBytesMultiPacket(this.packetBuf);
if (packets.length > 0) {
this.emit("rawpacketreceived", new RawPacketReceivedEvent(this.packetBuf));
packets.forEach((p) => {
this.emit("packetreceived", new PacketReceivedEvent(p));
});
this.packetBuf = new Uint8Array();
}
} catch (_e) {
if (this.debug) {
console.info(`Incomplete packet, ignoring:${Utils.bufToHex(this.packetBuf)}`);
}
}
}
/** /**
* Send raw bytes to the printer port. * Send raw bytes to the printer port.
* *

@ -1,7 +1,6 @@
import { ConnectEvent, DisconnectEvent, PacketReceivedEvent, RawPacketReceivedEvent, RawPacketSentEvent } from "../events"; import { ConnectEvent, DisconnectEvent, RawPacketSentEvent } from "../events";
import { ConnectionInfo, NiimbotAbstractClient } from "."; import { ConnectionInfo, NiimbotAbstractClient } from ".";
import { NiimbotPacket } from "../packets/packet"; import { ConnectResult } from "../packets";
import { ConnectResult, ResponseCommandId } from "../packets";
import { Utils } from "../utils"; import { Utils } from "../utils";
class BleConfiguration { class BleConfiguration {
@ -65,18 +64,7 @@ export class NiimbotBluetoothClient extends NiimbotAbstractClient {
channel.addEventListener("characteristicvaluechanged", (event: Event) => { channel.addEventListener("characteristicvaluechanged", (event: Event) => {
const target = event.target as BluetoothRemoteGATTCharacteristic; const target = event.target as BluetoothRemoteGATTCharacteristic;
this.processRawPacket(target.value!);
const data = new Uint8Array(target.value!.buffer);
this.emit("rawpacketreceived", new RawPacketReceivedEvent(data));
const packet = NiimbotPacket.fromBytes(data);
this.emit("packetreceived", new PacketReceivedEvent(packet));
if (!(packet.command in ResponseCommandId)) {
console.warn(`Unknown response command: 0x${Utils.numberToHex(packet.command)}`);
}
}); });
await channel.startNotifications(); await channel.startNotifications();

@ -1,19 +1,12 @@
import { import { ConnectEvent, DisconnectEvent, RawPacketSentEvent } from "../events";
ConnectEvent,
DisconnectEvent,
PacketReceivedEvent,
RawPacketReceivedEvent,
RawPacketSentEvent,
} from "../events";
import { ConnectionInfo, NiimbotAbstractClient } from "."; import { ConnectionInfo, NiimbotAbstractClient } from ".";
import { NiimbotPacket } from "../packets/packet";
import { ConnectResult } from "../packets"; import { ConnectResult } from "../packets";
import { Utils } from "../utils"; import { Utils } from "../utils";
import { BleCharacteristic, BleClient, BleDevice, BleService } from "@capacitor-community/bluetooth-le"; import { BleCharacteristic, BleClient, BleDevice, BleService } from "@capacitor-community/bluetooth-le";
/** /**
* @category Client * @category Client
*/ */
export interface NiimbotCapacitorBleClientConnectOptions { export interface NiimbotCapacitorBleClientConnectOptions {
/** /**
* Skip device picker dialog and connect to given device ID. * Skip device picker dialog and connect to given device ID.
@ -34,7 +27,6 @@ export class NiimbotCapacitorBleClient extends NiimbotAbstractClient {
private deviceId?: string; private deviceId?: string;
private serviceUUID?: string; private serviceUUID?: string;
private characteristicUUID?: string; private characteristicUUID?: string;
private packetBuf = new Uint8Array();
public async connect(options?: NiimbotCapacitorBleClientConnectOptions): Promise<ConnectionInfo> { public async connect(options?: NiimbotCapacitorBleClientConnectOptions): Promise<ConnectionInfo> {
await this.disconnect(); await this.disconnect();
@ -73,7 +65,7 @@ export class NiimbotCapacitorBleClient extends NiimbotAbstractClient {
} }
await BleClient.startNotifications(this.deviceId, this.serviceUUID, this.characteristicUUID, (value: DataView) => { await BleClient.startNotifications(this.deviceId, this.serviceUUID, this.characteristicUUID, (value: DataView) => {
this.onBlePacketReceived(value); this.processRawPacket(value);
}); });
try { try {
@ -116,32 +108,6 @@ export class NiimbotCapacitorBleClient extends NiimbotAbstractClient {
throw new Error("Unable to find suitable channel characteristic"); throw new Error("Unable to find suitable channel characteristic");
} }
private onBlePacketReceived(dv: DataView) {
if (dv.byteLength === 0) {
return;
}
this.packetBuf = Utils.u8ArrayAppend(this.packetBuf, new Uint8Array(dv.buffer));
try {
const packets: NiimbotPacket[] = NiimbotPacket.fromBytesMultiPacket(this.packetBuf);
if (packets.length > 0) {
this.emit("rawpacketreceived", new RawPacketReceivedEvent(this.packetBuf));
packets.forEach((p) => {
this.emit("packetreceived", new PacketReceivedEvent(p));
});
this.packetBuf = new Uint8Array();
}
} catch (_e) {
if (this.debug) {
console.info(`Incomplete packet, ignoring:${Utils.bufToHex(this.packetBuf)}`);
}
}
}
private onBleDisconnect() { private onBleDisconnect() {
this.deviceId = undefined; this.deviceId = undefined;
this.serviceUUID = undefined; this.serviceUUID = undefined;

@ -1,6 +1,5 @@
import { ConnectEvent, DisconnectEvent, PacketReceivedEvent, RawPacketReceivedEvent, RawPacketSentEvent } from "../events"; import { ConnectEvent, DisconnectEvent, RawPacketSentEvent } from "../events";
import { ConnectionInfo, NiimbotAbstractClient } from "."; import { ConnectionInfo, NiimbotAbstractClient } from ".";
import { NiimbotPacket } from "../packets/packet";
import { ConnectResult } from "../packets"; import { ConnectResult } from "../packets";
import { Utils } from "../utils"; import { Utils } from "../utils";
@ -63,8 +62,6 @@ export class NiimbotSerialClient extends NiimbotAbstractClient {
} }
private async waitSerialData() { private async waitSerialData() {
let buf = new Uint8Array();
while (true) { while (true) {
try { try {
const result = await this.reader!.read(); const result = await this.reader!.read();
@ -72,8 +69,7 @@ export class NiimbotSerialClient extends NiimbotAbstractClient {
if (this.debug) { if (this.debug) {
console.info(`<< serial chunk ${Utils.bufToHex(result.value)}`); console.info(`<< serial chunk ${Utils.bufToHex(result.value)}`);
} }
this.processRawPacket(result.value);
buf = Utils.u8ArrayAppend(buf, result.value);
} }
if (result.done) { if (result.done) {
@ -83,24 +79,6 @@ export class NiimbotSerialClient extends NiimbotAbstractClient {
} catch (_e) { } catch (_e) {
break; break;
} }
try {
const packets: NiimbotPacket[] = NiimbotPacket.fromBytesMultiPacket(buf);
if (packets.length > 0) {
this.emit("rawpacketreceived", new RawPacketReceivedEvent(buf));
packets.forEach((p) => {
this.emit("packetreceived", new PacketReceivedEvent(p));
});
buf = new Uint8Array();
}
} catch (_e) {
if (this.debug) {
console.info(`Incomplete packet, ignoring:${Utils.bufToHex(buf)}`);
}
}
} }
} }