@iotize/device-client.js
Version:
IoTize Device client for Javascript
326 lines (325 loc) • 13.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var rxjs_1 = require("rxjs");
var operators_1 = require("rxjs/operators");
var core_1 = require("../../core");
var logger_1 = require("../../logger");
var default_command_encoder_1 = require("./converter/default-command-encoder");
var response_decoder_1 = require("./converter/response-decoder");
var interceptors_1 = require("./interceptors");
var client_errors_1 = require("./client-errors");
var logger = logger_1.default('Client');
var DefaultIoTizeClient = /** @class */ (function () {
function DefaultIoTizeClient(requestEncoder, responseDecoder) {
var _this = this;
this._onProtocolChange = new rxjs_1.Subject();
this._commandEncoder = requestEncoder;
this._responseDecoder = responseDecoder;
this.protocols = {};
this._interceptorChain = new interceptors_1.InterceptorChain(function (context) {
try {
var command = context.command;
var bodyDecoder = context.bodyDecoder;
return _this._command(command, bodyDecoder);
}
catch (err) {
return rxjs_1.throwError(err);
}
});
}
DefaultIoTizeClient.create = function (protocol) {
var client = new DefaultIoTizeClient(new default_command_encoder_1.DefaultCommandEncoder(), new response_decoder_1.DefaultResponseDecoder());
if (protocol) {
client.addComProtocol(protocol);
}
return client;
};
Object.defineProperty(DefaultIoTizeClient.prototype, "interceptorChain", {
// public isEncryptionEnabled(): boolean {
// return this._options.encryption;
// }
// public get cryptedFrameConverter() {
// return this._cryptedFrameConverter;
// }
get: function () {
return this._interceptorChain;
},
enumerable: true,
configurable: true
});
DefaultIoTizeClient.prototype.addInterceptor = function (interceptor) {
this.interceptorChain.addInterceptor(interceptor);
return this;
};
// /**
// * Enable/Disable encrytion when communicating with a device
// * @param value true if requests must be encrypted
// * @param algo optional if you have already provided the algo with @{link setEncryptionAlgo(algo)} method
// */
// public enableEncryption(value: boolean, algo?: EncryptionAlgo): Promise<any> {
// if (value) {
// algo = algo || this._encryptionAlgo;
// if (!algo) {
// return Promise.reject(
// TapClientError.illegalArgument(
// 'Illegal argument, encryption algo must be set'
// )
// );
// }
// return this._startEncryption(algo);
// }
// else {
// return this._stopEncryption();
// }
// }
DefaultIoTizeClient.prototype.isConnected = function () {
return this.hasProtocol(this.currentProtocolId) && this.getCurrentProtocol().isConnected();
};
Object.defineProperty(DefaultIoTizeClient.prototype, "protocol", {
/**
* see {@link getCurrentProtocol}
*/
get: function () {
return this.getCurrentProtocol();
},
enumerable: true,
configurable: true
});
Object.defineProperty(DefaultIoTizeClient.prototype, "commandEncoder", {
get: function () {
return this._commandEncoder;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DefaultIoTizeClient.prototype, "responseDecoder", {
get: function () {
return this._responseDecoder;
},
enumerable: true,
configurable: true
});
/**
* Get current protocol or throw an error if no protocol
*/
DefaultIoTizeClient.prototype.getCurrentProtocol = function () {
if (!this.currentProtocolId) {
throw client_errors_1.TapClientError.illegalStateError("No protocol");
}
if (!this.hasProtocol(this.currentProtocolId)) {
throw client_errors_1.TapClientError.illegalArgument("Protocol " + this.currentProtocolId + " does not exist");
}
return this.protocols[this.currentProtocolId];
};
/**
* Register/replace a communication protocol with given id
* If no communication protocol is selected yet, it will select it.
* @param newProtocol
* @param id
*/
DefaultIoTizeClient.prototype.addComProtocol = function (newProtocol, id) {
if (id === void 0) { id = 'default'; }
this.protocols[id] = newProtocol;
if (!this.currentProtocolId) {
this.currentProtocolId = id;
}
return this;
};
/**
* Switch to given communication protocol identifier
* @throws if protocol identifier does not exist
* @param name
*/
DefaultIoTizeClient.prototype.switchProtocol = function (name) {
if (!this.hasProtocol(name)) {
throw client_errors_1.TapClientError.illegalArgument("Unkonwn protocol: " + name);
}
var oldProtocol = this.getCurrentProtocol();
this.currentProtocolId = name;
logger.debug("Changing protocol to: " + name);
this._onProtocolChange.next({
newProtocol: this.getCurrentProtocol(),
oldProtocol: oldProtocol
});
return this;
};
/**
* Change communication protocol
* @throws if protocol identifier does not exist
* @param protocol can either be the communication protocol instance or a string identifier
*/
DefaultIoTizeClient.prototype.useComProtocol = function (protocol) {
var protocolId;
if (typeof protocol == "string") {
protocolId = protocol;
}
else {
protocolId = protocol.constructor.name;
this.addComProtocol(protocol, protocolId);
}
this.switchProtocol(protocolId);
return this;
};
/**
* Return true if protocol identifier is registered
* @param id
*/
DefaultIoTizeClient.prototype.hasProtocol = function (id) {
return id in this.protocols;
};
DefaultIoTizeClient.prototype.connect = function () {
try {
return this.getCurrentProtocol().connect();
}
catch (err) {
return rxjs_1.throwError(err);
}
};
DefaultIoTizeClient.prototype.disconnect = function () {
try {
return this.getCurrentProtocol().disconnect();
}
catch (err) {
return rxjs_1.throwError(err);
}
};
/**
* Send command
* @param command
* @param bodyDecoder
*/
DefaultIoTizeClient.prototype.command = function (command, bodyDecoder) {
return this._interceptorChain.execute({
bodyDecoder: bodyDecoder,
command: command,
client: this
});
};
/**
* Send raw request
* No interceptors/No encryption will be triggered
* @param dataIn request bytes
* @param bodyDecoder optional body decoder to use
*/
DefaultIoTizeClient.prototype.send = function (dataIn, bodyDecoder) {
var _this = this;
try {
return this.getCurrentProtocol()
.send(dataIn)
.pipe(operators_1.map(function (result) {
logger.debug("Received result: ", core_1.FormatHelper.toHexString(result), "DECODER: ", (bodyDecoder ? bodyDecoder.constructor.name : 'NO'));
try {
var response = _this._responseDecoder.decode(result);
if (bodyDecoder) {
// logger.debug(`SETTING BODY DECODER: `, bodyDecoder);
response.setBodyDecoder(bodyDecoder);
}
return response;
}
catch (err) {
throw client_errors_1.TapClientError.decodeResponseError(err, dataIn);
}
}));
}
catch (err) {
return rxjs_1.throwError(err);
}
};
/**
* Listen to connection state change event
* We have to resubscribe when protocol change..
*/
DefaultIoTizeClient.prototype.onConnectionStateChange = function () {
try {
return this.getCurrentProtocol().onConnectionStateChange();
}
catch (err) {
return rxjs_1.throwError(err);
}
};
DefaultIoTizeClient.prototype.onProtocolChange = function () {
try {
return this._onProtocolChange.asObservable();
}
catch (err) {
return rxjs_1.throwError(err);
}
};
// protected _encryptedCommand<T>(command: Command, bodyDecoder?: BodyDecoder<T>): Observable<Response<T>> {
// if (!this._cryptedFrameConverter) {
// return throwError(
// TapClientError.illegalStateError(`Crypted convert has not been specified yet`)
// );
// }
// if (!this._encryptionAlgo) {
// return throwError(
// TapClientError.illegalStateError(`Cryto algo has not been specified yet`)
// );
// }
// let iotizeFrame = this._lwm2mCommandConverter.encode(command);
// let cryptedFrameWarpper = this._cryptedFrameConverter.encode(iotizeFrame);
// let cryptedFrame = this._encryptionAlgo.encode(cryptedFrameWarpper);
// return this
// ._command<Uint8Array>(ApiRequest.GET("/1024//48", cryptedFrame)) // TODO constants
// .pipe(
// map<Response<Uint8Array>, Response<T>>((crypterWarpperResponse: Response<Uint8Array>) => {
// logger.debug(`Iotize client crypted frame: ${crypterWarpperResponse}`);
// crypterWarpperResponse.successful();
// if (!this._encryptionAlgo) {
// throw TapClientError.illegalStateError(`Encryption algo has not been set yet`)
// }
// let cryptedFrameContent = this._encryptionAlgo.decode(crypterWarpperResponse.rawBody());
// logger.debug(`Decrypted frame value: ${FormatHelper.toHexString(cryptedFrameContent)}`);
// let apduFrame = this._cryptedFrameConverter.decode(cryptedFrameContent);
// let lwm2mResponseFrame = this._apduResponseConverter.decode(apduFrame);
// // TODO do we need to check apdu status ?
// let response: Response<any> = this.lwm2mResponseConverter.decode(lwm2mResponseFrame.data);
// if (bodyDecoder) {
// response.setBodyDecoder(bodyDecoder);
// }
// logger.debug(`Iotize client decoded response: ${response}`)
// return response as any as Response<T>;
// })
// );
// }
DefaultIoTizeClient.prototype._command = function (command, bodyDecoder) {
var _this = this;
try {
if (!this.isConnected()) {
return rxjs_1.throwError(client_errors_1.TapClientError.notConnectedError());
}
var dataIn = void 0;
try {
dataIn = this._commandEncoder.encode(command);
}
catch (e) {
return rxjs_1.throwError(client_errors_1.TapClientError.encodeRequestError(command, e));
}
logger.debug("Sending " + dataIn.length + " bytes 0x" + core_1.FormatHelper.toHexString(dataIn));
return this.getCurrentProtocol()
.send(dataIn)
.pipe(operators_1.map(function (result) {
logger.debug("Received result: ", core_1.FormatHelper.toHexString(result), "DECODER: ", (bodyDecoder ? bodyDecoder.constructor.name : 'NO'));
try {
var response = _this._responseDecoder.decode(result);
if (bodyDecoder) {
response.setBodyDecoder(bodyDecoder);
}
return response;
}
catch (err) {
throw client_errors_1.TapClientError.decodeResponseError(err, command);
}
}), operators_1.map(function (response) {
logger.debug("Command \"" + command.toString() + "\" => Response: " + response.toString());
response.setRequest(command);
return response;
}));
}
catch (err) {
return rxjs_1.throwError(err);
}
};
return DefaultIoTizeClient;
}());
exports.DefaultIoTizeClient = DefaultIoTizeClient;