All files packet.ts

100% Statements 60/60
100% Branches 22/22
100% Functions 9/9
100% Lines 59/59

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 991x   1x 1x   1x   69x 69x   69x     69x 69x 69x 69x 69x     1x 9x 8x 1x   8x 8x   8x   8x 8x   8x 8x   8x   9x     1x 3x 2x   1x       1x 2x 1x   1x       1x 2x 1x   1x       1x 3x 1x   2x 2x 2x   2x     1x 3x 1x   2x     1x 37x 37x   37x 21x     37x 37x 37x 37x 37x     1x
import { MessageCode } from './message-code';
import { MessageTypes } from "./message-types";
import { Util } from './utils';
import _ = require('lodash');
 
export class Packet {
 
    private preamble: number = 0xBB;
    private endMark: number = 0x7E;
    private bufferCommand: Buffer;
    public payload: number[] = [];
 
    constructor(
        public messageType: MessageTypes,
        public messageCode: MessageCode,
        public args?: number[],
        public response?: Buffer) {
        this.bufferCommand = Buffer.from([]);
    }
 
    command(): Buffer {
        if (this.bufferCommand.length === 0) {
            if (this.args === undefined) {
                this.args = [];
            }
            this.payload = Util.intTo2Bytes(this.args.length)
            this.args = [this.messageType, this.messageCode].concat(this.payload).concat(this.args);
 
            this.args.push(this.endMark); // Push end mark
 
            let buffer = Buffer.from(this.args);
            let crc16Vet = Util.toByteArray(Util.crc16(buffer).toString(16)); // calculate crc16 of command without preamble
 
            this.args = this.args.concat(crc16Vet); // concat crc16 to cmd buffer
            this.args.unshift(this.preamble); // add preamble on the first position
 
            this.bufferCommand = Buffer.from(this.args);
        }
        return this.bufferCommand;
    }
 
    data_str(): string {
        if (this.args !== undefined && this.args.length > 0) {
            return Util.Utf8ArrayToStr(Uint8Array.from(this.args));
        } else {
            return '';
        }
    }
 
    data_int(): number {
        if (this.args !== undefined && this.args.length > 0) {
            return parseInt(Buffer.from(this.args).toString('hex'), 16);
        } else {
            return 0;
        }
    }
 
    getEpc(): Buffer {
        if (this.args !== undefined && this.args.length > 0) {
            return Buffer.from(this.args);
        } else {
            return Buffer.from([]);
        }
    }
 
    isValid(): boolean {
        if (this.bufferCommand.length < 8)
            return false;
 
        let bf = Buffer.from(this.bufferCommand.subarray(1, this.bufferCommand.length - 2));
        let orCk = [].slice.call(this.bufferCommand.subarray(this.bufferCommand.length - 2));
        let ck = Util.toByteArray(Util.crc16(bf).toString(16));
 
        return _.isEqual(ck, orCk);
    }
 
    hasError(): boolean {
        if (this.bufferCommand.length < 8)
            return false;
 
        return this.messageCode === MessageCode.MC_COMMAND_FAILURE;
    }
 
    static from(buffer: Buffer): Packet {
        let payloadLength = buffer[3] + buffer[4];
        let args = buffer.subarray(5, 5 + payloadLength);
 
        while (args[args.length - 1] === 0 && args.length > 1) {
            args = args.subarray(0, args.length - 1);
        }
 
        let array = [].slice.call(args);
        let packet = new Packet(buffer[1], buffer[2], array);
        packet.payload = Util.intTo2Bytes(payloadLength);
        packet.bufferCommand = buffer;
        return packet;
    }
 
}