UNPKG

xiot-core-xcp-ts

Version:
217 lines (216 loc) 7.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XcpClientBase = void 0; const XcpClientVerifierImpl_1 = require("./XcpClientVerifierImpl"); const WebSocketBinaryFrameCodecImpl_1 = require("../codec/WebSocketBinaryFrameCodecImpl"); const xiot_core_spec_ts_1 = require("xiot-core-spec-ts"); const StanzaCodec_1 = require("../../stanza/codec/StanzaCodec"); const IQResult_1 = require("../../stanza/typedef/iq/IQResult"); const IQError_1 = require("../../stanza/typedef/iq/IQError"); const IQQuery_1 = require("../../stanza/typedef/iq/IQQuery"); const XcpFrameCodecType_1 = require("../common/XcpFrameCodecType"); const Uint8ArrayUtils_1 = require("../utils/Uint8ArrayUtils"); const IQ_1 = require("../../stanza/typedef/iq/IQ"); const IQType_1 = require("../../stanza/typedef/iq/IQType"); class XcpClientBase { constructor(serialNumber, productId, type, cipher, codec) { this.cipher = cipher; this.codec = codec; this.ws = null; this.verifier = null; this.verified = false; this.frameCodec = null; this.messageId = 1; this.verifyHandler = () => { }; this.disconnectHandler = () => { }; this.did = serialNumber + '@' + productId; this.type = type; this.messageCodec = new StanzaCodec_1.StanzaCodec(); this.resultHandlers = new Map(); this.queryHandlers = new Map(); } createWebSocket(url) { // this.ws = new WebSocket(url); throw Error('createWebSocket failed !'); } connect(host, port, uri) { const url = 'ws://' + host + ':' + port + uri; console.log('connect: ' + url); this.ws = this.createWebSocket(url); if (this.ws == null) { throw Error('new WebSocket Failed!'); } this.ws.addEventListener('open', () => this.onConnected()); this.ws.addEventListener('close', () => this.onDisconnect()); this.ws.addEventListener('error', () => this.onError()); this.ws.addEventListener('message', message => this.onMessage(message)); return new Promise((resolve, reject) => { this.verifyHandler = (result, err) => { if (result) { resolve(); return; } reject(err); }; }); } disconnect() { if (this.ws != null) { this.ws.close(); } } getDeviceId() { return this.did; } getDeviceType() { return this.type; } getNextStanzaId() { return Date.now() + '#' + this.messageId++; } addQueryHandler(method, handler) { console.log('addQueryHandler: ', method); this.queryHandlers.set(method, handler); } addDisconnectHandler(handler) { this.disconnectHandler = handler; } sendQuery(query) { this.write(this.messageCodec.encode(query)); return new Promise((resolve, reject) => { this.resultHandlers.set(query.id, (result, error) => { if (error != null) { reject(error); return; } if (result == null) { return; } resolve(result); }); }); } sendResult(result) { this.write(this.messageCodec.encode(result)); } sendError(error) { this.write(this.messageCodec.encode(error)); } sendMessage(message) { this.write(this.messageCodec.encode(message)); } onConnected() { console.log('onConnected'); this.startVerify('1.0') .then(() => this.verifyHandler(true)) .catch(e => this.verifyHandler(false, e)); } onDisconnect() { console.log('onDisconnect'); this.ws = null; this.disconnectHandler(); } onError() { console.log('onError'); this.ws = null; } onMessage(message) { let msg = null; if (this.frameCodec == null) { console.log(Date() + ' recv text frame: ', message.data); msg = this.messageCodec.decode(message.data); } else { const data = this.frameCodec.decrypt(message.data); if (data != null) { const s = Uint8ArrayUtils_1.Utf8ArrayToStr(data); console.log(Date() + ' recv binary frame: ', s); msg = this.messageCodec.decode(s); } } if (msg == null) { return; } this.handleMessage(msg); } handleMessage(message) { if (message instanceof IQ_1.IQ) { switch (message.type) { case IQType_1.IQType.QUERY: this.handleQuery(message); break; case IQType_1.IQType.RESULT: this.handleResult(message); break; case IQType_1.IQType.ERROR: this.handleError(message); break; default: console.log('invalid message: ', message); break; } } else { console.log('message not IQ: ', message); } } handleQuery(query) { if (!(query instanceof IQQuery_1.IQQuery)) { return; } const handler = this.queryHandlers.get(query.method); if (handler != null) { handler(query); } else { this.sendError(query.error(xiot_core_spec_ts_1.Status.UNDEFINED, 'Query Handler not found')); } } handleResult(result) { if (!(result instanceof IQResult_1.IQResult)) { return; } const handler = this.resultHandlers.get(result.id); if (handler != null) { handler(result, null); this.resultHandlers.delete(result.id); } else { console.log('handle for result not found: ', result.id); } } handleError(error) { if (!(error instanceof IQError_1.IQError)) { return; } const handler = this.resultHandlers.get(error.id); if (handler != null) { this.verifyHandler(false, error); handler(null, error); this.resultHandlers.delete(error.id); } else { console.log('handle for error not found: ', error.id); } } startVerify(version) { this.verifier = new XcpClientVerifierImpl_1.XcpClientVerifierImpl(this, version, this.cipher, this.codec); return this.verifier.start().then(x => this.setXcpSessionKey(x)); } setXcpSessionKey(key) { console.log('setXcpSessionKey, codec: ', key.codec); if (key.codec !== XcpFrameCodecType_1.XcpFrameCodecType.NOT_CRYPT) { this.frameCodec = new WebSocketBinaryFrameCodecImpl_1.WebSocketBinaryFrameCodecImpl(key.deviceToServer, key.serverToDevice); } console.log('verify succeed!'); this.verified = true; } write(o) { const s = JSON.stringify(o); console.log(Date() + ' write: ', s); if (this.ws != null) { this.ws.send(s); } } } exports.XcpClientBase = XcpClientBase;