UNPKG

knxnetjs

Version:

A TypeScript library for KNXnet/IP communication

161 lines 5.93 kB
"use strict"; /** * KNX USB Transfer Protocol implementation * Handles the KNX USB Transfer Protocol Header and Body structures */ Object.defineProperty(exports, "__esModule", { value: true }); exports.KNXUSBTransferFrame = exports.KNXUSBTransferEMIId = exports.KNXUSBTransferProtocolId = void 0; var KNXUSBTransferProtocolId; (function (KNXUSBTransferProtocolId) { KNXUSBTransferProtocolId[KNXUSBTransferProtocolId["KNXTunnel"] = 1] = "KNXTunnel"; KNXUSBTransferProtocolId[KNXUSBTransferProtocolId["BusAccessServerFeatureService"] = 15] = "BusAccessServerFeatureService"; })(KNXUSBTransferProtocolId || (exports.KNXUSBTransferProtocolId = KNXUSBTransferProtocolId = {})); var KNXUSBTransferEMIId; (function (KNXUSBTransferEMIId) { KNXUSBTransferEMIId[KNXUSBTransferEMIId["EMI1"] = 1] = "EMI1"; KNXUSBTransferEMIId[KNXUSBTransferEMIId["EMI2"] = 2] = "EMI2"; KNXUSBTransferEMIId[KNXUSBTransferEMIId["cEMI"] = 3] = "cEMI"; })(KNXUSBTransferEMIId || (exports.KNXUSBTransferEMIId = KNXUSBTransferEMIId = {})); class KNXUSBTransferFrame { constructor(header, body) { this.header = header; this.body = body; } /** * Creates a KNX USB Transfer Frame from a Buffer */ static fromBuffer(buffer) { if (buffer.length < 8) { throw new Error("Buffer too short for KNX USB Transfer Header"); } // Parse Header const header = { protocolVersion: buffer[0] || 0, headerLength: buffer[1] || 0, bodyLength: buffer.readUInt16BE(2), protocolId: buffer[4] || 0, emiId: buffer[5] || 0, manufacturerCode: buffer.readUInt16BE(6), }; // Validate header if (header.headerLength !== 0x08) { throw new Error(`Invalid header length: ${header.headerLength}`); } if (buffer.length < header.headerLength + 1) { throw new Error("Buffer too short for KNX USB Transfer Body"); } // Parse Body const bodyStart = header.headerLength; const emiMessageCode = buffer[bodyStart] || 0; const data = buffer.subarray(bodyStart + 1); const body = { emiMessageCode, data, }; return new KNXUSBTransferFrame(header, body); } /** * Converts the frame to a Buffer */ toBuffer() { const bodyBuffer = Buffer.allocUnsafe(1 + this.body.data.length); bodyBuffer[0] = this.body.emiMessageCode; this.body.data.copy(bodyBuffer, 1); const headerBuffer = Buffer.allocUnsafe(8); headerBuffer[0] = this.header.protocolVersion; headerBuffer[1] = this.header.headerLength; headerBuffer.writeUInt16BE(bodyBuffer.length, 2); // body length headerBuffer[4] = this.header.protocolId; headerBuffer[5] = this.header.emiId; headerBuffer.writeUInt16BE(this.header.manufacturerCode, 6); return Buffer.concat([headerBuffer, bodyBuffer]); } /** * Creates a KNX USB Transfer Frame for cEMI data */ static createForCEMI(cemiData, manufacturerCode = 0x0000) { const body = { emiMessageCode: cemiData[0], data: cemiData.subarray(1), }; const header = { protocolVersion: 0x00, headerLength: 0x08, bodyLength: 1 + cemiData.length, // message code + data protocolId: KNXUSBTransferProtocolId.KNXTunnel, emiId: KNXUSBTransferEMIId.cEMI, manufacturerCode, }; return new KNXUSBTransferFrame(header, body); } /** * Creates a KNX USB Transfer Frame for bus access */ static createForBusAccess(service, feature, value) { const body = { emiMessageCode: feature, data: value, }; const header = { protocolVersion: 0x00, headerLength: 0x08, bodyLength: 1 + value.length, // feature + data protocolId: KNXUSBTransferProtocolId.BusAccessServerFeatureService, emiId: service, manufacturerCode: 0x0000, }; return new KNXUSBTransferFrame(header, body); } /** * Validates if a buffer contains a valid KNX USB Transfer Frame */ static isValid(buffer) { if (buffer.length < 9) { // Minimum: 8-byte header + 1-byte EMI message code return false; } const protocolVersion = buffer[0]; const headerLength = buffer[1]; const protocolId = buffer[4]; const emiId = buffer[5]; return (protocolVersion === 0x00 && headerLength === 0x08 && protocolId === KNXUSBTransferProtocolId.KNXTunnel && emiId === KNXUSBTransferEMIId.cEMI); } /** * Gets the cEMI data from the frame body */ getCEMIData() { if (this.body.emiMessageCode === 0x11) { // cEMI format return this.body.data; } return null; } /** * Returns frame information as a string for debugging */ toString() { return `KNXUSBTransferFrame { header: { protocolVersion: 0x${this.header.protocolVersion .toString(16) .padStart(2, "0")}, headerLength: 0x${this.header.headerLength.toString(16).padStart(2, "0")}, bodyLength: ${this.header.bodyLength}, protocolId: 0x${this.header.protocolId.toString(16).padStart(2, "0")}, emiId: 0x${this.header.emiId.toString(16).padStart(2, "0")}, manufacturerCode: 0x${this.header.manufacturerCode .toString(16) .padStart(4, "0")} }, body: { emiMessageCode: 0x${this.body.emiMessageCode.toString(16).padStart(2, "0")}, dataLength: ${this.body.data.length} } }`; } } exports.KNXUSBTransferFrame = KNXUSBTransferFrame; //# sourceMappingURL=knx-usb-transfer.js.map