UNPKG

@iotize/device-client.js

Version:

IoTize Device client for Javascript

326 lines (325 loc) 13.3 kB
"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;