UNPKG

@stoprocent/bluetooth-hci-socket

Version:
97 lines (79 loc) 2.41 kB
const debug = require('debug')('hci-serial-parser'); const { Transform } = require('stream'); const HCI_COMMAND_PKT = 0x01; const HCI_ACLDATA_PKT = 0x02; const HCI_EVENT_PKT = 0x04; class HciSerialParser extends Transform { constructor (options) { super(options); this.reset(); } _transform (chunk, encoding, callback) { this.packetData = Buffer.concat([this.packetData, chunk]); debug('HciPacketParser._transform:', this.packetData.toString('hex')); if (this.packetType === -1 && this.packetData.length > 0) { this.packetType = this.packetData.readUInt8(0); } if (this.listenerCount('raw') > 0) { this.emit('raw', this.packetData); } while (this.packetData.length > 0) { if (this.packetSize === 0) { if (!this._determinePacketSize()) { break; } } if (this.packetData.length < this.prePacketSize + this.packetSize) { break; } const packet = this.packetData.slice(0, this.prePacketSize + this.packetSize); this.push(packet); this.packetData = this.packetData.slice(this.prePacketSize + this.packetSize); this.packetType = -1; this.packetSize = 0; this.prePacketSize = 0; if (this.packetData.length > 0) { this.packetType = this.packetData.readUInt8(0); } else { this.packetType = -1; } } callback(); } _determinePacketSize () { if (this.packetData.length < 1) { return false; } const packetType = this.packetData.readUInt8(0); if (packetType === HCI_EVENT_PKT || packetType === HCI_COMMAND_PKT) { if (this.packetData.length >= 3) { this.prePacketSize = 3; this.packetSize = this.packetData.readUInt8(2); return true; } } else if (packetType === HCI_ACLDATA_PKT) { if (this.packetData.length >= 5) { this.prePacketSize = 5; this.packetSize = this.packetData.readUInt16LE(3); return true; } } else { this.reset(); } return false; } reset () { this.packetData = Buffer.alloc(0); this.packetType = -1; this.packetSize = 0; this.prePacketSize = 0; } _flush (callback) { if (this.listenerCount('raw') > 0 && this.packetData.length > 0) { this.emit('raw', this.packetData); } this.reset(); callback(); } } module.exports = HciSerialParser;