UNPKG

@iotize/tap-scripts

Version:

IoTize Tap scripts

409 lines 31.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InstructionListVisitor = void 0; const byte_converter_1 = require("@iotize/common/byte-converter"); const tlv_1 = require("@iotize/common/tlv"); const api_1 = require("@iotize/tap/client/api"); const impl_1 = require("@iotize/tap/client/impl"); const definitions_1 = require("./definitions"); const errors_1 = require("./errors"); const instructions_1 = require("./instructions"); const ccom_instruction_1 = require("./instructions/ccom-instruction"); const connect_instruction_1 = require("./instructions/connect-instruction"); const login_instruction_1 = require("./instructions/login-instruction"); const logout_instruction_1 = require("./instructions/logout-instruction"); const output_instruction_1 = require("./instructions/output-instruction"); const wait_instruction_1 = require("./instructions/wait-instruction"); const fw_check_instruction_1 = require("./instructions/fw-check-instruction"); /** * Convert instruction in a file as an instruction list */ class InstructionListVisitor { constructor(tlvConverter = new impl_1.TLVConverter()) { this.tlvConverter = tlvConverter; } visitString(ctx) { return ctx.text.substr(1, ctx.text.length - 2); } visitProg(ctx) { let lines = ctx.line(); const cmd = []; for (let line of lines) { const lineResult = this.visitLine(line); if (lineResult != null) { cmd.push(lineResult); } } return cmd; } visitLine(ctx) { if (ctx.instructionLine()) { return this.visitInstructionLine(ctx.instructionLine()); } else if (ctx.labelLine()) { return this.visitLabelLine(ctx.labelLine()); } else { throw this._errorNotImplemented(ctx); } } visitLabelLine(ctx) { const name = this.visitLabelName(ctx.labelName()); return new instructions_1.LabelInstruction(name); } visitLabelName(ctx) { return ctx.text; } visitInstructionLine(ctx) { if (ctx.instruction()) { return this.visitInstruction(ctx.instruction()); } else { return undefined; } } visitInstruction(ctx) { if (ctx.displayInstructions()) { return this.visitDisplayInstructions(ctx.displayInstructions()); } else if (ctx.gotoInstruction()) { return this.visitGotoInstruction(ctx.gotoInstruction()); } else if (ctx.lwm2mInstruction()) { return this.visitLwm2mInstruction(ctx.lwm2mInstruction()); } else if (ctx.checkInstruction()) { return this.visitCheckInstruction(ctx.checkInstruction()); } else if (ctx.loginInstruction()) { return this.visitLoginInstruction(ctx.loginInstruction()); } else if (ctx.connectionInstructions()) { return this.visitConnectionInstructions(ctx.connectionInstructions()); } else if (ctx.waitInstruction()) { return this.visitWaitInstruction(ctx.waitInstruction()); } else if (ctx.connectionInstructions()) { return this.visitConnectionInstructions(ctx.connectionInstructions()); } else if (ctx.logoutInstruction()) { return this.visitLogoutInstruction(ctx.logoutInstruction()); } else if (ctx.outputInstruction()) { return this.visitOutputInstruction(ctx.outputInstruction()); } else if (ctx.ccomInstruction()) { return this.visitCcomInstruction(ctx.ccomInstruction()); } else if (ctx.end()) { return this.visitEnd(ctx.end()); } else if (ctx.endError()) { return this.visitEndError(ctx.endError()); } else if (ctx.fWMaxCheckInstruction()) { return this.visitFWMaxCheckInstruction(ctx.fWMaxCheckInstruction()); } else if (ctx.fWMinCheckInstruction()) { return this.visitFWMinCheckInstruction(ctx.fWMinCheckInstruction()); } throw this._errorNotImplemented(ctx); } visitComparisonRightOperand(ctx) { let stringNode = ctx.string(); if (stringNode) { return this.visitString(stringNode); } let numberArrayNode = ctx.numberArray(); if (numberArrayNode) { return this.visitNumberArray(numberArrayNode); } throw errors_1.ScriptError.instructionNotImplementedYet(ctx); } visitOutputInstruction(ctx) { return new output_instruction_1.OutputInstruction(); } visitLogoutInstruction(ctx) { return new logout_instruction_1.LogoutInstruction(ctx); } visitConnectionInstructions(ctx) { return new connect_instruction_1.ConnectInstruction(ctx); } visitLoginInstruction(ctx) { const login = this.visitString(ctx.string(0)); const pass = this.visitString(ctx.string(1)); const expectedResultCode = ctx.number() ? this.visitNumber(ctx.number()) : undefined; return new login_instruction_1.LoginInstruction(login, pass, expectedResultCode, ctx); } visitWaitInstruction(ctx) { let duration; const decimalIntegerNode = ctx.DECIMAL_INTEGER(); if (decimalIntegerNode) { duration = parseInt(decimalIntegerNode.text) * 1000; } return new wait_instruction_1.WaitInstruction(duration); } visitGotoInstruction(ctx) { let operator = 'ALWAYS'; if (ctx.gotoType()) { operator = this.visitGotoType(ctx.gotoType()); } const labelName = this.visitLabelName(ctx.labelName()); return new instructions_1.GotoInstruction(operator, labelName); } visitCheckInstruction(ctx) { let dataSizeOf; if (ctx.sizeOf()) { dataSizeOf = this.visitSizeOf(ctx.sizeOf()); } const comparisonInfo = this.visitComparison(ctx.comparison()); return new instructions_1.CheckInstruction(comparisonInfo, dataSizeOf, ctx); } visitFWMinCheckInstruction(ctx) { const minVersion = parseFloat(ctx.FLOAT().text); return new fw_check_instruction_1.FWCheckInstruction((version) => { return version >= minVersion; }); } visitFWMaxCheckInstruction(ctx) { const maxVersion = parseFloat(ctx.FLOAT().text); return new fw_check_instruction_1.FWCheckInstruction((version) => { return version <= maxVersion; }); } visitSizeOf(ctx) { if (!ctx) { return undefined; } return parseInt(ctx.text.substr(1)); } visitComparison(ctx) { const operator = this.visitComp_op(ctx.comp_op()); let dataLength; if (ctx.getChild(0)) { dataLength = parseInt(ctx.getChild(0).text); } const right = this.visitComparisonRightOperand(ctx.comparisonRightOperand()); return { endOffset: dataLength, operator: operator, right: right, }; } visitComp_op(ctx) { if (ctx.OP_EQ()) { return definitions_1.ComparisonOperatorType.EQ; } if (ctx.OP_GT()) { return definitions_1.ComparisonOperatorType.GT; } if (ctx.OP_GTE()) { return definitions_1.ComparisonOperatorType.GTE; } if (ctx.OP_LT()) { return definitions_1.ComparisonOperatorType.LT; } if (ctx.OP_LTE()) { return definitions_1.ComparisonOperatorType.LTE; } if (ctx.OPP_NQ()) { return definitions_1.ComparisonOperatorType.NQ; } if (ctx.OPP_NQ2()) { return definitions_1.ComparisonOperatorType.NQ2; } throw errors_1.ScriptError.instructionNotImplementedYet(ctx); } visitGotoType(ctx) { return ctx.text; // TODO check better } visitDisplayInstructions(ctx) { let text = ctx.text; let displayType = text.split(' ')[0]; let content = text.substr(displayType.length + 1); displayType = displayType.replace('Display', ''); switch (displayType) { case 'Error': return instructions_1.DisplayInstruction.Error(content); case 'Verbose': return instructions_1.DisplayInstruction.Verbose(content); case '': default: return instructions_1.DisplayInstruction.Message(content); } } // visitDisplayInstruction(ctx: DisplayInstructionContext) { // let content = this.visitRestOfLine(ctx.restOfLine()); // return DisplayInstruction.Simple(content); // } // visitDisplayVerboseInstruction(ctx: DisplayVerboseInstructionContext) { // let content = this.visitRestOfLine(ctx.restOfLine()); // return DisplayInstruction.Verbose(content); // } // visitDisplayErrorInstruction(ctx: DisplayErrorInstructionContext) { // let content = this.visitRestOfLine(ctx.restOfLine()); // return DisplayInstruction.Error(content); // } visitResponseLength(ctx) { return this.visitNumber(ctx.number()); } visitCcomInstruction(ctx) { if (ctx.CCOM_AUTO_RAND_START_OFF()) { return new ccom_instruction_1.CComInstruction(ccom_instruction_1.CComInstructionType.AutoRandStartOff, ctx); } else if (ctx.CCOM_AUTO_RAND_START_ON()) { return new ccom_instruction_1.CComInstruction(ccom_instruction_1.CComInstructionType.AutoRandStartOn, ctx); } else if (ctx.CCOM_DISABLE()) { return new ccom_instruction_1.CComInstruction(ccom_instruction_1.CComInstructionType.Disable, ctx); } else if (ctx.CCOM_ENABLE()) { return new ccom_instruction_1.CComInstruction(ccom_instruction_1.CComInstructionType.Enable, ctx); } else if (ctx.CCOM_RAND_START()) { return new ccom_instruction_1.CComInstruction(ccom_instruction_1.CComInstructionType.RandStart, ctx); } else { throw this._errorNotImplemented(ctx); } } visitLwm2mInstruction(ctx) { const method = this.visitLwm2mMethod(ctx.lwm2mMethod()); const path = this.visitLwm2mPath(ctx.lwm2mPath()); let body; const parameter = ctx.lwm2mParameter(); let expectedResponseLength; const responseLengthNode = ctx.responseLength(); if (responseLengthNode) { expectedResponseLength = this.visitResponseLength(responseLengthNode); } if (parameter) { body = this.visitLwm2mParameter(parameter); } const expectedResultCode = this.visitNumber(ctx.number()); const command = new instructions_1.Lwm2mCommandInstruction({ path, method, body, }, expectedResultCode, expectedResponseLength); command.context = ctx; return command; } visitLwm2mMethod(ctx) { if (ctx.GET() || ctx.GETP()) { return api_1.TapRequestFrame.MethodType.GET; } else if (ctx.POST()) { return api_1.TapRequestFrame.MethodType.POST; } else if (ctx.PUT()) { return api_1.TapRequestFrame.MethodType.PUT; } else { throw this._errorNotImplemented(ctx); } } visitLwm2mPath(ctx) { return ctx.text; } visitObjectParameter(ctx) { const numberContexts = ctx.number(); const values = []; for (let i = 0; i < numberContexts.length; i++) { const number = this.visitNumber(numberContexts[i]) >>> 0; if (number > 0xffff) { throw errors_1.ScriptError.invalidRunState(`TLV id is too big: ${number}. Maximum value is ${0xffff}`); } values[i] = number; } if (values.length != 2) { throw errors_1.ScriptError.instructionNotImplementedYet(ctx, `Object with a lengh != 2 is not implemented`); } const resourceInstanceId = values[0]; const value = values[1]; const node = { header: { id: resourceInstanceId, len: 1, type: tlv_1.TLV.IdentifierType.RESOURCE_INSTANCE, }, payload: impl_1.NumberConverter.uint8().encode(value), }; const encodedTlv = this.tlvConverter.encode(node); return encodedTlv; // new TLVConverter().encode(new TLV) // return Uint8Array.from([ // 0x40, // TLV TYPE for resource instance id // (resourceInstanceId >> 8) & 0xFF, // (resourceInstanceId & 0xFF), // (value >> 8) & 0xFF, // (value & 0xFF) // ]) } visitLwm2mParameter(ctx) { if (ctx.number()) { const number = this.visitNumber(ctx.number()); const sizeOf = this.visitSizeOf(ctx.sizeOf()) || 8; return impl_1.NumberConverter.toOpaqueMsb(number, sizeOf); } else if (ctx.hexArray()) { return this.visitHexArray(ctx.hexArray()); } else if (ctx.string()) { return (0, byte_converter_1.asciiStringToByteBuffer)(this.visitString(ctx.string())); } else if (ctx.objectParameter()) { return this.visitObjectParameter(ctx.objectParameter()); } else { throw this._errorNotImplemented(ctx); } } visitHexArray(ctx) { let content = ctx.text.substr(1, ctx.text.length - 2); return impl_1.HexStringConverter.instance().encode(content); } visitEnd(ctx) { return new instructions_1.EndInstruction(); } visitEndError(ctx) { return new instructions_1.EndInstruction(this.visitNumber(ctx.number())); } visitHexInteger(ctx) { return parseInt(ctx.text); } visitNumber(ctx) { return parseInt(ctx.text); } visitNumberArray(ctx) { const numberContexts = ctx.number(); const result = []; for (const numberCtx of numberContexts) { result.push(this.visitNumber(numberCtx)); } return result; } visitRestOfLine(ctx) { return ctx.text; } visit(tree) { return tree.accept(this); } visitChildren(node) { throw errors_1.ScriptError.internalError('Method visitChildren not implemented.'); } visitTerminal(node) { throw errors_1.ScriptError.internalError('Method visitTerminal not implemented.'); } visitErrorNode(node) { throw errors_1.ScriptError.internalError('Method visitErrorNode not implemented.'); } _errorNotImplemented(ctx) { return errors_1.ScriptError.instructionNotImplementedYet(ctx); } } exports.InstructionListVisitor = InstructionListVisitor; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdHJ1Y3Rpb24tbGlzdC12aXNpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9pbnN0cnVjdGlvbi1saXN0LXZpc2l0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsa0VBQXdFO0FBQ3hFLDRDQUF5QztBQUN6QyxnREFBeUQ7QUFDekQsa0RBSWlDO0FBOENqQywrQ0FLdUI7QUFDdkIscUNBQXVDO0FBQ3ZDLGlEQVF3QjtBQUN4QixzRUFHeUM7QUFDekMsNEVBQXdFO0FBQ3hFLHdFQUFvRTtBQUNwRSwwRUFBc0U7QUFDdEUsMEVBQXNFO0FBQ3RFLHNFQUFrRTtBQUNsRSw4RUFBeUU7QUFFekU7O0dBRUc7QUFDSCxNQUFhLHNCQUFzQjtJQUNqQyxZQUFtQixlQUFlLElBQUksbUJBQVksRUFBRTtRQUFqQyxpQkFBWSxHQUFaLFlBQVksQ0FBcUI7SUFBRyxDQUFDO0lBRXhELFdBQVcsQ0FBQyxHQUFrQjtRQUM1QixPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQWdCO1FBQ3hCLElBQUksS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN2QixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDZixLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssRUFBRTtZQUN0QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hDLElBQUksVUFBVSxJQUFJLElBQUksRUFBRTtnQkFDdEIsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUN0QjtTQUNGO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsU0FBUyxDQUNQLEdBQWdCO1FBRWhCLElBQUksR0FB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