UNPKG

bacstack

Version:

A BACnet protocol stack written in pure JavaScript.

193 lines (174 loc) 5.67 kB
'use strict'; const baEnum = require('./enum'); const getDecodedType = module.exports.getDecodedType = (buffer, offset) => { return buffer[offset]; }; module.exports.setDecodedType = (buffer, offset, type) => { buffer[offset] = type; }; module.exports.getDecodedInvokeId = (buffer, offset) => { const type = getDecodedType(buffer, offset); switch (type & baEnum.PDU_TYPE_MASK) { case baEnum.PduTypes.SIMPLE_ACK: case baEnum.PduTypes.COMPLEX_ACK: case baEnum.PduTypes.ERROR: case baEnum.PduTypes.REJECT: case baEnum.PduTypes.ABORT: return buffer[offset + 1]; case baEnum.PduTypes.CONFIRMED_REQUEST: return buffer[offset + 2]; default: return; } }; module.exports.encodeConfirmedServiceRequest = (buffer, type, service, maxSegments, maxApdu, invokeId, sequencenumber, proposedWindowSize) => { buffer.buffer[buffer.offset++] = type; buffer.buffer[buffer.offset++] = maxSegments | maxApdu; buffer.buffer[buffer.offset++] = invokeId; if ((type & baEnum.PduConReqBits.SEGMENTED_MESSAGE) > 0) { buffer.buffer[buffer.offset++] = sequencenumber; buffer.buffer[buffer.offset++] = proposedWindowSize; } buffer.buffer[buffer.offset++] = service; }; module.exports.decodeConfirmedServiceRequest = (buffer, offset) => { const orgOffset = offset; const type = buffer[offset++]; const maxSegments = buffer[offset] & 0xF0; const maxApdu = buffer[offset++] & 0x0F; const invokeId = buffer[offset++]; let sequencenumber = 0; let proposedWindowNumber = 0; if ((type & baEnum.PduConReqBits.SEGMENTED_MESSAGE) > 0) { sequencenumber = buffer[offset++]; proposedWindowNumber = buffer[offset++]; } const service = buffer[offset++]; return { len: offset - orgOffset, type: type, service: service, maxSegments: maxSegments, maxApdu: maxApdu, invokeId: invokeId, sequencenumber: sequencenumber, proposedWindowNumber: proposedWindowNumber }; }; module.exports.encodeUnconfirmedServiceRequest = (buffer, type, service) => { buffer.buffer[buffer.offset++] = type; buffer.buffer[buffer.offset++] = service; }; module.exports.decodeUnconfirmedServiceRequest = (buffer, offset) => { const orgOffset = offset; const type = buffer[offset++]; const service = buffer[offset++]; return { len: offset - orgOffset, type: type, service: service }; }; module.exports.encodeSimpleAck = (buffer, type, service, invokeId) => { buffer.buffer[buffer.offset++] = type; buffer.buffer[buffer.offset++] = invokeId; buffer.buffer[buffer.offset++] = service; }; module.exports.decodeSimpleAck = (buffer, offset) => { const orgOffset = offset; const type = buffer[offset++]; const invokeId = buffer[offset++]; const service = buffer[offset++]; return { len: offset - orgOffset, type: type, service: service, invokeId: invokeId }; }; module.exports.encodeComplexAck = (buffer, type, service, invokeId, sequencenumber, proposedWindowNumber) => { let len = 3; buffer.buffer[buffer.offset++] = type; buffer.buffer[buffer.offset++] = invokeId; if ((type & baEnum.PduConReqBits.SEGMENTED_MESSAGE) > 0) { buffer.buffer[buffer.offset++] = sequencenumber; buffer.buffer[buffer.offset++] = proposedWindowNumber; len += 2; } buffer.buffer[buffer.offset++] = service; return len; }; module.exports.decodeComplexAck = (buffer, offset) => { const orgOffset = offset; const type = buffer[offset++]; const invokeId = buffer[offset++]; let sequencenumber = 0; let proposedWindowNumber = 0; if ((type & baEnum.PduConReqBits.SEGMENTED_MESSAGE) > 0) { sequencenumber = buffer[offset++]; proposedWindowNumber = buffer[offset++]; } const service = buffer[offset++]; return { len: offset - orgOffset, type: type, service: service, invokeId: invokeId, sequencenumber: sequencenumber, proposedWindowNumber: proposedWindowNumber }; }; module.exports.encodeSegmentAck = (buffer, type, originalInvokeId, sequencenumber, actualWindowSize) => { buffer.buffer[buffer.offset++] = type; buffer.buffer[buffer.offset++] = originalInvokeId; buffer.buffer[buffer.offset++] = sequencenumber; buffer.buffer[buffer.offset++] = actualWindowSize; }; module.exports.decodeSegmentAck = (buffer, offset) => { const orgOffset = offset; const type = buffer[offset++]; const originalInvokeId = buffer[offset++]; const sequencenumber = buffer[offset++]; const actualWindowSize = buffer[offset++]; return { len: offset - orgOffset, type: type, originalInvokeId: originalInvokeId, sequencenumber: sequencenumber, actualWindowSize: actualWindowSize }; }; module.exports.encodeError = (buffer, type, service, invokeId) => { buffer.buffer[buffer.offset++] = type; buffer.buffer[buffer.offset++] = invokeId; buffer.buffer[buffer.offset++] = service; }; module.exports.decodeError = (buffer, offset) => { const orgOffset = offset; const type = buffer[offset++]; const invokeId = buffer[offset++]; const service = buffer[offset++]; return { len: offset - orgOffset, type: type, service: service, invokeId: invokeId }; }; module.exports.encodeAbort = (buffer, type, invokeId, reason) => { buffer.buffer[buffer.offset++] = type; buffer.buffer[buffer.offset++] = invokeId; buffer.buffer[buffer.offset++] = reason; }; module.exports.decodeAbort = (buffer, offset) => { const orgOffset = offset; const type = buffer[offset++]; const invokeId = buffer[offset++]; const reason = buffer[offset++]; return { len: offset - orgOffset, type: type, invokeId: invokeId, reason: reason }; };