@twilio/plugin-microvisor
Version:
Interact with your Twilio Microvisor devices
144 lines (143 loc) • 6.35 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProtobufToTunnel = void 0;
const node_events_1 = require("node:events");
const proto_1 = require("../../../../proto_gen/proto");
class ProtobufToTunnel extends node_events_1.EventEmitter {
constructor(tunnel) {
super();
this.messageEmitter = new node_events_1.EventEmitter();
this.tunnel = tunnel;
this.tunnel.on('data', (data) => {
// data is the decrypted contents of an envelope, containing
// exactly one protobuf message.
let dataArray = new Uint8Array(data);
if (dataArray.length === 0) {
return;
}
let method = ProtobufToTunnel.purposeToMethod.get(dataArray[0]);
let body = dataArray.subarray(1);
if (typeof method === 'undefined') {
return;
}
if (method === 'HaltReason' &&
this.messageEmitter.listeners('HaltReason').length === 0) {
this.emit('unsolicitedHalt', proto_1.HaltReasonResponse.decode(body));
}
else if (method === 'Ping') {
this.emit('pong');
}
else {
this.messageEmitter.emit(method, body);
}
});
this.tunnel.on('open', () => {
this.emit('open');
});
this.tunnel.on('close', () => {
this.emit('close');
});
this.tunnel.on('error', (_error) => {
this.emit('close');
});
}
rpcImpl(method, requestData, callback) {
let purpose = ProtobufToTunnel.methodToPurpose.get(method.name);
if (typeof purpose === 'undefined') {
callback(new Error(`Unknown method ${method.name}`), null);
return;
}
let header = new Uint8Array([purpose[0]]);
// Assuming calls to rpcImpl are serialized by the user, might change in future
this.messageEmitter.once(method.name, (data) => {
callback(null, data);
});
this.tunnel.write(Buffer.concat([header, requestData]));
}
async waitHaltReason() {
return new Promise((resolve, _reject) => {
this.messageEmitter.once('HaltReason', (data) => {
resolve(proto_1.HaltReasonResponse.decode(data));
});
});
}
sendPing(callback) {
this.once('pong', callback);
this.tunnel.write(Buffer.from([proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_PING_REQUEST]));
}
}
exports.ProtobufToTunnel = ProtobufToTunnel;
_a = ProtobufToTunnel;
ProtobufToTunnel.methodToPurpose = new Map([
['Hello', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_HELLO_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_HELLO_RESPONSE
]],
['Goodbye', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_GOODBYE_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_GOODBYE_RESPONSE
]],
['HaltReason', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_HALT_REASON_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_HALT_REASON_RESPONSE
]],
['ReadRegisters', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_READ_REGISTERS_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_READ_REGISTERS_RESPONSE
]],
['ReadRegister', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_READ_REGISTER_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_READ_REGISTER_RESPONSE
]],
['WriteRegisters', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_WRITE_REGISTERS_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_WRITE_REGISTERS_RESPONSE
]],
['WriteRegister', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_WRITE_REGISTER_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_WRITE_REGISTER_RESPONSE
]],
['ReadMemory', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_READ_MEMORY_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_READ_MEMORY_RESPONSE
]],
['WriteMemory', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_WRITE_MEMORY_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_WRITE_MEMORY_RESPONSE
]],
['Continue', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_CONTINUE_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_CONTINUE_RESPONSE
]],
['Halt', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_HALT_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_HALT_RESPONSE
]],
['InsertBreakpoint', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_INSERT_BREAKPOINT_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_INSERT_BREAKPOINT_RESPONSE
]],
['RemoveBreakpoint', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_REMOVE_BREAKPOINT_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_REMOVE_BREAKPOINT_RESPONSE
]],
['Step', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_STEP_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_STEP_RESPONSE
]],
['Ping', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_PING_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_PING_RESPONSE
]],
['PluginTelemetry', [
proto_1.DebugProtocol_ServerToDevice_MessageTypes.TYPE_S2D_PLUGIN_TELEMETRY_REQUEST,
proto_1.DebugProtocol_DeviceToServer_MessageTypes.TYPE_D2S_PLUGIN_TELEMETRY_RESPONSE
]]
]);
ProtobufToTunnel.purposeToMethod = new Map();
(() => {
for (const [key, value] of _a.methodToPurpose) {
_a.purposeToMethod.set(value[1], key);
}
})();