@iotile/iotile-device
Version:
A typescript library for interfacing with IOTile BLE devices
149 lines • 5.57 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
const iotile_common_1 = require("@iotile/iotile-common");
const errors_1 = require("./errors");
;
;
function rpc(address, rpcID, argFormat, respFormat) {
return function (target, propertyKey, descriptor) {
target.rpcData = {
argFormat: argFormat,
respFormat: respFormat,
rpcID: rpcID,
address: address
};
};
}
exports.rpc = rpc;
function tileRPC(rpcID, argFormat, respFormat) {
return function (target, propertyKey, descriptor) {
target[propertyKey].rpcData = {
argFormat: argFormat,
respFormat: respFormat,
rpcID: rpcID
};
};
}
exports.tileRPC = tileRPC;
class BaseRPCDispatcher {
constructor(defaultAddress) {
this.rpcTable = {};
this.address = defaultAddress;
this.findRPCHandlers(this);
}
addRPC(address, rpcID, argFormat, respFormat, handler, thisObject) {
let desc = {
argFormat: argFormat,
respFormat: respFormat,
handler: handler,
thisObject: thisObject
};
if (!(address in this.rpcTable))
this.rpcTable[address] = {};
if (rpcID in this.rpcTable[address])
throw new iotile_common_1.ArgumentError(`Attempted to add the same RPC ID twice, address: ${address}, rpcID: ${rpcID}`);
this.rpcTable[address][rpcID] = desc;
}
async rpc(address, rpcID, args) {
if (!(address in this.rpcTable) || !(rpcID in this.rpcTable[address])) {
throw new errors_1.RPCNotFound(address, rpcID);
}
let desc = this.rpcTable[address][rpcID];
let parsedArgs = [];
if (args != null && desc.argFormat.length > 0) {
parsedArgs = iotile_common_1.unpackArrayBuffer(desc.argFormat, args);
}
let response = desc.handler.apply(desc.thisObject, parsedArgs);
if (response instanceof Promise) {
response = await response;
}
return iotile_common_1.packArrayBuffer(desc.respFormat, ...response);
}
hasRPC(address, rpcID) {
if (!(address in this.rpcTable) || !(rpcID in this.rpcTable[address])) {
return false;
}
return true;
}
findRPCHandlers(obj) {
let prototype = obj;
let methods = [];
while (prototype != null) {
let ownMethods = Object.getOwnPropertyNames(prototype);
methods = methods.concat(ownMethods);
prototype = Object.getPrototypeOf(prototype);
}
for (let methodName of methods) {
let method = this[methodName];
if (method == null) {
continue;
}
if (method.rpcData != null) {
let address = method.rpcData.address;
if (address == null) {
if (this.address == null) {
throw new iotile_common_1.ArgumentError("Attempted to add an RPC without an address in a context with no default address");
}
address = this.address;
}
this.addRPC(address, method.rpcData.rpcID, method.rpcData.argFormat, method.rpcData.respFormat, method, obj);
}
}
}
}
exports.BaseRPCDispatcher = BaseRPCDispatcher;
class VirtualTile extends BaseRPCDispatcher {
constructor(address, name, firmwareVersion) {
super(address);
this.name = name;
this.firmwareVersion = firmwareVersion;
}
tile_status() {
return [0xFFFF, this.name, 1, 0, 0, 0];
}
}
__decorate([
tileRPC(0x0004, "", "H6sBBBB"),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Object)
], VirtualTile.prototype, "tile_status", null);
exports.VirtualTile = VirtualTile;
class VirtualDevice extends BaseRPCDispatcher {
constructor(iotileID, tiles) {
super();
this.tiles = tiles;
this.iotileID = iotileID;
for (let tile of tiles) {
if (tile.address == 8) {
this.controller = tile;
}
}
}
async rpc(address, rpcID, args) {
if (this.hasRPC(address, rpcID)) {
return super.rpc(address, rpcID, args);
}
for (let tile of this.tiles) {
if (tile.hasRPC(address, rpcID)) {
return await tile.rpc(address, rpcID, args);
}
}
throw new errors_1.RPCNotFound(address, rpcID);
}
}
exports.VirtualDevice = VirtualDevice;
function packError(subsystem, errorCode) {
return (subsystem << 16) | errorCode;
}
exports.packError = packError;
//# sourceMappingURL=virtual-device.js.map