From d46a5a37dcf015e38141e37854059319a62d631b Mon Sep 17 00:00:00 2001 From: olzzon Date: Wed, 18 Dec 2024 09:39:46 +0100 Subject: [PATCH 01/67] fix: some Ember implementations has an empty string as identifier --- src/Ember/Lib/util.ts | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Ember/Lib/util.ts b/src/Ember/Lib/util.ts index ba571e6..3c2e7eb 100644 --- a/src/Ember/Lib/util.ts +++ b/src/Ember/Lib/util.ts @@ -91,17 +91,15 @@ export function isEmptyNode(node: TreeElement): boolean { return false } - if ( - node.contents.description ?? - node.contents.identifier ?? - node.contents.isOnline ?? - node.contents.isRoot ?? - node.contents.schemaIdentifiers ?? - node.contents.templateReference - ) { - return false - } - - // node is a node, node has no children, node has no properties set => node must be empty - return true + // Check if any of these properties have a value, including empty strings as a node with an empty description is not empty) + const notEmpty = [ + node.contents.description, + node.contents.identifier, + node.contents.isOnline, + node.contents.isRoot, + node.contents.schemaIdentifiers, + node.contents.templateReference, + ].some((value) => value !== undefined && value !== null) + + return !notEmpty } From b9f9cdd99dd8a93f138aece7967912cbeb67ecfc Mon Sep 17 00:00:00 2001 From: olzzon Date: Wed, 18 Dec 2024 15:46:40 +0100 Subject: [PATCH 02/67] wip: implementing stream subsciption --- src/Ember/Client/index.ts | 88 ++++++++++++++--- src/Ember/Socket/S101Socket.ts | 2 + src/S101/S101Codec.ts | 118 ++++++++++++++++++++++- src/encodings/ber/decoder/StreamEntry.ts | 4 + 4 files changed, 194 insertions(+), 18 deletions(-) diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index 460475f..75e2d26 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -24,7 +24,7 @@ import { Subscribe, Invoke, } from '../../model/Command' -import { Parameter } from '../../model/Parameter' +import { Parameter, ParameterType } from '../../model/Parameter' import { Connection, ConnectionDisposition, ConnectionOperation } from '../../model/Connection' import { EmberNode } from '../../model/EmberNode' import { EventEmitter } from 'eventemitter3' @@ -34,6 +34,7 @@ import { berEncode } from '../..' import { NumberedTreeNodeImpl } from '../../model/Tree' import { EmberFunction } from '../../model/EmberFunction' import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult' +import { StreamEntry } from '../../model/StreamEntry' export type RequestPromise = Promise> export interface RequestPromiseArguments { @@ -97,6 +98,7 @@ export class EmberClient extends EventEmitter { private _lastInvocation = 0 private _client: S101Client private _subscriptions: Array = [] + private _streamSubscriptions: Map void> = new Map() private _timeout = 3000 private _resendTimeout = 1000 @@ -126,6 +128,7 @@ export class EmberClient extends EventEmitter { this._client = new S101Client(this.host, this.port) this._client.on('emberTree', (tree: DecodeResult) => this._handleIncoming(tree)) + this._client.on('streamPacket', (entries) => this._handleStreamPacket(entries)) this._client.on('error', (e) => this.emit('error', e)) this._client.on('connected', () => this.emit('connected')) @@ -222,22 +225,38 @@ export class EmberClient extends EventEmitter { const command: Subscribe = new SubscribeImpl() - if (Array.isArray(node)) { + // Handle stream subscriptions + if ( + 'contents' in node && + node.contents.type === ElementType.Parameter && + node.contents.streamIdentifier !== undefined + ) { + this._streamSubscriptions.set(node.contents.streamIdentifier, (value: EmberValue) => { + if (cb) { + const updatedNode = { ...node } + if ('value' in updatedNode.contents) { + updatedNode.contents.value = value + cb(updatedNode) + } + } + }) + } else { + if (Array.isArray(node)) { + if (cb) + this._subscriptions.push({ + path: undefined, + cb, + }) + + return this._sendRequest(new NumberedTreeNodeImpl(0, command), ExpectResponse.Any) + } + if (cb) this._subscriptions.push({ - path: undefined, + path: getPath(node), cb, }) - - return this._sendRequest(new NumberedTreeNodeImpl(0, command), ExpectResponse.Any) } - - if (cb) - this._subscriptions.push({ - path: getPath(node), - cb, - }) - return this._sendCommand(node, command, ExpectResponse.None) } async unsubscribe(node: NumberedTreeNode | Array): RequestPromise { @@ -292,8 +311,10 @@ export class EmberClient extends EventEmitter { const qualifiedParam = assertQualifiedEmberNode(node) as QualifiedElement - // TODO - validate value - // TODO - should other properties be scrapped? + if (!('value' in qualifiedParam.contents)) { + throw new Error('Node is not a parameter') + } + qualifiedParam.contents.value = value return this._sendRequest>( @@ -496,6 +517,28 @@ export class EmberClient extends EventEmitter { private _handleIncoming(incoming: DecodeResult) { const node = incoming.value + + // Check if this is a stream entry + if (Array.isArray(node) && node[0] && 'identifier' in node[0]) { + // This is a stream entry + const entries = node as StreamEntry[] + entries.forEach((entry) => { + // Find any subscriptions for this stream + const callback = this._streamSubscriptions.get(entry.identifier) + if (callback && entry.value) { + // For audio level data, extract the value properly + if (entry.value.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { + const view = new DataView(entry.value.value.buffer) + // Assuming 32-bit float in little-endian format + const value = view.getFloat32(0, true) + callback(value) + } else { + callback(entry.value.value) + } + } + }) + return + } // update tree: const changes = this._applyRootToTree(node) @@ -536,6 +579,23 @@ export class EmberClient extends EventEmitter { incoming.errors?.forEach((e) => this.emit('warn', e)) } + private _handleStreamPacket(entries: StreamEntry[]): void { + entries.forEach((entry) => { + const callback = this._streamSubscriptions.get(entry.identifier) + if (callback && entry.value) { + // Handle Octets value properly + if (entry.value.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { + // For audio level data, we can extract the first value if needed + const view = new DataView(entry.value.value.buffer) + const value = view.getFloat32(0, true) // Get first value, assuming little-endian + callback(value) + } else { + callback(entry.value.value) + } + } + }) + } + private _applyRootToTree(node: Root): Array { const changes: Array = [] diff --git a/src/Ember/Socket/S101Socket.ts b/src/Ember/Socket/S101Socket.ts index f86efa2..9de5892 100644 --- a/src/Ember/Socket/S101Socket.ts +++ b/src/Ember/Socket/S101Socket.ts @@ -7,6 +7,7 @@ import { ConnectionStatus } from '../Client' import { normalizeError } from '../Lib/util' import { Root } from '../../types' import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult' +import { StreamEntry } from '../../model' export type Request = any @@ -17,6 +18,7 @@ export type S101SocketEvents = { connecting: [] connected: [] disconnected: [] + streamPacket: [entries: StreamEntry[]] } export default class S101Socket extends EventEmitter { diff --git a/src/S101/S101Codec.ts b/src/S101/S101Codec.ts index 616dddb..adb5916 100644 --- a/src/S101/S101Codec.ts +++ b/src/S101/S101Codec.ts @@ -2,6 +2,10 @@ import { EventEmitter } from 'eventemitter3' import { SmartBuffer } from 'smart-buffer' import Debug from 'debug' import { format } from 'util' +import { ParameterType, StreamEntry } from '../model' +import { decodeStreamEntries } from '../encodings/ber/decoder/StreamEntry' +import { Reader } from '../Ber' +import { guarded } from '../encodings/ber/decoder/DecodeResult' const debug = Debug('emberplus-connection:S101Codec') const S101_BOF = 0xfe @@ -56,6 +60,7 @@ export type S101CodecEvents = { emberPacket: [packet: Buffer] keepaliveReq: [] keepaliveResp: [] + streamPacket: [entries: StreamEntry[]] } export default class S101Codec extends EventEmitter { @@ -63,6 +68,9 @@ export default class S101Codec extends EventEmitter { emberbuf = new SmartBuffer() escaped = false + private multiPacketBuffer?: SmartBuffer + private isMultiPacket = false + dataIn(buf: Buffer): void { for (let i = 0; i < buf.length; i++) { const b = buf.readUInt8(i) @@ -105,12 +113,113 @@ export default class S101Codec extends EventEmitter { debug('received keepalive response') this.emit('keepaliveResp') } else if (command === CMD_EMBER) { - this.handleEmberFrame(frame) + const remainingData = frame.readBuffer() + const emberFrame = SmartBuffer.fromBuffer(remainingData) + + emberFrame.skip(1) // Skip version byte + const flags = emberFrame.readUInt8() + + emberFrame.skip(1) // Skip dtd byte + const appBytes = emberFrame.readUInt8() + + if (appBytes > 0) { + emberFrame.readBuffer(appBytes) + } + + try { + const payload = emberFrame.readBuffer() + const data = payload.slice(0, payload.length - 2) // Remove CRC + + // Check first byte to determine packet type before processing + const packetType = data[0] + + if ((flags & FLAG_SINGLE_PACKET) === FLAG_SINGLE_PACKET) { + // Single packet message (0xC0) + if ((flags & FLAG_EMPTY_PACKET) === 0) { + if (packetType === 0x66) { + // Stream Collection + const reader = new Reader(data) + const entries = guarded(decodeStreamEntries(reader)) + this.emit('streamPacket', entries) + } else if (packetType === 0x60) { + // Root Ember Element + this.emit('emberPacket', data) + } else { + console.log('Unknown packet type:', packetType) + } + } + } else if (this.isMultiPacket && this.multiPacketBuffer) { + this.multiPacketBuffer.writeBuffer(data) + + if ((flags & FLAG_LAST_MULTI_PACKET) === FLAG_LAST_MULTI_PACKET) { + const completeData = this.multiPacketBuffer.toBuffer() + const completePacketType = completeData[0] + + if (completePacketType === 0x66) { + const reader = new Reader(completeData) + const entries = guarded(decodeStreamEntries(reader)) + this.emit('streamPacket', entries) + } else if (completePacketType === 0x60) { + this.emit('emberPacket', completeData) + } + + this.multiPacketBuffer = undefined + this.isMultiPacket = false + } + } else if ((flags & FLAG_FIRST_MULTI_PACKET) === FLAG_FIRST_MULTI_PACKET) { + console.log('Starting multi-packet message') + this.multiPacketBuffer = new SmartBuffer() + this.multiPacketBuffer.writeBuffer(data) + this.isMultiPacket = true + } + } catch (error) { + // Clean up if error occurs during multi-packet processing + this.resetMultiPacketBuffer() + throw new Error('Error processing frame:' + JSON.stringify(error, null, 2)) + } } else { throw new Error(format('dropping frame of length %d with unknown command %d', frame.length, command)) } } + handleStreamFrame(frame: SmartBuffer): void { + const reader = new Reader(frame.toBuffer()) + const entries = guarded(decodeStreamEntries(reader)) + this.emit('streamPacket', entries) + + // Process each stream entry individually + entries.forEach((entry) => { + // For audio level data stored as octets, extract the values + if (entry.value.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { + const buffer = entry.value.value + const values = [] + + // Assuming each value is a 32-bit float in little-endian + for (let i = 0; i < buffer.length; i += 4) { + values.push(buffer.readFloatLE(i)) + } + + // Emit the processed values + this.emit('streamPacket', [ + { + identifier: entry.identifier, + value: { + type: ParameterType.Real, + value: values[0], // Emit first value or handle multiple values as needed + }, + }, + ]) + } else { + this.emit('streamPacket', [entry]) + } + }) + } + + // Cleanup if multi-packet message is not completed + resetMultiPacketBuffer(): void { + this.multiPacketBuffer = undefined + } + handleEmberFrame(frame: SmartBuffer): void { const version = frame.readUInt8() const flags = frame.readUInt8() @@ -122,15 +231,16 @@ export default class S101Codec extends EventEmitter { } if (dtd !== DTD_GLOW) { - throw new Error('Dropping frame with non-Glow DTD') + // Don't throw, just warn and continue processing + debug('Warning: Received frame with DTD %d, expected %d', dtd, DTD_GLOW) } if (appBytes < 2) { debug('Warning: Frame missing Glow DTD version') frame.skip(appBytes) } else { - frame.readUInt8() // glowMinor - frame.readUInt8() // glowMajor + frame.skip(1) // Skip minor version + frame.skip(1) // Skip major version appBytes -= 2 if (appBytes > 0) { frame.skip(appBytes) diff --git a/src/encodings/ber/decoder/StreamEntry.ts b/src/encodings/ber/decoder/StreamEntry.ts index 84ea65f..5493a16 100644 --- a/src/encodings/ber/decoder/StreamEntry.ts +++ b/src/encodings/ber/decoder/StreamEntry.ts @@ -54,6 +54,10 @@ function decodeStreamEntry(reader: Ber.Reader, options: DecodeOptions = defaultD break case Ber.CONTEXT(1): value = reader.readValue() + // If type is Octets, ensure proper Buffer handling + if (value.type === ParameterType.Octets && typeof value.value === 'string') { + value.value = Buffer.from(value.value) + } break case 0: break // indefinite length From de3b2ef723455e8f5d57be1115720e6928a8147f Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 19 Dec 2024 10:32:16 +0100 Subject: [PATCH 03/67] wip: emit via normal subscription - meter data currently hardcoded --- src/S101/S101Codec.ts | 148 +++++++++++++---------- src/encodings/ber/decoder/StreamEntry.ts | 37 +++++- src/encodings/ber/index.ts | 3 + 3 files changed, 119 insertions(+), 69 deletions(-) diff --git a/src/S101/S101Codec.ts b/src/S101/S101Codec.ts index adb5916..9577bba 100644 --- a/src/S101/S101Codec.ts +++ b/src/S101/S101Codec.ts @@ -2,10 +2,12 @@ import { EventEmitter } from 'eventemitter3' import { SmartBuffer } from 'smart-buffer' import Debug from 'debug' import { format } from 'util' -import { ParameterType, StreamEntry } from '../model' import { decodeStreamEntries } from '../encodings/ber/decoder/StreamEntry' import { Reader } from '../Ber' -import { guarded } from '../encodings/ber/decoder/DecodeResult' +import { DecodeResult } from '../encodings/ber/decoder/DecodeResult' +import { berDecode, berEncode } from '../encodings/ber' +import { Root, RootType } from '../types' +import { ParameterType } from '../model' const debug = Debug('emberplus-connection:S101Codec') const S101_BOF = 0xfe @@ -60,7 +62,6 @@ export type S101CodecEvents = { emberPacket: [packet: Buffer] keepaliveReq: [] keepaliveResp: [] - streamPacket: [entries: StreamEntry[]] } export default class S101Codec extends EventEmitter { @@ -130,47 +131,25 @@ export default class S101Codec extends EventEmitter { const payload = emberFrame.readBuffer() const data = payload.slice(0, payload.length - 2) // Remove CRC - // Check first byte to determine packet type before processing - const packetType = data[0] - if ((flags & FLAG_SINGLE_PACKET) === FLAG_SINGLE_PACKET) { - // Single packet message (0xC0) if ((flags & FLAG_EMPTY_PACKET) === 0) { - if (packetType === 0x66) { - // Stream Collection - const reader = new Reader(data) - const entries = guarded(decodeStreamEntries(reader)) - this.emit('streamPacket', entries) - } else if (packetType === 0x60) { - // Root Ember Element - this.emit('emberPacket', data) - } else { - console.log('Unknown packet type:', packetType) - } + this.handlePacket(data) } - } else if (this.isMultiPacket && this.multiPacketBuffer) { - this.multiPacketBuffer.writeBuffer(data) - - if ((flags & FLAG_LAST_MULTI_PACKET) === FLAG_LAST_MULTI_PACKET) { - const completeData = this.multiPacketBuffer.toBuffer() - const completePacketType = completeData[0] - - if (completePacketType === 0x66) { - const reader = new Reader(completeData) - const entries = guarded(decodeStreamEntries(reader)) - this.emit('streamPacket', entries) - } else if (completePacketType === 0x60) { - this.emit('emberPacket', completeData) + } else { + // Multi-packet handling + if ((flags & FLAG_FIRST_MULTI_PACKET) === FLAG_FIRST_MULTI_PACKET) { + this.multiPacketBuffer = new SmartBuffer() + this.isMultiPacket = true + this.multiPacketBuffer.writeBuffer(data) + } else if (this.isMultiPacket && this.multiPacketBuffer) { + this.multiPacketBuffer.writeBuffer(data) + + if ((flags & FLAG_LAST_MULTI_PACKET) === FLAG_LAST_MULTI_PACKET) { + const completeData = this.multiPacketBuffer.toBuffer() + this.handlePacket(completeData) + this.resetMultiPacketBuffer() } - - this.multiPacketBuffer = undefined - this.isMultiPacket = false } - } else if ((flags & FLAG_FIRST_MULTI_PACKET) === FLAG_FIRST_MULTI_PACKET) { - console.log('Starting multi-packet message') - this.multiPacketBuffer = new SmartBuffer() - this.multiPacketBuffer.writeBuffer(data) - this.isMultiPacket = true } } catch (error) { // Clean up if error occurs during multi-packet processing @@ -182,37 +161,74 @@ export default class S101Codec extends EventEmitter { } } - handleStreamFrame(frame: SmartBuffer): void { - const reader = new Reader(frame.toBuffer()) - const entries = guarded(decodeStreamEntries(reader)) - this.emit('streamPacket', entries) - - // Process each stream entry individually - entries.forEach((entry) => { - // For audio level data stored as octets, extract the values - if (entry.value.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { - const buffer = entry.value.value - const values = [] - - // Assuming each value is a 32-bit float in little-endian - for (let i = 0; i < buffer.length; i += 4) { - values.push(buffer.readFloatLE(i)) + private handlePacket(data: Buffer): void { + const packetType = data[0] + + if (packetType === 0x60) { + // Standard Ember packet + try { + // Handle both regular ember data and stream data within 0x60 packets + const decoded = berDecode(data) + if (decoded.value) { + // Emit the standard ember packet + this.emit('emberPacket', data) + + // Check if the decoded data contains stream entries + if (this.hasStreamData(decoded)) { + this.handleStreamData(decoded) + } } + } catch (error) { + console.error('Error decoding 0x60 packet:', error) + } + } else if (packetType === 0x66) { + // Direct stream packet + try { + const reader = new Reader(data) + const entries = decodeStreamEntries(reader) + this.handleStreamEntries(entries) + } catch (error) { + console.error('Error decoding 0x66 packet:', error) + } + } + } + + //@ts-ignore - this method is not yet implemented and will be based on log output + private hasStreamData(decoded: DecodeResult): boolean { + // Check if the decoded data contains stream-related identifiers or structures + // This would depend on your specific protocol implementation + return false // Implement based on your ember protocol details + } + + //@ts-ignore - this method is not yet implemented and will be based on log output + private handleStreamData(decoded: DecodeResult): void { + console.log('Stream data:', decoded) + // Extract stream data from regular ember packet and emit through subscription + // Implementation depends on your ember protocol details + } - // Emit the processed values - this.emit('streamPacket', [ - { - identifier: entry.identifier, - value: { + private handleStreamEntries(entries: DecodeResult): void { + if (entries.value) { + entries.value.forEach((entry: any) => { + if (entry.value?.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { + // Convert octets to appropriate value type + const buffer = entry.value.value + const value = buffer.readFloatLE(0) + + // Create ember-style update for subscriptions + const emberUpdate = { + number: entry.identifier, + contents: { + value, type: ParameterType.Real, - value: values[0], // Emit first value or handle multiple values as needed }, - }, - ]) - } else { - this.emit('streamPacket', [entry]) - } - }) + } + + // Emit as regular ember packet to trigger subscriptions + this.emit('emberPacket', berEncode(emberUpdate, RootType.Elements)) + } + }) + } } // Cleanup if multi-packet message is not completed diff --git a/src/encodings/ber/decoder/StreamEntry.ts b/src/encodings/ber/decoder/StreamEntry.ts index 5493a16..b527b35 100644 --- a/src/encodings/ber/decoder/StreamEntry.ts +++ b/src/encodings/ber/decoder/StreamEntry.ts @@ -54,9 +54,40 @@ function decodeStreamEntry(reader: Ber.Reader, options: DecodeOptions = defaultD break case Ber.CONTEXT(1): value = reader.readValue() - // If type is Octets, ensure proper Buffer handling - if (value.type === ParameterType.Octets && typeof value.value === 'string') { - value.value = Buffer.from(value.value) + + // Special handling for audio level data + if (value.type === ParameterType.Octets && Buffer.isBuffer(value.value)) { + const buffer = value.value + + // THIS IS CURRENTLY A HACK + // HARDOCED TO 64 AND 68 + // BUT SHOULD FOLLOW THE NODE's offSet value + // Debug logging + console.log('Audio buffer analysis:') + console.log('Buffer length:', buffer.length) + console.log( + 'Buffer Bytes:', + Array.from(buffer) + .map((b) => '0x' + b.toString(16).padStart(2, '0')) + .join(' ') + ) + + if (buffer.length >= 4) { + // The buffer appears to contain pairs of float32 values + // First value is the current level, second is the peak + const currentLevel = buffer.readFloatLE(64) + const peakLevel = buffer.length >= 8 ? buffer.readFloatLE(68) : currentLevel + console.log('Decoded current level:', currentLevel) + console.log('Decoded peak level:', peakLevel) + + // Convert to Real type + value = { + type: ParameterType.Real, + value: currentLevel, + } + } else { + console.warn('Audio buffer too short:', buffer.length) + } } break case 0: diff --git a/src/encodings/ber/index.ts b/src/encodings/ber/index.ts index 26ad10f..4ef599d 100644 --- a/src/encodings/ber/index.ts +++ b/src/encodings/ber/index.ts @@ -61,6 +61,9 @@ function berDecode(b: Buffer, options: DecodeOptions = defaultDecode): DecodeRes reader.readSequence(tag) const rootSeqType = reader.peek() + // Add debug logging + console.log('Root sequence type:', rootSeqType, '(0x' + rootSeqType?.toString(16) + ')') + if (rootSeqType === RootElementsBERID) { // RootElementCollection const root: DecodeResult> = decodeRootElements(reader, options) From 2b638fd6adff9800a3998060c7029eacee8b6f10 Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 07:11:43 +0100 Subject: [PATCH 04/67] feat: StreamManager class for handling stream subscriptions --- src/Ember/Client/StreamManager.ts | 66 +++++++++++++ src/Ember/Client/index.ts | 86 ++++++++--------- src/S101/S101Codec.ts | 115 ++++++++++++----------- src/encodings/ber/decoder/StreamEntry.ts | 36 +------ src/encodings/ber/index.ts | 3 - src/index.ts | 3 + src/model/Parameter.ts | 56 +++++++++++ 7 files changed, 225 insertions(+), 140 deletions(-) create mode 100644 src/Ember/Client/StreamManager.ts diff --git a/src/Ember/Client/StreamManager.ts b/src/Ember/Client/StreamManager.ts new file mode 100644 index 0000000..17d2437 --- /dev/null +++ b/src/Ember/Client/StreamManager.ts @@ -0,0 +1,66 @@ +import { Parameter } from '../../model/Parameter' +import { StreamDescription } from '../../model/StreamDescription' +import { EmberValue } from '../../types' +import { EventEmitter } from 'eventemitter3' + +export type StreamManagerEvents = { + streamUpdate: [streamId: number, value: EmberValue] +} + +export class StreamManager extends EventEmitter { + private static instance: StreamManager + private registeredParameters: Map = new Map() + private streamDescriptors: Map = new Map() + + private constructor() { + super() + } + + public static getInstance(): StreamManager { + if (!StreamManager.instance) { + StreamManager.instance = new StreamManager() + } + return StreamManager.instance + } + + public registerParameter(parameter: Parameter): void { + if (!parameter.streamIdentifier) { + return + } + + this.registeredParameters.set(parameter.streamIdentifier, parameter) + + if (parameter.streamDescriptor) { + this.streamDescriptors.set(parameter.streamIdentifier, parameter.streamDescriptor) + } + } + + public unregisterParameter(parameter: Parameter): void { + if (!parameter.streamIdentifier) { + return + } + + this.registeredParameters.delete(parameter.streamIdentifier) + this.streamDescriptors.delete(parameter.streamIdentifier) + } + + public getStreamDescriptor(streamId: number): StreamDescription | undefined { + return this.streamDescriptors.get(streamId) + } + + public getParameter(streamId: number): Parameter | undefined { + return this.registeredParameters.get(streamId) + } + + public hasStream(streamId: number): boolean { + return this.registeredParameters.has(streamId) + } + + public updateStreamValue(streamId: number, value: EmberValue): void { + const parameter = this.registeredParameters.get(streamId) + if (parameter) { + parameter.value = value + this.emit('streamUpdate', streamId, value) + } + } +} diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index 75e2d26..cdc7547 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -30,7 +30,7 @@ import { EmberNode } from '../../model/EmberNode' import { EventEmitter } from 'eventemitter3' import { S101Client } from '../Socket' import { getPath, assertQualifiedEmberNode, insertCommand, updateProps, isEmptyNode } from '../Lib/util' -import { berEncode } from '../..' +import { berEncode, StreamManager } from '../..' import { NumberedTreeNodeImpl } from '../../model/Tree' import { EmberFunction } from '../../model/EmberFunction' import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult' @@ -128,7 +128,6 @@ export class EmberClient extends EventEmitter { this._client = new S101Client(this.host, this.port) this._client.on('emberTree', (tree: DecodeResult) => this._handleIncoming(tree)) - this._client.on('streamPacket', (entries) => this._handleStreamPacket(entries)) this._client.on('error', (e) => this.emit('error', e)) this._client.on('connected', () => this.emit('connected')) @@ -225,38 +224,35 @@ export class EmberClient extends EventEmitter { const command: Subscribe = new SubscribeImpl() - // Handle stream subscriptions - if ( - 'contents' in node && - node.contents.type === ElementType.Parameter && - node.contents.streamIdentifier !== undefined - ) { - this._streamSubscriptions.set(node.contents.streamIdentifier, (value: EmberValue) => { - if (cb) { - const updatedNode = { ...node } - if ('value' in updatedNode.contents) { - updatedNode.contents.value = value - cb(updatedNode) - } - } - }) - } else { - if (Array.isArray(node)) { - if (cb) - this._subscriptions.push({ - path: undefined, - cb, - }) - - return this._sendRequest(new NumberedTreeNodeImpl(0, command), ExpectResponse.Any) - } - + if (Array.isArray(node)) { if (cb) this._subscriptions.push({ - path: getPath(node), + path: undefined, cb, }) + + return this._sendRequest(new NumberedTreeNodeImpl(0, command), ExpectResponse.Any) + } + + // Check if this is a Parameter with streamIdentifier + if (node.contents.type === ElementType.Parameter) { + const parameter = node.contents + if (parameter.streamIdentifier !== undefined) { + console.log('Registering parameter with StreamManager:', { + streamId: parameter.streamIdentifier, + identifier: parameter.identifier, + path: getPath(node), + }) + StreamManager.getInstance().registerParameter(parameter) + } } + + if (cb) + this._subscriptions.push({ + path: getPath(node), + cb, + }) + return this._sendCommand(node, command, ExpectResponse.None) } async unsubscribe(node: NumberedTreeNode | Array): RequestPromise { @@ -267,12 +263,27 @@ export class EmberClient extends EventEmitter { const command: Unsubscribe = new UnsubscribeImpl() const path = Array.isArray(node) ? '' : getPath(node) + + // Clean up subscriptions for (const i in this._subscriptions) { if (this._subscriptions[i].path === path) { this._subscriptions.splice(Number(i), 1) } } + // Deregister from StreamManager if this was a Parameter with streamIdentifier + if (!Array.isArray(node) && node.contents.type === ElementType.Parameter) { + const parameter = node.contents + if (parameter.streamIdentifier !== undefined) { + console.log('Deregistering parameter from StreamManager:', { + streamId: parameter.streamIdentifier, + identifier: parameter.identifier, + path: path, + }) + StreamManager.getInstance().unregisterParameter(parameter) + } + } + if (Array.isArray(node)) { return this._sendRequest(new NumberedTreeNodeImpl(0, command), ExpectResponse.Any) } @@ -579,23 +590,6 @@ export class EmberClient extends EventEmitter { incoming.errors?.forEach((e) => this.emit('warn', e)) } - private _handleStreamPacket(entries: StreamEntry[]): void { - entries.forEach((entry) => { - const callback = this._streamSubscriptions.get(entry.identifier) - if (callback && entry.value) { - // Handle Octets value properly - if (entry.value.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { - // For audio level data, we can extract the first value if needed - const view = new DataView(entry.value.value.buffer) - const value = view.getFloat32(0, true) // Get first value, assuming little-endian - callback(value) - } else { - callback(entry.value.value) - } - } - }) - } - private _applyRootToTree(node: Root): Array { const changes: Array = [] diff --git a/src/S101/S101Codec.ts b/src/S101/S101Codec.ts index 9577bba..f111bbd 100644 --- a/src/S101/S101Codec.ts +++ b/src/S101/S101Codec.ts @@ -2,12 +2,10 @@ import { EventEmitter } from 'eventemitter3' import { SmartBuffer } from 'smart-buffer' import Debug from 'debug' import { format } from 'util' -import { decodeStreamEntries } from '../encodings/ber/decoder/StreamEntry' -import { Reader } from '../Ber' -import { DecodeResult } from '../encodings/ber/decoder/DecodeResult' -import { berDecode, berEncode } from '../encodings/ber' -import { Root, RootType } from '../types' -import { ParameterType } from '../model' +import { berDecode } from '../encodings/ber' +import { ParameterType, StreamEntry, StreamFormat } from '../model' +import { StreamManager } from '../Ember/Client/StreamManager' +import { Collection } from '../types/types' const debug = Debug('emberplus-connection:S101Codec') const S101_BOF = 0xfe @@ -162,72 +160,77 @@ export default class S101Codec extends EventEmitter { } private handlePacket(data: Buffer): void { - const packetType = data[0] - - if (packetType === 0x60) { - // Standard Ember packet - try { - // Handle both regular ember data and stream data within 0x60 packets + try { + if (data[2] === 0x66) { + this.handleStreamPacket(data) + } else if (data[0] === 0x60) { const decoded = berDecode(data) if (decoded.value) { - // Emit the standard ember packet this.emit('emberPacket', data) - - // Check if the decoded data contains stream entries - if (this.hasStreamData(decoded)) { - this.handleStreamData(decoded) - } } - } catch (error) { - console.error('Error decoding 0x60 packet:', error) - } - } else if (packetType === 0x66) { - // Direct stream packet - try { - const reader = new Reader(data) - const entries = decodeStreamEntries(reader) - this.handleStreamEntries(entries) - } catch (error) { - console.error('Error decoding 0x66 packet:', error) } + } catch (error) { + console.error('Error decoding 0x60 packet:', error) } } - //@ts-ignore - this method is not yet implemented and will be based on log output - private hasStreamData(decoded: DecodeResult): boolean { - // Check if the decoded data contains stream-related identifiers or structures - // This would depend on your specific protocol implementation - return false // Implement based on your ember protocol details - } + private handleStreamPacket(data: Buffer): void { + const streamManager = StreamManager.getInstance() - //@ts-ignore - this method is not yet implemented and will be based on log output - private handleStreamData(decoded: DecodeResult): void { - console.log('Stream data:', decoded) - // Extract stream data from regular ember packet and emit through subscription - // Implementation depends on your ember protocol details - } + try { + const decoded = berDecode(data) + const entries = decoded.value as Collection + + if (!entries || typeof entries !== 'object') { + console.warn('Invalid stream entries format') + return + } + + // Process each stream entry + Object.values(entries).forEach((entry: StreamEntry) => { + const streamId = entry.identifier + + if (!streamManager.hasStream(streamId)) { + console.warn(`Received stream data for unregistered stream ${streamId}`) + return + } + + const descriptor = streamManager.getStreamDescriptor(streamId) + if (!descriptor) { + console.warn(`No stream descriptor for stream ${streamId}`) + return + } - private handleStreamEntries(entries: DecodeResult): void { - if (entries.value) { - entries.value.forEach((entry: any) => { if (entry.value?.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { - // Convert octets to appropriate value type const buffer = entry.value.value - const value = buffer.readFloatLE(0) - - // Create ember-style update for subscriptions - const emberUpdate = { - number: entry.identifier, - contents: { - value, - type: ParameterType.Real, - }, + + // Handle the stream format + let value: number + switch (descriptor.format) { + case StreamFormat.Float32LE: + value = buffer.readFloatLE(descriptor.offset) + break + case StreamFormat.Float32BE: + value = buffer.readFloatBE(descriptor.offset) + break + case StreamFormat.Int32LE: + value = buffer.readInt32LE(descriptor.offset) + break + case StreamFormat.Int32BE: + value = buffer.readInt32BE(descriptor.offset) + break + // Add other format handlers as needed + default: + console.warn(`Unsupported stream format: ${descriptor.format}`) + return } - // Emit as regular ember packet to trigger subscriptions - this.emit('emberPacket', berEncode(emberUpdate, RootType.Elements)) + // Update the stream value + streamManager.updateStreamValue(streamId, value) } }) + } catch (error) { + console.error('Error processing stream packet:', error) } } diff --git a/src/encodings/ber/decoder/StreamEntry.ts b/src/encodings/ber/decoder/StreamEntry.ts index b527b35..d8a4ce8 100644 --- a/src/encodings/ber/decoder/StreamEntry.ts +++ b/src/encodings/ber/decoder/StreamEntry.ts @@ -54,41 +54,7 @@ function decodeStreamEntry(reader: Ber.Reader, options: DecodeOptions = defaultD break case Ber.CONTEXT(1): value = reader.readValue() - - // Special handling for audio level data - if (value.type === ParameterType.Octets && Buffer.isBuffer(value.value)) { - const buffer = value.value - - // THIS IS CURRENTLY A HACK - // HARDOCED TO 64 AND 68 - // BUT SHOULD FOLLOW THE NODE's offSet value - // Debug logging - console.log('Audio buffer analysis:') - console.log('Buffer length:', buffer.length) - console.log( - 'Buffer Bytes:', - Array.from(buffer) - .map((b) => '0x' + b.toString(16).padStart(2, '0')) - .join(' ') - ) - - if (buffer.length >= 4) { - // The buffer appears to contain pairs of float32 values - // First value is the current level, second is the peak - const currentLevel = buffer.readFloatLE(64) - const peakLevel = buffer.length >= 8 ? buffer.readFloatLE(68) : currentLevel - console.log('Decoded current level:', currentLevel) - console.log('Decoded peak level:', peakLevel) - - // Convert to Real type - value = { - type: ParameterType.Real, - value: currentLevel, - } - } else { - console.warn('Audio buffer too short:', buffer.length) - } - } + // return the full stream for later processing break case 0: break // indefinite length diff --git a/src/encodings/ber/index.ts b/src/encodings/ber/index.ts index 4ef599d..26ad10f 100644 --- a/src/encodings/ber/index.ts +++ b/src/encodings/ber/index.ts @@ -61,9 +61,6 @@ function berDecode(b: Buffer, options: DecodeOptions = defaultDecode): DecodeRes reader.readSequence(tag) const rootSeqType = reader.peek() - // Add debug logging - console.log('Root sequence type:', rootSeqType, '(0x' + rootSeqType?.toString(16) + ')') - if (rootSeqType === RootElementsBERID) { // RootElementCollection const root: DecodeResult> = decodeRootElements(reader, options) diff --git a/src/index.ts b/src/index.ts index 49a0fd1..5bee15f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import { EmberClient, EmberClientEvents } from './Ember/Client/index' +import { StreamManager, StreamManagerEvents } from './Ember/Client/StreamManager' import { EmberLib } from './Ember/Lib/index' import { EmberServer, EmberServerEvents } from './Ember/Server/index' import { S101Codec } from './S101/index' @@ -40,6 +41,8 @@ const Decoder = EmberLib.DecodeBuffer export { EmberClient, + StreamManagerEvents, + StreamManager, EmberClientEvents, Decoder, EmberLib, diff --git a/src/model/Parameter.ts b/src/model/Parameter.ts index 0193dbc..6f6c582 100644 --- a/src/model/Parameter.ts +++ b/src/model/Parameter.ts @@ -1,6 +1,7 @@ import { EmberBaseElement, ElementType, isEmberElement } from './EmberElement' import { EmberValue, MinMax, StringIntegerCollection, RelativeOID } from '../types/types' import { StreamDescription } from './StreamDescription' +import { StreamManager } from '../Ember/Client/StreamManager' export { Parameter, ParameterType, ParameterAccess, isParameter, ParameterImpl } @@ -124,3 +125,58 @@ class ParameterImpl implements Parameter { public templateReference?: RelativeOID ) {} } + +// Define interface for stream-capable parameters +export interface StreamCapableParameter extends EmberBaseElement { + type: ElementType.Parameter + streamIdentifier?: number + streamDescriptor?: StreamDescription + value?: EmberValue +} + +// Define interface for the methods we'll add +export interface StreamMethods { + setStreamIdentifier(value: number | undefined): void + hasStreamIdentifier(): boolean + subscribed(): void + unsubscribed(): void +} + +type Constructor = new (...args: any[]) => T + +// Create a mixin function that adds stream capabilities +export function withStreamSupport>( + Base: TBase +): TBase & Constructor { + return class extends Base implements StreamMethods { + setStreamIdentifier(value: number | undefined): void { + if (this.streamIdentifier !== value) { + const hadStream = this.hasStreamIdentifier() + this.streamIdentifier = value + + // If stream status changed, update registration + if (hadStream !== this.hasStreamIdentifier()) { + if (this.hasStreamIdentifier()) { + this.subscribed() + } else { + this.unsubscribed() + } + } + } + } + + hasStreamIdentifier(): boolean { + return typeof this.streamIdentifier === 'number' + } + + subscribed(): void { + if (this.hasStreamIdentifier() || this.streamDescriptor) { + StreamManager.getInstance().registerParameter(this) + } + } + + unsubscribed(): void { + StreamManager.getInstance().unregisterParameter(this) + } + } +} From a396b0d9e708d00d8de507370a946f33132a9c5d Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 09:15:30 +0100 Subject: [PATCH 05/67] feat: use path to register streams and handle decoding in StreamManager --- src/Ember/Client/StreamManager.ts | 118 ++++++++++++++++++++++-------- src/Ember/Client/index.ts | 5 +- src/S101/S101Codec.ts | 48 +----------- src/model/Parameter.ts | 56 -------------- 4 files changed, 95 insertions(+), 132 deletions(-) diff --git a/src/Ember/Client/StreamManager.ts b/src/Ember/Client/StreamManager.ts index 17d2437..84786fa 100644 --- a/src/Ember/Client/StreamManager.ts +++ b/src/Ember/Client/StreamManager.ts @@ -1,16 +1,23 @@ -import { Parameter } from '../../model/Parameter' -import { StreamDescription } from '../../model/StreamDescription' -import { EmberValue } from '../../types' import { EventEmitter } from 'eventemitter3' +import { Parameter, ParameterType } from '../../model/Parameter' +import { EmberValue } from '../../types' +import { Collection } from '../../types/types' +import { StreamEntry } from '../../model' export type StreamManagerEvents = { - streamUpdate: [streamId: number, value: EmberValue] + streamUpdate: [path: string, value: EmberValue] +} + +interface StreamInfo { + parameter: Parameter + path: string + streamIdentifier: number + offset: number } export class StreamManager extends EventEmitter { private static instance: StreamManager - private registeredParameters: Map = new Map() - private streamDescriptors: Map = new Map() + private registeredStreams: Map = new Map() private constructor() { super() @@ -23,44 +30,97 @@ export class StreamManager extends EventEmitter { return StreamManager.instance } - public registerParameter(parameter: Parameter): void { - if (!parameter.streamIdentifier) { + public registerParameter(parameter: Parameter, path: string): void { + if (!parameter.streamIdentifier || !parameter.streamDescriptor?.offset) { return } - this.registeredParameters.set(parameter.streamIdentifier, parameter) - - if (parameter.streamDescriptor) { - this.streamDescriptors.set(parameter.streamIdentifier, parameter.streamDescriptor) + const streamInfo: StreamInfo = { + parameter, + path, + streamIdentifier: parameter.streamIdentifier, + offset: parameter.streamDescriptor.offset, } + + // Store both mappings + this.registeredStreams.set(path, streamInfo) + + console.log('Registered stream:', { + path: path, + identifier: parameter.identifier, + offset: parameter.streamDescriptor.offset, + }) } - public unregisterParameter(parameter: Parameter): void { - if (!parameter.streamIdentifier) { - return + public unregisterParameter(path: string): void { + const streamInfo = this.registeredStreams.get(path) + if (streamInfo && streamInfo.parameter.streamIdentifier) { + this.registeredStreams.delete(path) + console.log('Unregistered stream:', { + path: path, + identifier: streamInfo.parameter.identifier, + }) } - - this.registeredParameters.delete(parameter.streamIdentifier) - this.streamDescriptors.delete(parameter.streamIdentifier) } - public getStreamDescriptor(streamId: number): StreamDescription | undefined { - return this.streamDescriptors.get(streamId) + public getStreamInfoByPath(path: string): StreamInfo | undefined { + return this.registeredStreams.get(path) } - public getParameter(streamId: number): Parameter | undefined { - return this.registeredParameters.get(streamId) + public hasStream(identifier: string): boolean { + return this.registeredStreams.has(identifier) } - public hasStream(streamId: number): boolean { - return this.registeredParameters.has(streamId) + public updateAllStreamValues(streamEntries: Collection): void { + Object.values(streamEntries).forEach((streamEntry) => { + this.registeredStreams.forEach((streamInfo, path) => { + // Only process if IDs match + if (streamInfo.streamIdentifier === streamEntry.identifier) { + // If this is a stream with a descriptor and we have a value + if (streamInfo.parameter.streamDescriptor && streamEntry.value) { + const value = streamEntry.value + if (value.type === ParameterType.Octets && Buffer.isBuffer(value.value)) { + const buffer = value.value + if (buffer.length >= streamInfo.offset + 4) { + // Float32 is 4 bytes + const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.length) + // decode as little-endian + const decodedValue = view.getFloat32(streamInfo.offset, true) + + this.updateStreamValue(path, decodedValue) + } + } + } + } + }) + }) } - public updateStreamValue(streamId: number, value: EmberValue): void { - const parameter = this.registeredParameters.get(streamId) - if (parameter) { - parameter.value = value - this.emit('streamUpdate', streamId, value) + public updateStreamValue(path: string, value: EmberValue): void { + if (path) { + const streamInfo = this.registeredStreams.get(path) + if (streamInfo) { + streamInfo.parameter.value = value + this.emit('streamUpdate', path, value) + } } } + + public getAllRegisteredPaths(): string[] { + return Array.from(this.registeredStreams.keys()) + } + + // Debug helper + public printStreamState(): void { + console.log('\nCurrent Stream State:') + console.log('Registered Streams:') + this.registeredStreams.forEach((info, path) => { + console.log(` Path: ${path}`) + console.log(` Identifier: ${info.parameter.identifier}`) + console.log(` StreamId: ${info.parameter.streamIdentifier}`) + console.log(` Current Value: ${info.parameter.value}`) + }) + } } + +export default StreamManager diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index cdc7547..f6b617a 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -240,10 +240,11 @@ export class EmberClient extends EventEmitter { if (parameter.streamIdentifier !== undefined) { console.log('Registering parameter with StreamManager:', { streamId: parameter.streamIdentifier, + offSet: parameter.streamDescriptor?.offset, identifier: parameter.identifier, path: getPath(node), }) - StreamManager.getInstance().registerParameter(parameter) + StreamManager.getInstance().registerParameter(parameter, getPath(node)) } } @@ -280,7 +281,7 @@ export class EmberClient extends EventEmitter { identifier: parameter.identifier, path: path, }) - StreamManager.getInstance().unregisterParameter(parameter) + StreamManager.getInstance().unregisterParameter(path) } } diff --git a/src/S101/S101Codec.ts b/src/S101/S101Codec.ts index f111bbd..8d4edea 100644 --- a/src/S101/S101Codec.ts +++ b/src/S101/S101Codec.ts @@ -3,7 +3,7 @@ import { SmartBuffer } from 'smart-buffer' import Debug from 'debug' import { format } from 'util' import { berDecode } from '../encodings/ber' -import { ParameterType, StreamEntry, StreamFormat } from '../model' +import { StreamEntry } from '../model' import { StreamManager } from '../Ember/Client/StreamManager' import { Collection } from '../types/types' const debug = Debug('emberplus-connection:S101Codec') @@ -185,50 +185,8 @@ export default class S101Codec extends EventEmitter { console.warn('Invalid stream entries format') return } - - // Process each stream entry - Object.values(entries).forEach((entry: StreamEntry) => { - const streamId = entry.identifier - - if (!streamManager.hasStream(streamId)) { - console.warn(`Received stream data for unregistered stream ${streamId}`) - return - } - - const descriptor = streamManager.getStreamDescriptor(streamId) - if (!descriptor) { - console.warn(`No stream descriptor for stream ${streamId}`) - return - } - - if (entry.value?.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { - const buffer = entry.value.value - - // Handle the stream format - let value: number - switch (descriptor.format) { - case StreamFormat.Float32LE: - value = buffer.readFloatLE(descriptor.offset) - break - case StreamFormat.Float32BE: - value = buffer.readFloatBE(descriptor.offset) - break - case StreamFormat.Int32LE: - value = buffer.readInt32LE(descriptor.offset) - break - case StreamFormat.Int32BE: - value = buffer.readInt32BE(descriptor.offset) - break - // Add other format handlers as needed - default: - console.warn(`Unsupported stream format: ${descriptor.format}`) - return - } - - // Update the stream value - streamManager.updateStreamValue(streamId, value) - } - }) + // Update the stream value + streamManager.updateAllStreamValues(entries) } catch (error) { console.error('Error processing stream packet:', error) } diff --git a/src/model/Parameter.ts b/src/model/Parameter.ts index 6f6c582..0193dbc 100644 --- a/src/model/Parameter.ts +++ b/src/model/Parameter.ts @@ -1,7 +1,6 @@ import { EmberBaseElement, ElementType, isEmberElement } from './EmberElement' import { EmberValue, MinMax, StringIntegerCollection, RelativeOID } from '../types/types' import { StreamDescription } from './StreamDescription' -import { StreamManager } from '../Ember/Client/StreamManager' export { Parameter, ParameterType, ParameterAccess, isParameter, ParameterImpl } @@ -125,58 +124,3 @@ class ParameterImpl implements Parameter { public templateReference?: RelativeOID ) {} } - -// Define interface for stream-capable parameters -export interface StreamCapableParameter extends EmberBaseElement { - type: ElementType.Parameter - streamIdentifier?: number - streamDescriptor?: StreamDescription - value?: EmberValue -} - -// Define interface for the methods we'll add -export interface StreamMethods { - setStreamIdentifier(value: number | undefined): void - hasStreamIdentifier(): boolean - subscribed(): void - unsubscribed(): void -} - -type Constructor = new (...args: any[]) => T - -// Create a mixin function that adds stream capabilities -export function withStreamSupport>( - Base: TBase -): TBase & Constructor { - return class extends Base implements StreamMethods { - setStreamIdentifier(value: number | undefined): void { - if (this.streamIdentifier !== value) { - const hadStream = this.hasStreamIdentifier() - this.streamIdentifier = value - - // If stream status changed, update registration - if (hadStream !== this.hasStreamIdentifier()) { - if (this.hasStreamIdentifier()) { - this.subscribed() - } else { - this.unsubscribed() - } - } - } - } - - hasStreamIdentifier(): boolean { - return typeof this.streamIdentifier === 'number' - } - - subscribed(): void { - if (this.hasStreamIdentifier() || this.streamDescriptor) { - StreamManager.getInstance().registerParameter(this) - } - } - - unsubscribed(): void { - StreamManager.getInstance().unregisterParameter(this) - } - } -} From 78c16601a94a8fc3d1facb29b6cb44342594764b Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 11:01:07 +0100 Subject: [PATCH 06/67] fix: handle offset=0 --- src/Ember/Client/StreamManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ember/Client/StreamManager.ts b/src/Ember/Client/StreamManager.ts index 84786fa..9c7bf13 100644 --- a/src/Ember/Client/StreamManager.ts +++ b/src/Ember/Client/StreamManager.ts @@ -31,7 +31,7 @@ export class StreamManager extends EventEmitter { } public registerParameter(parameter: Parameter, path: string): void { - if (!parameter.streamIdentifier || !parameter.streamDescriptor?.offset) { + if (!parameter.streamIdentifier || parameter.streamDescriptor?.offset === undefined) { return } From 03f609f78462fd20bb699825de19b27d3d78dba7 Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 11:01:54 +0100 Subject: [PATCH 07/67] wip: test of streaming manager --- src/Ember/Client/__tests__/index.spec.ts | 269 ++++++++++++++++++++++- 1 file changed, 268 insertions(+), 1 deletion(-) diff --git a/src/Ember/Client/__tests__/index.spec.ts b/src/Ember/Client/__tests__/index.spec.ts index acc15f2..1250718 100644 --- a/src/Ember/Client/__tests__/index.spec.ts +++ b/src/Ember/Client/__tests__/index.spec.ts @@ -6,11 +6,15 @@ import { ParameterImpl, ParameterType, QualifiedElementImpl, + StreamFormat, } from '../../../model' -import { Collection, Root, RootElement } from '../../../types/types' +import { Collection, EmberTypedValue, Root, RootElement } from '../../../types/types' import { EmberClient } from '../' import S101ClientMock from '../../../__mocks__/S101Client' import { DecodeResult } from '../../../encodings/ber/decoder/DecodeResult' +import { StreamDescriptionImpl } from '../../../model/StreamDescription' +import StreamManager from '../StreamManager' +import { StreamEntryImpl } from '../../../model/StreamEntry' // import { EmberTreeNode, RootElement } from '../../../types/types' // import { ElementType, EmberElement } from '../../../model/EmberElement' // import { Parameter, ParameterType } from '../../../model/Parameter' @@ -107,6 +111,40 @@ describe('client', () => { } } + function createStreamParameter(opts: { + identifier: string + streamId: number + value?: number + offset?: number + format?: StreamFormat + }) { + return new ParameterImpl( + ParameterType.Real, + opts.identifier, + undefined, // description + opts.value ?? 0.0, + undefined, // maximum + undefined, // minimum + undefined, // access + undefined, // format + undefined, // enumeration + undefined, // factor + undefined, // isOnline + undefined, // formula + undefined, // step + undefined, // defaultValue + opts.streamId, + undefined, // enumMap + new StreamDescriptionImpl(opts.format ?? StreamFormat.Float32LE, opts.offset ?? 0) + ) + } + + function createStreamEntryResponse(entries: Array<{ identifier: number; value: EmberTypedValue }>) { + return { + value: entries.map((entry) => new StreamEntryImpl(entry.identifier, entry.value)), + } + } + it('getDirectory resolves', async () => { await runWithConnection(async (client, socket) => { // Do initial load @@ -382,4 +420,233 @@ describe('client', () => { expect(res).toBeTruthy() }) }) + + describe('StreamManager Integration', () => { + it('registers stream parameter when subscribing', async () => { + await runWithConnection(async (client, socket) => { + const streamParam = createStreamParameter({ + identifier: 'test-stream', + streamId: 1, + value: 0.5, + offset: 0, + }) + + const paramNode = new NumberedTreeNodeImpl(1, streamParam) + + // Subscribe to parameter + const subscribeReq = await client.subscribe(paramNode) + subscribeReq.response?.catch(() => null) + + expect(onSocketWrite).toHaveBeenCalledTimes(1) + + // Mock successful subscription + socket.mockData(createQualifiedNodeResponse('1', streamParam, undefined)) + + // Wait for registration to complete + await new Promise(setImmediate) + + // Get StreamManager instance and check registration + const streamManager = StreamManager.getInstance() + const streamInfo = streamManager.getStreamInfoByPath('1') + + expect(streamInfo).toBeDefined() + expect(streamInfo?.parameter.streamIdentifier).toBe(1) + expect(streamInfo?.parameter.value).toBe(0.5) + }) + }) + + it('deregisters stream parameter when unsubscribing', async () => { + await runWithConnection(async (client, socket) => { + const streamParam = createStreamParameter({ + identifier: 'test-stream', + streamId: 1, + }) + + const paramNode = new NumberedTreeNodeImpl(1, streamParam) + + // First subscribe + const subscribeReq = await client.subscribe(paramNode) + subscribeReq.response?.catch(() => null) + + socket.mockData(createQualifiedNodeResponse('1', streamParam, undefined)) + + await new Promise(setImmediate) + + // Then unsubscribe + const unsubscribeReq = await client.unsubscribe(paramNode) + unsubscribeReq.response?.catch(() => null) + + socket.mockData(createQualifiedNodeResponse('1', streamParam, undefined)) + + // Mock receiving stream data + const streamData = createStreamEntryResponse([ + { + identifier: 1, + value: { type: ParameterType.Real, value: 42.5 }, + }, + ]) + socket.mockData(streamData) + + await new Promise(setImmediate) + + // Check parameter was deregistered + const streamManager = StreamManager.getInstance() + const streamInfo = streamManager.getStreamInfoByPath('1') + + expect(streamInfo).toBeUndefined() + }) + }) + + it('updates stream values when receiving stream data', async () => { + await runWithConnection(async (client, socket) => { + const streamParam = createStreamParameter({ + identifier: 'test-stream', + streamId: 1, + value: 0, + }) + + const paramNode = new NumberedTreeNodeImpl(1, streamParam) + + // Subscribe to parameter + const subscribeReq = await client.subscribe(paramNode) + subscribeReq.response?.catch(() => null) + + socket.mockData(createQualifiedNodeResponse('1', streamParam, undefined)) + + await new Promise(setImmediate) + + // Mock receiving stream data + const streamData: DecodeResult = { + value: [ + { + identifier: 1, + value: { type: ParameterType.Real, value: 42.5 }, + }, + ], + } + socket.mockData(streamData) + + await new Promise(setImmediate) + + // Check value was updated + const streamManager = StreamManager.getInstance() + const streamInfo = streamManager.getStreamInfoByPath('1') + + expect(streamInfo?.parameter.value).toBe(42.5) + }) + }) + + it('processes stream data with specific offsets', async () => { + await runWithConnection(async (client, socket) => { + // Create test parameters with specific offsets + const streamParam1 = createStreamParameter({ + identifier: '1.3.17.3', + streamId: 1, + offset: 64, // Specific offset from example + format: StreamFormat.Float32LE, + }) + + const streamParam2 = createStreamParameter({ + identifier: '1.3.18.3', + streamId: 1, + offset: 68, // Specific offset from example + format: StreamFormat.Float32LE, + }) + + const param1Node = new NumberedTreeNodeImpl(1, streamParam1) + const param2Node = new NumberedTreeNodeImpl(2, streamParam2) + + // Subscribe to parameters + const subscribe1 = await client.subscribe(param1Node) + const subscribe2 = await client.subscribe(param2Node) + + subscribe1.response?.catch(() => null) + subscribe2.response?.catch(() => null) + + // Mock successful subscriptions + socket.mockData(createQualifiedNodeResponse('1.3.17.3', streamParam1, undefined)) + socket.mockData(createQualifiedNodeResponse('1.3.18.3', streamParam2, undefined)) + + await new Promise(setImmediate) + + // Create test buffer with the specific values + const buffer = Buffer.from([ + 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, + 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, + 195, 0, 0, 72, 195, 116, 183, 30, 194, 182, 225, 190, 193, + ]) + + // Mock receiving stream data + const streamData: DecodeResult = { + value: [ + { + identifier: 1, + value: { + type: ParameterType.Octets, + value: buffer, + }, + }, + ], + } + + socket.mockData(streamData) + await new Promise(setImmediate) + + // Get StreamManager instance and verify values + const streamManager = StreamManager.getInstance() + + const stream1 = streamManager.getStreamInfoByPath('1.3.17.3') + const stream2 = streamManager.getStreamInfoByPath('1.3.18.3') + + expect(stream1?.parameter.value).toBeCloseTo(-39.67915344238281) + expect(stream2?.parameter.value).toBeCloseTo(-23.860210418701172) + }) + }) + + it('handles octet stream values correctly', async () => { + const offSet = 12 + await runWithConnection(async (client, socket) => { + const streamParam = createStreamParameter({ + identifier: 'audio-level', + streamId: 1, + offset: offSet, + value: 0, + format: StreamFormat.Float32LE, + }) + + const paramNode = new NumberedTreeNodeImpl(1, streamParam) + + // Subscribe to parameter + const subscribeReq = await client.subscribe(paramNode) + subscribeReq.response?.catch(() => null) + + socket.mockData(createQualifiedNodeResponse('1', streamParam, undefined)) + + await new Promise(setImmediate) + + // Create buffer with float32 value + const buffer = Buffer.alloc(16) + buffer.writeFloatLE(-6.5, offSet) + + // Mock receiving octet stream data + const streamData = { + value: [ + { + identifier: 1, + value: { type: ParameterType.Octets, value: buffer }, + }, + ], + } + socket.mockData(streamData) + + await new Promise(setImmediate) + + // Check value was decoded correctly + const streamManager = StreamManager.getInstance() + const streamInfo = streamManager.getStreamInfoByPath('1') + + expect(streamInfo?.parameter.value).toBeCloseTo(-6.5) + }) + }) + }) }) From 60a0e8ffc75fd35265e002e5ca87c274c4d819a8 Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 12:43:00 +0100 Subject: [PATCH 08/67] fix: streamEntry.value can be zero --- src/Ember/Client/StreamManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ember/Client/StreamManager.ts b/src/Ember/Client/StreamManager.ts index 9c7bf13..d29bc16 100644 --- a/src/Ember/Client/StreamManager.ts +++ b/src/Ember/Client/StreamManager.ts @@ -77,7 +77,7 @@ export class StreamManager extends EventEmitter { // Only process if IDs match if (streamInfo.streamIdentifier === streamEntry.identifier) { // If this is a stream with a descriptor and we have a value - if (streamInfo.parameter.streamDescriptor && streamEntry.value) { + if (streamInfo.parameter.streamDescriptor !== undefined && streamEntry.value !== undefined) { const value = streamEntry.value if (value.type === ParameterType.Octets && Buffer.isBuffer(value.value)) { const buffer = value.value From 63dea41999a6365d1029f6744780a123f0be6de2 Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 12:44:14 +0100 Subject: [PATCH 09/67] fix: StreamManager test use real values. --- src/Ember/Client/__tests__/index.spec.ts | 234 +++++++++++------------ 1 file changed, 113 insertions(+), 121 deletions(-) diff --git a/src/Ember/Client/__tests__/index.spec.ts b/src/Ember/Client/__tests__/index.spec.ts index 1250718..962ab1d 100644 --- a/src/Ember/Client/__tests__/index.spec.ts +++ b/src/Ember/Client/__tests__/index.spec.ts @@ -14,7 +14,7 @@ import S101ClientMock from '../../../__mocks__/S101Client' import { DecodeResult } from '../../../encodings/ber/decoder/DecodeResult' import { StreamDescriptionImpl } from '../../../model/StreamDescription' import StreamManager from '../StreamManager' -import { StreamEntryImpl } from '../../../model/StreamEntry' +import { StreamEntry, StreamEntryImpl } from '../../../model/StreamEntry' // import { EmberTreeNode, RootElement } from '../../../types/types' // import { ElementType, EmberElement } from '../../../model/EmberElement' // import { Parameter, ParameterType } from '../../../model/Parameter' @@ -482,7 +482,7 @@ describe('client', () => { const streamData = createStreamEntryResponse([ { identifier: 1, - value: { type: ParameterType.Real, value: 42.5 }, + value: { type: ParameterType.Octets, value: 42.5 }, }, ]) socket.mockData(streamData) @@ -497,155 +497,147 @@ describe('client', () => { }) }) - it('updates stream values when receiving stream data', async () => { - await runWithConnection(async (client, socket) => { - const streamParam = createStreamParameter({ - identifier: 'test-stream', - streamId: 1, - value: 0, - }) - - const paramNode = new NumberedTreeNodeImpl(1, streamParam) - - // Subscribe to parameter - const subscribeReq = await client.subscribe(paramNode) - subscribeReq.response?.catch(() => null) - - socket.mockData(createQualifiedNodeResponse('1', streamParam, undefined)) - - await new Promise(setImmediate) - - // Mock receiving stream data - const streamData: DecodeResult = { - value: [ - { - identifier: 1, - value: { type: ParameterType.Real, value: 42.5 }, - }, - ], - } - socket.mockData(streamData) - - await new Promise(setImmediate) - - // Check value was updated - const streamManager = StreamManager.getInstance() - const streamInfo = streamManager.getStreamInfoByPath('1') - - expect(streamInfo?.parameter.value).toBe(42.5) - }) - }) - it('processes stream data with specific offsets', async () => { await runWithConnection(async (client, socket) => { // Create test parameters with specific offsets const streamParam1 = createStreamParameter({ - identifier: '1.3.17.3', + identifier: 'test-stream1', streamId: 1, - offset: 64, // Specific offset from example + offset: 64, format: StreamFormat.Float32LE, }) const streamParam2 = createStreamParameter({ - identifier: '1.3.18.3', + identifier: 'test-stream2', streamId: 1, - offset: 68, // Specific offset from example + offset: 68, format: StreamFormat.Float32LE, }) - const param1Node = new NumberedTreeNodeImpl(1, streamParam1) - const param2Node = new NumberedTreeNodeImpl(2, streamParam2) + const path1 = '1.3.17.3' + const path2 = '1.3.18.3' + + // Create qualified element wrappers for the parameters + const param1Element = new QualifiedElementImpl(path1, streamParam1) + const param2Element = new QualifiedElementImpl(path2, streamParam2) - // Subscribe to parameters - const subscribe1 = await client.subscribe(param1Node) - const subscribe2 = await client.subscribe(param2Node) + // Subscribe to parameters using qualified elements + const subscribe1 = await client.subscribe(param1Element) + const subscribe2 = await client.subscribe(param2Element) subscribe1.response?.catch(() => null) subscribe2.response?.catch(() => null) - // Mock successful subscriptions - socket.mockData(createQualifiedNodeResponse('1.3.17.3', streamParam1, undefined)) - socket.mockData(createQualifiedNodeResponse('1.3.18.3', streamParam2, undefined)) + // Mock successful subscriptions with qualified paths + socket.mockData({ + value: { + 1: param1Element, + }, + }) + socket.mockData({ + value: { + 1: param2Element, + }, + }) await new Promise(setImmediate) - // Create test buffer with the specific values + // Create the buffer with repeating values except last 8 bytes const buffer = Buffer.from([ - 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, - 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, 195, 0, 0, 72, - 195, 0, 0, 72, 195, 116, 183, 30, 194, 182, 225, 190, 193, + 0x00, + 0x00, + 0x48, + 0xc3, // -200.0 repeated multiple times + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x00, + 0x00, + 0x48, + 0xc3, + 0x74, + 0xb7, + 0x1e, + 0xc2, // -39.67915344238281 at offset 64 + 0xb6, + 0xe1, + 0xbe, + 0xc1, // -23.860210418701172 at offset 68 ]) - // Mock receiving stream data - const streamData: DecodeResult = { - value: [ - { - identifier: 1, - value: { - type: ParameterType.Octets, - value: buffer, - }, - }, - ], - } - - socket.mockData(streamData) - await new Promise(setImmediate) - // Get StreamManager instance and verify values const streamManager = StreamManager.getInstance() - const stream1 = streamManager.getStreamInfoByPath('1.3.17.3') - const stream2 = streamManager.getStreamInfoByPath('1.3.18.3') - - expect(stream1?.parameter.value).toBeCloseTo(-39.67915344238281) - expect(stream2?.parameter.value).toBeCloseTo(-23.860210418701172) - }) - }) - - it('handles octet stream values correctly', async () => { - const offSet = 12 - await runWithConnection(async (client, socket) => { - const streamParam = createStreamParameter({ - identifier: 'audio-level', - streamId: 1, - offset: offSet, - value: 0, - format: StreamFormat.Float32LE, - }) - - const paramNode = new NumberedTreeNodeImpl(1, streamParam) - - // Subscribe to parameter - const subscribeReq = await client.subscribe(paramNode) - subscribeReq.response?.catch(() => null) - - socket.mockData(createQualifiedNodeResponse('1', streamParam, undefined)) - - await new Promise(setImmediate) - - // Create buffer with float32 value - const buffer = Buffer.alloc(16) - buffer.writeFloatLE(-6.5, offSet) - - // Mock receiving octet stream data - const streamData = { - value: [ - { - identifier: 1, - value: { type: ParameterType.Octets, value: buffer }, + const decoded: Collection = [ + { + identifier: 1, + value: { + type: ParameterType.Octets, + value: buffer, }, - ], - } - socket.mockData(streamData) + }, + ] - await new Promise(setImmediate) + streamManager.updateAllStreamValues(decoded) + const stream1 = streamManager.getStreamInfoByPath(path1) + console.log('stream1', stream1) + const stream2 = streamManager.getStreamInfoByPath(path2) - // Check value was decoded correctly - const streamManager = StreamManager.getInstance() - const streamInfo = streamManager.getStreamInfoByPath('1') - - expect(streamInfo?.parameter.value).toBeCloseTo(-6.5) + expect(stream1?.parameter.value).toBeCloseTo(-39.67915344238281) + expect(stream2?.parameter.value).toBeCloseTo(-23.860210418701172) }) }) }) From 1284b2828a15fb9f787ce53ecebcc7e992ec2e2c Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 13:35:04 +0100 Subject: [PATCH 10/67] feat: cleaup code from first stream implementation --- src/Ember/Client/index.ts | 25 +------------------------ src/Ember/Socket/S101Socket.ts | 2 -- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index f6b617a..7f2b2da 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -24,7 +24,7 @@ import { Subscribe, Invoke, } from '../../model/Command' -import { Parameter, ParameterType } from '../../model/Parameter' +import { Parameter } from '../../model/Parameter' import { Connection, ConnectionDisposition, ConnectionOperation } from '../../model/Connection' import { EmberNode } from '../../model/EmberNode' import { EventEmitter } from 'eventemitter3' @@ -34,7 +34,6 @@ import { berEncode, StreamManager } from '../..' import { NumberedTreeNodeImpl } from '../../model/Tree' import { EmberFunction } from '../../model/EmberFunction' import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult' -import { StreamEntry } from '../../model/StreamEntry' export type RequestPromise = Promise> export interface RequestPromiseArguments { @@ -98,7 +97,6 @@ export class EmberClient extends EventEmitter { private _lastInvocation = 0 private _client: S101Client private _subscriptions: Array = [] - private _streamSubscriptions: Map void> = new Map() private _timeout = 3000 private _resendTimeout = 1000 @@ -530,27 +528,6 @@ export class EmberClient extends EventEmitter { private _handleIncoming(incoming: DecodeResult) { const node = incoming.value - // Check if this is a stream entry - if (Array.isArray(node) && node[0] && 'identifier' in node[0]) { - // This is a stream entry - const entries = node as StreamEntry[] - entries.forEach((entry) => { - // Find any subscriptions for this stream - const callback = this._streamSubscriptions.get(entry.identifier) - if (callback && entry.value) { - // For audio level data, extract the value properly - if (entry.value.type === ParameterType.Octets && Buffer.isBuffer(entry.value.value)) { - const view = new DataView(entry.value.value.buffer) - // Assuming 32-bit float in little-endian format - const value = view.getFloat32(0, true) - callback(value) - } else { - callback(entry.value.value) - } - } - }) - return - } // update tree: const changes = this._applyRootToTree(node) diff --git a/src/Ember/Socket/S101Socket.ts b/src/Ember/Socket/S101Socket.ts index 9de5892..f86efa2 100644 --- a/src/Ember/Socket/S101Socket.ts +++ b/src/Ember/Socket/S101Socket.ts @@ -7,7 +7,6 @@ import { ConnectionStatus } from '../Client' import { normalizeError } from '../Lib/util' import { Root } from '../../types' import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult' -import { StreamEntry } from '../../model' export type Request = any @@ -18,7 +17,6 @@ export type S101SocketEvents = { connecting: [] connected: [] disconnected: [] - streamPacket: [entries: StreamEntry[]] } export default class S101Socket extends EventEmitter { From 5cbbac4be21c33949bb8cb053b38f943cc153883 Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 20:04:37 +0100 Subject: [PATCH 11/67] docs: update README.md with StreamManager --- README.md | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 4268154..9ea91f3 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,14 @@ It has been tested with _Lawo Ruby_, _Lawo R3lay_, and _Lawo MxGUI_. The current version is very losely based on the original library and Mr Gilles Dufour's rewrites. It is however rewritten almost completely from scratch and bears little to no resemblance to earlier libraries. ### Repository-specific Info for Developers -* [Developer Info](DEVELOPER.md) -* [Contribution Guidelines](CONTRIBUTING.md) - -### General Sofie System Info -* [Documentation](https://nrkno.github.io/sofie-core/) -* [Releases](https://nrkno.github.io/sofie-core/releases) +- [Developer Info](DEVELOPER.md) +- [Contribution Guidelines](CONTRIBUTING.md) +### General Sofie System Info +- [Documentation](https://nrkno.github.io/sofie-core/) +- [Releases](https://nrkno.github.io/sofie-core/releases) --- @@ -26,12 +25,20 @@ The current version is very losely based on the original library and Mr Gilles D Get Full tree: ```javascript -const { EmberClient } = require('emberplus-connection'); +const { EmberClient, StreamManager } = require('emberplus-connection'); const client = new EmberClient("10.9.8.7", 9000); client.on("error", e => { console.log(e); }); await client.connect() + +// If you want to listen to stream updates - you can do it like this: +StreamManager.getInstance().on('streamUpdate', (path, value) => { + console.log('Stream Update:', { + path: path, + value: value, + }) +}) // Get Root info const req = await client.getDirectory(client.tree) await req.response @@ -91,7 +98,9 @@ client ```javascript client = new EmberClient(LOCALHOST, PORT) await client.connect() -await (await client.getDirectory()).response +await ( + await client.getDirectory() +).response const req = await client.setValue(await client.getElementByPath('0.0.1'), 'gdnet') await req.response console.log('result', req.response) @@ -107,7 +116,9 @@ const { EmberClient, EmberLib } = require('node-emberplus') const client = new EmberClient(HOST, PORT) await client.connect() -await (await client.getDirectory()).response +await ( + await client.getDirectory() +).response const fn = await client.getElementByPath('path.to.function') const req = await client.invoke(fn, 1, 2, 3) console.log('result', await req.response) @@ -126,7 +137,7 @@ const { ParameterAccess, MatrixImpl, MatrixType, - MatrixAddressingMode + MatrixAddressingMode, } = require('emberplus-connection') const s = new EmberServer(9000) // start server on port 9000 @@ -187,14 +198,14 @@ const tree = { undefined, ParameterAccess.ReadWrite ) - ) + ), }), 2: new NumberedTreeNodeImpl(2, new EmberNodeImpl('Functions', undefined, undefined, true), { 1: new NumberedTreeNodeImpl( 1, new EmberFunctionImpl(undefined, undefined) //, [{ type: ParameterType.Boolean, name: 'Test' }]) - ) + ), }), 3: new NumberedTreeNodeImpl(3, new EmberNodeImpl('Matrices', undefined, undefined, true), { @@ -211,13 +222,14 @@ const tree = { 5, 5 ) - ) - }) - }) + ), + }), + }), } s.init(tree) // initiate the provider with the tree ``` + --- _The NRK logo is a registered trademark of Norsk rikskringkasting AS. The license does not grant any right to use, in any way, any trademarks, service marks or logos of Norsk rikskringkasting AS._ From bb3ca20b8e5727909a471d457fac6b7a2d41bdbc Mon Sep 17 00:00:00 2001 From: olzzon Date: Thu, 26 Dec 2024 20:05:13 +0100 Subject: [PATCH 12/67] fix: handle integer stream type --- src/Ember/Client/StreamManager.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Ember/Client/StreamManager.ts b/src/Ember/Client/StreamManager.ts index d29bc16..dbe2616 100644 --- a/src/Ember/Client/StreamManager.ts +++ b/src/Ember/Client/StreamManager.ts @@ -31,15 +31,17 @@ export class StreamManager extends EventEmitter { } public registerParameter(parameter: Parameter, path: string): void { - if (!parameter.streamIdentifier || parameter.streamDescriptor?.offset === undefined) { + if (!parameter.streamIdentifier) { return } + const offset = parameter.streamDescriptor?.offset || 0 + const streamInfo: StreamInfo = { parameter, path, streamIdentifier: parameter.streamIdentifier, - offset: parameter.streamDescriptor.offset, + offset: offset, } // Store both mappings @@ -48,7 +50,7 @@ export class StreamManager extends EventEmitter { console.log('Registered stream:', { path: path, identifier: parameter.identifier, - offset: parameter.streamDescriptor.offset, + offset: offset, }) } @@ -76,10 +78,14 @@ export class StreamManager extends EventEmitter { this.registeredStreams.forEach((streamInfo, path) => { // Only process if IDs match if (streamInfo.streamIdentifier === streamEntry.identifier) { - // If this is a stream with a descriptor and we have a value - if (streamInfo.parameter.streamDescriptor !== undefined && streamEntry.value !== undefined) { + if (streamEntry.value) { const value = streamEntry.value - if (value.type === ParameterType.Octets && Buffer.isBuffer(value.value)) { + + if (value.type === ParameterType.Integer) { + // Handle direct integer values + this.updateStreamValue(path, value.value) + } else if (value.type === ParameterType.Octets && Buffer.isBuffer(value.value)) { + // Handle existing float32 buffer case const buffer = value.value if (buffer.length >= streamInfo.offset + 4) { // Float32 is 4 bytes From 99541a0317010b12f780b6851b2347612e7c2dd4 Mon Sep 17 00:00:00 2001 From: olzzon Date: Sat, 28 Dec 2024 09:43:37 +0100 Subject: [PATCH 13/67] feat: getInternalNodePath() to handle that there's no path on numbered Tree nodes and this must be calculated. --- src/Ember/Client/index.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index 7f2b2da..99dbeed 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -449,6 +449,31 @@ export class EmberClient extends EventEmitter { return tree } + // This function handles the fact that the path in the Ember+ tree is not always the same as the path in requested from the provider + getInternalNodePath(node: TreeElement): string | undefined { + if ('path' in node && typeof node.path === 'string') { + // QualifiedElement case + return node.path + } else if ('number' in node) { + // NumberedTreeNode case + const numbers: number[] = [] + let current: NumberedTreeNode | undefined = node as NumberedTreeNode + + while (current) { + numbers.unshift(current.number) + if (current.parent && 'number' in current.parent) { + current = current.parent as NumberedTreeNode + } else { + current = undefined + } + } + + return numbers.join('.') + } + + return undefined + } + private async _matrixMutation( matrix: QualifiedElement | NumberedTreeNode, target: number, From 3ac2fbec8d4f52880ae8baaf9d58c09c2fcee687 Mon Sep 17 00:00:00 2001 From: olzzon Date: Sat, 28 Dec 2024 09:49:54 +0100 Subject: [PATCH 14/67] doc: include getInternalNodePath() in README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9ea91f3..798460b 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,10 @@ client }) .then(() => client.getElementByPath('0.2')) .then(async (node) => { + // You can get the internal node path, the internal path can be different from the requested, + // depending on wheter it's a qualified node or a numbered node + console.log('This is the internal node path :', client.getInternalNodePath(node)) + // For non-streams a getDirectory will automatically subscribe for update return ( await client.getDirectory(node, (update) => { From 22d61b9bd75d984981a0b1b0eeb0911bb0a5ef68 Mon Sep 17 00:00:00 2001 From: olzzon Date: Mon, 6 Jan 2025 13:10:46 +0100 Subject: [PATCH 15/67] fix: StreamManager should not be a singleton --- src/Ember/Client/StreamManager.ts | 12 +-- src/Ember/Client/index.ts | 35 +++++--- src/S101/S101Codec.ts | 139 +++++++++--------------------- 3 files changed, 64 insertions(+), 122 deletions(-) diff --git a/src/Ember/Client/StreamManager.ts b/src/Ember/Client/StreamManager.ts index dbe2616..59be704 100644 --- a/src/Ember/Client/StreamManager.ts +++ b/src/Ember/Client/StreamManager.ts @@ -16,20 +16,12 @@ interface StreamInfo { } export class StreamManager extends EventEmitter { - private static instance: StreamManager private registeredStreams: Map = new Map() - private constructor() { + constructor() { super() } - public static getInstance(): StreamManager { - if (!StreamManager.instance) { - StreamManager.instance = new StreamManager() - } - return StreamManager.instance - } - public registerParameter(parameter: Parameter, path: string): void { if (!parameter.streamIdentifier) { return @@ -128,5 +120,3 @@ export class StreamManager extends EventEmitter { }) } } - -export default StreamManager diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index 99dbeed..3b39545 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -34,6 +34,7 @@ import { berEncode, StreamManager } from '../..' import { NumberedTreeNodeImpl } from '../../model/Tree' import { EmberFunction } from '../../model/EmberFunction' import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult' +import { StreamEntry } from '../../model/StreamEntry' export type RequestPromise = Promise> export interface RequestPromiseArguments { @@ -86,6 +87,7 @@ export type EmberClientEvents = { connected: [] disconnected: [] + streamUpdate: [path: string, value: EmberValue] } export class EmberClient extends EventEmitter { @@ -93,6 +95,7 @@ export class EmberClient extends EventEmitter { port: number tree: Collection> = [] + private _streamManager: StreamManager private _requests = new Map() private _lastInvocation = 0 private _client: S101Client @@ -111,6 +114,12 @@ export class EmberClient extends EventEmitter { this._timeout = timeout this._resendTimeout = resendTimeout this._resends = enableResends + this._streamManager = new StreamManager() + + // Forward stream events from StreamManager + this._streamManager.on('streamUpdate', (path, value) => { + this.emit('streamUpdate', path, value) + }) // resend timer runs at greatest common divisor of timeouts and resends const findGcd = (a: number, b: number) => { @@ -125,7 +134,16 @@ export class EmberClient extends EventEmitter { this._timer = setInterval(() => this._resendTimer(), findGcd(this._timeout, this._resendTimeout)) this._client = new S101Client(this.host, this.port) - this._client.on('emberTree', (tree: DecodeResult) => this._handleIncoming(tree)) + this._client.on('emberTree', (tree: DecodeResult) => { + if (tree.value && Array.isArray(tree.value) && tree.value[0]?.identifier !== undefined) { + // It's a stream packet + const entries = tree.value as Collection + this._streamManager.updateAllStreamValues(entries) + } else { + // Regular ember tree + this._handleIncoming(tree) + } + }) this._client.on('error', (e) => this.emit('error', e)) this._client.on('connected', () => this.emit('connected')) @@ -236,13 +254,7 @@ export class EmberClient extends EventEmitter { if (node.contents.type === ElementType.Parameter) { const parameter = node.contents if (parameter.streamIdentifier !== undefined) { - console.log('Registering parameter with StreamManager:', { - streamId: parameter.streamIdentifier, - offSet: parameter.streamDescriptor?.offset, - identifier: parameter.identifier, - path: getPath(node), - }) - StreamManager.getInstance().registerParameter(parameter, getPath(node)) + this._streamManager.registerParameter(parameter, getPath(node)) } } @@ -274,12 +286,7 @@ export class EmberClient extends EventEmitter { if (!Array.isArray(node) && node.contents.type === ElementType.Parameter) { const parameter = node.contents if (parameter.streamIdentifier !== undefined) { - console.log('Deregistering parameter from StreamManager:', { - streamId: parameter.streamIdentifier, - identifier: parameter.identifier, - path: path, - }) - StreamManager.getInstance().unregisterParameter(path) + this._streamManager.unregisterParameter(path) } } diff --git a/src/S101/S101Codec.ts b/src/S101/S101Codec.ts index 8d4edea..74d0d57 100644 --- a/src/S101/S101Codec.ts +++ b/src/S101/S101Codec.ts @@ -3,9 +3,7 @@ import { SmartBuffer } from 'smart-buffer' import Debug from 'debug' import { format } from 'util' import { berDecode } from '../encodings/ber' -import { StreamEntry } from '../model' -import { StreamManager } from '../Ember/Client/StreamManager' -import { Collection } from '../types/types' + const debug = Debug('emberplus-connection:S101Codec') const S101_BOF = 0xfe @@ -114,89 +112,12 @@ export default class S101Codec extends EventEmitter { } else if (command === CMD_EMBER) { const remainingData = frame.readBuffer() const emberFrame = SmartBuffer.fromBuffer(remainingData) - - emberFrame.skip(1) // Skip version byte - const flags = emberFrame.readUInt8() - - emberFrame.skip(1) // Skip dtd byte - const appBytes = emberFrame.readUInt8() - - if (appBytes > 0) { - emberFrame.readBuffer(appBytes) - } - - try { - const payload = emberFrame.readBuffer() - const data = payload.slice(0, payload.length - 2) // Remove CRC - - if ((flags & FLAG_SINGLE_PACKET) === FLAG_SINGLE_PACKET) { - if ((flags & FLAG_EMPTY_PACKET) === 0) { - this.handlePacket(data) - } - } else { - // Multi-packet handling - if ((flags & FLAG_FIRST_MULTI_PACKET) === FLAG_FIRST_MULTI_PACKET) { - this.multiPacketBuffer = new SmartBuffer() - this.isMultiPacket = true - this.multiPacketBuffer.writeBuffer(data) - } else if (this.isMultiPacket && this.multiPacketBuffer) { - this.multiPacketBuffer.writeBuffer(data) - - if ((flags & FLAG_LAST_MULTI_PACKET) === FLAG_LAST_MULTI_PACKET) { - const completeData = this.multiPacketBuffer.toBuffer() - this.handlePacket(completeData) - this.resetMultiPacketBuffer() - } - } - } - } catch (error) { - // Clean up if error occurs during multi-packet processing - this.resetMultiPacketBuffer() - throw new Error('Error processing frame:' + JSON.stringify(error, null, 2)) - } + this.handleEmberFrame(emberFrame) } else { throw new Error(format('dropping frame of length %d with unknown command %d', frame.length, command)) } } - private handlePacket(data: Buffer): void { - try { - if (data[2] === 0x66) { - this.handleStreamPacket(data) - } else if (data[0] === 0x60) { - const decoded = berDecode(data) - if (decoded.value) { - this.emit('emberPacket', data) - } - } - } catch (error) { - console.error('Error decoding 0x60 packet:', error) - } - } - - private handleStreamPacket(data: Buffer): void { - const streamManager = StreamManager.getInstance() - - try { - const decoded = berDecode(data) - const entries = decoded.value as Collection - - if (!entries || typeof entries !== 'object') { - console.warn('Invalid stream entries format') - return - } - // Update the stream value - streamManager.updateAllStreamValues(entries) - } catch (error) { - console.error('Error processing stream packet:', error) - } - } - - // Cleanup if multi-packet message is not completed - resetMultiPacketBuffer(): void { - this.multiPacketBuffer = undefined - } - handleEmberFrame(frame: SmartBuffer): void { const version = frame.readUInt8() const flags = frame.readUInt8() @@ -226,26 +147,50 @@ export default class S101Codec extends EventEmitter { } let payload = frame.readBuffer() - payload = payload.slice(0, payload.length - 2) - if (flags & FLAG_FIRST_MULTI_PACKET) { - debug('multi ember packet start') - this.emberbuf.clear() - } - if ((flags & FLAG_EMPTY_PACKET) === 0) { - // not empty, save the payload - this.emberbuf.writeBuffer(payload) + payload = payload.slice(0, payload.length - 2) // Remove CRC + + if ((flags & FLAG_SINGLE_PACKET) === FLAG_SINGLE_PACKET) { + if ((flags & FLAG_EMPTY_PACKET) === 0) { + this.handleEmberPacket(payload) + } + } else { + // Multi-packet handling + if ((flags & FLAG_FIRST_MULTI_PACKET) === FLAG_FIRST_MULTI_PACKET) { + debug('multi ember packet start') + this.multiPacketBuffer = new SmartBuffer() + this.isMultiPacket = true + this.multiPacketBuffer.writeBuffer(payload) + } else if (this.isMultiPacket && this.multiPacketBuffer) { + this.multiPacketBuffer.writeBuffer(payload) + + if ((flags & FLAG_LAST_MULTI_PACKET) === FLAG_LAST_MULTI_PACKET) { + debug('multi ember packet end') + const completeData = this.multiPacketBuffer.toBuffer() + this.handleEmberPacket(completeData) + this.resetMultiPacketBuffer() + } + } } - if (flags & FLAG_LAST_MULTI_PACKET) { - debug('multi ember packet end') - this.emberbuf.moveTo(0) - this.handleEmberPacket(this.emberbuf) - this.emberbuf.clear() + } + + private handleEmberPacket(data: Buffer): void { + try { + const decoded = berDecode(data) + if (data[0] === 0x60) { + // Root tag check + if (decoded.value) { + this.emit('emberPacket', data) + } + } + } catch (error) { + console.error('Error decoding packet:', error) + this.resetMultiPacketBuffer() } } - handleEmberPacket(packet: SmartBuffer): void { - debug('ember packet') - this.emit('emberPacket', packet.toBuffer()) + resetMultiPacketBuffer(): void { + this.multiPacketBuffer = undefined + this.isMultiPacket = false } encodeBER(data: Buffer): Buffer[] { From c00bb108abcca329d9cdf6a25a8a420fabd20824 Mon Sep 17 00:00:00 2001 From: olzzon Date: Mon, 6 Jan 2025 16:47:12 +0100 Subject: [PATCH 16/67] feat: separate emberPackets and emberStreamPackets --- src/Ember/Client/index.ts | 15 +++++++-------- src/Ember/Socket/S101Socket.ts | 13 +++++++++++-- src/S101/S101Codec.ts | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index 3b39545..d0fd4b1 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -135,14 +135,13 @@ export class EmberClient extends EventEmitter { this._client = new S101Client(this.host, this.port) this._client.on('emberTree', (tree: DecodeResult) => { - if (tree.value && Array.isArray(tree.value) && tree.value[0]?.identifier !== undefined) { - // It's a stream packet - const entries = tree.value as Collection - this._streamManager.updateAllStreamValues(entries) - } else { - // Regular ember tree - this._handleIncoming(tree) - } + // Regular ember tree + this._handleIncoming(tree) + }) + this._client.on('emberStreamTree', (tree: DecodeResult) => { + // Ember Tree with Stream + const entries = tree.value as Collection + this._streamManager.updateAllStreamValues(entries) }) this._client.on('error', (e) => this.emit('error', e)) diff --git a/src/Ember/Socket/S101Socket.ts b/src/Ember/Socket/S101Socket.ts index f86efa2..de47cc5 100644 --- a/src/Ember/Socket/S101Socket.ts +++ b/src/Ember/Socket/S101Socket.ts @@ -12,8 +12,8 @@ export type Request = any export type S101SocketEvents = { error: [Error] - emberPacket: [packet: Buffer] emberTree: [root: DecodeResult] + emberStreamTree: [root: DecodeResult] connecting: [] connected: [] disconnected: [] @@ -44,7 +44,16 @@ export default class S101Socket extends EventEmitter { }) this.codec.on('emberPacket', (packet) => { - this.emit('emberPacket', packet) + try { + const root = berDecode(packet) + if (root != null) { + this.emit('emberTree', root) + } + } catch (e) { + this.emit('error', normalizeError(e)) + } + }) + this.codec.on('emberStreamPacket', (packet) => { try { const root = berDecode(packet) if (root != null) { diff --git a/src/S101/S101Codec.ts b/src/S101/S101Codec.ts index 74d0d57..377ea73 100644 --- a/src/S101/S101Codec.ts +++ b/src/S101/S101Codec.ts @@ -56,6 +56,7 @@ const CRC_TABLE = [ export type S101CodecEvents = { emberPacket: [packet: Buffer] + emberStreamPacket: [packet: Buffer] keepaliveReq: [] keepaliveResp: [] } @@ -166,7 +167,7 @@ export default class S101Codec extends EventEmitter { if ((flags & FLAG_LAST_MULTI_PACKET) === FLAG_LAST_MULTI_PACKET) { debug('multi ember packet end') const completeData = this.multiPacketBuffer.toBuffer() - this.handleEmberPacket(completeData) + this.handleEmberStreamPacket(completeData) this.resetMultiPacketBuffer() } } @@ -184,6 +185,20 @@ export default class S101Codec extends EventEmitter { } } catch (error) { console.error('Error decoding packet:', error) + } + } + + private handleEmberStreamPacket(data: Buffer): void { + try { + const decoded = berDecode(data) + if (data[0] === 0x60 && data[2] === 0x66) { + // Root and stream tag check + if (decoded.value) { + this.emit('emberStreamPacket', data) + } + } + } catch (error) { + console.error('Error decoding stream packet:', error) this.resetMultiPacketBuffer() } } From e2d5072ad0b6da5521dc70ccf4de2911c9733e32 Mon Sep 17 00:00:00 2001 From: olzzon Date: Tue, 7 Jan 2025 14:25:44 +0100 Subject: [PATCH 17/67] feat: StreamManager is only used internally --- src/Ember/Client/index.ts | 3 ++- src/index.ts | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Ember/Client/index.ts b/src/Ember/Client/index.ts index d0fd4b1..3383246 100644 --- a/src/Ember/Client/index.ts +++ b/src/Ember/Client/index.ts @@ -30,11 +30,12 @@ import { EmberNode } from '../../model/EmberNode' import { EventEmitter } from 'eventemitter3' import { S101Client } from '../Socket' import { getPath, assertQualifiedEmberNode, insertCommand, updateProps, isEmptyNode } from '../Lib/util' -import { berEncode, StreamManager } from '../..' +import { berEncode } from '../../encodings/ber' import { NumberedTreeNodeImpl } from '../../model/Tree' import { EmberFunction } from '../../model/EmberFunction' import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult' import { StreamEntry } from '../../model/StreamEntry' +import { StreamManager } from './StreamManager' export type RequestPromise = Promise> export interface RequestPromiseArguments { diff --git a/src/index.ts b/src/index.ts index 5bee15f..49a0fd1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,4 @@ import { EmberClient, EmberClientEvents } from './Ember/Client/index' -import { StreamManager, StreamManagerEvents } from './Ember/Client/StreamManager' import { EmberLib } from './Ember/Lib/index' import { EmberServer, EmberServerEvents } from './Ember/Server/index' import { S101Codec } from './S101/index' @@ -41,8 +40,6 @@ const Decoder = EmberLib.DecodeBuffer export { EmberClient, - StreamManagerEvents, - StreamManager, EmberClientEvents, Decoder, EmberLib, From 616d8ccc96c81fc2771c5926e812b5134a9f18fa Mon Sep 17 00:00:00 2001 From: olzzon Date: Tue, 7 Jan 2025 14:27:40 +0100 Subject: [PATCH 18/67] feat: update README.md --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 798460b..e7d3ebf 100644 --- a/README.md +++ b/README.md @@ -25,15 +25,15 @@ The current version is very losely based on the original library and Mr Gilles D Get Full tree: ```javascript -const { EmberClient, StreamManager } = require('emberplus-connection'); -const client = new EmberClient("10.9.8.7", 9000); -client.on("error", e => { - console.log(e); -}); +const { EmberClient, StreamManager } = require('emberplus-connection') +const client = new EmberClient('10.9.8.7', 9000) +client.on('error', (e) => { + console.log(e) +}) await client.connect() // If you want to listen to stream updates - you can do it like this: -StreamManager.getInstance().on('streamUpdate', (path, value) => { +client.on('streamUpdate', (path, value) => { console.log('Stream Update:', { path: path, value: value, @@ -43,14 +43,14 @@ StreamManager.getInstance().on('streamUpdate', (path, value) => { const req = await client.getDirectory(client.tree) await req.response // Get a Specific Node -const node = await client.getElementByPath("0.0.2") -console.log(node); +const node = await client.getElementByPath('0.0.2') +console.log(node) // Get a node by its path identifiers -const node2 = await client.getElementByPath("path.to.node")) -console.log(node2); +const node2 = await client.getElementByPath('path.to.node') +console.log(node2) // Get a node by its path descriptions -const node3 = await client.getElementByPath("descr1.descr2.descr3")) -console.log(node3); +const node3 = await client.getElementByPath('descr1.descr2.descr3') +console.log(node3) // Expand entire tree under node 0 await client.expand(client.tree) console.log(client.tree) @@ -78,7 +78,7 @@ client .then(() => client.getElementByPath('0.2')) .then(async (node) => { // You can get the internal node path, the internal path can be different from the requested, - // depending on wheter it's a qualified node or a numbered node + // depending on wheter you request a numbered node or via the description console.log('This is the internal node path :', client.getInternalNodePath(node)) // For non-streams a getDirectory will automatically subscribe for update From bb6077816f0410a94fee820fbcb5a72749538787 Mon Sep 17 00:00:00 2001 From: olzzon Date: Tue, 7 Jan 2025 14:51:00 +0100 Subject: [PATCH 19/67] feat: update tests to client's internal StreamManager --- src/Ember/Client/__tests__/index.spec.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Ember/Client/__tests__/index.spec.ts b/src/Ember/Client/__tests__/index.spec.ts index 962ab1d..5bfa9cd 100644 --- a/src/Ember/Client/__tests__/index.spec.ts +++ b/src/Ember/Client/__tests__/index.spec.ts @@ -13,7 +13,6 @@ import { EmberClient } from '../' import S101ClientMock from '../../../__mocks__/S101Client' import { DecodeResult } from '../../../encodings/ber/decoder/DecodeResult' import { StreamDescriptionImpl } from '../../../model/StreamDescription' -import StreamManager from '../StreamManager' import { StreamEntry, StreamEntryImpl } from '../../../model/StreamEntry' // import { EmberTreeNode, RootElement } from '../../../types/types' // import { ElementType, EmberElement } from '../../../model/EmberElement' @@ -446,7 +445,8 @@ describe('client', () => { await new Promise(setImmediate) // Get StreamManager instance and check registration - const streamManager = StreamManager.getInstance() + //@ts-expect-error - private method + const streamManager = client._streamManager const streamInfo = streamManager.getStreamInfoByPath('1') expect(streamInfo).toBeDefined() @@ -490,7 +490,8 @@ describe('client', () => { await new Promise(setImmediate) // Check parameter was deregistered - const streamManager = StreamManager.getInstance() + //@ts-expect-error - private method + const streamManager = client._streamManager const streamInfo = streamManager.getStreamInfoByPath('1') expect(streamInfo).toBeUndefined() @@ -619,7 +620,8 @@ describe('client', () => { ]) // Get StreamManager instance and verify values - const streamManager = StreamManager.getInstance() + //@ts-expect-error - private method + const streamManager = client._streamManager const decoded: Collection = [ { From c586ac9b0a5c4c4dfc77fc7978f223893750bd11 Mon Sep 17 00:00:00 2001 From: olzzon Date: Tue, 7 Jan 2025 14:54:32 +0100 Subject: [PATCH 20/67] chore: gitignore allow dist folder --- .gitignore | 1 - dist/Ber/BERDataTypes.d.ts | 20 + dist/Ber/BERDataTypes.d.ts.map | 1 + dist/Ber/BERDataTypes.js | 24 + dist/Ber/BERDataTypes.js.map | 1 + dist/Ber/Reader.d.ts | 10 + dist/Ber/Reader.d.ts.map | 1 + dist/Ber/Reader.js | 106 +++ dist/Ber/Reader.js.map | 1 + dist/Ber/Writer.d.ts | 13 + dist/Ber/Writer.d.ts.map | 1 + dist/Ber/Writer.js | 208 ++++++ dist/Ber/Writer.js.map | 1 + dist/Ber/functions.d.ts | 6 + dist/Ber/functions.d.ts.map | 1 + dist/Ber/functions.js | 17 + dist/Ber/functions.js.map | 1 + dist/Ber/index.d.ts | 6 + dist/Ber/index.d.ts.map | 1 + dist/Ber/index.js | 14 + dist/Ber/index.js.map | 1 + dist/Ember/Client/StreamManager.d.ts | 28 + dist/Ember/Client/StreamManager.d.ts.map | 1 + dist/Ember/Client/StreamManager.js | 98 +++ dist/Ember/Client/StreamManager.js.map | 1 + dist/Ember/Client/index.d.ts | 111 ++++ dist/Ember/Client/index.d.ts.map | 1 + dist/Ember/Client/index.js | 616 ++++++++++++++++++ dist/Ember/Client/index.js.map | 1 + dist/Ember/Lib/index.d.ts | 5 + dist/Ember/Lib/index.d.ts.map | 1 + dist/Ember/Lib/index.js | 8 + dist/Ember/Lib/index.js.map | 1 + dist/Ember/Lib/util.d.ts | 15 + dist/Ember/Lib/util.d.ts.map | 1 + dist/Ember/Lib/util.js | 93 +++ dist/Ember/Lib/util.js.map | 1 + dist/Ember/Server/index.d.ts | 37 ++ dist/Ember/Server/index.d.ts.map | 1 + dist/Ember/Server/index.js | 292 +++++++++ dist/Ember/Server/index.js.map | 1 + dist/Ember/Socket/S101Client.d.ts | 28 + dist/Ember/Socket/S101Client.d.ts.map | 1 + dist/Ember/Socket/S101Client.js | 153 +++++ dist/Ember/Socket/S101Client.js.map | 1 + dist/Ember/Socket/S101Server.d.ts | 20 + dist/Ember/Socket/S101Server.d.ts.map | 1 + dist/Ember/Socket/S101Server.js | 48 ++ dist/Ember/Socket/S101Server.js.map | 1 + dist/Ember/Socket/S101Socket.d.ts | 49 ++ dist/Ember/Socket/S101Socket.d.ts.map | 1 + dist/Ember/Socket/S101Socket.js | 180 +++++ dist/Ember/Socket/S101Socket.js.map | 1 + dist/Ember/Socket/index.d.ts | 3 + dist/Ember/Socket/index.d.ts.map | 1 + dist/Ember/Socket/index.js | 7 + dist/Ember/Socket/index.js.map | 1 + dist/Errors.d.ts | 68 ++ dist/Errors.d.ts.map | 1 + dist/Errors.js | 151 +++++ dist/Errors.js.map | 1 + dist/S101/S101Codec.d.ts | 31 + dist/S101/S101Codec.d.ts.map | 1 + dist/S101/S101Codec.js | 301 +++++++++ dist/S101/S101Codec.js.map | 1 + dist/S101/index.d.ts | 3 + dist/S101/index.d.ts.map | 1 + dist/S101/index.js | 7 + dist/S101/index.js.map | 1 + dist/encodings/ber/constants.d.ts | 28 + dist/encodings/ber/constants.d.ts.map | 1 + dist/encodings/ber/constants.js | 58 ++ dist/encodings/ber/constants.js.map | 1 + dist/encodings/ber/decoder/Command.d.ts | 6 + dist/encodings/ber/decoder/Command.d.ts.map | 1 + dist/encodings/ber/decoder/Command.js | 68 ++ dist/encodings/ber/decoder/Command.js.map | 1 + dist/encodings/ber/decoder/Connection.d.ts | 6 + .../encodings/ber/decoder/Connection.d.ts.map | 1 + dist/encodings/ber/decoder/Connection.js | 77 +++ dist/encodings/ber/decoder/Connection.js.map | 1 + dist/encodings/ber/decoder/DecodeResult.d.ts | 124 ++++ .../ber/decoder/DecodeResult.d.ts.map | 1 + dist/encodings/ber/decoder/DecodeResult.js | 223 +++++++ .../encodings/ber/decoder/DecodeResult.js.map | 1 + dist/encodings/ber/decoder/EmberFunction.d.ts | 6 + .../ber/decoder/EmberFunction.d.ts.map | 1 + dist/encodings/ber/decoder/EmberFunction.js | 78 +++ .../ber/decoder/EmberFunction.js.map | 1 + dist/encodings/ber/decoder/EmberNode.d.ts | 6 + dist/encodings/ber/decoder/EmberNode.d.ts.map | 1 + dist/encodings/ber/decoder/EmberNode.js | 50 ++ dist/encodings/ber/decoder/EmberNode.js.map | 1 + .../ber/decoder/FunctionArgument.d.ts | 6 + .../ber/decoder/FunctionArgument.d.ts.map | 1 + .../encodings/ber/decoder/FunctionArgument.js | 38 ++ .../ber/decoder/FunctionArgument.js.map | 1 + dist/encodings/ber/decoder/Invocation.d.ts | 6 + .../encodings/ber/decoder/Invocation.d.ts.map | 1 + dist/encodings/ber/decoder/Invocation.js | 47 ++ dist/encodings/ber/decoder/Invocation.js.map | 1 + .../ber/decoder/InvocationResult.d.ts | 5 + .../ber/decoder/InvocationResult.d.ts.map | 1 + .../encodings/ber/decoder/InvocationResult.js | 54 ++ .../ber/decoder/InvocationResult.js.map | 1 + dist/encodings/ber/decoder/Label.d.ts | 6 + dist/encodings/ber/decoder/Label.d.ts.map | 1 + dist/encodings/ber/decoder/Label.js | 37 ++ dist/encodings/ber/decoder/Label.js.map | 1 + dist/encodings/ber/decoder/Matrix.d.ts | 7 + dist/encodings/ber/decoder/Matrix.d.ts.map | 1 + dist/encodings/ber/decoder/Matrix.js | 232 +++++++ dist/encodings/ber/decoder/Matrix.js.map | 1 + dist/encodings/ber/decoder/Parameter.d.ts | 7 + dist/encodings/ber/decoder/Parameter.d.ts.map | 1 + dist/encodings/ber/decoder/Parameter.js | 154 +++++ dist/encodings/ber/decoder/Parameter.js.map | 1 + .../ber/decoder/StreamDescription.d.ts | 5 + .../ber/decoder/StreamDescription.d.ts.map | 1 + .../ber/decoder/StreamDescription.js | 79 +++ .../ber/decoder/StreamDescription.js.map | 1 + dist/encodings/ber/decoder/StreamEntry.d.ts | 7 + .../ber/decoder/StreamEntry.d.ts.map | 1 + dist/encodings/ber/decoder/StreamEntry.js | 62 ++ dist/encodings/ber/decoder/StreamEntry.js.map | 1 + .../ber/decoder/StringIntegerCollection.d.ts | 6 + .../decoder/StringIntegerCollection.d.ts.map | 1 + .../ber/decoder/StringIntegerCollection.js | 55 ++ .../decoder/StringIntegerCollection.js.map | 1 + dist/encodings/ber/decoder/Template.d.ts | 6 + dist/encodings/ber/decoder/Template.d.ts.map | 1 + dist/encodings/ber/decoder/Template.js | 54 ++ dist/encodings/ber/decoder/Template.js.map | 1 + dist/encodings/ber/decoder/Tree.d.ts | 9 + dist/encodings/ber/decoder/Tree.d.ts.map | 1 + dist/encodings/ber/decoder/Tree.js | 207 ++++++ dist/encodings/ber/decoder/Tree.js.map | 1 + dist/encodings/ber/encoder/Command.d.ts | 4 + dist/encodings/ber/encoder/Command.d.ts.map | 1 + dist/encodings/ber/encoder/Command.js | 46 ++ dist/encodings/ber/encoder/Command.js.map | 1 + dist/encodings/ber/encoder/Connection.d.ts | 4 + .../encodings/ber/encoder/Connection.d.ts.map | 1 + dist/encodings/ber/encoder/Connection.js | 48 ++ dist/encodings/ber/encoder/Connection.js.map | 1 + dist/encodings/ber/encoder/EmberElement.d.ts | 4 + .../ber/encoder/EmberElement.d.ts.map | 1 + dist/encodings/ber/encoder/EmberElement.js | 34 + .../encodings/ber/encoder/EmberElement.js.map | 1 + dist/encodings/ber/encoder/EmberFunction.d.ts | 4 + .../ber/encoder/EmberFunction.d.ts.map | 1 + dist/encodings/ber/encoder/EmberFunction.js | 50 ++ .../ber/encoder/EmberFunction.js.map | 1 + dist/encodings/ber/encoder/EmberNode.d.ts | 4 + dist/encodings/ber/encoder/EmberNode.d.ts.map | 1 + dist/encodings/ber/encoder/EmberNode.js | 41 ++ dist/encodings/ber/encoder/EmberNode.js.map | 1 + .../ber/encoder/FunctionArgument.d.ts | 4 + .../ber/encoder/FunctionArgument.d.ts.map | 1 + .../encodings/ber/encoder/FunctionArgument.js | 38 ++ .../ber/encoder/FunctionArgument.js.map | 1 + dist/encodings/ber/encoder/Invocation.d.ts | 4 + .../encodings/ber/encoder/Invocation.d.ts.map | 1 + dist/encodings/ber/encoder/Invocation.js | 26 + dist/encodings/ber/encoder/Invocation.js.map | 1 + .../ber/encoder/InvocationResult.d.ts | 4 + .../ber/encoder/InvocationResult.d.ts.map | 1 + .../encodings/ber/encoder/InvocationResult.js | 33 + .../ber/encoder/InvocationResult.js.map | 1 + dist/encodings/ber/encoder/Label.d.ts | 4 + dist/encodings/ber/encoder/Label.d.ts.map | 1 + dist/encodings/ber/encoder/Label.js | 25 + dist/encodings/ber/encoder/Label.js.map | 1 + dist/encodings/ber/encoder/Matrix.d.ts | 10 + dist/encodings/ber/encoder/Matrix.d.ts.map | 1 + dist/encodings/ber/encoder/Matrix.js | 97 +++ dist/encodings/ber/encoder/Matrix.js.map | 1 + dist/encodings/ber/encoder/Parameter.d.ts | 4 + dist/encodings/ber/encoder/Parameter.d.ts.map | 1 + dist/encodings/ber/encoder/Parameter.js | 114 ++++ dist/encodings/ber/encoder/Parameter.js.map | 1 + dist/encodings/ber/encoder/Qualified.d.ts | 5 + dist/encodings/ber/encoder/Qualified.d.ts.map | 1 + dist/encodings/ber/encoder/Qualified.js | 34 + dist/encodings/ber/encoder/Qualified.js.map | 1 + dist/encodings/ber/encoder/RootElement.d.ts | 4 + .../ber/encoder/RootElement.d.ts.map | 1 + dist/encodings/ber/encoder/RootElement.js | 15 + dist/encodings/ber/encoder/RootElement.js.map | 1 + .../ber/encoder/StreamDescription.d.ts | 4 + .../ber/encoder/StreamDescription.d.ts.map | 1 + .../ber/encoder/StreamDescription.js | 38 ++ .../ber/encoder/StreamDescription.js.map | 1 + dist/encodings/ber/encoder/StreamEntry.d.ts | 4 + .../ber/encoder/StreamEntry.d.ts.map | 1 + dist/encodings/ber/encoder/StreamEntry.js | 22 + dist/encodings/ber/encoder/StreamEntry.js.map | 1 + .../ber/encoder/StringIntegerCollection.d.ts | 4 + .../encoder/StringIntegerCollection.d.ts.map | 1 + .../ber/encoder/StringIntegerCollection.js | 24 + .../encoder/StringIntegerCollection.js.map | 1 + dist/encodings/ber/encoder/Template.d.ts | 4 + dist/encodings/ber/encoder/Template.d.ts.map | 1 + dist/encodings/ber/encoder/Template.js | 20 + dist/encodings/ber/encoder/Template.js.map | 1 + dist/encodings/ber/encoder/Tree.d.ts | 6 + dist/encodings/ber/encoder/Tree.d.ts.map | 1 + dist/encodings/ber/encoder/Tree.js | 126 ++++ dist/encodings/ber/encoder/Tree.js.map | 1 + dist/encodings/ber/index.d.ts | 7 + dist/encodings/ber/index.d.ts.map | 1 + dist/encodings/ber/index.js | 76 +++ dist/encodings/ber/index.js.map | 1 + dist/index.d.ts | 11 + dist/index.d.ts.map | 1 + dist/index.js | 37 ++ dist/index.js.map | 1 + dist/model/Command.d.ts | 83 +++ dist/model/Command.d.ts.map | 1 + dist/model/Command.js | 70 ++ dist/model/Command.js.map | 1 + dist/model/Connection.d.ts | 44 ++ dist/model/Connection.d.ts.map | 1 + dist/model/Connection.js | 38 ++ dist/model/Connection.js.map | 1 + dist/model/EmberElement.d.ts | 23 + dist/model/EmberElement.d.ts.map | 1 + dist/model/EmberElement.js | 28 + dist/model/EmberElement.js.map | 1 + dist/model/EmberFunction.d.ts | 31 + dist/model/EmberFunction.d.ts.map | 1 + dist/model/EmberFunction.js | 16 + dist/model/EmberFunction.js.map | 1 + dist/model/EmberNode.d.ts | 33 + dist/model/EmberNode.d.ts.map | 1 + dist/model/EmberNode.js | 17 + dist/model/EmberNode.js.map | 1 + dist/model/FunctionArgument.d.ts | 17 + dist/model/FunctionArgument.d.ts.map | 1 + dist/model/FunctionArgument.js | 11 + dist/model/FunctionArgument.js.map | 1 + dist/model/Invocation.d.ts | 19 + dist/model/Invocation.d.ts.map | 1 + dist/model/Invocation.js | 11 + dist/model/Invocation.js.map | 1 + dist/model/InvocationResult.d.ts | 20 + dist/model/InvocationResult.d.ts.map | 1 + dist/model/InvocationResult.js | 12 + dist/model/InvocationResult.js.map | 1 + dist/model/Label.d.ts | 15 + dist/model/Label.d.ts.map | 1 + dist/model/Label.js | 11 + dist/model/Label.js.map | 1 + dist/model/Matrix.d.ts | 95 +++ dist/model/Matrix.d.ts.map | 1 + dist/model/Matrix.js | 54 ++ dist/model/Matrix.js.map | 1 + dist/model/Parameter.d.ts | 106 +++ dist/model/Parameter.d.ts.map | 1 + dist/model/Parameter.js | 74 +++ dist/model/Parameter.js.map | 1 + dist/model/StreamDescription.d.ts | 31 + dist/model/StreamDescription.d.ts.map | 1 + dist/model/StreamDescription.js | 33 + dist/model/StreamDescription.js.map | 1 + dist/model/StreamEntry.d.ts | 12 + dist/model/StreamEntry.d.ts.map | 1 + dist/model/StreamEntry.js | 11 + dist/model/StreamEntry.js.map | 1 + dist/model/Template.d.ts | 25 + dist/model/Template.d.ts.map | 1 + dist/model/Template.js | 13 + dist/model/Template.js.map | 1 + dist/model/Tree.d.ts | 31 + dist/model/Tree.d.ts.map | 1 + dist/model/Tree.js | 26 + dist/model/Tree.js.map | 1 + dist/model/index.d.ts | 15 + dist/model/index.d.ts.map | 1 + dist/model/index.js | 27 + dist/model/index.js.map | 1 + dist/types/index.d.ts | 3 + dist/types/index.d.ts.map | 1 + dist/types/index.js | 6 + dist/types/index.js.map | 1 + dist/types/types.d.ts | 32 + dist/types/types.d.ts.map | 1 + dist/types/types.js | 15 + dist/types/types.js.map | 1 + 289 files changed, 6890 insertions(+), 1 deletion(-) create mode 100644 dist/Ber/BERDataTypes.d.ts create mode 100644 dist/Ber/BERDataTypes.d.ts.map create mode 100644 dist/Ber/BERDataTypes.js create mode 100644 dist/Ber/BERDataTypes.js.map create mode 100644 dist/Ber/Reader.d.ts create mode 100644 dist/Ber/Reader.d.ts.map create mode 100644 dist/Ber/Reader.js create mode 100644 dist/Ber/Reader.js.map create mode 100644 dist/Ber/Writer.d.ts create mode 100644 dist/Ber/Writer.d.ts.map create mode 100644 dist/Ber/Writer.js create mode 100644 dist/Ber/Writer.js.map create mode 100644 dist/Ber/functions.d.ts create mode 100644 dist/Ber/functions.d.ts.map create mode 100644 dist/Ber/functions.js create mode 100644 dist/Ber/functions.js.map create mode 100644 dist/Ber/index.d.ts create mode 100644 dist/Ber/index.d.ts.map create mode 100644 dist/Ber/index.js create mode 100644 dist/Ber/index.js.map create mode 100644 dist/Ember/Client/StreamManager.d.ts create mode 100644 dist/Ember/Client/StreamManager.d.ts.map create mode 100644 dist/Ember/Client/StreamManager.js create mode 100644 dist/Ember/Client/StreamManager.js.map create mode 100644 dist/Ember/Client/index.d.ts create mode 100644 dist/Ember/Client/index.d.ts.map create mode 100644 dist/Ember/Client/index.js create mode 100644 dist/Ember/Client/index.js.map create mode 100644 dist/Ember/Lib/index.d.ts create mode 100644 dist/Ember/Lib/index.d.ts.map create mode 100644 dist/Ember/Lib/index.js create mode 100644 dist/Ember/Lib/index.js.map create mode 100644 dist/Ember/Lib/util.d.ts create mode 100644 dist/Ember/Lib/util.d.ts.map create mode 100644 dist/Ember/Lib/util.js create mode 100644 dist/Ember/Lib/util.js.map create mode 100644 dist/Ember/Server/index.d.ts create mode 100644 dist/Ember/Server/index.d.ts.map create mode 100644 dist/Ember/Server/index.js create mode 100644 dist/Ember/Server/index.js.map create mode 100644 dist/Ember/Socket/S101Client.d.ts create mode 100644 dist/Ember/Socket/S101Client.d.ts.map create mode 100644 dist/Ember/Socket/S101Client.js create mode 100644 dist/Ember/Socket/S101Client.js.map create mode 100644 dist/Ember/Socket/S101Server.d.ts create mode 100644 dist/Ember/Socket/S101Server.d.ts.map create mode 100644 dist/Ember/Socket/S101Server.js create mode 100644 dist/Ember/Socket/S101Server.js.map create mode 100644 dist/Ember/Socket/S101Socket.d.ts create mode 100644 dist/Ember/Socket/S101Socket.d.ts.map create mode 100644 dist/Ember/Socket/S101Socket.js create mode 100644 dist/Ember/Socket/S101Socket.js.map create mode 100644 dist/Ember/Socket/index.d.ts create mode 100644 dist/Ember/Socket/index.d.ts.map create mode 100644 dist/Ember/Socket/index.js create mode 100644 dist/Ember/Socket/index.js.map create mode 100644 dist/Errors.d.ts create mode 100644 dist/Errors.d.ts.map create mode 100644 dist/Errors.js create mode 100644 dist/Errors.js.map create mode 100644 dist/S101/S101Codec.d.ts create mode 100644 dist/S101/S101Codec.d.ts.map create mode 100644 dist/S101/S101Codec.js create mode 100644 dist/S101/S101Codec.js.map create mode 100644 dist/S101/index.d.ts create mode 100644 dist/S101/index.d.ts.map create mode 100644 dist/S101/index.js create mode 100644 dist/S101/index.js.map create mode 100644 dist/encodings/ber/constants.d.ts create mode 100644 dist/encodings/ber/constants.d.ts.map create mode 100644 dist/encodings/ber/constants.js create mode 100644 dist/encodings/ber/constants.js.map create mode 100644 dist/encodings/ber/decoder/Command.d.ts create mode 100644 dist/encodings/ber/decoder/Command.d.ts.map create mode 100644 dist/encodings/ber/decoder/Command.js create mode 100644 dist/encodings/ber/decoder/Command.js.map create mode 100644 dist/encodings/ber/decoder/Connection.d.ts create mode 100644 dist/encodings/ber/decoder/Connection.d.ts.map create mode 100644 dist/encodings/ber/decoder/Connection.js create mode 100644 dist/encodings/ber/decoder/Connection.js.map create mode 100644 dist/encodings/ber/decoder/DecodeResult.d.ts create mode 100644 dist/encodings/ber/decoder/DecodeResult.d.ts.map create mode 100644 dist/encodings/ber/decoder/DecodeResult.js create mode 100644 dist/encodings/ber/decoder/DecodeResult.js.map create mode 100644 dist/encodings/ber/decoder/EmberFunction.d.ts create mode 100644 dist/encodings/ber/decoder/EmberFunction.d.ts.map create mode 100644 dist/encodings/ber/decoder/EmberFunction.js create mode 100644 dist/encodings/ber/decoder/EmberFunction.js.map create mode 100644 dist/encodings/ber/decoder/EmberNode.d.ts create mode 100644 dist/encodings/ber/decoder/EmberNode.d.ts.map create mode 100644 dist/encodings/ber/decoder/EmberNode.js create mode 100644 dist/encodings/ber/decoder/EmberNode.js.map create mode 100644 dist/encodings/ber/decoder/FunctionArgument.d.ts create mode 100644 dist/encodings/ber/decoder/FunctionArgument.d.ts.map create mode 100644 dist/encodings/ber/decoder/FunctionArgument.js create mode 100644 dist/encodings/ber/decoder/FunctionArgument.js.map create mode 100644 dist/encodings/ber/decoder/Invocation.d.ts create mode 100644 dist/encodings/ber/decoder/Invocation.d.ts.map create mode 100644 dist/encodings/ber/decoder/Invocation.js create mode 100644 dist/encodings/ber/decoder/Invocation.js.map create mode 100644 dist/encodings/ber/decoder/InvocationResult.d.ts create mode 100644 dist/encodings/ber/decoder/InvocationResult.d.ts.map create mode 100644 dist/encodings/ber/decoder/InvocationResult.js create mode 100644 dist/encodings/ber/decoder/InvocationResult.js.map create mode 100644 dist/encodings/ber/decoder/Label.d.ts create mode 100644 dist/encodings/ber/decoder/Label.d.ts.map create mode 100644 dist/encodings/ber/decoder/Label.js create mode 100644 dist/encodings/ber/decoder/Label.js.map create mode 100644 dist/encodings/ber/decoder/Matrix.d.ts create mode 100644 dist/encodings/ber/decoder/Matrix.d.ts.map create mode 100644 dist/encodings/ber/decoder/Matrix.js create mode 100644 dist/encodings/ber/decoder/Matrix.js.map create mode 100644 dist/encodings/ber/decoder/Parameter.d.ts create mode 100644 dist/encodings/ber/decoder/Parameter.d.ts.map create mode 100644 dist/encodings/ber/decoder/Parameter.js create mode 100644 dist/encodings/ber/decoder/Parameter.js.map create mode 100644 dist/encodings/ber/decoder/StreamDescription.d.ts create mode 100644 dist/encodings/ber/decoder/StreamDescription.d.ts.map create mode 100644 dist/encodings/ber/decoder/StreamDescription.js create mode 100644 dist/encodings/ber/decoder/StreamDescription.js.map create mode 100644 dist/encodings/ber/decoder/StreamEntry.d.ts create mode 100644 dist/encodings/ber/decoder/StreamEntry.d.ts.map create mode 100644 dist/encodings/ber/decoder/StreamEntry.js create mode 100644 dist/encodings/ber/decoder/StreamEntry.js.map create mode 100644 dist/encodings/ber/decoder/StringIntegerCollection.d.ts create mode 100644 dist/encodings/ber/decoder/StringIntegerCollection.d.ts.map create mode 100644 dist/encodings/ber/decoder/StringIntegerCollection.js create mode 100644 dist/encodings/ber/decoder/StringIntegerCollection.js.map create mode 100644 dist/encodings/ber/decoder/Template.d.ts create mode 100644 dist/encodings/ber/decoder/Template.d.ts.map create mode 100644 dist/encodings/ber/decoder/Template.js create mode 100644 dist/encodings/ber/decoder/Template.js.map create mode 100644 dist/encodings/ber/decoder/Tree.d.ts create mode 100644 dist/encodings/ber/decoder/Tree.d.ts.map create mode 100644 dist/encodings/ber/decoder/Tree.js create mode 100644 dist/encodings/ber/decoder/Tree.js.map create mode 100644 dist/encodings/ber/encoder/Command.d.ts create mode 100644 dist/encodings/ber/encoder/Command.d.ts.map create mode 100644 dist/encodings/ber/encoder/Command.js create mode 100644 dist/encodings/ber/encoder/Command.js.map create mode 100644 dist/encodings/ber/encoder/Connection.d.ts create mode 100644 dist/encodings/ber/encoder/Connection.d.ts.map create mode 100644 dist/encodings/ber/encoder/Connection.js create mode 100644 dist/encodings/ber/encoder/Connection.js.map create mode 100644 dist/encodings/ber/encoder/EmberElement.d.ts create mode 100644 dist/encodings/ber/encoder/EmberElement.d.ts.map create mode 100644 dist/encodings/ber/encoder/EmberElement.js create mode 100644 dist/encodings/ber/encoder/EmberElement.js.map create mode 100644 dist/encodings/ber/encoder/EmberFunction.d.ts create mode 100644 dist/encodings/ber/encoder/EmberFunction.d.ts.map create mode 100644 dist/encodings/ber/encoder/EmberFunction.js create mode 100644 dist/encodings/ber/encoder/EmberFunction.js.map create mode 100644 dist/encodings/ber/encoder/EmberNode.d.ts create mode 100644 dist/encodings/ber/encoder/EmberNode.d.ts.map create mode 100644 dist/encodings/ber/encoder/EmberNode.js create mode 100644 dist/encodings/ber/encoder/EmberNode.js.map create mode 100644 dist/encodings/ber/encoder/FunctionArgument.d.ts create mode 100644 dist/encodings/ber/encoder/FunctionArgument.d.ts.map create mode 100644 dist/encodings/ber/encoder/FunctionArgument.js create mode 100644 dist/encodings/ber/encoder/FunctionArgument.js.map create mode 100644 dist/encodings/ber/encoder/Invocation.d.ts create mode 100644 dist/encodings/ber/encoder/Invocation.d.ts.map create mode 100644 dist/encodings/ber/encoder/Invocation.js create mode 100644 dist/encodings/ber/encoder/Invocation.js.map create mode 100644 dist/encodings/ber/encoder/InvocationResult.d.ts create mode 100644 dist/encodings/ber/encoder/InvocationResult.d.ts.map create mode 100644 dist/encodings/ber/encoder/InvocationResult.js create mode 100644 dist/encodings/ber/encoder/InvocationResult.js.map create mode 100644 dist/encodings/ber/encoder/Label.d.ts create mode 100644 dist/encodings/ber/encoder/Label.d.ts.map create mode 100644 dist/encodings/ber/encoder/Label.js create mode 100644 dist/encodings/ber/encoder/Label.js.map create mode 100644 dist/encodings/ber/encoder/Matrix.d.ts create mode 100644 dist/encodings/ber/encoder/Matrix.d.ts.map create mode 100644 dist/encodings/ber/encoder/Matrix.js create mode 100644 dist/encodings/ber/encoder/Matrix.js.map create mode 100644 dist/encodings/ber/encoder/Parameter.d.ts create mode 100644 dist/encodings/ber/encoder/Parameter.d.ts.map create mode 100644 dist/encodings/ber/encoder/Parameter.js create mode 100644 dist/encodings/ber/encoder/Parameter.js.map create mode 100644 dist/encodings/ber/encoder/Qualified.d.ts create mode 100644 dist/encodings/ber/encoder/Qualified.d.ts.map create mode 100644 dist/encodings/ber/encoder/Qualified.js create mode 100644 dist/encodings/ber/encoder/Qualified.js.map create mode 100644 dist/encodings/ber/encoder/RootElement.d.ts create mode 100644 dist/encodings/ber/encoder/RootElement.d.ts.map create mode 100644 dist/encodings/ber/encoder/RootElement.js create mode 100644 dist/encodings/ber/encoder/RootElement.js.map create mode 100644 dist/encodings/ber/encoder/StreamDescription.d.ts create mode 100644 dist/encodings/ber/encoder/StreamDescription.d.ts.map create mode 100644 dist/encodings/ber/encoder/StreamDescription.js create mode 100644 dist/encodings/ber/encoder/StreamDescription.js.map create mode 100644 dist/encodings/ber/encoder/StreamEntry.d.ts create mode 100644 dist/encodings/ber/encoder/StreamEntry.d.ts.map create mode 100644 dist/encodings/ber/encoder/StreamEntry.js create mode 100644 dist/encodings/ber/encoder/StreamEntry.js.map create mode 100644 dist/encodings/ber/encoder/StringIntegerCollection.d.ts create mode 100644 dist/encodings/ber/encoder/StringIntegerCollection.d.ts.map create mode 100644 dist/encodings/ber/encoder/StringIntegerCollection.js create mode 100644 dist/encodings/ber/encoder/StringIntegerCollection.js.map create mode 100644 dist/encodings/ber/encoder/Template.d.ts create mode 100644 dist/encodings/ber/encoder/Template.d.ts.map create mode 100644 dist/encodings/ber/encoder/Template.js create mode 100644 dist/encodings/ber/encoder/Template.js.map create mode 100644 dist/encodings/ber/encoder/Tree.d.ts create mode 100644 dist/encodings/ber/encoder/Tree.d.ts.map create mode 100644 dist/encodings/ber/encoder/Tree.js create mode 100644 dist/encodings/ber/encoder/Tree.js.map create mode 100644 dist/encodings/ber/index.d.ts create mode 100644 dist/encodings/ber/index.d.ts.map create mode 100644 dist/encodings/ber/index.js create mode 100644 dist/encodings/ber/index.js.map create mode 100644 dist/index.d.ts create mode 100644 dist/index.d.ts.map create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/model/Command.d.ts create mode 100644 dist/model/Command.d.ts.map create mode 100644 dist/model/Command.js create mode 100644 dist/model/Command.js.map create mode 100644 dist/model/Connection.d.ts create mode 100644 dist/model/Connection.d.ts.map create mode 100644 dist/model/Connection.js create mode 100644 dist/model/Connection.js.map create mode 100644 dist/model/EmberElement.d.ts create mode 100644 dist/model/EmberElement.d.ts.map create mode 100644 dist/model/EmberElement.js create mode 100644 dist/model/EmberElement.js.map create mode 100644 dist/model/EmberFunction.d.ts create mode 100644 dist/model/EmberFunction.d.ts.map create mode 100644 dist/model/EmberFunction.js create mode 100644 dist/model/EmberFunction.js.map create mode 100644 dist/model/EmberNode.d.ts create mode 100644 dist/model/EmberNode.d.ts.map create mode 100644 dist/model/EmberNode.js create mode 100644 dist/model/EmberNode.js.map create mode 100644 dist/model/FunctionArgument.d.ts create mode 100644 dist/model/FunctionArgument.d.ts.map create mode 100644 dist/model/FunctionArgument.js create mode 100644 dist/model/FunctionArgument.js.map create mode 100644 dist/model/Invocation.d.ts create mode 100644 dist/model/Invocation.d.ts.map create mode 100644 dist/model/Invocation.js create mode 100644 dist/model/Invocation.js.map create mode 100644 dist/model/InvocationResult.d.ts create mode 100644 dist/model/InvocationResult.d.ts.map create mode 100644 dist/model/InvocationResult.js create mode 100644 dist/model/InvocationResult.js.map create mode 100644 dist/model/Label.d.ts create mode 100644 dist/model/Label.d.ts.map create mode 100644 dist/model/Label.js create mode 100644 dist/model/Label.js.map create mode 100644 dist/model/Matrix.d.ts create mode 100644 dist/model/Matrix.d.ts.map create mode 100644 dist/model/Matrix.js create mode 100644 dist/model/Matrix.js.map create mode 100644 dist/model/Parameter.d.ts create mode 100644 dist/model/Parameter.d.ts.map create mode 100644 dist/model/Parameter.js create mode 100644 dist/model/Parameter.js.map create mode 100644 dist/model/StreamDescription.d.ts create mode 100644 dist/model/StreamDescription.d.ts.map create mode 100644 dist/model/StreamDescription.js create mode 100644 dist/model/StreamDescription.js.map create mode 100644 dist/model/StreamEntry.d.ts create mode 100644 dist/model/StreamEntry.d.ts.map create mode 100644 dist/model/StreamEntry.js create mode 100644 dist/model/StreamEntry.js.map create mode 100644 dist/model/Template.d.ts create mode 100644 dist/model/Template.d.ts.map create mode 100644 dist/model/Template.js create mode 100644 dist/model/Template.js.map create mode 100644 dist/model/Tree.d.ts create mode 100644 dist/model/Tree.d.ts.map create mode 100644 dist/model/Tree.js create mode 100644 dist/model/Tree.js.map create mode 100644 dist/model/index.d.ts create mode 100644 dist/model/index.d.ts.map create mode 100644 dist/model/index.js create mode 100644 dist/model/index.js.map create mode 100644 dist/types/index.d.ts create mode 100644 dist/types/index.d.ts.map create mode 100644 dist/types/index.js create mode 100644 dist/types/index.js.map create mode 100644 dist/types/types.d.ts create mode 100644 dist/types/types.d.ts.map create mode 100644 dist/types/types.js create mode 100644 dist/types/types.js.map diff --git a/.gitignore b/.gitignore index 2b0331f..3d886f6 100755 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ node_modules package-lock.json yarn-error.log /lib -/dist /scratch .pnp.* diff --git a/dist/Ber/BERDataTypes.d.ts b/dist/Ber/BERDataTypes.d.ts new file mode 100644 index 0000000..52dc0e6 --- /dev/null +++ b/dist/Ber/BERDataTypes.d.ts @@ -0,0 +1,20 @@ +/** ITU-TX.690 (08/2015) Chapter 8 */ +declare enum BERDataTypes { + BOOLEAN = 1, + INTEGER = 2, + BITSTRING = 3, + OCTETSTRING = 4, + NULL = 5, + OBJECTIDENTIFIER = 6, + OBJECTDESCRIPTOR = 7, + EXTERNAL = 8, + REAL = 9, + ENUMERATED = 10, + EMBEDDED = 11, + STRING = 12, + RELATIVE_OID = 13, + SEQUENCE = 48, + SET = 49 +} +export { BERDataTypes }; +//# sourceMappingURL=BERDataTypes.d.ts.map \ No newline at end of file diff --git a/dist/Ber/BERDataTypes.d.ts.map b/dist/Ber/BERDataTypes.d.ts.map new file mode 100644 index 0000000..aac91c0 --- /dev/null +++ b/dist/Ber/BERDataTypes.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"BERDataTypes.d.ts","sourceRoot":"","sources":["../../src/Ber/BERDataTypes.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,aAAK,YAAY;IAChB,OAAO,IAAI;IACX,OAAO,IAAI;IACX,SAAS,IAAI;IACb,WAAW,IAAI;IACf,IAAI,IAAI;IACR,gBAAgB,IAAI;IACpB,gBAAgB,IAAI;IACpB,QAAQ,IAAI;IACZ,IAAI,IAAI;IACR,UAAU,KAAK;IACf,QAAQ,KAAK;IACb,MAAM,KAAK;IACX,YAAY,KAAK;IACjB,QAAQ,KAAY;IACpB,GAAG,KAAY;CACf;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"} \ No newline at end of file diff --git a/dist/Ber/BERDataTypes.js b/dist/Ber/BERDataTypes.js new file mode 100644 index 0000000..0d039e1 --- /dev/null +++ b/dist/Ber/BERDataTypes.js @@ -0,0 +1,24 @@ +"use strict"; +/** ITU-TX.690 (08/2015) Chapter 8 */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BERDataTypes = void 0; +var BERDataTypes; +(function (BERDataTypes) { + BERDataTypes[BERDataTypes["BOOLEAN"] = 1] = "BOOLEAN"; + BERDataTypes[BERDataTypes["INTEGER"] = 2] = "INTEGER"; + BERDataTypes[BERDataTypes["BITSTRING"] = 3] = "BITSTRING"; + BERDataTypes[BERDataTypes["OCTETSTRING"] = 4] = "OCTETSTRING"; + BERDataTypes[BERDataTypes["NULL"] = 5] = "NULL"; + BERDataTypes[BERDataTypes["OBJECTIDENTIFIER"] = 6] = "OBJECTIDENTIFIER"; + BERDataTypes[BERDataTypes["OBJECTDESCRIPTOR"] = 7] = "OBJECTDESCRIPTOR"; + BERDataTypes[BERDataTypes["EXTERNAL"] = 8] = "EXTERNAL"; + BERDataTypes[BERDataTypes["REAL"] = 9] = "REAL"; + BERDataTypes[BERDataTypes["ENUMERATED"] = 10] = "ENUMERATED"; + BERDataTypes[BERDataTypes["EMBEDDED"] = 11] = "EMBEDDED"; + BERDataTypes[BERDataTypes["STRING"] = 12] = "STRING"; + BERDataTypes[BERDataTypes["RELATIVE_OID"] = 13] = "RELATIVE_OID"; + BERDataTypes[BERDataTypes["SEQUENCE"] = 48] = "SEQUENCE"; + BERDataTypes[BERDataTypes["SET"] = 49] = "SET"; +})(BERDataTypes || (BERDataTypes = {})); +exports.BERDataTypes = BERDataTypes; +//# sourceMappingURL=BERDataTypes.js.map \ No newline at end of file diff --git a/dist/Ber/BERDataTypes.js.map b/dist/Ber/BERDataTypes.js.map new file mode 100644 index 0000000..ca73c62 --- /dev/null +++ b/dist/Ber/BERDataTypes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"BERDataTypes.js","sourceRoot":"","sources":["../../src/Ber/BERDataTypes.ts"],"names":[],"mappings":";AAAA,sCAAsC;;;AAEtC,IAAK,YAgBJ;AAhBD,WAAK,YAAY;IAChB,qDAAW,CAAA;IACX,qDAAW,CAAA;IACX,yDAAa,CAAA;IACb,6DAAe,CAAA;IACf,+CAAQ,CAAA;IACR,uEAAoB,CAAA;IACpB,uEAAoB,CAAA;IACpB,uDAAY,CAAA;IACZ,+CAAQ,CAAA;IACR,4DAAe,CAAA;IACf,wDAAa,CAAA;IACb,oDAAW,CAAA;IACX,gEAAiB,CAAA;IACjB,wDAAoB,CAAA;IACpB,8CAAe,CAAA;AAChB,CAAC,EAhBI,YAAY,KAAZ,YAAY,QAgBhB;AAEQ,oCAAY"} \ No newline at end of file diff --git a/dist/Ber/Reader.d.ts b/dist/Ber/Reader.d.ts new file mode 100644 index 0000000..96f9857 --- /dev/null +++ b/dist/Ber/Reader.d.ts @@ -0,0 +1,10 @@ +/// +import { Reader } from 'asn1'; +import { EmberTypedValue } from '../types/types'; +export { ExtendedReader as Reader }; +declare class ExtendedReader extends Reader { + constructor(data: Buffer); + readValue(): EmberTypedValue; + readReal(tag?: number): number | null; +} +//# sourceMappingURL=Reader.d.ts.map \ No newline at end of file diff --git a/dist/Ber/Reader.d.ts.map b/dist/Ber/Reader.d.ts.map new file mode 100644 index 0000000..b4b60ff --- /dev/null +++ b/dist/Ber/Reader.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Reader.d.ts","sourceRoot":"","sources":["../../src/Ber/Reader.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAK7B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGhD,OAAO,EAAE,cAAc,IAAI,MAAM,EAAE,CAAA;AAEnC,cAAM,cAAe,SAAQ,MAAM;gBACtB,IAAI,EAAE,MAAM;IAUxB,SAAS,IAAI,eAAe;IA4B5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CA2ErC"} \ No newline at end of file diff --git a/dist/Ber/Reader.js b/dist/Ber/Reader.js new file mode 100644 index 0000000..1070c86 --- /dev/null +++ b/dist/Ber/Reader.js @@ -0,0 +1,106 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Reader = void 0; +const tslib_1 = require("tslib"); +const asn1_1 = require("asn1"); +const long_1 = tslib_1.__importDefault(require("long")); +const Errors_1 = require("../Errors"); +const BERDataTypes_1 = require("./BERDataTypes"); +const functions_1 = require("./functions"); +const Parameter_1 = require("../model/Parameter"); +class ExtendedReader extends asn1_1.Reader { + constructor(data) { + super(data); + } + // This is bad. No need to create a new reader for every tag! + // getSequence(tag: number): ExtendedReader { + // const buf = this.readString(tag, true) + // return new ExtendedReader(buf) + // } + readValue() { + const tag = this.peek(); + if (!tag) { + throw new Error('No tag available'); + } + switch (tag) { + case BERDataTypes_1.BERDataTypes.STRING: + return { type: Parameter_1.ParameterType.String, value: this.readString(BERDataTypes_1.BERDataTypes.STRING) }; + case BERDataTypes_1.BERDataTypes.INTEGER: + return { type: Parameter_1.ParameterType.Integer, value: this.readInt() }; + case BERDataTypes_1.BERDataTypes.REAL: + return { type: Parameter_1.ParameterType.Real, value: this.readReal() }; + case BERDataTypes_1.BERDataTypes.BOOLEAN: + return { type: Parameter_1.ParameterType.Boolean, value: this.readBoolean() }; + case BERDataTypes_1.BERDataTypes.OCTETSTRING: + return { type: Parameter_1.ParameterType.Octets, value: this.readString((0, functions_1.UNIVERSAL)(4), true) }; + case BERDataTypes_1.BERDataTypes.RELATIVE_OID: + return { type: Parameter_1.ParameterType.String, value: this.readOID(BERDataTypes_1.BERDataTypes.RELATIVE_OID) }; + case BERDataTypes_1.BERDataTypes.NULL: // Note: No readNull in BER library but writer writes 2 bytes + this.readByte(false); // Read past - ASN1.NULL tag 0x05 + this.readByte(false); // and - 0x00 length + return { type: Parameter_1.ParameterType.Null, value: null }; + default: + throw new Errors_1.UnimplementedEmberTypeError(tag); + } + } + readReal(tag) { + if (tag !== null) { + tag = (0, functions_1.UNIVERSAL)(9); + } + const b = this.peek(); + if (b === null) { + return null; + } + const buf = this.readString(b, true); + if (buf.length === 0) { + return 0; + } + const preamble = buf.readUInt8(0); + let o = 1; + if (buf.length === 1) { + switch (preamble) { + case 0x40: + return Infinity; + case 0x41: + return -Infinity; + case 0x42: + return NaN; + } + } + const sign = preamble & 0x40 ? -1 : 1; + const exponentLength = 1 + (preamble & 3); + const significandShift = (preamble >> 2) & 3; + let exponent = 0; + if (buf.readUInt8(o) & 0x80) { + exponent = -1; + } + if (buf.length - o < exponentLength) { + throw new Errors_1.ASN1Error('Invalid ASN.1; not enough length to contain exponent'); + } + for (let i = 0; i < exponentLength; i++) { + exponent = (exponent << 8) | buf.readUInt8(o++); + } + let significand = new long_1.default(0, 0, true); + while (o < buf.length) { + significand = significand.shl(8).or(buf.readUInt8(o++)); + } + significand = significand.shl(significandShift); + while (significand.and(long_1.default.fromBits(0x00000000, 0x7ffff000, true)).eq(0)) { + significand = significand.shl(8); + } + while (significand.and(long_1.default.fromBits(0x00000000, 0x7ff00000, true)).eq(0)) { + significand = significand.shl(1); + } + significand = significand.and(long_1.default.fromBits(0xffffffff, 0x000fffff, true)); + let bits = long_1.default.fromNumber(exponent).add(1023).shl(52).or(significand); + if (sign < 0) { + bits = bits.or(long_1.default.fromBits(0x00000000, 0x80000000, true)); + } + const fbuf = Buffer.alloc(8); + fbuf.writeUInt32LE(bits.getLowBitsUnsigned(), 0); + fbuf.writeUInt32LE(bits.getHighBitsUnsigned(), 4); + return fbuf.readDoubleLE(0); + } +} +exports.Reader = ExtendedReader; +//# sourceMappingURL=Reader.js.map \ No newline at end of file diff --git a/dist/Ber/Reader.js.map b/dist/Ber/Reader.js.map new file mode 100644 index 0000000..f98ff2d --- /dev/null +++ b/dist/Ber/Reader.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Reader.js","sourceRoot":"","sources":["../../src/Ber/Reader.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ber/Writer.d.ts b/dist/Ber/Writer.d.ts new file mode 100644 index 0000000..bed6d60 --- /dev/null +++ b/dist/Ber/Writer.d.ts @@ -0,0 +1,13 @@ +import { Writer, WriterOptions } from 'asn1'; +import { Parameter } from '../model/Parameter'; +import { EmberValue, EmberTypedValue } from '../types/types'; +export { ExtendedWriter as Writer }; +declare class ExtendedWriter extends Writer { + constructor(options?: WriterOptions); + writeReal(value: number, tag: number): void; + writeValue(value: EmberValue, tag?: number): void; + writeValue(typedValue: EmberTypedValue): void; + writeEmberParameter(value: Parameter): void; + writeIfDefined(property: T | undefined, writer: (value: T, tag: number) => void, outer: number, inner: number): void; +} +//# sourceMappingURL=Writer.d.ts.map \ No newline at end of file diff --git a/dist/Ber/Writer.d.ts.map b/dist/Ber/Writer.d.ts.map new file mode 100644 index 0000000..abe7295 --- /dev/null +++ b/dist/Ber/Writer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Writer.d.ts","sourceRoot":"","sources":["../../src/Ber/Writer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAI5C,OAAO,EAAE,SAAS,EAA8B,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE5D,OAAO,EAAE,cAAc,IAAI,MAAM,EAAE,CAAA;AAEnC,cAAM,cAAe,SAAQ,MAAM;gBACtB,OAAO,CAAC,EAAE,aAAa;IAInC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAwE3C,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IACjD,UAAU,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IA2D7C,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAkC3C,cAAc,CAAC,CAAC,EACf,QAAQ,EAAE,CAAC,GAAG,SAAS,EACvB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EACvC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACX,IAAI;CAOP"} \ No newline at end of file diff --git a/dist/Ber/Writer.js b/dist/Ber/Writer.js new file mode 100644 index 0000000..92f6002 --- /dev/null +++ b/dist/Ber/Writer.js @@ -0,0 +1,208 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Writer = void 0; +const tslib_1 = require("tslib"); +const long_1 = tslib_1.__importDefault(require("long")); +const asn1_1 = require("asn1"); +const functions_1 = require("./functions"); +const BERDataTypes_1 = require("./BERDataTypes"); +const Parameter_1 = require("../model/Parameter"); +class ExtendedWriter extends asn1_1.Writer { + constructor(options) { + super(options); + } + writeReal(value, tag) { + if (tag === undefined) { + tag = (0, functions_1.UNIVERSAL)(9); + } + this.writeByte(tag); + switch (value) { + case 0: + this.writeLength(0); + return; + case Infinity: + this.writeLength(1); + this.writeByte(0x40); + return; + case -Infinity: + this.writeLength(1); + this.writeByte(0x41); + return; + default: + if (isNaN(value)) { + this.writeLength(1); + this.writeByte(0x42); + return; + } + } + const fbuf = Buffer.alloc(8); + fbuf.writeDoubleLE(value, 0); + const bits = long_1.default.fromBits(fbuf.readUInt32LE(0), fbuf.readUInt32LE(4), true); + let significand = bits + .and(long_1.default.fromBits(0xffffffff, 0x000fffff, true)) + .or(long_1.default.fromBits(0x00000000, 0x00100000, true)); + let exponent = bits + .and(long_1.default.fromBits(0x00000000, 0x7ff00000, true)) + .shru(52) + .sub(1023) + .toSigned(); + while (significand.and(0xff).toNumber() === 0) { + significand = significand.shru(8); + } + while (significand.and(0x01).toNumber() === 0) { + significand = significand.shru(1); + } + exponent = exponent.toNumber(); + const shortExp = shorten(exponent); + const shortSig = shortenLong(significand); + this.writeLength(1 + shortExp.size + shortSig.size); + const preamble = value < 0 ? 0x80 | 0x40 : 0x80; // in what case will 0x80|0x40 be anything but 0xC0? + this.writeByte(preamble); + for (let i = 0; i < shortExp.size; i++) { + this.writeByte((shortExp.value & 0xff000000) >> 24); + shortExp.value <<= 8; + } + const mask = long_1.default.fromBits(0x00000000, 0xff000000, true); + for (let i = 0; i < shortSig.size; i++) { + this.writeByte(shortSig.value.and(mask).shru(56).toNumber()); + shortSig.value = shortSig.value.shl(8); + } + } + writeValue(arg1, tag) { + let value; + if (arg1 && typeof arg1 === 'object' && 'type' in arg1) { + value = arg1.value; + tag = parameterTypetoBERTAG(arg1.type); + } + else { + value = arg1; + } + if (tag === BERDataTypes_1.BERDataTypes.NULL && (value === null || value === undefined)) { + this.writeNull(); + return; + } + if (value === null || value === undefined) { + this.writeNull(); + return; + } + if (typeof value === 'number') { + if (tag !== BERDataTypes_1.BERDataTypes.REAL && Number.isInteger(value)) { + if (tag === undefined) { + tag = BERDataTypes_1.BERDataTypes.INTEGER; + } + this.writeInt(value, tag); + return; + } + if (tag === undefined) { + tag = BERDataTypes_1.BERDataTypes.REAL; + } + this.writeReal(value, tag); + return; + } + if (typeof value == 'boolean') { + if (tag === undefined) { + tag = BERDataTypes_1.BERDataTypes.BOOLEAN; + } + this.writeBoolean(value, tag); + return; + } + if (Buffer.isBuffer(value) && tag) { + if (value.length === 0) { + this.writeByte(tag); + this.writeLength(0); + } + else { + this.writeBuffer(value, tag); + } + return; + } + if (tag === undefined) { + tag = BERDataTypes_1.BERDataTypes.STRING; + } + this.writeString(value.toString(), tag); + } + writeEmberParameter(value) { + if ((0, Parameter_1.isParameter)(value)) { + switch (value.parameterType) { + case Parameter_1.ParameterType.Real: + this.writeReal(value.value, BERDataTypes_1.BERDataTypes.REAL); + break; + case Parameter_1.ParameterType.Integer: + this.writeInt(value.value, BERDataTypes_1.BERDataTypes.INTEGER); + break; + case Parameter_1.ParameterType.Boolean: + this.writeBoolean(value.value, BERDataTypes_1.BERDataTypes.BOOLEAN); + break; + case Parameter_1.ParameterType.Octets: + if (!Buffer.isBuffer(value.value)) { + value.value = Buffer.from(`${value.value}`); + } + if (value.value.length) { + this.writeByte(BERDataTypes_1.BERDataTypes.OCTETSTRING); + this.writeLength(0); + } + else { + this.writeBuffer(value.value, BERDataTypes_1.BERDataTypes.OCTETSTRING); + } + break; + case Parameter_1.ParameterType.Null: + this.writeNull(); + break; + default: + this.writeString(value.value, BERDataTypes_1.BERDataTypes.STRING); + } + } + else { + this.writeValue(value.value, undefined); + } + } + writeIfDefined(property, writer, outer, inner) { + if (property != null) { + this.startSequence((0, functions_1.CONTEXT)(outer)); + writer.call(this, property, inner); + this.endSequence(); + } + } +} +exports.Writer = ExtendedWriter; +function shorten(value) { + let size = 4; + while (((value & 0xff800000) === 0 || (value & 0xff800000) === 0xff800000 >> 0) && size > 1) { + size--; + value <<= 8; + } + return { size, value }; +} +function shortenLong(value) { + const mask = long_1.default.fromBits(0x00000000, 0xff800000, true); + value = value.toUnsigned(); + let size = 8; + while (value.and(mask).eq(0) || (value.and(mask).eq(mask) && size > 1)) { + size--; + value = value.shl(8); + } + return { size, value }; +} +function parameterTypetoBERTAG(parameterType) { + switch (parameterType) { + case Parameter_1.ParameterType.Integer: + return BERDataTypes_1.BERDataTypes.INTEGER; + case Parameter_1.ParameterType.Real: + return BERDataTypes_1.BERDataTypes.REAL; + case Parameter_1.ParameterType.String: + return BERDataTypes_1.BERDataTypes.STRING; + case Parameter_1.ParameterType.Boolean: + return BERDataTypes_1.BERDataTypes.BOOLEAN; + case Parameter_1.ParameterType.Trigger: + return BERDataTypes_1.BERDataTypes.STRING; // TODO: this is a guess + case Parameter_1.ParameterType.Enum: + return BERDataTypes_1.BERDataTypes.ENUMERATED; + case Parameter_1.ParameterType.Octets: + return BERDataTypes_1.BERDataTypes.OCTETSTRING; + case Parameter_1.ParameterType.Null: + return BERDataTypes_1.BERDataTypes.NULL; + default: + throw new Error(``); + } +} +//# sourceMappingURL=Writer.js.map \ No newline at end of file diff --git a/dist/Ber/Writer.js.map b/dist/Ber/Writer.js.map new file mode 100644 index 0000000..32edf57 --- /dev/null +++ b/dist/Ber/Writer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Writer.js","sourceRoot":"","sources":["../../src/Ber/Writer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ber/functions.d.ts b/dist/Ber/functions.d.ts new file mode 100644 index 0000000..5e2d753 --- /dev/null +++ b/dist/Ber/functions.d.ts @@ -0,0 +1,6 @@ +/** ITU-TX.690 (08/2015) 8.1.2 */ +declare function APPLICATION(x: number): number; +declare function CONTEXT(x: number): number; +declare function UNIVERSAL(x: number): number; +export { APPLICATION, CONTEXT, UNIVERSAL }; +//# sourceMappingURL=functions.d.ts.map \ No newline at end of file diff --git a/dist/Ber/functions.d.ts.map b/dist/Ber/functions.d.ts.map new file mode 100644 index 0000000..7740b1b --- /dev/null +++ b/dist/Ber/functions.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/Ber/functions.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,iBAAS,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtC;AACD,iBAAS,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAElC;AACD,iBAAS,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpC;AAED,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA"} \ No newline at end of file diff --git a/dist/Ber/functions.js b/dist/Ber/functions.js new file mode 100644 index 0000000..14f351c --- /dev/null +++ b/dist/Ber/functions.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UNIVERSAL = exports.CONTEXT = exports.APPLICATION = void 0; +/** ITU-TX.690 (08/2015) 8.1.2 */ +function APPLICATION(x) { + return x | 0x60; +} +exports.APPLICATION = APPLICATION; +function CONTEXT(x) { + return x | 0xa0; +} +exports.CONTEXT = CONTEXT; +function UNIVERSAL(x) { + return x; +} +exports.UNIVERSAL = UNIVERSAL; +//# sourceMappingURL=functions.js.map \ No newline at end of file diff --git a/dist/Ber/functions.js.map b/dist/Ber/functions.js.map new file mode 100644 index 0000000..0073b0f --- /dev/null +++ b/dist/Ber/functions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/Ber/functions.ts"],"names":[],"mappings":";;;AAAA,kCAAkC;AAClC,SAAS,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,GAAG,IAAI,CAAA;AAChB,CAAC;AAQQ,kCAAW;AAPpB,SAAS,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,GAAG,IAAI,CAAA;AAChB,CAAC;AAKqB,0BAAO;AAJ7B,SAAS,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAA;AACT,CAAC;AAE8B,8BAAS"} \ No newline at end of file diff --git a/dist/Ber/index.d.ts b/dist/Ber/index.d.ts new file mode 100644 index 0000000..fe863d9 --- /dev/null +++ b/dist/Ber/index.d.ts @@ -0,0 +1,6 @@ +import { Reader } from './Reader'; +import { Writer } from './Writer'; +import { BERDataTypes } from './BERDataTypes'; +import { APPLICATION, CONTEXT, UNIVERSAL } from './functions'; +export { Reader, Writer, BERDataTypes, APPLICATION, CONTEXT, UNIVERSAL }; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/Ber/index.d.ts.map b/dist/Ber/index.d.ts.map new file mode 100644 index 0000000..9871548 --- /dev/null +++ b/dist/Ber/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Ber/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA"} \ No newline at end of file diff --git a/dist/Ber/index.js b/dist/Ber/index.js new file mode 100644 index 0000000..235d5a1 --- /dev/null +++ b/dist/Ber/index.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UNIVERSAL = exports.CONTEXT = exports.APPLICATION = exports.BERDataTypes = exports.Writer = exports.Reader = void 0; +const Reader_1 = require("./Reader"); +Object.defineProperty(exports, "Reader", { enumerable: true, get: function () { return Reader_1.Reader; } }); +const Writer_1 = require("./Writer"); +Object.defineProperty(exports, "Writer", { enumerable: true, get: function () { return Writer_1.Writer; } }); +const BERDataTypes_1 = require("./BERDataTypes"); +Object.defineProperty(exports, "BERDataTypes", { enumerable: true, get: function () { return BERDataTypes_1.BERDataTypes; } }); +const functions_1 = require("./functions"); +Object.defineProperty(exports, "APPLICATION", { enumerable: true, get: function () { return functions_1.APPLICATION; } }); +Object.defineProperty(exports, "CONTEXT", { enumerable: true, get: function () { return functions_1.CONTEXT; } }); +Object.defineProperty(exports, "UNIVERSAL", { enumerable: true, get: function () { return functions_1.UNIVERSAL; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/Ber/index.js.map b/dist/Ber/index.js.map new file mode 100644 index 0000000..48c88f2 --- /dev/null +++ b/dist/Ber/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Ber/index.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AAKxB,uFALA,eAAM,OAKA;AAJf,qCAAiC;AAIhB,uFAJR,eAAM,OAIQ;AAHvB,iDAA6C;AAGpB,6FAHhB,2BAAY,OAGgB;AAFrC,2CAA6D;AAEtB,4FAF9B,uBAAW,OAE8B;AAAE,wFAF9B,mBAAO,OAE8B;AAAE,0FAF9B,qBAAS,OAE8B"} \ No newline at end of file diff --git a/dist/Ember/Client/StreamManager.d.ts b/dist/Ember/Client/StreamManager.d.ts new file mode 100644 index 0000000..5c9f791 --- /dev/null +++ b/dist/Ember/Client/StreamManager.d.ts @@ -0,0 +1,28 @@ +import { EventEmitter } from 'eventemitter3'; +import { Parameter } from '../../model/Parameter'; +import { EmberValue } from '../../types'; +import { Collection } from '../../types/types'; +import { StreamEntry } from '../../model'; +export type StreamManagerEvents = { + streamUpdate: [path: string, value: EmberValue]; +}; +interface StreamInfo { + parameter: Parameter; + path: string; + streamIdentifier: number; + offset: number; +} +export declare class StreamManager extends EventEmitter { + private registeredStreams; + constructor(); + registerParameter(parameter: Parameter, path: string): void; + unregisterParameter(path: string): void; + getStreamInfoByPath(path: string): StreamInfo | undefined; + hasStream(identifier: string): boolean; + updateAllStreamValues(streamEntries: Collection): void; + updateStreamValue(path: string, value: EmberValue): void; + getAllRegisteredPaths(): string[]; + printStreamState(): void; +} +export {}; +//# sourceMappingURL=StreamManager.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Client/StreamManager.d.ts.map b/dist/Ember/Client/StreamManager.d.ts.map new file mode 100644 index 0000000..69c2019 --- /dev/null +++ b/dist/Ember/Client/StreamManager.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamManager.d.ts","sourceRoot":"","sources":["../../../src/Ember/Client/StreamManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAiB,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,MAAM,mBAAmB,GAAG;IACjC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAA;CAC/C,CAAA;AAED,UAAU,UAAU;IACnB,SAAS,EAAE,SAAS,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,gBAAgB,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;CACd;AAED,qBAAa,aAAc,SAAQ,YAAY,CAAC,mBAAmB,CAAC;IACnE,OAAO,CAAC,iBAAiB,CAAqC;;IAMvD,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAwB3D,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAWvC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIzD,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAItC,qBAAqB,CAAC,aAAa,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI;IA6BnE,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAUxD,qBAAqB,IAAI,MAAM,EAAE;IAKjC,gBAAgB,IAAI,IAAI;CAU/B"} \ No newline at end of file diff --git a/dist/Ember/Client/StreamManager.js b/dist/Ember/Client/StreamManager.js new file mode 100644 index 0000000..7bffb95 --- /dev/null +++ b/dist/Ember/Client/StreamManager.js @@ -0,0 +1,98 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.StreamManager = void 0; +const eventemitter3_1 = require("eventemitter3"); +const Parameter_1 = require("../../model/Parameter"); +class StreamManager extends eventemitter3_1.EventEmitter { + constructor() { + super(); + this.registeredStreams = new Map(); + } + registerParameter(parameter, path) { + if (!parameter.streamIdentifier) { + return; + } + const offset = parameter.streamDescriptor?.offset || 0; + const streamInfo = { + parameter, + path, + streamIdentifier: parameter.streamIdentifier, + offset: offset, + }; + // Store both mappings + this.registeredStreams.set(path, streamInfo); + console.log('Registered stream:', { + path: path, + identifier: parameter.identifier, + offset: offset, + }); + } + unregisterParameter(path) { + const streamInfo = this.registeredStreams.get(path); + if (streamInfo && streamInfo.parameter.streamIdentifier) { + this.registeredStreams.delete(path); + console.log('Unregistered stream:', { + path: path, + identifier: streamInfo.parameter.identifier, + }); + } + } + getStreamInfoByPath(path) { + return this.registeredStreams.get(path); + } + hasStream(identifier) { + return this.registeredStreams.has(identifier); + } + updateAllStreamValues(streamEntries) { + Object.values(streamEntries).forEach((streamEntry) => { + this.registeredStreams.forEach((streamInfo, path) => { + // Only process if IDs match + if (streamInfo.streamIdentifier === streamEntry.identifier) { + if (streamEntry.value) { + const value = streamEntry.value; + if (value.type === Parameter_1.ParameterType.Integer) { + // Handle direct integer values + this.updateStreamValue(path, value.value); + } + else if (value.type === Parameter_1.ParameterType.Octets && Buffer.isBuffer(value.value)) { + // Handle existing float32 buffer case + const buffer = value.value; + if (buffer.length >= streamInfo.offset + 4) { + // Float32 is 4 bytes + const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.length); + // decode as little-endian + const decodedValue = view.getFloat32(streamInfo.offset, true); + this.updateStreamValue(path, decodedValue); + } + } + } + } + }); + }); + } + updateStreamValue(path, value) { + if (path) { + const streamInfo = this.registeredStreams.get(path); + if (streamInfo) { + streamInfo.parameter.value = value; + this.emit('streamUpdate', path, value); + } + } + } + getAllRegisteredPaths() { + return Array.from(this.registeredStreams.keys()); + } + // Debug helper + printStreamState() { + console.log('\nCurrent Stream State:'); + console.log('Registered Streams:'); + this.registeredStreams.forEach((info, path) => { + console.log(` Path: ${path}`); + console.log(` Identifier: ${info.parameter.identifier}`); + console.log(` StreamId: ${info.parameter.streamIdentifier}`); + console.log(` Current Value: ${info.parameter.value}`); + }); + } +} +exports.StreamManager = StreamManager; +//# sourceMappingURL=StreamManager.js.map \ No newline at end of file diff --git a/dist/Ember/Client/StreamManager.js.map b/dist/Ember/Client/StreamManager.js.map new file mode 100644 index 0000000..a96e3d8 --- /dev/null +++ b/dist/Ember/Client/StreamManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamManager.js","sourceRoot":"","sources":["../../../src/Ember/Client/StreamManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ember/Client/index.d.ts b/dist/Ember/Client/index.d.ts new file mode 100644 index 0000000..aab4ffb --- /dev/null +++ b/dist/Ember/Client/index.d.ts @@ -0,0 +1,111 @@ +/// +import { EmberValue, RootElement, QualifiedElement, TreeElement, NumberedTreeNode, EmberTypedValue, Collection, Root } from '../../types/types'; +import { InvocationResult } from '../../model/InvocationResult'; +import { Matrix } from '../../model/Matrix'; +import { EmberElement } from '../../model/EmberElement'; +import { FieldFlags } from '../../model/Command'; +import { Parameter } from '../../model/Parameter'; +import { EventEmitter } from 'eventemitter3'; +import { EmberFunction } from '../../model/EmberFunction'; +export type RequestPromise = Promise>; +export interface RequestPromiseArguments { + sentOk: boolean; + reqId?: string; + cancel?: () => void; + response?: Promise; +} +export declare enum ExpectResponse { + None = "none", + Any = "any", + HasChildren = "has-children" +} +export interface Request { + reqId: string; + node: RootElement; + nodeResponse: ExpectResponse; + resolve: (res: any) => void; + reject: (err: Error) => void; + cb?: (EmberNode: TreeElement) => void; + message: Buffer; + firstSent: number; + lastSent: number; +} +export interface Subscription { + path: string | undefined; + cb: (EmberNode: TreeElement) => void; +} +export interface Change { + path: string | undefined; + node: RootElement; + emptyNode?: boolean; +} +export declare enum ConnectionStatus { + Error = 0, + Disconnected = 1, + Connecting = 2, + Connected = 3 +} +export type EmberClientEvents = { + error: [Error]; + warn: [Error]; + connected: []; + disconnected: []; + streamUpdate: [path: string, value: EmberValue]; +}; +export declare class EmberClient extends EventEmitter { + host: string; + port: number; + tree: Collection>; + private _streamManager; + private _requests; + private _lastInvocation; + private _client; + private _subscriptions; + private _timeout; + private _resendTimeout; + private _resends; + private _timer; + constructor(host: string, port?: number, timeout?: number, enableResends?: boolean, resendTimeout?: number); + /** + * Opens an s101 socket to the provider. + * @param host The host of the emberplus provider + * @param port Port of the provider + */ + connect(host?: string, port?: number): Promise; + /** + * Closes the s101 socket to the provider + */ + disconnect(): Promise; + /** + * Discards any outgoing connections, removes all requests and clears any timing loops + * + * This is destructive, using this class after discarding will cause errors. + */ + discard(): void; + get connected(): boolean; + /** Ember+ commands: */ + getDirectory(node: RootElement | Collection, dirFieldMask?: FieldFlags, cb?: (EmberNode: TreeElement) => void): RequestPromise; + subscribe(node: RootElement | Array, cb?: (EmberNode: TreeElement) => void): RequestPromise; + unsubscribe(node: NumberedTreeNode | Array): RequestPromise; + invoke(node: NumberedTreeNode | QualifiedElement, ...args: Array): RequestPromise; + /** Sending ember+ values */ + setValue(node: QualifiedElement | NumberedTreeNode, value: EmberValue, awaitResponse?: boolean): RequestPromise>; + matrixConnect(matrix: QualifiedElement | NumberedTreeNode, target: number, sources: Array): RequestPromise>; + matrixDisconnect(matrix: QualifiedElement | NumberedTreeNode, target: number, sources: Array): RequestPromise>; + matrixSetConnection(matrix: QualifiedElement | NumberedTreeNode, target: number, sources: Array): RequestPromise>; + /** Getting the tree: */ + expand(node: NumberedTreeNode | Collection): Promise; + getElementByPath(path: string, cb?: (EmberNode: TreeElement) => void, delimiter?: string): Promise | undefined>; + getInternalNodePath(node: TreeElement): string | undefined; + private _matrixMutation; + private _sendCommand; + private _sendRequest; + private _handleIncoming; + private _applyRootToTree; + private _updateTree; + private _updateEmberNode; + private _updateParameter; + private _updateMatrix; + private _resendTimer; +} +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Client/index.d.ts.map b/dist/Ember/Client/index.d.ts.map new file mode 100644 index 0000000..70e36bf --- /dev/null +++ b/dist/Ember/Client/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Ember/Client/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ember/Client/index.js b/dist/Ember/Client/index.js new file mode 100644 index 0000000..4caa0f4 --- /dev/null +++ b/dist/Ember/Client/index.js @@ -0,0 +1,616 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EmberClient = exports.ConnectionStatus = exports.ExpectResponse = void 0; +const types_1 = require("../../types/types"); +const EmberElement_1 = require("../../model/EmberElement"); +const Command_1 = require("../../model/Command"); +const Connection_1 = require("../../model/Connection"); +const eventemitter3_1 = require("eventemitter3"); +const Socket_1 = require("../Socket"); +const util_1 = require("../Lib/util"); +const ber_1 = require("../../encodings/ber"); +const Tree_1 = require("../../model/Tree"); +const StreamManager_1 = require("./StreamManager"); +var ExpectResponse; +(function (ExpectResponse) { + ExpectResponse["None"] = "none"; + ExpectResponse["Any"] = "any"; + ExpectResponse["HasChildren"] = "has-children"; +})(ExpectResponse = exports.ExpectResponse || (exports.ExpectResponse = {})); +var ConnectionStatus; +(function (ConnectionStatus) { + ConnectionStatus[ConnectionStatus["Error"] = 0] = "Error"; + ConnectionStatus[ConnectionStatus["Disconnected"] = 1] = "Disconnected"; + ConnectionStatus[ConnectionStatus["Connecting"] = 2] = "Connecting"; + ConnectionStatus[ConnectionStatus["Connected"] = 3] = "Connected"; +})(ConnectionStatus = exports.ConnectionStatus || (exports.ConnectionStatus = {})); +class EmberClient extends eventemitter3_1.EventEmitter { + constructor(host, port = 9000, timeout = 3000, enableResends = false, resendTimeout = 1000) { + super(); + this.tree = []; + this._requests = new Map(); + this._lastInvocation = 0; + this._subscriptions = []; + this._timeout = 3000; + this._resendTimeout = 1000; + this._resends = false; + this.host = host; + this.port = port; + this._timeout = timeout; + this._resendTimeout = resendTimeout; + this._resends = enableResends; + this._streamManager = new StreamManager_1.StreamManager(); + // Forward stream events from StreamManager + this._streamManager.on('streamUpdate', (path, value) => { + this.emit('streamUpdate', path, value); + }); + // resend timer runs at greatest common divisor of timeouts and resends + const findGcd = (a, b) => { + // assuming a and b are greater than 0 + while (b) { + const t = b; + b = a % b; + a = t; + } + return a; + }; + this._timer = setInterval(() => this._resendTimer(), findGcd(this._timeout, this._resendTimeout)); + this._client = new Socket_1.S101Client(this.host, this.port); + this._client.on('emberTree', (tree) => { + // Regular ember tree + this._handleIncoming(tree); + }); + this._client.on('emberStreamTree', (tree) => { + // Ember Tree with Stream + const entries = tree.value; + this._streamManager.updateAllStreamValues(entries); + }); + this._client.on('error', (e) => this.emit('error', e)); + this._client.on('connected', () => this.emit('connected')); + this._client.on('disconnected', () => { + this._requests.forEach((req) => { + req.reject(new Error('Socket was disconnected')); + this._requests.delete(req.reqId); + }); + this.emit('disconnected'); + }); + } + /** + * Opens an s101 socket to the provider. + * @param host The host of the emberplus provider + * @param port Port of the provider + */ + async connect(host, port) { + if (host) + this.host = host; + if (port) + this.port = port; + if (!this.host) + return Promise.reject('No host specified'); + this._client.address = this.host; + this._client.port = this.port; + return this._client.connect(); + } + /** + * Closes the s101 socket to the provider + */ + async disconnect() { + return this._client.disconnect(); + } + /** + * Discards any outgoing connections, removes all requests and clears any timing loops + * + * This is destructive, using this class after discarding will cause errors. + */ + discard() { + this.disconnect().catch(() => null); // we're not worried about errors after this + this._client.removeAllListeners(); + // @ts-expect-error: after using this method, properties are no longer expected to always exist + delete this._client; + this._requests.forEach((req) => { + req.reject(new Error('Socket was disconnected')); + this._requests.delete(req.reqId); + }); + clearInterval(this._timer); + } + get connected() { + return this._client.status === ConnectionStatus.Connected; + } + /** Ember+ commands: */ + async getDirectory(node, dirFieldMask, cb) { + if (!node) { + throw new Error('No node specified'); + } + const command = new Command_1.GetDirectoryImpl(dirFieldMask); + if (!('number' in node || 'path' in node)) { + if (cb) + this._subscriptions.push({ + path: undefined, + cb, + }); + return this._sendRequest(new Tree_1.NumberedTreeNodeImpl(0, command), ExpectResponse.Any); + } + if (cb) + this._subscriptions.push({ + path: (0, util_1.getPath)(node), + cb, + }); + return this._sendCommand(node, command, ExpectResponse.HasChildren); + } + async subscribe(node, cb) { + if (!node) { + throw new Error('No node specified'); + } + const command = new Command_1.SubscribeImpl(); + if (Array.isArray(node)) { + if (cb) + this._subscriptions.push({ + path: undefined, + cb, + }); + return this._sendRequest(new Tree_1.NumberedTreeNodeImpl(0, command), ExpectResponse.Any); + } + // Check if this is a Parameter with streamIdentifier + if (node.contents.type === EmberElement_1.ElementType.Parameter) { + const parameter = node.contents; + if (parameter.streamIdentifier !== undefined) { + this._streamManager.registerParameter(parameter, (0, util_1.getPath)(node)); + } + } + if (cb) + this._subscriptions.push({ + path: (0, util_1.getPath)(node), + cb, + }); + return this._sendCommand(node, command, ExpectResponse.None); + } + async unsubscribe(node) { + if (!node) { + throw new Error('No node specified'); + } + const command = new Command_1.UnsubscribeImpl(); + const path = Array.isArray(node) ? '' : (0, util_1.getPath)(node); + // Clean up subscriptions + for (const i in this._subscriptions) { + if (this._subscriptions[i].path === path) { + this._subscriptions.splice(Number(i), 1); + } + } + // Deregister from StreamManager if this was a Parameter with streamIdentifier + if (!Array.isArray(node) && node.contents.type === EmberElement_1.ElementType.Parameter) { + const parameter = node.contents; + if (parameter.streamIdentifier !== undefined) { + this._streamManager.unregisterParameter(path); + } + } + if (Array.isArray(node)) { + return this._sendRequest(new Tree_1.NumberedTreeNodeImpl(0, command), ExpectResponse.Any); + } + return this._sendCommand(node, command, ExpectResponse.None); + } + async invoke(node, ...args) { + if (!node) { + throw new Error('No node specified'); + } + // TODO - validate arguments + const command = { + type: EmberElement_1.ElementType.Command, + number: Command_1.CommandType.Invoke, + invocation: { + id: ++this._lastInvocation, + args, + }, + }; + return this._sendCommand(node, command, ExpectResponse.Any); + } + /** Sending ember+ values */ + async setValue(node, value, awaitResponse = true) { + if (!node) { + throw new Error('No node specified'); + } + const qualifiedParam = (0, util_1.assertQualifiedEmberNode)(node); + if (!('value' in qualifiedParam.contents)) { + throw new Error('Node is not a parameter'); + } + qualifiedParam.contents.value = value; + return this._sendRequest(qualifiedParam, awaitResponse ? ExpectResponse.Any : ExpectResponse.None); + } + async matrixConnect(matrix, target, sources) { + return this._matrixMutation(matrix, target, sources, Connection_1.ConnectionOperation.Connect); + } + async matrixDisconnect(matrix, target, sources) { + return this._matrixMutation(matrix, target, sources, Connection_1.ConnectionOperation.Disconnect); + } + async matrixSetConnection(matrix, target, sources) { + return this._matrixMutation(matrix, target, sources, Connection_1.ConnectionOperation.Absolute); + } + /** Getting the tree: */ + async expand(node) { + if (!node) { + throw new Error('No node specified'); + } + if (!('number' in node)) { + await (await this.getDirectory(node)).response; + for (const root of Object.values(this.tree)) + await this.expand(root); + return; + } + const emberNodes = [node]; + const canBeExpanded = (node) => { + if (node.contents.type === EmberElement_1.ElementType.Node) { + return node.contents.isOnline !== false; + } + else { + return node.contents.type !== EmberElement_1.ElementType.Parameter && node.contents.type !== EmberElement_1.ElementType.Function; + } + }; + let curEmberNode; + while ((curEmberNode = emberNodes.shift())) { + if (curEmberNode.children) { + emberNodes.push(...Object.values(curEmberNode.children).filter(canBeExpanded)); + } + else { + const req = await this.getDirectory(curEmberNode); + if (!req.response) + continue; + const res = (await req.response); + if (res.children) { + Object.values(res.children).forEach((c) => canBeExpanded(c) && emberNodes.push(c)); + } + } + } + } + async getElementByPath(path, cb, delimiter = '.') { + const getNodeInCollection = (elements, identifier) => Object.values(elements || {}).find((r) => r.number === Number(identifier) || + r.contents.identifier === identifier || + r.contents.description === identifier); + const getNextChild = (node, identifier) => node.children && getNodeInCollection(node.children, identifier); + const numberedPath = []; + const pathArr = path.split(delimiter); + const firstIdentifier = pathArr.shift(); + if (!firstIdentifier) + throw new Error('Expected at least one segment in the path'); + let tree = getNodeInCollection(this.tree, firstIdentifier); + if (tree?.number !== undefined) + numberedPath.push(tree.number); + while (pathArr.length) { + const i = pathArr.shift(); + if (i === undefined) + break; // TODO - this will break the loop if the path was `1..0` + if (!tree) + break; + let next = getNextChild(tree, i); + if (!next) { + const req = await this.getDirectory(tree); + tree = (await req.response); + next = getNextChild(tree, i); + } + tree = next; + if (!tree) + throw new Error(`Could not find node ${i} on given path ${numberedPath.join()}`); + if (tree?.number !== undefined) + numberedPath.push(tree.number); + } + if (tree?.contents.type === EmberElement_1.ElementType.Parameter) { + // do an additional getDirectory because Providers do not _have_ to send updates without that (should vs shall) + const req = await this.getDirectory(tree); + await req.response; + } + if (cb && numberedPath) { + this._subscriptions.push({ + path: numberedPath.join('.'), + cb, + }); + } + return tree; + } + // This function handles the fact that the path in the Ember+ tree is not always the same as the path in requested from the provider + getInternalNodePath(node) { + if ('path' in node && typeof node.path === 'string') { + // QualifiedElement case + return node.path; + } + else if ('number' in node) { + // NumberedTreeNode case + const numbers = []; + let current = node; + while (current) { + numbers.unshift(current.number); + if (current.parent && 'number' in current.parent) { + current = current.parent; + } + else { + current = undefined; + } + } + return numbers.join('.'); + } + return undefined; + } + async _matrixMutation(matrix, target, sources, operation) { + if (!matrix) { + throw new Error('No matrix specified'); + } + const qualifiedMatrix = (0, util_1.assertQualifiedEmberNode)(matrix); + const connection = { + operation, + target, + sources, + }; + qualifiedMatrix.contents.connections = [connection]; + return this._sendRequest(qualifiedMatrix, ExpectResponse.Any); + } + async _sendCommand(node, command, expectResponse) { + // assert a qualified EmberNode + const qualifiedEmberNode = (0, util_1.assertQualifiedEmberNode)(node); + // insert command + const commandEmberNode = (0, util_1.insertCommand)(qualifiedEmberNode, command); + // send request + return this._sendRequest(commandEmberNode, expectResponse); + } + async _sendRequest(node, expectResponse) { + const reqId = Math.random().toString(24).substr(-4); + const requestPromise = { + reqId, + sentOk: false, + }; + const message = (0, ber_1.berEncode)([node], types_1.RootType.Elements); + if (expectResponse !== ExpectResponse.None) { + const p = new Promise((resolve, reject) => { + const request = { + reqId, + node, + nodeResponse: expectResponse, + resolve, + reject, + message, + firstSent: Date.now(), + lastSent: Date.now(), + }; + this._requests.set(reqId, request); + requestPromise.cancel = () => { + reject(new Error('Request cancelled')); + this._requests.delete(reqId); + }; + }); + requestPromise.response = p; + } + const sentOk = this._client.sendBER(message); // TODO - if sending multiple values to same path, should we do synchronous requests? + if (!sentOk && requestPromise.cancel) { + this._requests.get(reqId)?.reject(new Error('Request was not sent correctly')); + this._requests.delete(reqId); + } + return { + ...requestPromise, + sentOk, + }; + } + _handleIncoming(incoming) { + const node = incoming.value; + // update tree: + const changes = this._applyRootToTree(node); + // check for subscriptiions: + for (const change of changes) { + const subscription = this._subscriptions.find((s) => s.path === change.path); + if (subscription && change.node) + subscription.cb(change.node); + } + // check for any outstanding requests and resolve them + // iterate over requests, check path, if Invocation check id + // resolve requests + for (const change of changes) { + const reqs = Array.from(this._requests.values()).filter((s) => (!('path' in s.node) && !change.path) || ('path' in s.node && s.node.path === change.path)); + for (const req of reqs) { + // Don't complete the response, if the call was expecting the children to be loaded + if (req.nodeResponse === ExpectResponse.HasChildren && !change.node.children) { + if (change.node.contents.type === EmberElement_1.ElementType.Parameter) { + // can't have children, therefore don't continue + } + else if (change.emptyNode) { + // update comes from an empty node, so we can't continue anyway + } + else { + continue; + } + } + if (req.cb) + req.cb(change.node); + if (req.resolve) { + req.resolve(change.node); + this._requests.delete(req.reqId); + } + } + } + // at last, emit the errors for logging purposes + incoming.errors?.forEach((e) => this.emit('warn', e)); + } + _applyRootToTree(node) { + const changes = []; + if ('id' in node) { + // node is an InvocationResult + this._requests.forEach((req) => { + if (req.node.contents.type === EmberElement_1.ElementType.Function) { + if (req.node.children && req.node.children[0]) { + if ('invocation' in req.node.children[0].contents) { + if (req.node.children[0].contents.invocation?.id && + req.node.children[0].contents.invocation?.id === node.id) { + req.resolve(node); + this._requests.delete(req.reqId); + } + } + } + } + }); + } + else { + // EmberNode is not an InvocationResult + // walk tree + for (const rootElement of Object.values(node)) { + if ('identifier' in rootElement) { + // rootElement is a StreamEntry + continue; + } + else if ('path' in rootElement) { + // element is qualified + const path = rootElement.path.split('.'); + let tree = this.tree[Number(path.shift())]; + let inserted = false; + if (!tree) { + if (path.length) { + // Assuming this means that no get directory was done on the root of the tree. + changes.push({ path: rootElement.path, node: rootElement }); + continue; + } + else { + const number = Number(rootElement.path); + // Insert node into root + this.tree[number] = new Tree_1.NumberedTreeNodeImpl(number, rootElement.contents, rootElement.children); + changes.push({ path: undefined, node: this.tree[number] }); + continue; + } + } + for (const number of path) { + if (!tree.children) + tree.children = {}; + if (!tree.children[Number(number)]) { + tree.children[Number(number)] = { + ...rootElement, + number: Number(number), + parent: tree, + }; + changes.push({ + path: rootElement.path.split('.').slice(0, -1).join('.'), + node: tree, + }); + inserted = true; + break; + } + tree = tree.children[Number(number)]; + } + if (inserted) + continue; + changes.push(...this._updateTree(rootElement, tree)); + } + else { + if (rootElement.children) { + if (this.tree[rootElement.number]) { + changes.push(...this._updateTree(rootElement, this.tree[rootElement.number])); + } + else { + this.tree[rootElement.number] = rootElement; + changes.push({ path: undefined, node: rootElement }); + } + } + else if ((0, util_1.isEmptyNode)(rootElement)) { + // empty node on the root of the tree must mean we have done a getDir on that specific node + changes.push({ path: rootElement.number + '', node: rootElement, emptyNode: true }); + } + else { + // this must have been something on the root of the tree (like GetDirectory) + this.tree[rootElement.number] = rootElement; + changes.push({ path: undefined, node: rootElement }); + } + } + } + } + return changes; + } + _updateTree(update, tree) { + const changes = []; + if (update.contents.type === tree.contents.type) { + changes.push({ path: (0, util_1.getPath)(tree), node: tree, emptyNode: (0, util_1.isEmptyNode)(update) }); + // changes.push({ path: getPath(tree), node: tree }) + switch (tree.contents.type) { + case EmberElement_1.ElementType.Node: + this._updateEmberNode(update.contents, tree.contents); + break; + case EmberElement_1.ElementType.Parameter: + this._updateParameter(update.contents, tree.contents); + break; + case EmberElement_1.ElementType.Matrix: + this._updateMatrix(update.contents, tree.contents); + break; + } + } + if (update.children && tree.children) { + // Update children + for (const child of Object.values(update.children)) { + const i = child.number; + const oldChild = tree.children[i]; // as NumberedTreeNode | undefined // TODO + changes.push(...this._updateTree(child, oldChild)); + } + } + else if (update.children) { + changes.push({ path: (0, util_1.getPath)(tree), node: tree }); + tree.children = update.children; + for (const c of Object.values(update.children)) { + c.parent = tree; + } + } + return changes; + } + _updateEmberNode(update, EmberNode) { + (0, util_1.updateProps)(EmberNode, update, ['isOnline']); + } + _updateParameter(update, parameter) { + (0, util_1.updateProps)(parameter, update, ['value', 'isOnline', 'access']); + } + _updateMatrix(update, matrix) { + (0, util_1.updateProps)(matrix, update, ['targets', 'targetCount', 'sources', 'sourceCount', 'connections']); + // update connections + if (update.connections) { + if (matrix.connections) { + // matrix already has connections + for (const connection of Object.values(update.connections)) { + if (!connection.disposition || + !(connection.disposition === Connection_1.ConnectionDisposition.Locked || + connection.disposition === Connection_1.ConnectionDisposition.Pending)) { + // update is either generic, tally or modification + let exists = false; + for (const i in matrix.connections) { + if (matrix.connections[i].target === connection.target) { + // found connection to update + exists = true; + matrix.connections[i].sources = connection.sources; + } + } + if (!exists) { + // connection to target does not exist yet + matrix.connections[connection.target] = { + target: connection.target, + sources: connection.sources, + }; + } + } + } + } + else { + // connections have not been set yet + matrix.connections = update.connections; + } + } + } + _resendTimer() { + if (this.connected) { + this._requests.forEach((req) => { + const sinceSent = Date.now() - req.lastSent; + const sinceFirstSent = Date.now() - req.firstSent; + if (this._resends && sinceSent >= this._resendTimeout) { + const sent = this._client.sendBER(req.message); + if (sent) { + req.lastSent = Date.now(); + } + else { + req.reject(new Error('Request was not sent correctly')); + } + } + if (sinceFirstSent >= this._timeout) { + req.reject(new Error('Request timed out')); + this._requests.delete(req.reqId); + } + }); + } + } +} +exports.EmberClient = EmberClient; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/Ember/Client/index.js.map b/dist/Ember/Client/index.js.map new file mode 100644 index 0000000..831b387 --- /dev/null +++ b/dist/Ember/Client/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Ember/Client/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ember/Lib/index.d.ts b/dist/Ember/Lib/index.d.ts new file mode 100644 index 0000000..5a4a9f2 --- /dev/null +++ b/dist/Ember/Lib/index.d.ts @@ -0,0 +1,5 @@ +declare const EmberLib: { + DecodeBuffer: null; +}; +export { EmberLib }; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Lib/index.d.ts.map b/dist/Ember/Lib/index.d.ts.map new file mode 100644 index 0000000..e3f6c5f --- /dev/null +++ b/dist/Ember/Lib/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Ember/Lib/index.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,QAAQ;;CAEb,CAAA;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"} \ No newline at end of file diff --git a/dist/Ember/Lib/index.js b/dist/Ember/Lib/index.js new file mode 100644 index 0000000..4b2852a --- /dev/null +++ b/dist/Ember/Lib/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EmberLib = void 0; +const EmberLib = { + DecodeBuffer: null, +}; +exports.EmberLib = EmberLib; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/Ember/Lib/index.js.map b/dist/Ember/Lib/index.js.map new file mode 100644 index 0000000..4d88731 --- /dev/null +++ b/dist/Ember/Lib/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Ember/Lib/index.ts"],"names":[],"mappings":";;;AAAA,MAAM,QAAQ,GAAG;IAChB,YAAY,EAAE,IAAI;CAClB,CAAA;AAEQ,4BAAQ"} \ No newline at end of file diff --git a/dist/Ember/Lib/util.d.ts b/dist/Ember/Lib/util.d.ts new file mode 100644 index 0000000..666ed85 --- /dev/null +++ b/dist/Ember/Lib/util.d.ts @@ -0,0 +1,15 @@ +import { NumberedTreeNode, RootElement } from '../../types/types'; +import { EmberElement } from '../../model/EmberElement'; +import { Command } from '../../model/Command'; +import { TreeElement } from '../../model/Tree'; +export declare function assertQualifiedEmberNode(node: RootElement): Exclude>; +export declare function getPath(node: RootElement): string; +export declare function toQualifiedEmberNode(EmberNode: NumberedTreeNode): Exclude>; +export declare function insertCommand(node: Exclude>, command: Command): Exclude>; +export declare function updateProps(oldProps: T, newProps: T, props?: Array): void; +/** + * Check if a value is an error, or wrap it in one + */ +export declare function normalizeError(e: unknown): Error; +export declare function isEmptyNode(node: TreeElement): boolean; +//# sourceMappingURL=util.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Lib/util.d.ts.map b/dist/Ember/Lib/util.d.ts.map new file mode 100644 index 0000000..9962660 --- /dev/null +++ b/dist/Ember/Lib/util.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/Ember/Lib/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,gBAAgB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACnF,OAAO,EAAE,YAAY,EAAe,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAA8C,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAG1F,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAMhH;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAkBjD;AAED,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,gBAAgB,CAAC,YAAY,CAAC,GACvC,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAYtD;AAED,wBAAgB,aAAa,CAC5B,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC,EAC1D,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAItD;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAQpG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAMhD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,YAAY,CAAC,GAAG,OAAO,CAwBpE"} \ No newline at end of file diff --git a/dist/Ember/Lib/util.js b/dist/Ember/Lib/util.js new file mode 100644 index 0000000..63c51ff --- /dev/null +++ b/dist/Ember/Lib/util.js @@ -0,0 +1,93 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isEmptyNode = exports.normalizeError = exports.updateProps = exports.insertCommand = exports.toQualifiedEmberNode = exports.getPath = exports.assertQualifiedEmberNode = void 0; +const EmberElement_1 = require("../../model/EmberElement"); +const Tree_1 = require("../../model/Tree"); +function assertQualifiedEmberNode(node) { + if ('path' in node) { + return node; + } + else { + return toQualifiedEmberNode(node); + } +} +exports.assertQualifiedEmberNode = assertQualifiedEmberNode; +function getPath(node) { + function isQualified(node) { + return 'path' in node; + } + function isNumbered(node) { + return 'number' in node; + } + if (isQualified(node)) { + return node.path; + } + else if (isNumbered(node)) { + if (node.parent) { + return getPath(node.parent) + '.' + node.number; + } + else { + return node.number + ''; + } + } + return ''; +} +exports.getPath = getPath; +function toQualifiedEmberNode(EmberNode) { + const path = getPath(EmberNode); + if (EmberNode.contents.type === EmberElement_1.ElementType.Command) { + throw new Error('Cannot convert a command to a qualified node'); + } + return new Tree_1.QualifiedElementImpl(path, EmberNode.contents, EmberNode.children // TODO - do we want the children? + ); +} +exports.toQualifiedEmberNode = toQualifiedEmberNode; +function insertCommand(node, command) { + return new Tree_1.QualifiedElementImpl(node.path, node.contents, [ + new Tree_1.NumberedTreeNodeImpl(0, command), + ]); +} +exports.insertCommand = insertCommand; +function updateProps(oldProps, newProps, props) { + if (!props) + props = Object.keys(newProps); + for (const key of props) { + if (newProps[key] !== undefined && newProps[key] !== oldProps[key]) { + oldProps[key] = newProps[key]; + } + } +} +exports.updateProps = updateProps; +/** + * Check if a value is an error, or wrap it in one + */ +function normalizeError(e) { + if (e instanceof Error) { + return e; + } + return new Error(typeof e === 'string' ? e : e?.toString()); +} +exports.normalizeError = normalizeError; +function isEmptyNode(node) { + const isNode = (node) => { + return node.contents.type === EmberElement_1.ElementType.Node; + }; + if (!isNode(node)) { + return false; + } + if (node.children) { + return false; + } + // Check if any of these properties have a value, including empty strings as a node with an empty description is not empty) + const notEmpty = [ + node.contents.description, + node.contents.identifier, + node.contents.isOnline, + node.contents.isRoot, + node.contents.schemaIdentifiers, + node.contents.templateReference, + ].some((value) => value !== undefined && value !== null); + return !notEmpty; +} +exports.isEmptyNode = isEmptyNode; +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/dist/Ember/Lib/util.js.map b/dist/Ember/Lib/util.js.map new file mode 100644 index 0000000..8aaa7dc --- /dev/null +++ b/dist/Ember/Lib/util.js.map @@ -0,0 +1 @@ +{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/Ember/Lib/util.ts"],"names":[],"mappings":";;;AACA,2DAAoE;AAEpE,2CAA0F;AAG1F,SAAgB,wBAAwB,CAAC,IAAiB;IACzD,IAAI,MAAM,IAAI,IAAI,EAAE;QACnB,OAAO,IAAI,CAAA;KACX;SAAM;QACN,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAA;KACjC;AACF,CAAC;AAND,4DAMC;AAED,SAAgB,OAAO,CAAC,IAAiB;IACxC,SAAS,WAAW,CAAC,IAA+B;QACnD,OAAO,MAAM,IAAI,IAAI,CAAA;IACtB,CAAC;IACD,SAAS,UAAU,CAAC,IAA+B;QAClD,OAAO,QAAQ,IAAI,IAAI,CAAA;IACxB,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;QACtB,OAAO,IAAI,CAAC,IAAI,CAAA;KAChB;SAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;QAC5B,IAAI,IAAI,CAAC,MAAM,EAAE;YAChB,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAA;SAC/C;aAAM;YACN,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAA;SACvB;KACD;IAED,OAAO,EAAE,CAAA;AACV,CAAC;AAlBD,0BAkBC;AAED,SAAgB,oBAAoB,CACnC,SAAyC;IAEzC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAE/B,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,KAAK,0BAAW,CAAC,OAAO,EAAE;QACpD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;KAC/D;IAED,OAAO,IAAI,2BAAoB,CAC9B,IAAI,EACJ,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,QAAQ,CAAC,kCAAkC;KACG,CAAA;AAC1D,CAAC;AAdD,oDAcC;AAED,SAAgB,aAAa,CAC5B,IAA0D,EAC1D,OAAgB;IAEhB,OAAO,IAAI,2BAAoB,CAAe,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;QACvE,IAAI,2BAAoB,CAAC,CAAC,EAAE,OAAO,CAAC;KACpC,CAAyD,CAAA;AAC3D,CAAC;AAPD,sCAOC;AAED,SAAgB,WAAW,CAAmB,QAAW,EAAE,QAAW,EAAE,KAAsB;IAC7F,IAAI,CAAC,KAAK;QAAE,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAmB,CAAA;IAE3D,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE;QACxB,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,EAAE;YACnE,QAAQ,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;SAC7B;KACD;AACF,CAAC;AARD,kCAQC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,CAAU;IACxC,IAAI,CAAC,YAAY,KAAK,EAAE;QACvB,OAAO,CAAC,CAAA;KACR;IAED,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAS,EAAE,QAAQ,EAAE,CAAC,CAAA;AACrE,CAAC;AAND,wCAMC;AAED,SAAgB,WAAW,CAAC,IAA+B;IAC1D,MAAM,MAAM,GAAG,CAAC,IAA+B,EAAkC,EAAE;QAClF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,0BAAW,CAAC,IAAI,CAAA;IAC/C,CAAC,CAAA;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QAClB,OAAO,KAAK,CAAA;KACZ;IAED,IAAI,IAAI,CAAC,QAAQ,EAAE;QAClB,OAAO,KAAK,CAAA;KACZ;IAED,2HAA2H;IAC3H,MAAM,QAAQ,GAAG;QAChB,IAAI,CAAC,QAAQ,CAAC,WAAW;QACzB,IAAI,CAAC,QAAQ,CAAC,UAAU;QACxB,IAAI,CAAC,QAAQ,CAAC,QAAQ;QACtB,IAAI,CAAC,QAAQ,CAAC,MAAM;QACpB,IAAI,CAAC,QAAQ,CAAC,iBAAiB;QAC/B,IAAI,CAAC,QAAQ,CAAC,iBAAiB;KAC/B,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,CAAA;IAExD,OAAO,CAAC,QAAQ,CAAA;AACjB,CAAC;AAxBD,kCAwBC"} \ No newline at end of file diff --git a/dist/Ember/Server/index.d.ts b/dist/Ember/Server/index.d.ts new file mode 100644 index 0000000..da94a92 --- /dev/null +++ b/dist/Ember/Server/index.d.ts @@ -0,0 +1,37 @@ +import { EventEmitter } from 'eventemitter3'; +import { EmberElement, EmberFunction, InvocationResult, Parameter, Matrix, Connections } from '../../model'; +import { Collection, NumberedTreeNode, EmberValue } from '../../types/types'; +import { Invoke } from '../../model/Command'; +import { Connection } from '../../model/Connection'; +import S101Socket from '../Socket/S101Socket'; +export type EmberServerEvents = { + error: [Error]; + clientError: [client: S101Socket, error: Error]; +}; +export declare class EmberServer extends EventEmitter { + address: string | undefined; + port: number; + tree: Collection>; + onInvocation?: (emberFunction: NumberedTreeNode, invocation: NumberedTreeNode) => Promise; + onSetValue?: (parameter: NumberedTreeNode, value: EmberValue) => Promise; + onMatrixOperation?: (Matrix: NumberedTreeNode, connection: Connections) => Promise; + private _server; + private _clients; + private _subscriptions; + constructor(port: number, address?: string); + init(tree: Collection>): Promise; + discard(): void; + update(element: NumberedTreeNode, update: Partial): void; + updateMatrixConnection(element: NumberedTreeNode, update: Connection): void; + private _handleIncoming; + private _handleNode; + private _handleMatrix; + private _handleSetValue; + private _handleCommand; + getElementByPath(path: string, delimiter?: string): NumberedTreeNode | undefined; + private _subscribe; + private _unsubscribe; + private _clearSubscription; + private _handleGetDirectory; +} +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Server/index.d.ts.map b/dist/Ember/Server/index.d.ts.map new file mode 100644 index 0000000..fc689f1 --- /dev/null +++ b/dist/Ember/Server/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Ember/Server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,OAAO,EACN,YAAY,EAGZ,aAAa,EACb,gBAAgB,EAEhB,SAAS,EAET,MAAM,EACN,WAAW,EAEX,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,UAAU,EAEV,gBAAgB,EAIhB,UAAU,EACV,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAAkD,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5F,OAAO,EAAE,UAAU,EAAuC,MAAM,wBAAwB,CAAA;AAExF,OAAO,UAAU,MAAM,sBAAsB,CAAA;AAE7C,MAAM,MAAM,iBAAiB,GAAG;IAC/B,KAAK,EAAE,CAAC,KAAK,CAAC,CAAA;IACd,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;CAC/C,CAAA;AAED,qBAAa,WAAY,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IAC/D,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAK;IAErD,YAAY,CAAC,EAAE,CACd,aAAa,EAAE,gBAAgB,CAAC,aAAa,CAAC,EAC9C,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,KAChC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC9B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5F,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAEhG,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,cAAc,CAA4C;gBAEtD,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAuBpC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB3E,OAAO,IAAI,IAAI;IAQf,MAAM,CAAC,CAAC,SAAS,YAAY,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAgCtF,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IA2CnF,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,WAAW;YA6BL,aAAa;YASb,eAAe;YAqBf,cAAc;IAuB5B,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,GAAG,SAAS;IAiC3F,OAAO,CAAC,UAAU;IAGlB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,mBAAmB;CAsD3B"} \ No newline at end of file diff --git a/dist/Ember/Server/index.js b/dist/Ember/Server/index.js new file mode 100644 index 0000000..209729f --- /dev/null +++ b/dist/Ember/Server/index.js @@ -0,0 +1,292 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EmberServer = void 0; +const eventemitter3_1 = require("eventemitter3"); +const S101Server_1 = require("../Socket/S101Server"); +const model_1 = require("../../model"); +const types_1 = require("../../types/types"); +const util_1 = require("../Lib/util"); +const ber_1 = require("../../encodings/ber"); +const Command_1 = require("../../model/Command"); +const Connection_1 = require("../../model/Connection"); +const InvocationResult_1 = require("../../model/InvocationResult"); +class EmberServer extends eventemitter3_1.EventEmitter { + constructor(port, address) { + super(); + this.tree = {}; + this._clients = new Set(); + this._subscriptions = {}; + this.address = address; + this.port = port; + this._server = new S101Server_1.S101Server(port, address); + this._server.on('connection', (client) => { + this._clients.add(client); + client.on('emberTree', (tree) => this._handleIncoming(tree, client)); + client.on('error', (e) => { + this.emit('clientError', client, e); + }); + client.on('disconnected', () => { + this._clearSubscription(client); + this._clients.delete(client); + }); + }); + } + async init(tree) { + const setParent = (parent, child) => { + child.parent = parent; + if (child.children) { + for (const c of Object.values(child.children)) { + setParent(child, c); + } + } + }; + for (const rootEl of Object.values(tree)) { + if (rootEl.children) { + for (const c of Object.values(rootEl.children)) { + setParent(rootEl, c); + } + } + } + this.tree = tree; + return this._server.listen(); + } + discard() { + this._clients.forEach((c) => { + c.removeAllListeners(); + }); + this._clients.clear(); + this._server.server?.close(); + } + update(element, update) { + if (element.contents.type === model_1.ElementType.Matrix) { + const matrix = element; + const matrixUpdate = update; + if (matrixUpdate.connections) { + for (const connection of Object.values(matrixUpdate.connections)) { + this.updateMatrixConnection(matrix, connection); + } + } + } + for (const [key, value] of Object.entries(update)) { + element.contents[key] = value; + } + const el = (0, util_1.toQualifiedEmberNode)(element); + const data = (0, ber_1.berEncode)([el], types_1.RootType.Elements); + let elPath = el.path; + if (el.contents.type !== model_1.ElementType.Node && !('targets' in update || 'sources' in update)) { + elPath = elPath.slice(0, -2); // remove the last element number + } + for (const [path, clients] of Object.entries(this._subscriptions)) { + if (elPath === path) { + clients.forEach((client) => { + client.sendBER(data); + }); + } + } + } + updateMatrixConnection(element, update) { + if (!element.contents.connections) + element.contents.connections = {}; + let connection = element.contents.connections[update.target]; + if (!connection) { + element.contents.connections[update.target] = new Connection_1.ConnectionImpl(update.target, []); + connection = element.contents.connections[update.target]; + } + if (!connection.sources) + connection.sources = []; + switch (update.operation) { + case Connection_1.ConnectionOperation.Connect: + for (const source of update.sources || []) { + if (!connection.sources.find((v) => v === source)) { + connection.sources.push(source); + } + } + break; + case Connection_1.ConnectionOperation.Disconnect: + for (const source of update.sources || []) { + connection.sources = connection.sources.filter((oldSource) => oldSource !== source); + } + break; + case Connection_1.ConnectionOperation.Absolute: + default: + connection.sources = update.sources; + break; + } + const qualified = (0, util_1.toQualifiedEmberNode)(element); + qualified.contents = new model_1.MatrixImpl(qualified.contents.identifier, undefined, undefined, { + [connection.target]: connection, + }); + const data = (0, ber_1.berEncode)([qualified], types_1.RootType.Elements); + for (const [path, clients] of Object.entries(this._subscriptions)) { + if (qualified.path === path) { + clients.forEach((client) => { + client.sendBER(data); + }); + } + } + } + _handleIncoming(incoming, client) { + for (const rootEl of Object.values(incoming.value)) { + if (rootEl.contents.type === model_1.ElementType.Command) { + // command on root + this._handleCommand('', rootEl, client).catch((e) => this.emit('error', e)); + } + else if ('path' in rootEl) { + this._handleNode(rootEl.path || '', rootEl, client); + } + else if ('number' in rootEl) { + this._handleNode(rootEl.number + '' || '', rootEl, client); + } + } + } + _handleNode(path, el, client) { + const children = Object.values(el.children || {}); + if (children[0] && children[0].contents.type === model_1.ElementType.Command) { + this._handleCommand(path, children[0], client).catch((e) => this.emit('error', e)); + return; + } + else if (el.contents.type === model_1.ElementType.Matrix && 'connections' in el.contents) { + this._handleMatrix(path, el).catch((e) => this.emit('error', e)); + } + if (!el.children) { + if (el.contents.type === model_1.ElementType.Parameter) { + this._handleSetValue(path, el, client).catch((e) => this.emit('error', e)); + } + } + else { + for (const c of children) { + this._handleNode(path + '.' + c.number, c, client); + } + } + } + async _handleMatrix(path, el) { + if (this.onMatrixOperation) { + const tree = this.getElementByPath(path); + if (!tree || tree.contents.type !== model_1.ElementType.Matrix || !el.contents.connections) + return; + return this.onMatrixOperation(tree, el.contents.connections); + } + } + async _handleSetValue(path, el, client) { + const tree = this.getElementByPath(path); + if (!tree || tree.contents.type !== model_1.ElementType.Parameter || el.contents.value === undefined) + return; + let success = false; + if (this.onSetValue) { + success = await this.onSetValue(tree, el.contents.value); + } + if (!success) { + const qualified = (0, util_1.toQualifiedEmberNode)(tree); + const encoded = (0, ber_1.berEncode)([qualified], types_1.RootType.Elements); + client.sendBER(encoded); + } + } + async _handleCommand(path, el, client) { + const tree = path ? this.getElementByPath(path) : this.tree; + if (!tree) + return; + if (el.contents.number === Command_1.CommandType.Subscribe) { + this._subscribe(path, client); + } + else if (el.contents.number === Command_1.CommandType.Unsubscribe) { + this._unsubscribe(path, client); + } + else if (el.contents.number === Command_1.CommandType.GetDirectory) { + this._subscribe(path, client); // send updates to client + this._handleGetDirectory(tree, el.contents.dirFieldMask || Command_1.FieldFlags.Default, client); + } + else if (el.contents.number === Command_1.CommandType.Invoke) { + let result; + if (this.onInvocation) { + result = await this.onInvocation(tree, el); + } + else { + result = new InvocationResult_1.InvocationResultImpl(el.contents.invocation?.id || -1, false); + } + const encoded = (0, ber_1.berEncode)(result, types_1.RootType.InvocationResult); + client.sendBER(encoded); + } + } + getElementByPath(path, delimiter = '.') { + const getNext = (elements, i) => Object.values(elements || {}).find((r) => r.number === Number(i) || + r.contents.identifier === i || + r.contents.description === i); + const getNextChild = (node, i) => node.children && getNext(node.children, i); + const numberedPath = []; + const pathArr = path.split(delimiter); + const i = pathArr.shift(); + let tree = getNext(this.tree, i); + if (tree?.number) + numberedPath.push(tree?.number); + while (pathArr.length) { + const i = pathArr.shift(); + if (!i) + break; + if (!tree) + break; + const next = getNextChild(tree, i); + if (!next) { + // not found + return; + } + tree = next; + if (!tree) + return; + if (tree?.number) + numberedPath.push(tree?.number); + } + return tree; + } + _subscribe(path, client) { + this._subscriptions[path] = [...(this._subscriptions[path] || []), client]; + } + _unsubscribe(path, client) { + if (!this._subscriptions[path]) + return; + this._subscriptions[path].forEach((c, i) => { + if (c === client) { + this._subscriptions[path].splice(i, 1); + } + }); + } + _clearSubscription(client) { + for (const path of Object.keys(this._subscriptions)) { + this._unsubscribe(path, client); + } + } + _handleGetDirectory(tree, _dirFieldMasks, client) { + if (tree === this.tree) { + // getDir on root + const response = { ...this.tree }; + for (const [i, rootEl] of Object.entries(this.tree)) { + response[i] = new model_1.NumberedTreeNodeImpl(rootEl.number, rootEl.contents); + } + const data = (0, ber_1.berEncode)(response, types_1.RootType.Elements); + client.sendBER(data); + } + else { + const qualified = (0, util_1.toQualifiedEmberNode)(tree); + qualified.children = {}; // destroy ref to this.tree + if ('children' in tree && tree.children) { + for (const [i, child] of Object.entries(tree.children)) { + if (child.contents.type === model_1.ElementType.Matrix) { + // matrix should not have connections, targets and sources: + qualified.children[i] = new model_1.NumberedTreeNodeImpl(child.number, new model_1.MatrixImpl(child.contents.identifier, undefined, undefined, undefined, child.contents.description, child.contents.matrixType, child.contents.addressingMode, child.contents.targetCount, child.contents.sourceCount, child.contents.maximumTotalConnects, child.contents.maximumConnectsPerTarget, child.contents.parametersLocation, child.contents.gainParameterNumber, child.contents.labels, child.contents.schemaIdentifiers, child.contents.templateReference)); + } + else { + qualified.children[i] = new model_1.NumberedTreeNodeImpl(child.number, child.contents); + } + } + } + else if (qualified.contents.type === model_1.ElementType.Node && !('children' in tree && tree.children)) { + // node without children -> none of the properties should be set + qualified.contents = new model_1.EmberNodeImpl(); + qualified.children = undefined; + } + const data = (0, ber_1.berEncode)([qualified], types_1.RootType.Elements); + client.sendBER(data); + } + } +} +exports.EmberServer = EmberServer; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/Ember/Server/index.js.map b/dist/Ember/Server/index.js.map new file mode 100644 index 0000000..01a5be6 --- /dev/null +++ b/dist/Ember/Server/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Ember/Server/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ember/Socket/S101Client.d.ts b/dist/Ember/Socket/S101Client.d.ts new file mode 100644 index 0000000..21fff01 --- /dev/null +++ b/dist/Ember/Socket/S101Client.d.ts @@ -0,0 +1,28 @@ +import S101Socket from './S101Socket'; +export default class S101Client extends S101Socket { + address: string; + port: number; + autoConnect: boolean; + private _autoReconnect; + private _autoReconnectDelay; + private _connectionAttemptTimer; + private _reconnectAttempt; + private _reconnectAttempts; + private _shouldBeConnected; + private _lastConnectionAttempt; + /** + * + * @param {string} address + * @param {number} port=9000 + */ + constructor(address: string, port?: number, autoConnect?: boolean); + connect(timeout?: number): Promise; + disconnect(timeout?: number): Promise; + protected handleClose(): void; + private _autoReconnectionAttempt; + private _clearConnectionAttemptTimer; + private _onConnect; + private _onError; + private _onClose; +} +//# sourceMappingURL=S101Client.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Socket/S101Client.d.ts.map b/dist/Ember/Socket/S101Client.d.ts.map new file mode 100644 index 0000000..708bbf4 --- /dev/null +++ b/dist/Ember/Socket/S101Client.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Client.d.ts","sourceRoot":"","sources":["../../../src/Ember/Socket/S101Client.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,cAAc,CAAA;AAQrC,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,UAAU;IACjD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,UAAQ;IAEnB,OAAO,CAAC,cAAc,CAAO;IAC7B,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,uBAAuB,CAAwC;IACvE,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,sBAAsB,CAAI;IAElC;;;;OAIG;gBACS,OAAO,EAAE,MAAM,EAAE,IAAI,SAAe,EAAE,WAAW,CAAC,EAAE,OAAO;IAWjE,OAAO,CAAC,OAAO,SAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAgE3C,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,SAAS,CAAC,WAAW,IAAI,IAAI;IAK7B,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,4BAA4B;IAQpC,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,QAAQ;CAShB"} \ No newline at end of file diff --git a/dist/Ember/Socket/S101Client.js b/dist/Ember/Socket/S101Client.js new file mode 100644 index 0000000..317fd34 --- /dev/null +++ b/dist/Ember/Socket/S101Client.js @@ -0,0 +1,153 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const net_1 = tslib_1.__importDefault(require("net")); +const S101Socket_1 = tslib_1.__importDefault(require("./S101Socket")); +const Client_1 = require("../Client"); +const util_1 = require("../Lib/util"); +const DEFAULT_PORT = 9000; +const RECONNECT_ATTEMPTS = 60; +const AUTO_RECONNECT_DELAY = 5000; +class S101Client extends S101Socket_1.default { + /** + * + * @param {string} address + * @param {number} port=9000 + */ + constructor(address, port = DEFAULT_PORT, autoConnect) { + super(); + this.autoConnect = false; + this._autoReconnect = true; + this._autoReconnectDelay = AUTO_RECONNECT_DELAY; + this._connectionAttemptTimer = undefined; + this._reconnectAttempt = 0; + this._reconnectAttempts = RECONNECT_ATTEMPTS; + this._lastConnectionAttempt = 0; + this.address = address; + this.port = port; + this.autoConnect = !!autoConnect; + this._shouldBeConnected = this.autoConnect; + if (this.autoConnect) + this.connect().catch(() => null); // errors are already emitted + } + async connect(timeout = 5) { + return new Promise((resolve) => { + if (this.status !== Client_1.ConnectionStatus.Disconnected) { + // TODO - perhaps we should reconnect when addresses/ports have changed + resolve(); + return; + } + if (!this._lastConnectionAttempt || Date.now() - this._lastConnectionAttempt >= this._autoReconnectDelay) { + // !_lastReconnectionAttempt means first attempt, OR > _reconnectionDelay since last attempt + // recreates client if new attempt + if (this.socket && this.socket.connecting) { + this.socket.destroy(); + this.socket.removeAllListeners(); + delete this.socket; + // @todo: fire event telling it gives up! + } + // (re)creates client, either on first run or new attempt + if (!this.socket) { + this.socket = new net_1.default.Socket(); + this.socket.on('close', (hadError) => this._onClose(hadError)); + this.socket.on('connect', () => this._onConnect()); + this.socket.on('data', (data) => { + try { + this.codec.dataIn(data); + } + catch (e) { + this.emit('error', (0, util_1.normalizeError)(e)); + } + }); + this.socket.on('error', (error) => this._onError(error)); + } + this.emit('connecting'); + this.status = Client_1.ConnectionStatus.Disconnected; + const connectTimeoutListener = () => { + if (this.socket) { + this.socket.destroy(); + this.socket.removeAllListeners(); + delete this.socket; + } + const reason = new Error(`Could not connect to ${this.address}:${this.port} after a timeout of ${timeout} seconds`); + resolve(reason); + if (!this._connectionAttemptTimer) + this.connect().catch(() => null); + }; + const timer = setTimeout(() => connectTimeoutListener(), timeout * 1000); + this.socket.connect(this.port, this.address); + this.socket.once('connect', () => { + clearInterval(timer); + resolve(); + }); + this._shouldBeConnected = true; + this._lastConnectionAttempt = Date.now(); + } + // sets timer to retry when needed + if (!this._connectionAttemptTimer) { + this._connectionAttemptTimer = setInterval(() => this._autoReconnectionAttempt(), this._autoReconnectDelay); + } + }); + } + async disconnect(timeout) { + this._shouldBeConnected = false; + return super.disconnect(timeout); + } + handleClose() { + if (this.keepaliveIntervalTimer) + clearInterval(this.keepaliveIntervalTimer); + this.socket?.destroy(); + } + _autoReconnectionAttempt() { + if (this._autoReconnect) { + if (this._reconnectAttempts > 0) { + // no reconnection if no valid reconnectionAttemps is set + if (this._reconnectAttempt >= this._reconnectAttempts) { + // if current attempt is not less than max attempts + // reset reconnection behaviour + this._clearConnectionAttemptTimer(); + this.status = Client_1.ConnectionStatus.Disconnected; + return; + } + // new attempt if not already connected + if (this.status !== Client_1.ConnectionStatus.Connected) { + this._reconnectAttempt++; + this.connect().catch(() => null); + } + } + } + } + _clearConnectionAttemptTimer() { + // @todo create event telling reconnection ended with result: true/false + // only if reconnection interval is true + this._reconnectAttempt = 0; + if (this._connectionAttemptTimer) + clearInterval(this._connectionAttemptTimer); + delete this._connectionAttemptTimer; + } + _onConnect() { + this._clearConnectionAttemptTimer(); + this.startKeepAlive(); + // this._sentKeepalive = Date.now() + // this._receivedKeepalive = this._sentKeepalive + 1 // for some reason keepalive doesn't return directly after conn. + this.status = Client_1.ConnectionStatus.Connected; + this.emit('connected'); + } + _onError(error) { + if (error.message.match(/ECONNREFUSED/)) { + return; // we handle this internally through reconnections + } + this.emit('error', error); + } + _onClose(_hadError) { + if (this.status !== Client_1.ConnectionStatus.Disconnected) + this.emit('disconnected'); + this.status = Client_1.ConnectionStatus.Disconnected; + if (this._shouldBeConnected === true) { + this.emit('connecting'); + this.connect().catch(() => null); + } + } +} +exports.default = S101Client; +//# sourceMappingURL=S101Client.js.map \ No newline at end of file diff --git a/dist/Ember/Socket/S101Client.js.map b/dist/Ember/Socket/S101Client.js.map new file mode 100644 index 0000000..032780e --- /dev/null +++ b/dist/Ember/Socket/S101Client.js.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Client.js","sourceRoot":"","sources":["../../../src/Ember/Socket/S101Client.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ember/Socket/S101Server.d.ts b/dist/Ember/Socket/S101Server.d.ts new file mode 100644 index 0000000..7c8cd36 --- /dev/null +++ b/dist/Ember/Socket/S101Server.d.ts @@ -0,0 +1,20 @@ +/// +import { EventEmitter } from 'eventemitter3'; +import { Socket, Server } from 'net'; +import S101Socket from './S101Socket'; +export type S101ServerEvents = { + error: [Error]; + listening: []; + connection: [client: S101Socket]; +}; +export declare class S101Server extends EventEmitter { + port: number; + address: string | undefined; + server: Server | null; + status: string; + constructor(port: number, address?: string); + addClient(socket: Socket): void; + listen(): Promise; + discard(): void; +} +//# sourceMappingURL=S101Server.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Socket/S101Server.d.ts.map b/dist/Ember/Socket/S101Server.d.ts.map new file mode 100644 index 0000000..f5c85ff --- /dev/null +++ b/dist/Ember/Socket/S101Server.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Server.d.ts","sourceRoot":"","sources":["../../../src/Ember/Socket/S101Server.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAgB,MAAM,EAAE,MAAM,KAAK,CAAA;AAClD,OAAO,UAAU,MAAM,cAAc,CAAA;AAErC,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,CAAC,KAAK,CAAC,CAAA;IACd,SAAS,EAAE,EAAE,CAAA;IACb,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAChC,CAAA;AACD,qBAAa,UAAW,SAAQ,YAAY,CAAC,gBAAgB,CAAC;IAC7D,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;gBAEF,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAQ1C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMzB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB7B,OAAO,IAAI,IAAI;CAGf"} \ No newline at end of file diff --git a/dist/Ember/Socket/S101Server.js b/dist/Ember/Socket/S101Server.js new file mode 100644 index 0000000..2dd081f --- /dev/null +++ b/dist/Ember/Socket/S101Server.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.S101Server = void 0; +const tslib_1 = require("tslib"); +const eventemitter3_1 = require("eventemitter3"); +const net_1 = require("net"); +const S101Socket_1 = tslib_1.__importDefault(require("./S101Socket")); +class S101Server extends eventemitter3_1.EventEmitter { + constructor(port, address) { + super(); + this.port = port; + this.address = address; + this.server = null; + this.status = 'disconnected'; + } + addClient(socket) { + // Wrap the tcp socket into an S101Socket. + const client = new S101Socket_1.default(socket); + this.emit('connection', client); + } + async listen() { + return new Promise((resolve, reject) => { + if (this.status !== 'disconnected') { + return reject(new Error('Already listening')); + } + this.server = (0, net_1.createServer)((socket) => { + this.addClient(socket); + }) + .on('error', (e) => { + this.emit('error', e); + if (this.status === 'disconnected') { + return reject(e); + } + }) + .on('listening', () => { + this.emit('listening'); + this.status = 'listening'; + resolve(undefined); + }); + this.server.listen(this.port, this.address); + }); + } + discard() { + this.server?.close(); + } +} +exports.S101Server = S101Server; +//# sourceMappingURL=S101Server.js.map \ No newline at end of file diff --git a/dist/Ember/Socket/S101Server.js.map b/dist/Ember/Socket/S101Server.js.map new file mode 100644 index 0000000..8d14d66 --- /dev/null +++ b/dist/Ember/Socket/S101Server.js.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Server.js","sourceRoot":"","sources":["../../../src/Ember/Socket/S101Server.ts"],"names":[],"mappings":";;;;AAAA,iDAA4C;AAC5C,6BAAkD;AAClD,sEAAqC;AAOrC,MAAa,UAAW,SAAQ,4BAA8B;IAM7D,YAAY,IAAY,EAAE,OAAgB;QACzC,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,cAAc,CAAA;IAC7B,CAAC;IAED,SAAS,CAAC,MAAc;QACvB,0CAA0C;QAC1C,MAAM,MAAM,GAAG,IAAI,oBAAU,CAAC,MAAM,CAAC,CAAA;QACrC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,MAAM;QACX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc,EAAE;gBACnC,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAA;aAC7C;YACD,IAAI,CAAC,MAAM,GAAG,IAAA,kBAAY,EAAC,CAAC,MAAM,EAAE,EAAE;gBACrC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;YACvB,CAAC,CAAC;iBACA,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gBAClB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;gBACrB,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc,EAAE;oBACnC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;iBAChB;YACF,CAAC,CAAC;iBACD,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;gBACrB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACtB,IAAI,CAAC,MAAM,GAAG,WAAW,CAAA;gBACzB,OAAO,CAAC,SAAS,CAAC,CAAA;YACnB,CAAC,CAAC,CAAA;YACH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;IACH,CAAC;IAED,OAAO;QACN,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAA;IACrB,CAAC;CACD;AA9CD,gCA8CC"} \ No newline at end of file diff --git a/dist/Ember/Socket/S101Socket.d.ts b/dist/Ember/Socket/S101Socket.d.ts new file mode 100644 index 0000000..74b0750 --- /dev/null +++ b/dist/Ember/Socket/S101Socket.d.ts @@ -0,0 +1,49 @@ +/// +/// +/// +import { EventEmitter } from 'eventemitter3'; +import { Socket } from 'net'; +import { S101Codec } from '../../S101'; +import { ConnectionStatus } from '../Client'; +import { Root } from '../../types'; +import { DecodeResult } from '../../encodings/ber/decoder/DecodeResult'; +export type Request = any; +export type S101SocketEvents = { + error: [Error]; + emberTree: [root: DecodeResult]; + emberStreamTree: [root: DecodeResult]; + connecting: []; + connected: []; + disconnected: []; +}; +export default class S101Socket extends EventEmitter { + protected socket: Socket | undefined; + private readonly keepaliveInterval; + private readonly keepaliveMaxResponseTime; + protected keepaliveIntervalTimer: NodeJS.Timeout | undefined; + private keepaliveResponseWindowTimer; + status: ConnectionStatus; + protected readonly codec: S101Codec; + constructor(socket?: Socket); + private _initSocket; + /** + * @param {number} timeout=2 + */ + disconnect(timeout?: number): Promise; + /** + * + */ + protected handleClose(): void; + private isConnected; + sendBER(data: Buffer): boolean; + /** + * + */ + private sendKeepaliveRequest; + /** + * + */ + private sendKeepaliveResponse; + protected startKeepAlive(): void; +} +//# sourceMappingURL=S101Socket.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Socket/S101Socket.d.ts.map b/dist/Ember/Socket/S101Socket.d.ts.map new file mode 100644 index 0000000..0fb9ba7 --- /dev/null +++ b/dist/Ember/Socket/S101Socket.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Socket.d.ts","sourceRoot":"","sources":["../../../src/Ember/Socket/S101Socket.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAE5C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAEvE,MAAM,MAAM,OAAO,GAAG,GAAG,CAAA;AAEzB,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,CAAC,KAAK,CAAC,CAAA;IACd,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;IACrC,eAAe,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3C,UAAU,EAAE,EAAE,CAAA;IACd,SAAS,EAAE,EAAE,CAAA;IACb,YAAY,EAAE,EAAE,CAAA;CAChB,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,YAAY,CAAC,gBAAgB,CAAC;IACrE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAK;IACvC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAM;IAC/C,SAAS,CAAC,sBAAsB,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,CAAA;IAC5D,OAAO,CAAC,4BAA4B,CAAqB;IACzD,MAAM,EAAE,gBAAgB,CAAA;IACxB,SAAS,CAAC,QAAQ,CAAC,KAAK,YAAkB;gBAE9B,MAAM,CAAC,EAAE,MAAM;IAuC3B,OAAO,CAAC,WAAW;IAuBnB;;OAEG;IACG,UAAU,CAAC,OAAO,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAgC5C;;OAEG;IACH,SAAS,CAAC,WAAW,IAAI,IAAI;IAO7B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAiB9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B,SAAS,CAAC,cAAc,IAAI,IAAI;CAShC"} \ No newline at end of file diff --git a/dist/Ember/Socket/S101Socket.js b/dist/Ember/Socket/S101Socket.js new file mode 100644 index 0000000..595a36d --- /dev/null +++ b/dist/Ember/Socket/S101Socket.js @@ -0,0 +1,180 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const eventemitter3_1 = require("eventemitter3"); +const S101_1 = require("../../S101"); +const __1 = require("../.."); +const Client_1 = require("../Client"); +const util_1 = require("../Lib/util"); +class S101Socket extends eventemitter3_1.EventEmitter { + constructor(socket) { + super(); + this.keepaliveInterval = 10; + this.keepaliveMaxResponseTime = 500; + this.codec = new S101_1.S101Codec(); + this.socket = socket; + this.keepaliveIntervalTimer = undefined; + this.keepaliveResponseWindowTimer = null; + this.status = this.isConnected() ? Client_1.ConnectionStatus.Connected : Client_1.ConnectionStatus.Disconnected; + this.codec.on('keepaliveReq', () => { + this.sendKeepaliveResponse(); + }); + this.codec.on('keepaliveResp', () => { + clearInterval(this.keepaliveResponseWindowTimer); + }); + this.codec.on('emberPacket', (packet) => { + try { + const root = (0, __1.berDecode)(packet); + if (root != null) { + this.emit('emberTree', root); + } + } + catch (e) { + this.emit('error', (0, util_1.normalizeError)(e)); + } + }); + this.codec.on('emberStreamPacket', (packet) => { + try { + const root = (0, __1.berDecode)(packet); + if (root != null) { + this.emit('emberTree', root); + } + } + catch (e) { + this.emit('error', (0, util_1.normalizeError)(e)); + } + }); + this._initSocket(); + } + _initSocket() { + if (this.socket != null) { + this.socket.on('data', (data) => { + try { + this.codec.dataIn(data); + } + catch (e) { + this.emit('error', (0, util_1.normalizeError)(e)); + } + }); + this.socket.on('close', () => { + this.emit('disconnected'); + this.status = Client_1.ConnectionStatus.Connected; + this.socket?.removeAllListeners(); + this.socket = undefined; + }); + this.socket.on('error', (e) => { + this.emit('error', e); + }); + } + } + /** + * @param {number} timeout=2 + */ + async disconnect(timeout = 2) { + if (!this.isConnected() || this.socket === undefined) { + return Promise.resolve(); + } + return new Promise((resolve) => { + if (this.keepaliveIntervalTimer != null) { + clearInterval(this.keepaliveIntervalTimer); + this.keepaliveIntervalTimer = undefined; + } + if (this.socket) { + let done = false; + const cb = () => { + if (done) { + return; + } + done = true; + if (timer !== undefined) { + clearTimeout(timer); + timer = undefined; + } + resolve(); + }; + let timer; + if (timeout != null && !isNaN(timeout) && timeout > 0) { + timer = setTimeout(cb, 100 * timeout); + } + this.socket.end(cb); + } + this.status = Client_1.ConnectionStatus.Disconnected; + }); + } + /** + * + */ + handleClose() { + this.socket = undefined; + if (this.keepaliveIntervalTimer) + clearInterval(this.keepaliveIntervalTimer); + this.status = Client_1.ConnectionStatus.Disconnected; + this.emit('disconnected'); + } + isConnected() { + return this.socket !== undefined && !!this.socket; + } + sendBER(data) { + if (this.isConnected() && this.socket) { + try { + const frames = this.codec.encodeBER(data); + for (let i = 0; i < frames.length; i++) { + this.socket.write(frames[i]); + } + return true; + } + catch (e) { + this.handleClose(); + return false; + } + } + else { + return false; + } + } + /** + * + */ + sendKeepaliveRequest() { + if (this.isConnected() && this.socket) { + try { + this.socket.write(this.codec.keepAliveRequest()); + this.keepaliveResponseWindowTimer = setTimeout(() => { + this.handleClose(); + }, this.keepaliveMaxResponseTime); + } + catch (e) { + this.handleClose(); + } + } + } + /** + * + */ + sendKeepaliveResponse() { + if (this.isConnected() && this.socket) { + try { + this.socket.write(this.codec.keepAliveResponse()); + } + catch (e) { + this.handleClose(); + } + } + } + // sendBERNode(node: Root) { + // if (!node) return + // const ber = berEncode(node) + // this.sendBER(ber) + // } + startKeepAlive() { + this.keepaliveIntervalTimer = setInterval(() => { + try { + this.sendKeepaliveRequest(); + } + catch (e) { + this.emit('error', (0, util_1.normalizeError)(e)); + } + }, 1000 * this.keepaliveInterval); + } +} +exports.default = S101Socket; +//# sourceMappingURL=S101Socket.js.map \ No newline at end of file diff --git a/dist/Ember/Socket/S101Socket.js.map b/dist/Ember/Socket/S101Socket.js.map new file mode 100644 index 0000000..df195a2 --- /dev/null +++ b/dist/Ember/Socket/S101Socket.js.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Socket.js","sourceRoot":"","sources":["../../../src/Ember/Socket/S101Socket.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Ember/Socket/index.d.ts b/dist/Ember/Socket/index.d.ts new file mode 100644 index 0000000..ef96515 --- /dev/null +++ b/dist/Ember/Socket/index.d.ts @@ -0,0 +1,3 @@ +import S101Client from './S101Client'; +export { S101Client }; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/Ember/Socket/index.d.ts.map b/dist/Ember/Socket/index.d.ts.map new file mode 100644 index 0000000..1c88109 --- /dev/null +++ b/dist/Ember/Socket/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Ember/Socket/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,cAAc,CAAA;AAErC,OAAO,EAAE,UAAU,EAAE,CAAA"} \ No newline at end of file diff --git a/dist/Ember/Socket/index.js b/dist/Ember/Socket/index.js new file mode 100644 index 0000000..a467852 --- /dev/null +++ b/dist/Ember/Socket/index.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.S101Client = void 0; +const tslib_1 = require("tslib"); +const S101Client_1 = tslib_1.__importDefault(require("./S101Client")); +exports.S101Client = S101Client_1.default; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/Ember/Socket/index.js.map b/dist/Ember/Socket/index.js.map new file mode 100644 index 0000000..8f075ca --- /dev/null +++ b/dist/Ember/Socket/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Ember/Socket/index.ts"],"names":[],"mappings":";;;;AAAA,sEAAqC;AAE5B,qBAFF,oBAAU,CAEE"} \ No newline at end of file diff --git a/dist/Errors.d.ts b/dist/Errors.d.ts new file mode 100644 index 0000000..bb168f4 --- /dev/null +++ b/dist/Errors.d.ts @@ -0,0 +1,68 @@ +export { UnimplementedEmberTypeError, InvalidEmberNode, InvalidRequestFormat, InvalidEmberResponse, InvalidRequest, InvalidSourcesFormat, UnknownElement, MissingElementContents, MissingElementNumber, InvalidCommand, EmberTimeoutError, EmberAccessError, ASN1Error, S101SocketError, InvalidBERFormat, InvalidResultFormat, InvalidMatrixSignal, InvalidRequesrFormat, InvalidStringPair, PathDiscoveryFailure, }; +declare class UnimplementedEmberTypeError extends Error { + constructor(tag: number); +} +declare class S101SocketError extends Error { + constructor(message: string | undefined); +} +declare class ASN1Error extends Error { + constructor(message: string | undefined); +} +declare class EmberAccessError extends Error { + constructor(message: string | undefined); +} +declare class EmberTimeoutError extends Error { + constructor(message: string | undefined); +} +declare class InvalidCommand extends Error { + constructor(number: number); +} +declare class MissingElementNumber extends Error { + constructor(); +} +declare class MissingElementContents extends Error { + constructor(path: string); +} +declare class UnknownElement extends Error { + constructor(path: string); +} +declare class InvalidRequest extends Error { + constructor(); +} +declare class InvalidRequestFormat extends Error { + constructor(path: string); +} +declare class InvalidEmberNode extends Error { + constructor(path?: string, info?: string); +} +declare class InvalidEmberResponse extends Error { + constructor(req: string); +} +declare class PathDiscoveryFailure extends Error { + constructor(path: string); + setPath(path: string): void; + static getMessage(path: string): string; +} +declare class InvalidSourcesFormat extends Error { + constructor(); +} +declare class InvalidBERFormat extends Error { + /** + * + * @param {string} info + */ + constructor(info?: string); +} +declare class InvalidResultFormat extends Error { + constructor(info?: string); +} +declare class InvalidMatrixSignal extends Error { + constructor(value: number, info: string); +} +declare class InvalidStringPair extends Error { + constructor(); +} +declare class InvalidRequesrFormat extends Error { + constructor(path: string); +} +//# sourceMappingURL=Errors.d.ts.map \ No newline at end of file diff --git a/dist/Errors.d.ts.map b/dist/Errors.d.ts.map new file mode 100644 index 0000000..bf8b058 --- /dev/null +++ b/dist/Errors.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Errors.d.ts","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,2BAA2B,EAC3B,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,GACpB,CAAA;AAED,cAAM,2BAA4B,SAAQ,KAAK;gBAClC,GAAG,EAAE,MAAM;CAiBvB;AAED,cAAM,eAAgB,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM,GAAG,SAAS;CAGvC;AAED,cAAM,SAAU,SAAQ,KAAK;gBAChB,OAAO,EAAE,MAAM,GAAG,SAAS;CAGvC;AAED,cAAM,gBAAiB,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM,GAAG,SAAS;CAGvC;AAED,cAAM,iBAAkB,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,GAAG,SAAS;CAGvC;AAED,cAAM,cAAe,SAAQ,KAAK;gBACrB,MAAM,EAAE,MAAM;CAG1B;AAED,cAAM,oBAAqB,SAAQ,KAAK;;CAIvC;AAED,cAAM,sBAAuB,SAAQ,KAAK;gBAC7B,IAAI,EAAE,MAAM;CAGxB;AAED,cAAM,cAAe,SAAQ,KAAK;gBACrB,IAAI,EAAE,MAAM;CAGxB;AAED,cAAM,cAAe,SAAQ,KAAK;;CAIjC;AAED,cAAM,oBAAqB,SAAQ,KAAK;gBAC3B,IAAI,EAAE,MAAM;CAGxB;AAED,cAAM,gBAAiB,SAAQ,KAAK;gBACvB,IAAI,SAAY,EAAE,IAAI,SAAK;CAGvC;AAED,cAAM,oBAAqB,SAAQ,KAAK;gBAC3B,GAAG,EAAE,MAAM;CAGvB;AAED,cAAM,oBAAqB,SAAQ,KAAK;gBAC3B,IAAI,EAAE,MAAM;IAIxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI3B,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAGvC;AAED,cAAM,oBAAqB,SAAQ,KAAK;;CAIvC;AAED,cAAM,gBAAiB,SAAQ,KAAK;IACnC;;;OAGG;gBACS,IAAI,SAAK;CAGrB;AAED,cAAM,mBAAoB,SAAQ,KAAK;gBAC1B,IAAI,SAAK;CAGrB;AAED,cAAM,mBAAoB,SAAQ,KAAK;gBAC1B,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAGvC;AAED,cAAM,iBAAkB,SAAQ,KAAK;;CAIpC;AAED,cAAM,oBAAqB,SAAQ,KAAK;gBAC3B,IAAI,EAAE,MAAM;CAGxB"} \ No newline at end of file diff --git a/dist/Errors.js b/dist/Errors.js new file mode 100644 index 0000000..b424da2 --- /dev/null +++ b/dist/Errors.js @@ -0,0 +1,151 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PathDiscoveryFailure = exports.InvalidStringPair = exports.InvalidRequesrFormat = exports.InvalidMatrixSignal = exports.InvalidResultFormat = exports.InvalidBERFormat = exports.S101SocketError = exports.ASN1Error = exports.EmberAccessError = exports.EmberTimeoutError = exports.InvalidCommand = exports.MissingElementNumber = exports.MissingElementContents = exports.UnknownElement = exports.InvalidSourcesFormat = exports.InvalidRequest = exports.InvalidEmberResponse = exports.InvalidRequestFormat = exports.InvalidEmberNode = exports.UnimplementedEmberTypeError = void 0; +class UnimplementedEmberTypeError extends Error { + constructor(tag) { + super(); + this.name = this.constructor.name; + const identifier = (tag & 0xc0) >> 6; + const value = (tag & 0x1f).toString(); + let tagStr = tag.toString(); + if (identifier == 0) { + tagStr = '[UNIVERSAL ' + value + ']'; + } + else if (identifier == 1) { + tagStr = '[APPLICATION ' + value + ']'; + } + else if (identifier == 2) { + tagStr = '[CONTEXT ' + value + ']'; + } + else { + tagStr = '[PRIVATE ' + value + ']'; + } + this.message = 'Unimplemented EmBER type ' + tagStr; + } +} +exports.UnimplementedEmberTypeError = UnimplementedEmberTypeError; +class S101SocketError extends Error { + constructor(message) { + super(message); + } +} +exports.S101SocketError = S101SocketError; +class ASN1Error extends Error { + constructor(message) { + super(message); + } +} +exports.ASN1Error = ASN1Error; +class EmberAccessError extends Error { + constructor(message) { + super(message); + } +} +exports.EmberAccessError = EmberAccessError; +class EmberTimeoutError extends Error { + constructor(message) { + super(message); + } +} +exports.EmberTimeoutError = EmberTimeoutError; +class InvalidCommand extends Error { + constructor(number) { + super(`Invalid command ${number}`); + } +} +exports.InvalidCommand = InvalidCommand; +class MissingElementNumber extends Error { + constructor() { + super('Missing element number'); + } +} +exports.MissingElementNumber = MissingElementNumber; +class MissingElementContents extends Error { + constructor(path) { + super(`Missing element contents at ${path}`); + } +} +exports.MissingElementContents = MissingElementContents; +class UnknownElement extends Error { + constructor(path) { + super(`No element at path ${path}`); + } +} +exports.UnknownElement = UnknownElement; +class InvalidRequest extends Error { + constructor() { + super('Invalid Request'); + } +} +exports.InvalidRequest = InvalidRequest; +class InvalidRequestFormat extends Error { + constructor(path) { + super(`Invalid Request Format with path ${path}`); + } +} +exports.InvalidRequestFormat = InvalidRequestFormat; +class InvalidEmberNode extends Error { + constructor(path = 'unknown', info = '') { + super(`Invalid Ember Node at ${path}: ${info}`); + } +} +exports.InvalidEmberNode = InvalidEmberNode; +class InvalidEmberResponse extends Error { + constructor(req) { + super(`Invalid Ember Response to ${req}`); + } +} +exports.InvalidEmberResponse = InvalidEmberResponse; +class PathDiscoveryFailure extends Error { + constructor(path) { + super(PathDiscoveryFailure.getMessage(path)); + } + setPath(path) { + this.message = PathDiscoveryFailure.getMessage(path); + } + static getMessage(path) { + return `Failed path discovery at ${path}`; + } +} +exports.PathDiscoveryFailure = PathDiscoveryFailure; +class InvalidSourcesFormat extends Error { + constructor() { + super('Sources should be an array'); + } +} +exports.InvalidSourcesFormat = InvalidSourcesFormat; +class InvalidBERFormat extends Error { + /** + * + * @param {string} info + */ + constructor(info = '') { + super(`Invalid BER format: ${info}`); + } +} +exports.InvalidBERFormat = InvalidBERFormat; +class InvalidResultFormat extends Error { + constructor(info = '') { + super(`Invalid Result format: ${info}`); + } +} +exports.InvalidResultFormat = InvalidResultFormat; +class InvalidMatrixSignal extends Error { + constructor(value, info) { + super(`Invalid Matrix Signal ${value}: ${info}`); + } +} +exports.InvalidMatrixSignal = InvalidMatrixSignal; +class InvalidStringPair extends Error { + constructor() { + super('Invalid StringPair Value'); + } +} +exports.InvalidStringPair = InvalidStringPair; +class InvalidRequesrFormat extends Error { + constructor(path) { + super(`Can't process request for node ${path}`); + } +} +exports.InvalidRequesrFormat = InvalidRequesrFormat; +//# sourceMappingURL=Errors.js.map \ No newline at end of file diff --git a/dist/Errors.js.map b/dist/Errors.js.map new file mode 100644 index 0000000..c32353e --- /dev/null +++ b/dist/Errors.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Errors.js","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/S101/S101Codec.d.ts b/dist/S101/S101Codec.d.ts new file mode 100644 index 0000000..ff552cd --- /dev/null +++ b/dist/S101/S101Codec.d.ts @@ -0,0 +1,31 @@ +/// +import { EventEmitter } from 'eventemitter3'; +import { SmartBuffer } from 'smart-buffer'; +export type S101CodecEvents = { + emberPacket: [packet: Buffer]; + emberStreamPacket: [packet: Buffer]; + keepaliveReq: []; + keepaliveResp: []; +}; +export default class S101Codec extends EventEmitter { + inbuf: SmartBuffer; + emberbuf: SmartBuffer; + escaped: boolean; + private multiPacketBuffer?; + private isMultiPacket; + dataIn(buf: Buffer): void; + handleFrame(frame: SmartBuffer): void; + handleEmberFrame(frame: SmartBuffer): void; + private handleEmberPacket; + private handleEmberStreamPacket; + resetMultiPacketBuffer(): void; + encodeBER(data: Buffer): Buffer[]; + keepAliveRequest(): Buffer; + keepAliveResponse(): Buffer; + validateFrame(buf: Buffer): boolean; + private _makeBERFrame; + private _finalizeBuffer; + private _calculateCRC; + private _calculateCRCCE; +} +//# sourceMappingURL=S101Codec.d.ts.map \ No newline at end of file diff --git a/dist/S101/S101Codec.d.ts.map b/dist/S101/S101Codec.d.ts.map new file mode 100644 index 0000000..13c930a --- /dev/null +++ b/dist/S101/S101Codec.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Codec.d.ts","sourceRoot":"","sources":["../../src/S101/S101Codec.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAuD1C,MAAM,MAAM,eAAe,GAAG;IAC7B,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,YAAY,EAAE,EAAE,CAAA;IAChB,aAAa,EAAE,EAAE,CAAA;CACjB,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,YAAY,CAAC,eAAe,CAAC;IACnE,KAAK,cAAoB;IACzB,QAAQ,cAAoB;IAC5B,OAAO,UAAQ;IAEf,OAAO,CAAC,iBAAiB,CAAC,CAAa;IACvC,OAAO,CAAC,aAAa,CAAQ;IAE7B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAqBzB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IA6BrC,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAuD1C,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,uBAAuB;IAe/B,sBAAsB,IAAI,IAAI;IAK9B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IA+BjC,gBAAgB,IAAI,MAAM;IAU1B,iBAAiB,IAAI,MAAM;IAU3B,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAInC,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,eAAe;CAWvB"} \ No newline at end of file diff --git a/dist/S101/S101Codec.js b/dist/S101/S101Codec.js new file mode 100644 index 0000000..2cd43bf --- /dev/null +++ b/dist/S101/S101Codec.js @@ -0,0 +1,301 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +const eventemitter3_1 = require("eventemitter3"); +const smart_buffer_1 = require("smart-buffer"); +const debug_1 = tslib_1.__importDefault(require("debug")); +const util_1 = require("util"); +const ber_1 = require("../encodings/ber"); +const debug = (0, debug_1.default)('emberplus-connection:S101Codec'); +const S101_BOF = 0xfe; +const S101_EOF = 0xff; +const S101_CE = 0xfd; +const S101_XOR = 0x20; +const S101_INV = 0xf8; +const SLOT = 0x00; +const MSG_EMBER = 0x0e; +const CMD_EMBER = 0x00; +const CMD_KEEPALIVE_REQ = 0x01; +const CMD_KEEPALIVE_RESP = 0x02; +const VERSION = 0x01; +const FLAG_SINGLE_PACKET = 0xc0; +const FLAG_FIRST_MULTI_PACKET = 0x80; +const FLAG_LAST_MULTI_PACKET = 0x40; +const FLAG_EMPTY_PACKET = 0x20; +const FLAG_MULTI_PACKET = 0x00; +const DTD_GLOW = 0x01; +const DTD_VERSION_MAJOR = 0x02; +const DTD_VERSION_MINOR = 0x1f; +const CRC_TABLE = [ + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, + 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, + 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, + 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, + 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, + 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, + 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, + 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, + 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, + 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, + 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, + 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, + 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, + 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, + 0x3de3, 0x2c6a, 0x1ef1, 0x0f78, +]; +class S101Codec extends eventemitter3_1.EventEmitter { + constructor() { + super(...arguments); + this.inbuf = new smart_buffer_1.SmartBuffer(); + this.emberbuf = new smart_buffer_1.SmartBuffer(); + this.escaped = false; + this.isMultiPacket = false; + } + dataIn(buf) { + for (let i = 0; i < buf.length; i++) { + const b = buf.readUInt8(i); + if (this.escaped) { + this.inbuf.writeUInt8(b ^ S101_XOR); + this.escaped = false; + } + else if (b === S101_CE) { + this.escaped = true; + } + else if (b === S101_BOF) { + this.inbuf.clear(); + this.escaped = false; + } + else if (b === S101_EOF) { + this.inbuf.moveTo(0); + this.handleFrame(this.inbuf); + this.inbuf.clear(); + } + else { + this.inbuf.writeUInt8(b); + } + } + } + handleFrame(frame) { + if (!this.validateFrame(frame.toBuffer())) { + throw new Error((0, util_1.format)('dropping frame of length %d with invalid CRC', frame.length)); + } + const slot = frame.readUInt8(); + const message = frame.readUInt8(); + if (slot != SLOT || message != MSG_EMBER) { + throw new Error((0, util_1.format)('dropping frame of length %d (not an ember frame; slot=%d, msg=%d)', frame.length, slot, message)); + } + const command = frame.readUInt8(); + if (command === CMD_KEEPALIVE_REQ) { + debug('received keepalive request'); + this.emit('keepaliveReq'); + } + else if (command === CMD_KEEPALIVE_RESP) { + debug('received keepalive response'); + this.emit('keepaliveResp'); + } + else if (command === CMD_EMBER) { + const remainingData = frame.readBuffer(); + const emberFrame = smart_buffer_1.SmartBuffer.fromBuffer(remainingData); + this.handleEmberFrame(emberFrame); + } + else { + throw new Error((0, util_1.format)('dropping frame of length %d with unknown command %d', frame.length, command)); + } + } + handleEmberFrame(frame) { + const version = frame.readUInt8(); + const flags = frame.readUInt8(); + const dtd = frame.readUInt8(); + let appBytes = frame.readUInt8(); + if (version !== VERSION) { + debug('Warning: Unknown ember frame version %d', version); + } + if (dtd !== DTD_GLOW) { + // Don't throw, just warn and continue processing + debug('Warning: Received frame with DTD %d, expected %d', dtd, DTD_GLOW); + } + if (appBytes < 2) { + debug('Warning: Frame missing Glow DTD version'); + frame.skip(appBytes); + } + else { + frame.skip(1); // Skip minor version + frame.skip(1); // Skip major version + appBytes -= 2; + if (appBytes > 0) { + frame.skip(appBytes); + debug('Warning: App bytes with unknown meaning left over'); + } + } + let payload = frame.readBuffer(); + payload = payload.slice(0, payload.length - 2); // Remove CRC + if ((flags & FLAG_SINGLE_PACKET) === FLAG_SINGLE_PACKET) { + if ((flags & FLAG_EMPTY_PACKET) === 0) { + this.handleEmberPacket(payload); + } + } + else { + // Multi-packet handling + if ((flags & FLAG_FIRST_MULTI_PACKET) === FLAG_FIRST_MULTI_PACKET) { + debug('multi ember packet start'); + this.multiPacketBuffer = new smart_buffer_1.SmartBuffer(); + this.isMultiPacket = true; + this.multiPacketBuffer.writeBuffer(payload); + } + else if (this.isMultiPacket && this.multiPacketBuffer) { + this.multiPacketBuffer.writeBuffer(payload); + if ((flags & FLAG_LAST_MULTI_PACKET) === FLAG_LAST_MULTI_PACKET) { + debug('multi ember packet end'); + const completeData = this.multiPacketBuffer.toBuffer(); + this.handleEmberStreamPacket(completeData); + this.resetMultiPacketBuffer(); + } + } + } + } + handleEmberPacket(data) { + try { + const decoded = (0, ber_1.berDecode)(data); + if (data[0] === 0x60) { + // Root tag check + if (decoded.value) { + this.emit('emberPacket', data); + } + } + } + catch (error) { + console.error('Error decoding packet:', error); + } + } + handleEmberStreamPacket(data) { + try { + const decoded = (0, ber_1.berDecode)(data); + if (data[0] === 0x60 && data[2] === 0x66) { + // Root and stream tag check + if (decoded.value) { + this.emit('emberStreamPacket', data); + } + } + } + catch (error) { + console.error('Error decoding stream packet:', error); + this.resetMultiPacketBuffer(); + } + } + resetMultiPacketBuffer() { + this.multiPacketBuffer = undefined; + this.isMultiPacket = false; + } + encodeBER(data) { + const frames = []; + const encbuf = new smart_buffer_1.SmartBuffer(); + for (let i = 0; i < data.length; i++) { + const b = data.readUInt8(i); + if (b < S101_INV) { + encbuf.writeUInt8(b); + } + else { + encbuf.writeUInt8(S101_CE); + encbuf.writeUInt8(b ^ S101_XOR); + } + if (encbuf.length >= 1024 && i < data.length - 1) { + if (frames.length === 0) { + frames.push(this._makeBERFrame(FLAG_FIRST_MULTI_PACKET, encbuf.toBuffer())); + } + else { + frames.push(this._makeBERFrame(FLAG_MULTI_PACKET, encbuf.toBuffer())); + } + encbuf.clear(); + } + } + if (frames.length == 0) { + frames.push(this._makeBERFrame(FLAG_SINGLE_PACKET, encbuf.toBuffer())); + } + else { + frames.push(this._makeBERFrame(FLAG_LAST_MULTI_PACKET, encbuf.toBuffer())); + } + return frames; + } + keepAliveRequest() { + const packet = new smart_buffer_1.SmartBuffer(); + packet.writeUInt8(S101_BOF); + packet.writeUInt8(SLOT); + packet.writeUInt8(MSG_EMBER); + packet.writeUInt8(CMD_KEEPALIVE_REQ); + packet.writeUInt8(VERSION); + return this._finalizeBuffer(packet); + } + keepAliveResponse() { + const packet = new smart_buffer_1.SmartBuffer(); + packet.writeUInt8(S101_BOF); + packet.writeUInt8(SLOT); + packet.writeUInt8(MSG_EMBER); + packet.writeUInt8(CMD_KEEPALIVE_RESP); + packet.writeUInt8(VERSION); + return this._finalizeBuffer(packet); + } + validateFrame(buf) { + return this._calculateCRC(buf) == 0xf0b8; + } + _makeBERFrame(flags, data) { + const frame = new smart_buffer_1.SmartBuffer(); + frame.writeUInt8(S101_BOF); + frame.writeUInt8(SLOT); + frame.writeUInt8(MSG_EMBER); + frame.writeUInt8(CMD_EMBER); + frame.writeUInt8(VERSION); + frame.writeUInt8(flags); + frame.writeUInt8(DTD_GLOW); + frame.writeUInt8(2); // number of app bytes + frame.writeUInt8(DTD_VERSION_MINOR); + frame.writeUInt8(DTD_VERSION_MAJOR); + frame.writeBuffer(data); + return this._finalizeBuffer(frame); + } + _finalizeBuffer(smartbuf) { + const crc = ~this._calculateCRCCE(smartbuf.toBuffer().slice(1, smartbuf.length)) & 0xffff; + const crcHi = crc >> 8; + const crcLo = crc & 0xff; + if (crcLo < S101_INV) { + smartbuf.writeUInt8(crcLo); + } + else { + smartbuf.writeUInt8(S101_CE); + smartbuf.writeUInt8(crcLo ^ S101_XOR); + } + if (crcHi < S101_INV) { + smartbuf.writeUInt8(crcHi); + } + else { + smartbuf.writeUInt8(S101_CE); + smartbuf.writeUInt8(crcHi ^ S101_XOR); + } + smartbuf.writeUInt8(S101_EOF); + return smartbuf.toBuffer(); + } + _calculateCRC(buf) { + let crc = 0xffff; + for (let i = 0; i < buf.length; i++) { + const b = buf.readUInt8(i); + crc = ((crc >> 8) ^ CRC_TABLE[(crc ^ b) & 0xff]) & 0xffff; + } + return crc; + } + _calculateCRCCE(buf) { + let crc = 0xffff; + for (let i = 0; i < buf.length; i++) { + let b = buf.readUInt8(i); + if (b == S101_CE) { + b = S101_XOR ^ buf.readUInt8(++i); + } + crc = ((crc >> 8) ^ CRC_TABLE[(crc ^ b) & 0xff]) & 0xffff; + } + return crc; + } +} +exports.default = S101Codec; +//# sourceMappingURL=S101Codec.js.map \ No newline at end of file diff --git a/dist/S101/S101Codec.js.map b/dist/S101/S101Codec.js.map new file mode 100644 index 0000000..bfec991 --- /dev/null +++ b/dist/S101/S101Codec.js.map @@ -0,0 +1 @@ +{"version":3,"file":"S101Codec.js","sourceRoot":"","sources":["../../src/S101/S101Codec.ts"],"names":[],"mappings":";;;AAAA,iDAA4C;AAC5C,+CAA0C;AAC1C,0DAAyB;AACzB,+BAA6B;AAC7B,0CAA4C;AAE5C,MAAM,KAAK,GAAG,IAAA,eAAK,EAAC,gCAAgC,CAAC,CAAA;AAErD,MAAM,QAAQ,GAAG,IAAI,CAAA;AACrB,MAAM,QAAQ,GAAG,IAAI,CAAA;AACrB,MAAM,OAAO,GAAG,IAAI,CAAA;AACpB,MAAM,QAAQ,GAAG,IAAI,CAAA;AACrB,MAAM,QAAQ,GAAG,IAAI,CAAA;AAErB,MAAM,IAAI,GAAG,IAAI,CAAA;AAEjB,MAAM,SAAS,GAAG,IAAI,CAAA;AAEtB,MAAM,SAAS,GAAG,IAAI,CAAA;AACtB,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAC9B,MAAM,kBAAkB,GAAG,IAAI,CAAA;AAE/B,MAAM,OAAO,GAAG,IAAI,CAAA;AAEpB,MAAM,kBAAkB,GAAG,IAAI,CAAA;AAC/B,MAAM,uBAAuB,GAAG,IAAI,CAAA;AACpC,MAAM,sBAAsB,GAAG,IAAI,CAAA;AACnC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAC9B,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAE9B,MAAM,QAAQ,GAAG,IAAI,CAAA;AACrB,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAC9B,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAE9B,MAAM,SAAS,GAAG;IACjB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAC9B,CAAA;AASD,MAAqB,SAAU,SAAQ,4BAA6B;IAApE;;QACC,UAAK,GAAG,IAAI,0BAAW,EAAE,CAAA;QACzB,aAAQ,GAAG,IAAI,0BAAW,EAAE,CAAA;QAC5B,YAAO,GAAG,KAAK,CAAA;QAGP,kBAAa,GAAG,KAAK,CAAA;IA+P9B,CAAC;IA7PA,MAAM,CAAC,GAAW;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACpC,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;YAC1B,IAAI,IAAI,CAAC,OAAO,EAAE;gBACjB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAA;gBACnC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;aACpB;iBAAM,IAAI,CAAC,KAAK,OAAO,EAAE;gBACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;aACnB;iBAAM,IAAI,CAAC,KAAK,QAAQ,EAAE;gBAC1B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;gBAClB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;aACpB;iBAAM,IAAI,CAAC,KAAK,QAAQ,EAAE;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;gBACpB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC5B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;aAClB;iBAAM;gBACN,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;aACxB;SACD;IACF,CAAC;IAED,WAAW,CAAC,KAAkB;QAC7B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE;YAC1C,MAAM,IAAI,KAAK,CAAC,IAAA,aAAM,EAAC,8CAA8C,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;SACrF;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QACjC,IAAI,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,SAAS,EAAE;YACzC,MAAM,IAAI,KAAK,CACd,IAAA,aAAM,EAAC,mEAAmE,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CACxG,CAAA;SACD;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QACjC,IAAI,OAAO,KAAK,iBAAiB,EAAE;YAClC,KAAK,CAAC,4BAA4B,CAAC,CAAA;YACnC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;SACzB;aAAM,IAAI,OAAO,KAAK,kBAAkB,EAAE;YAC1C,KAAK,CAAC,6BAA6B,CAAC,CAAA;YACpC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;SAC1B;aAAM,IAAI,OAAO,KAAK,SAAS,EAAE;YACjC,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,EAAE,CAAA;YACxC,MAAM,UAAU,GAAG,0BAAW,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;YACxD,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAA;SACjC;aAAM;YACN,MAAM,IAAI,KAAK,CAAC,IAAA,aAAM,EAAC,qDAAqD,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;SACrG;IACF,CAAC;IAED,gBAAgB,CAAC,KAAkB;QAClC,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QACjC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QAC7B,IAAI,QAAQ,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;QAEhC,IAAI,OAAO,KAAK,OAAO,EAAE;YACxB,KAAK,CAAC,yCAAyC,EAAE,OAAO,CAAC,CAAA;SACzD;QAED,IAAI,GAAG,KAAK,QAAQ,EAAE;YACrB,iDAAiD;YACjD,KAAK,CAAC,kDAAkD,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;SACxE;QAED,IAAI,QAAQ,GAAG,CAAC,EAAE;YACjB,KAAK,CAAC,yCAAyC,CAAC,CAAA;YAChD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;SACpB;aAAM;YACN,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,qBAAqB;YACnC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,qBAAqB;YACnC,QAAQ,IAAI,CAAC,CAAA;YACb,IAAI,QAAQ,GAAG,CAAC,EAAE;gBACjB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACpB,KAAK,CAAC,mDAAmD,CAAC,CAAA;aAC1D;SACD;QAED,IAAI,OAAO,GAAG,KAAK,CAAC,UAAU,EAAE,CAAA;QAChC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA,CAAC,aAAa;QAE5D,IAAI,CAAC,KAAK,GAAG,kBAAkB,CAAC,KAAK,kBAAkB,EAAE;YACxD,IAAI,CAAC,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,EAAE;gBACtC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAA;aAC/B;SACD;aAAM;YACN,wBAAwB;YACxB,IAAI,CAAC,KAAK,GAAG,uBAAuB,CAAC,KAAK,uBAAuB,EAAE;gBAClE,KAAK,CAAC,0BAA0B,CAAC,CAAA;gBACjC,IAAI,CAAC,iBAAiB,GAAG,IAAI,0BAAW,EAAE,CAAA;gBAC1C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;gBACzB,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;aAC3C;iBAAM,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,iBAAiB,EAAE;gBACxD,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;gBAE3C,IAAI,CAAC,KAAK,GAAG,sBAAsB,CAAC,KAAK,sBAAsB,EAAE;oBAChE,KAAK,CAAC,wBAAwB,CAAC,CAAA;oBAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAA;oBACtD,IAAI,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAA;oBAC1C,IAAI,CAAC,sBAAsB,EAAE,CAAA;iBAC7B;aACD;SACD;IACF,CAAC;IAEO,iBAAiB,CAAC,IAAY;QACrC,IAAI;YACH,MAAM,OAAO,GAAG,IAAA,eAAS,EAAC,IAAI,CAAC,CAAA;YAC/B,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;gBACrB,iBAAiB;gBACjB,IAAI,OAAO,CAAC,KAAK,EAAE;oBAClB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;iBAC9B;aACD;SACD;QAAC,OAAO,KAAK,EAAE;YACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAA;SAC9C;IACF,CAAC;IAEO,uBAAuB,CAAC,IAAY;QAC3C,IAAI;YACH,MAAM,OAAO,GAAG,IAAA,eAAS,EAAC,IAAI,CAAC,CAAA;YAC/B,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;gBACzC,4BAA4B;gBAC5B,IAAI,OAAO,CAAC,KAAK,EAAE;oBAClB,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;iBACpC;aACD;SACD;QAAC,OAAO,KAAK,EAAE;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;YACrD,IAAI,CAAC,sBAAsB,EAAE,CAAA;SAC7B;IACF,CAAC;IAED,sBAAsB;QACrB,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAA;QAClC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;IAC3B,CAAC;IAED,SAAS,CAAC,IAAY;QACrB,MAAM,MAAM,GAAG,EAAE,CAAA;QACjB,MAAM,MAAM,GAAG,IAAI,0BAAW,EAAE,CAAA;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;YAC3B,IAAI,CAAC,GAAG,QAAQ,EAAE;gBACjB,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;aACpB;iBAAM;gBACN,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBAC1B,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAA;aAC/B;YAED,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;gBACjD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;oBACxB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;iBAC3E;qBAAM;oBACN,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;iBACrE;gBACD,MAAM,CAAC,KAAK,EAAE,CAAA;aACd;SACD;QAED,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE;YACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;SACtE;aAAM;YACN,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,sBAAsB,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;SAC1E;QAED,OAAO,MAAM,CAAA;IACd,CAAC;IAED,gBAAgB;QACf,MAAM,MAAM,GAAG,IAAI,0BAAW,EAAE,CAAA;QAChC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC3B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACvB,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QAC5B,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;QACpC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC;IAED,iBAAiB;QAChB,MAAM,MAAM,GAAG,IAAI,0BAAW,EAAE,CAAA;QAChC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC3B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACvB,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QAC5B,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;QACrC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC;IAED,aAAa,CAAC,GAAW;QACxB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,MAAM,CAAA;IACzC,CAAC;IAEO,aAAa,CAAC,KAAa,EAAE,IAAY;QAChD,MAAM,KAAK,GAAG,IAAI,0BAAW,EAAE,CAAA;QAC/B,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC1B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACtB,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QAC3B,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QAC3B,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACzB,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QACvB,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC1B,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA,CAAC,sBAAsB;QAC1C,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;QACnC,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;QACnC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACvB,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC;IAEO,eAAe,CAAC,QAAqB;QAC5C,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAA;QACzF,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,CAAA;QACtB,MAAM,KAAK,GAAG,GAAG,GAAG,IAAI,CAAA;QAExB,IAAI,KAAK,GAAG,QAAQ,EAAE;YACrB,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;SAC1B;aAAM;YACN,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;YAC5B,QAAQ,CAAC,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAA;SACrC;QAED,IAAI,KAAK,GAAG,QAAQ,EAAE;YACrB,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;SAC1B;aAAM;YACN,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;YAC5B,QAAQ,CAAC,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAA;SACrC;QAED,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC7B,OAAO,QAAQ,CAAC,QAAQ,EAAE,CAAA;IAC3B,CAAC;IAEO,aAAa,CAAC,GAAW;QAChC,IAAI,GAAG,GAAG,MAAM,CAAA;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACpC,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;YAC1B,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAAA;SACzD;QACD,OAAO,GAAG,CAAA;IACX,CAAC;IAEO,eAAe,CAAC,GAAW;QAClC,IAAI,GAAG,GAAG,MAAM,CAAA;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACpC,IAAI,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;YACxB,IAAI,CAAC,IAAI,OAAO,EAAE;gBACjB,CAAC,GAAG,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAA;aACjC;YACD,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAAA;SACzD;QACD,OAAO,GAAG,CAAA;IACX,CAAC;CACD;AArQD,4BAqQC"} \ No newline at end of file diff --git a/dist/S101/index.d.ts b/dist/S101/index.d.ts new file mode 100644 index 0000000..e7d4c40 --- /dev/null +++ b/dist/S101/index.d.ts @@ -0,0 +1,3 @@ +import S101Codec from './S101Codec'; +export { S101Codec }; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/S101/index.d.ts.map b/dist/S101/index.d.ts.map new file mode 100644 index 0000000..ff8b67d --- /dev/null +++ b/dist/S101/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/S101/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,aAAa,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAE,CAAA"} \ No newline at end of file diff --git a/dist/S101/index.js b/dist/S101/index.js new file mode 100644 index 0000000..c1299de --- /dev/null +++ b/dist/S101/index.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.S101Codec = void 0; +const tslib_1 = require("tslib"); +const S101Codec_1 = tslib_1.__importDefault(require("./S101Codec")); +exports.S101Codec = S101Codec_1.default; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/S101/index.js.map b/dist/S101/index.js.map new file mode 100644 index 0000000..b2863de --- /dev/null +++ b/dist/S101/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/S101/index.ts"],"names":[],"mappings":";;;;AAAA,oEAAmC;AAE1B,oBAFF,mBAAS,CAEE"} \ No newline at end of file diff --git a/dist/encodings/ber/constants.d.ts b/dist/encodings/ber/constants.d.ts new file mode 100644 index 0000000..1ea003c --- /dev/null +++ b/dist/encodings/ber/constants.d.ts @@ -0,0 +1,28 @@ +export { RootBERID, ParameterBERID, CommandBERID, NodeBERID, ElementCollectionBERID, StreamEntryBERID, StreamEntriesBERID, StringIntegerPairBERID, StringIntegerCollectionBERID, QualifiedParameterBERID, QualifiedNodeBERID, RootElementsBERID, StreamDescriptionBERID, MatrixBERID, TargetBERID, SourceBERID, ConnectionBERID, QualifiedMatrixBERID, LabelBERID, FunctionBERID, QualifiedFunctionBERID, FunctionArgumentBERID, InvocationBERID, InvocationResultBERID, TemplateBERID, QualifiedTemplateBERID, }; +declare const RootBERID: number; +declare const ParameterBERID: number; +declare const CommandBERID: number; +declare const NodeBERID: number; +declare const ElementCollectionBERID: number; +declare const StreamEntryBERID: number; +declare const StreamEntriesBERID: number; +declare const StringIntegerPairBERID: number; +declare const StringIntegerCollectionBERID: number; +declare const QualifiedParameterBERID: number; +declare const QualifiedNodeBERID: number; +declare const RootElementsBERID: number; +declare const StreamDescriptionBERID: number; +declare const MatrixBERID: number; +declare const TargetBERID: number; +declare const SourceBERID: number; +declare const ConnectionBERID: number; +declare const QualifiedMatrixBERID: number; +declare const LabelBERID: number; +declare const FunctionBERID: number; +declare const QualifiedFunctionBERID: number; +declare const FunctionArgumentBERID: number; +declare const InvocationBERID: number; +declare const InvocationResultBERID: number; +declare const TemplateBERID: number; +declare const QualifiedTemplateBERID: number; +//# sourceMappingURL=constants.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/constants.d.ts.map b/dist/encodings/ber/constants.d.ts.map new file mode 100644 index 0000000..26aaea9 --- /dev/null +++ b/dist/encodings/ber/constants.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/encodings/ber/constants.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,SAAS,EACT,cAAc,EACd,YAAY,EACZ,SAAS,EACT,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,WAAW,EACX,WAAW,EACX,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,sBAAsB,GACtB,CAAA;AAED,QAAA,MAAM,SAAS,QAAqB,CAAA;AACpC,QAAA,MAAM,cAAc,QAAqB,CAAA;AACzC,QAAA,MAAM,YAAY,QAAqB,CAAA;AACvC,QAAA,MAAM,SAAS,QAAqB,CAAA;AACpC,QAAA,MAAM,sBAAsB,QAAqB,CAAA;AACjD,QAAA,MAAM,gBAAgB,QAAqB,CAAA;AAC3C,QAAA,MAAM,kBAAkB,QAAqB,CAAA;AAC7C,QAAA,MAAM,sBAAsB,QAAqB,CAAA;AACjD,QAAA,MAAM,4BAA4B,QAAqB,CAAA;AACvD,QAAA,MAAM,uBAAuB,QAAqB,CAAA;AAClD,QAAA,MAAM,kBAAkB,QAAsB,CAAA;AAC9C,QAAA,MAAM,iBAAiB,QAAsB,CAAA;AAC7C,QAAA,MAAM,sBAAsB,QAAsB,CAAA;AAClD,QAAA,MAAM,WAAW,QAAsB,CAAA;AACvC,QAAA,MAAM,WAAW,QAAsB,CAAA;AACvC,QAAA,MAAM,WAAW,QAAsB,CAAA;AACvC,QAAA,MAAM,eAAe,QAAsB,CAAA;AAC3C,QAAA,MAAM,oBAAoB,QAAsB,CAAA;AAChD,QAAA,MAAM,UAAU,QAAsB,CAAA;AACtC,QAAA,MAAM,aAAa,QAAsB,CAAA;AACzC,QAAA,MAAM,sBAAsB,QAAsB,CAAA;AAClD,QAAA,MAAM,qBAAqB,QAAsB,CAAA;AACjD,QAAA,MAAM,eAAe,QAAsB,CAAA;AAC3C,QAAA,MAAM,qBAAqB,QAAsB,CAAA;AACjD,QAAA,MAAM,aAAa,QAAsB,CAAA;AACzC,QAAA,MAAM,sBAAsB,QAAsB,CAAA"} \ No newline at end of file diff --git a/dist/encodings/ber/constants.js b/dist/encodings/ber/constants.js new file mode 100644 index 0000000..0783f10 --- /dev/null +++ b/dist/encodings/ber/constants.js @@ -0,0 +1,58 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.QualifiedTemplateBERID = exports.TemplateBERID = exports.InvocationResultBERID = exports.InvocationBERID = exports.FunctionArgumentBERID = exports.QualifiedFunctionBERID = exports.FunctionBERID = exports.LabelBERID = exports.QualifiedMatrixBERID = exports.ConnectionBERID = exports.SourceBERID = exports.TargetBERID = exports.MatrixBERID = exports.StreamDescriptionBERID = exports.RootElementsBERID = exports.QualifiedNodeBERID = exports.QualifiedParameterBERID = exports.StringIntegerCollectionBERID = exports.StringIntegerPairBERID = exports.StreamEntriesBERID = exports.StreamEntryBERID = exports.ElementCollectionBERID = exports.NodeBERID = exports.CommandBERID = exports.ParameterBERID = exports.RootBERID = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../Ber")); +const RootBERID = Ber.APPLICATION(0); +exports.RootBERID = RootBERID; +const ParameterBERID = Ber.APPLICATION(1); +exports.ParameterBERID = ParameterBERID; +const CommandBERID = Ber.APPLICATION(2); +exports.CommandBERID = CommandBERID; +const NodeBERID = Ber.APPLICATION(3); +exports.NodeBERID = NodeBERID; +const ElementCollectionBERID = Ber.APPLICATION(4); +exports.ElementCollectionBERID = ElementCollectionBERID; +const StreamEntryBERID = Ber.APPLICATION(5); +exports.StreamEntryBERID = StreamEntryBERID; +const StreamEntriesBERID = Ber.APPLICATION(6); +exports.StreamEntriesBERID = StreamEntriesBERID; +const StringIntegerPairBERID = Ber.APPLICATION(7); +exports.StringIntegerPairBERID = StringIntegerPairBERID; +const StringIntegerCollectionBERID = Ber.APPLICATION(8); +exports.StringIntegerCollectionBERID = StringIntegerCollectionBERID; +const QualifiedParameterBERID = Ber.APPLICATION(9); +exports.QualifiedParameterBERID = QualifiedParameterBERID; +const QualifiedNodeBERID = Ber.APPLICATION(10); +exports.QualifiedNodeBERID = QualifiedNodeBERID; +const RootElementsBERID = Ber.APPLICATION(11); +exports.RootElementsBERID = RootElementsBERID; +const StreamDescriptionBERID = Ber.APPLICATION(12); +exports.StreamDescriptionBERID = StreamDescriptionBERID; +const MatrixBERID = Ber.APPLICATION(13); +exports.MatrixBERID = MatrixBERID; +const TargetBERID = Ber.APPLICATION(14); +exports.TargetBERID = TargetBERID; +const SourceBERID = Ber.APPLICATION(15); +exports.SourceBERID = SourceBERID; +const ConnectionBERID = Ber.APPLICATION(16); +exports.ConnectionBERID = ConnectionBERID; +const QualifiedMatrixBERID = Ber.APPLICATION(17); +exports.QualifiedMatrixBERID = QualifiedMatrixBERID; +const LabelBERID = Ber.APPLICATION(18); +exports.LabelBERID = LabelBERID; +const FunctionBERID = Ber.APPLICATION(19); +exports.FunctionBERID = FunctionBERID; +const QualifiedFunctionBERID = Ber.APPLICATION(20); +exports.QualifiedFunctionBERID = QualifiedFunctionBERID; +const FunctionArgumentBERID = Ber.APPLICATION(21); +exports.FunctionArgumentBERID = FunctionArgumentBERID; +const InvocationBERID = Ber.APPLICATION(22); +exports.InvocationBERID = InvocationBERID; +const InvocationResultBERID = Ber.APPLICATION(23); +exports.InvocationResultBERID = InvocationResultBERID; +const TemplateBERID = Ber.APPLICATION(24); +exports.TemplateBERID = TemplateBERID; +const QualifiedTemplateBERID = Ber.APPLICATION(25); +exports.QualifiedTemplateBERID = QualifiedTemplateBERID; +//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/dist/encodings/ber/constants.js.map b/dist/encodings/ber/constants.js.map new file mode 100644 index 0000000..22554eb --- /dev/null +++ b/dist/encodings/ber/constants.js.map @@ -0,0 +1 @@ +{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/encodings/ber/constants.ts"],"names":[],"mappings":";;;;AAAA,uDAAgC;AA+BhC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BnC,8BAAS;AA6BV,MAAM,cAAc,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BxC,wCAAc;AA6Bf,MAAM,YAAY,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BtC,oCAAY;AA6Bb,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BnC,8BAAS;AA6BV,MAAM,sBAAsB,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BhD,wDAAsB;AA6BvB,MAAM,gBAAgB,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5B1C,4CAAgB;AA6BjB,MAAM,kBAAkB,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5B5C,gDAAkB;AA6BnB,MAAM,sBAAsB,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BhD,wDAAsB;AA6BvB,MAAM,4BAA4B,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BtD,oEAA4B;AA6B7B,MAAM,uBAAuB,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AA5BjD,0DAAuB;AA6BxB,MAAM,kBAAkB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5B7C,gDAAkB;AA6BnB,MAAM,iBAAiB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5B5C,8CAAiB;AA6BlB,MAAM,sBAAsB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BjD,wDAAsB;AA6BvB,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BtC,kCAAW;AA6BZ,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BtC,kCAAW;AA6BZ,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BtC,kCAAW;AA6BZ,MAAM,eAAe,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5B1C,0CAAe;AA6BhB,MAAM,oBAAoB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5B/C,oDAAoB;AA6BrB,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BrC,gCAAU;AA6BX,MAAM,aAAa,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BxC,sCAAa;AA6Bd,MAAM,sBAAsB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BjD,wDAAsB;AA6BvB,MAAM,qBAAqB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BhD,sDAAqB;AA6BtB,MAAM,eAAe,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5B1C,0CAAe;AA6BhB,MAAM,qBAAqB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BhD,sDAAqB;AA6BtB,MAAM,aAAa,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BxC,sCAAa;AA6Bd,MAAM,sBAAsB,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AA5BjD,wDAAsB"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Command.d.ts b/dist/encodings/ber/decoder/Command.d.ts new file mode 100644 index 0000000..f5e457a --- /dev/null +++ b/dist/encodings/ber/decoder/Command.d.ts @@ -0,0 +1,6 @@ +import * as Ber from '../../../Ber'; +import { Command } from '../../../model/Command'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export { decodeCommand }; +declare function decodeCommand(reader: Ber.Reader, options?: DecodeOptions): DecodeResult; +//# sourceMappingURL=Command.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Command.d.ts.map b/dist/encodings/ber/decoder/Command.d.ts.map new file mode 100644 index 0000000..eb9cd8f --- /dev/null +++ b/dist/encodings/ber/decoder/Command.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Command.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/Command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,EACN,OAAO,EAOP,MAAM,wBAAwB,CAAA;AAI/B,OAAO,EACN,aAAa,EAEb,YAAY,EAOZ,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,aAAa,EAAE,CAAA;AAiBxB,iBAAS,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAE,aAA6B,GAAG,YAAY,CAAC,OAAO,CAAC,CAiDxG"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Command.js b/dist/encodings/ber/decoder/Command.js new file mode 100644 index 0000000..c4aadba --- /dev/null +++ b/dist/encodings/ber/decoder/Command.js @@ -0,0 +1,68 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeCommand = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../../Ber")); +const Command_1 = require("../../../model/Command"); +const Invocation_1 = require("./Invocation"); +const constants_1 = require("../constants"); +const DecodeResult_1 = require("./DecodeResult"); +function readDirFieldMask(reader) { + const intToMask = { + [-2]: Command_1.FieldFlags.Sparse, + [-1]: Command_1.FieldFlags.All, + [0]: Command_1.FieldFlags.Default, + [1]: Command_1.FieldFlags.Identifier, + [2]: Command_1.FieldFlags.Description, + [3]: Command_1.FieldFlags.Tree, + [4]: Command_1.FieldFlags.Value, + [5]: Command_1.FieldFlags.Connections, + }; + return intToMask[reader.readInt()]; +} +function decodeCommand(reader, options = DecodeResult_1.defaultDecode) { + reader.readSequence(constants_1.CommandBERID); + let type = null; + let dirFieldMask = undefined; + let invocation = undefined; + const errors = []; + const endOffset = reader.offset + reader.length; + while (reader.offset < endOffset) { + const tag = reader.readSequence(); + switch (tag) { + case Ber.CONTEXT(0): + type = reader.readInt(); + break; + case Ber.CONTEXT(1): + dirFieldMask = readDirFieldMask(reader); + if (!dirFieldMask) { + errors.push(new Error(`decode command: encounted unknown dir field mask`)); + } + break; + case Ber.CONTEXT(2): + invocation = (0, DecodeResult_1.appendErrors)((0, Invocation_1.decodeInvocation)(reader, options), errors); + break; + case 0: + break; // Indefinite lengths + default: + (0, DecodeResult_1.unknownContext)(errors, 'decode command', tag, options); + (0, DecodeResult_1.skipNext)(reader); + break; + } + } + type = (0, DecodeResult_1.check)(type, 'decode command', 'type', Command_1.CommandType.Subscribe, errors, options); + switch (type) { + case Command_1.CommandType.Subscribe: + return (0, DecodeResult_1.makeResult)(new Command_1.SubscribeImpl(), errors); + case Command_1.CommandType.Unsubscribe: + return (0, DecodeResult_1.makeResult)(new Command_1.UnsubscribeImpl(), errors); + case Command_1.CommandType.GetDirectory: + return (0, DecodeResult_1.makeResult)(new Command_1.GetDirectoryImpl(dirFieldMask), errors); + case Command_1.CommandType.Invoke: + return (0, DecodeResult_1.makeResult)(new Command_1.InvokeImpl(invocation), errors); + default: + return (0, DecodeResult_1.unexpected)(errors, 'decode command', `command type '${type}' is not recognized`, new Command_1.SubscribeImpl(), options); + } +} +exports.decodeCommand = decodeCommand; +//# sourceMappingURL=Command.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Command.js.map b/dist/encodings/ber/decoder/Command.js.map new file mode 100644 index 0000000..0937982 --- /dev/null +++ b/dist/encodings/ber/decoder/Command.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Command.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/Command.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Connection.d.ts b/dist/encodings/ber/decoder/Connection.d.ts new file mode 100644 index 0000000..09046ae --- /dev/null +++ b/dist/encodings/ber/decoder/Connection.d.ts @@ -0,0 +1,6 @@ +import * as Ber from '../../../Ber'; +import { Connection } from '../../../model/Connection'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export { decodeConnection }; +declare function decodeConnection(reader: Ber.Reader, options?: DecodeOptions): DecodeResult; +//# sourceMappingURL=Connection.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Connection.d.ts.map b/dist/encodings/ber/decoder/Connection.d.ts.map new file mode 100644 index 0000000..8620e0f --- /dev/null +++ b/dist/encodings/ber/decoder/Connection.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Connection.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/Connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,UAAU,EAA8D,MAAM,2BAA2B,CAAA;AAElH,OAAO,EACN,aAAa,EAEb,YAAY,EAOZ,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAE3B,iBAAS,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAE,aAA6B,GAAG,YAAY,CAAC,UAAU,CAAC,CAuC9G"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Connection.js b/dist/encodings/ber/decoder/Connection.js new file mode 100644 index 0000000..b906b27 --- /dev/null +++ b/dist/encodings/ber/decoder/Connection.js @@ -0,0 +1,77 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeConnection = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../../Ber")); +const Connection_1 = require("../../../model/Connection"); +const constants_1 = require("../constants"); +const DecodeResult_1 = require("./DecodeResult"); +function decodeConnection(reader, options = DecodeResult_1.defaultDecode) { + reader.readSequence(constants_1.ConnectionBERID); + let target = null; + let sources = undefined; + let operation = undefined; + let disposition = undefined; + let encodedSources; + const errors = []; + const endOffset = reader.offset + reader.length; + while (reader.offset < endOffset) { + const tag = reader.readSequence(); + switch (tag) { + case Ber.CONTEXT(0): + target = reader.readInt(); + break; + case Ber.CONTEXT(1): + encodedSources = reader.readRelativeOID(Ber.BERDataTypes.RELATIVE_OID); + if (encodedSources.length === 0) { + sources = []; + } + else { + sources = encodedSources.split('.').map((i) => Number(i)); + } + break; + case Ber.CONTEXT(2): + operation = (0, DecodeResult_1.appendErrors)(readConnectionOperation(reader.readInt(), options), errors); + break; + case Ber.CONTEXT(3): + disposition = (0, DecodeResult_1.appendErrors)(readConnectionDisposition(reader.readInt(), options), errors); + break; + case 0: + break; // Indefinite lengths + default: + (0, DecodeResult_1.unknownContext)(errors, 'decode connection', tag, options); + (0, DecodeResult_1.skipNext)(reader); + break; + } + } + target = (0, DecodeResult_1.check)(target, 'deocde connection', 'target', -1, errors, options); + return (0, DecodeResult_1.makeResult)(new Connection_1.ConnectionImpl(target, sources, operation, disposition), errors); +} +exports.decodeConnection = decodeConnection; +function readConnectionOperation(value, options = DecodeResult_1.defaultDecode) { + switch (value) { + case 0: + return (0, DecodeResult_1.makeResult)(Connection_1.ConnectionOperation.Absolute); + case 1: + return (0, DecodeResult_1.makeResult)(Connection_1.ConnectionOperation.Connect); + case 2: + return (0, DecodeResult_1.makeResult)(Connection_1.ConnectionOperation.Disconnect); + default: + return (0, DecodeResult_1.unexpected)([], 'read connection options', `unexpected connection operation '${value}'`, Connection_1.ConnectionOperation.Absolute, options); + } +} +function readConnectionDisposition(value, options = DecodeResult_1.defaultDecode) { + switch (value) { + case 0: + return (0, DecodeResult_1.makeResult)(Connection_1.ConnectionDisposition.Tally); + case 1: + return (0, DecodeResult_1.makeResult)(Connection_1.ConnectionDisposition.Modified); + case 2: + return (0, DecodeResult_1.makeResult)(Connection_1.ConnectionDisposition.Pending); + case 3: + return (0, DecodeResult_1.makeResult)(Connection_1.ConnectionDisposition.Locked); + default: + return (0, DecodeResult_1.unexpected)([], 'read connection options', `unexpected connection operation '${value}'`, Connection_1.ConnectionDisposition.Tally, options); + } +} +//# sourceMappingURL=Connection.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Connection.js.map b/dist/encodings/ber/decoder/Connection.js.map new file mode 100644 index 0000000..7416445 --- /dev/null +++ b/dist/encodings/ber/decoder/Connection.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Connection.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/Connection.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/DecodeResult.d.ts b/dist/encodings/ber/decoder/DecodeResult.d.ts new file mode 100644 index 0000000..bc39e46 --- /dev/null +++ b/dist/encodings/ber/decoder/DecodeResult.d.ts @@ -0,0 +1,124 @@ +import * as Ber from '../../../Ber'; +export { DecodeOptions, defaultDecode, DecodeResult, whatever, check, DecodeError, makeResult, unknownContext, unknownApplication, safeSet, guarded, appendErrors, unexpected, skipNext, }; +/** + * Control what cuases an exception during decoding. + */ +interface DecodeOptions { + /** Skip unknown application tags, used to identify objects. */ + skipApplicationTags: boolean; + /** Skip unknown context tags, used to identify the properties of objects. */ + skipContextTags: boolean; + /** Substitute a default value when a required value is missing. */ + substituteForRequired: boolean; + /** Skip past unexpected enumeration values. */ + skipUnexpected: boolean; +} +/** + * Default decoding values. Prevents throwing exceptions while decoding. + */ +declare const defaultDecode: DecodeOptions; +/** + * Decoders are forgiving and return both a candidate value and a list of + * errors found in the source data. + */ +interface DecodeResult { + /** Candicate decoded value. */ + value: T; + /** List of errors, if any, found during decoding. */ + errors?: Array; +} +/** + * Return the decoded result whatever errors are reported. + * @param decres Result of decoding. + * @returns Candidate result of decoding, ignoring any errors. + * @ + */ +declare function whatever(decres: DecodeResult): T; +/** + * Compound error containing details of all problems encountered when + * decoding an EmberPlus BER stream. + */ +declare class DecodeError extends Error { + /** Details of each error enountered during encoding. */ + readonly sub: Array; + /** + * Create an error with details of decoding issues. + * @param errors List of decoding sub-errors. + */ + constructor(errors: Array); +} +/** + * Return the decoded result if no errors, otherwise throw a summary error. + * @param decres Result of decoding. + * @returns Candidate result of decoding, only if no errors. + * @throws Summary when errors exists. + */ +declare function guarded(decres: DecodeResult): T; +/** + * Make a decoded result from an initial value with an empty list if errors. + * @param t Value to embed in the initial result. + */ +declare function makeResult(t: T, errors?: Array): DecodeResult; +/** + * Process a decoding problem when a context parameter tag is not recognized. + * @param decres Decoding result to add the error to (if appropriate). + * @param context Description of where the tag is. + * @param tag Unrecognized tag. + * @param options Control the processing of the error. + */ +declare function unknownContext(decres: DecodeResult | Array, context: string, tag: number | null, options?: DecodeOptions): void; +/** + * Process a decoding problem when an application tag is not recognized. + * @param decres Decoding result to add the error to (if appropriate). + * @param context Description of where the tag is. + * @param tag Unrecognized tag. + * @param options Control the processing of the error. + */ +declare function unknownApplication(decres: DecodeResult | Array, context: string, tag: number | null, options?: DecodeOptions): void; +/** + * Safely update a value from another decoding stage, merging errors. + * @param result Result of a decoding stage. + * @param update Value to be updated. + * @param fn Function to use to update a value with the result. + */ +declare function safeSet(result: DecodeResult, update: DecodeResult, fn: (s: S, t: T) => T): DecodeResult; +/** + * Check a value and if it is _null_ or _undefined_ then follow the options + * to either substitute a replacement truthy value, reporting an issue in the + * errors list, or throw an error when `subsituteForRequired` is `false`. + * @param value Value that may be somehow not defined. + * @param context Description of where the value is. + * @param propertyName Name of the property. + * @param substitute Substitute value in the event that the value is missing. + * @param decres A decoding result with an error list to be extended or a + * stand alone error list. + * @param options Control the processing of the check. + * @returns Value or, if somehow not defined, the substitute. + */ +declare function check(value: T | null | undefined, context: string, propertyName: string, substitute: T, decres: DecodeResult | Array, options?: DecodeOptions): T; +/** + * Extend an error list using any errors in the given source, returning the + * source value. + * @param source Decoding result to split apart. + * @param decres Decoding result to extend the error list of or a stand alone + * error list. + * @returns The value embedded in the source. + */ +declare function appendErrors(source: DecodeResult, decres: DecodeResult | Array): T; +/** + * Handle an unexpected enumeration value, returning a substitute value or + * throwing an errors depending on option `skipUnexpected`. + * @param decres Decoding result to add the error to (if appropriate). + * @param context Description of where the tag is. + * @param message Description of the unexpected value. + * @param substitute Value to substitute (if appropriate). + * @param options Control the processing of the check. + * @returns Decode result with the substitute value and an error. + */ +declare function unexpected(decres: DecodeResult | Array, context: string, message: string | undefined, substitute: T, options?: DecodeOptions): DecodeResult; +/** + * Skip over a single value in the stream when it is not recognized. + * @param reader Reader to skip over the next tag for. + */ +declare function skipNext(reader: Ber.Reader): void; +//# sourceMappingURL=DecodeResult.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/DecodeResult.d.ts.map b/dist/encodings/ber/decoder/DecodeResult.d.ts.map new file mode 100644 index 0000000..c85fa9a --- /dev/null +++ b/dist/encodings/ber/decoder/DecodeResult.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"DecodeResult.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/DecodeResult.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/DecodeResult.js b/dist/encodings/ber/decoder/DecodeResult.js new file mode 100644 index 0000000..c2e1693 --- /dev/null +++ b/dist/encodings/ber/decoder/DecodeResult.js @@ -0,0 +1,223 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.skipNext = exports.unexpected = exports.appendErrors = exports.guarded = exports.safeSet = exports.unknownApplication = exports.unknownContext = exports.makeResult = exports.DecodeError = exports.check = exports.whatever = exports.defaultDecode = void 0; +const types_1 = require("../../../types/types"); +/** + * Default decoding values. Prevents throwing exceptions while decoding. + */ +const defaultDecode = (0, types_1.literal)({ + skipApplicationTags: true, + skipContextTags: true, + substituteForRequired: true, + skipUnexpected: true, +}); +exports.defaultDecode = defaultDecode; +/** + * Return the decoded result whatever errors are reported. + * @param decres Result of decoding. + * @returns Candidate result of decoding, ignoring any errors. + * @ + */ +function whatever(decres) { + return decres.value; +} +exports.whatever = whatever; +/** + * Compound error containing details of all problems encountered when + * decoding an EmberPlus BER stream. + */ +class DecodeError extends Error { + /** + * Create an error with details of decoding issues. + * @param errors List of decoding sub-errors. + */ + constructor(errors) { + super(`Decoding failed. Errors are:\n${errors.join('\n')}`); + this.sub = errors; + } +} +exports.DecodeError = DecodeError; +/** + * Return the decoded result if no errors, otherwise throw a summary error. + * @param decres Result of decoding. + * @returns Candidate result of decoding, only if no errors. + * @throws Summary when errors exists. + */ +function guarded(decres) { + if (decres.errors && decres.errors.length > 0) { + throw new DecodeError(decres.errors); + } + return decres.value; +} +exports.guarded = guarded; +/** + * Make a decoded result from an initial value with an empty list if errors. + * @param t Value to embed in the initial result. + */ +function makeResult(t, errors) { + return (0, types_1.literal)({ + value: t, + errors: Array.isArray(errors) ? errors : [], + }); +} +exports.makeResult = makeResult; +/** + * Process a decoding problem when a context parameter tag is not recognized. + * @param decres Decoding result to add the error to (if appropriate). + * @param context Description of where the tag is. + * @param tag Unrecognized tag. + * @param options Control the processing of the error. + */ +function unknownContext(decres, context, tag, options = defaultDecode) { + const err = new Error(`${context}: Unexpected BER context tag '${tag}'`); + let errors = Array.isArray(decres) ? decres : decres.errors; + if (options.skipContextTags) { + if (!errors) { + errors = []; + } + errors.push(err); + if (!Array.isArray(decres)) { + decres.errors = errors; + } + } + else { + throw err; + } +} +exports.unknownContext = unknownContext; +/** + * Process a decoding problem when an application tag is not recognized. + * @param decres Decoding result to add the error to (if appropriate). + * @param context Description of where the tag is. + * @param tag Unrecognized tag. + * @param options Control the processing of the error. + */ +function unknownApplication(decres, context, tag, options = defaultDecode) { + const err = new Error(`${context}: Unexpected BER application tag '${tag}'`); + let errors = Array.isArray(decres) ? decres : decres.errors; + if (options.skipApplicationTags) { + if (!errors) { + errors = []; + } + errors.push(err); + if (!Array.isArray(decres)) { + decres.errors = errors; + } + } + else { + throw err; + } +} +exports.unknownApplication = unknownApplication; +/** + * Safely update a value from another decoding stage, merging errors. + * @param result Result of a decoding stage. + * @param update Value to be updated. + * @param fn Function to use to update a value with the result. + */ +function safeSet(result, update, fn) { + if (result.errors && result.errors.length > 0) { + update.errors = update.errors ? update.errors.concat(result.errors) : result.errors; + } + update.value = fn(result.value, update.value); + return update; +} +exports.safeSet = safeSet; +/** + * Check a value and if it is _null_ or _undefined_ then follow the options + * to either substitute a replacement truthy value, reporting an issue in the + * errors list, or throw an error when `subsituteForRequired` is `false`. + * @param value Value that may be somehow not defined. + * @param context Description of where the value is. + * @param propertyName Name of the property. + * @param substitute Substitute value in the event that the value is missing. + * @param decres A decoding result with an error list to be extended or a + * stand alone error list. + * @param options Control the processing of the check. + * @returns Value or, if somehow not defined, the substitute. + */ +function check(value, context, propertyName, substitute, decres, options = defaultDecode) { + if (value === null || value === undefined) { + const errMsg = `${context}: For required property '${propertyName}', value is missing.`; + if (options.substituteForRequired) { + let errors = Array.isArray(decres) ? decres : decres.errors; + if (!errors) { + errors = []; + } + errors.push(new Error(errMsg + ` Substituting '${substitute}'`)); + if (!Array.isArray(decres)) { + decres.errors = errors; + } + return substitute; + } + else { + throw new Error(errMsg); + } + } + return value; +} +exports.check = check; +/** + * Extend an error list using any errors in the given source, returning the + * source value. + * @param source Decoding result to split apart. + * @param decres Decoding result to extend the error list of or a stand alone + * error list. + * @returns The value embedded in the source. + */ +function appendErrors(source, decres) { + if (source.errors && source.errors.length > 0) { + if (Array.isArray(decres)) { + decres.push(...source.errors); + } + else { + decres.errors = decres.errors ? decres.errors.concat(source.errors) : source.errors; + } + } + return source.value; +} +exports.appendErrors = appendErrors; +/** + * Handle an unexpected enumeration value, returning a substitute value or + * throwing an errors depending on option `skipUnexpected`. + * @param decres Decoding result to add the error to (if appropriate). + * @param context Description of where the tag is. + * @param message Description of the unexpected value. + * @param substitute Value to substitute (if appropriate). + * @param options Control the processing of the check. + * @returns Decode result with the substitute value and an error. + */ +function unexpected(decres, context, message = '', substitute, options = defaultDecode) { + let errors = Array.isArray(decres) ? decres : decres.errors; + const err = new Error(`${context}${message ? ': ' + message : ''}`); + if (options.skipUnexpected) { + if (!errors) { + errors = []; + } + errors.push(err); + if (Array.isArray(decres)) { + return makeResult(substitute, errors); + } + else { + decres.errors = errors; + decres.value = substitute; + return decres; + } + } + else { + throw err; + } +} +exports.unexpected = unexpected; +/** + * Skip over a single value in the stream when it is not recognized. + * @param reader Reader to skip over the next tag for. + */ +function skipNext(reader) { + const skipTag = reader.peek(); + if (skipTag) { + reader.readString(skipTag, true); + } +} +exports.skipNext = skipNext; +//# sourceMappingURL=DecodeResult.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/DecodeResult.js.map b/dist/encodings/ber/decoder/DecodeResult.js.map new file mode 100644 index 0000000..7a1bc26 --- /dev/null +++ b/dist/encodings/ber/decoder/DecodeResult.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DecodeResult.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/DecodeResult.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberFunction.d.ts b/dist/encodings/ber/decoder/EmberFunction.d.ts new file mode 100644 index 0000000..83b7150 --- /dev/null +++ b/dist/encodings/ber/decoder/EmberFunction.d.ts @@ -0,0 +1,6 @@ +import * as Ber from '../../../Ber'; +import { EmberFunction } from '../../../model/EmberFunction'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export { decodeFunctionContent }; +declare function decodeFunctionContent(reader: Ber.Reader, options?: DecodeOptions): DecodeResult; +//# sourceMappingURL=EmberFunction.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberFunction.d.ts.map b/dist/encodings/ber/decoder/EmberFunction.d.ts.map new file mode 100644 index 0000000..bccb22b --- /dev/null +++ b/dist/encodings/ber/decoder/EmberFunction.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"EmberFunction.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/EmberFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AAEnC,OAAO,EAAE,aAAa,EAAqB,MAAM,8BAA8B,CAAA;AAE/E,OAAO,EACN,aAAa,EAEb,YAAY,EAKZ,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAEhC,iBAAS,qBAAqB,CAC7B,MAAM,EAAE,GAAG,CAAC,MAAM,EAClB,OAAO,GAAE,aAA6B,GACpC,YAAY,CAAC,aAAa,CAAC,CAiE7B"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberFunction.js b/dist/encodings/ber/decoder/EmberFunction.js new file mode 100644 index 0000000..a524c54 --- /dev/null +++ b/dist/encodings/ber/decoder/EmberFunction.js @@ -0,0 +1,78 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeFunctionContent = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../../Ber")); +// import { EmberFunction, EmberFunctionImpl } from '../../../model/EmberFunction' +const EmberFunction_1 = require("../../../model/EmberFunction"); +const FunctionArgument_1 = require("./FunctionArgument"); +const DecodeResult_1 = require("./DecodeResult"); +function decodeFunctionContent(reader, options = DecodeResult_1.defaultDecode) { + reader.readSequence(Ber.BERDataTypes.SET); + let identifier = undefined; + let description = undefined; + let args = undefined; + let result = undefined; + let templateReference = undefined; + let seqOffset; + let resOffset; + const errors = []; + const endOffset = reader.offset + reader.length; + while (reader.offset < endOffset) { + const tag = reader.readSequence(); + switch (tag) { + case Ber.CONTEXT(0): + identifier = reader.readString(Ber.BERDataTypes.STRING); + break; + case Ber.CONTEXT(1): + description = reader.readString(Ber.BERDataTypes.STRING); + break; + case Ber.CONTEXT(2): + args = []; + reader.readSequence(Ber.BERDataTypes.SEQUENCE); + seqOffset = reader.offset + reader.length; + while (reader.offset < seqOffset) { + const argTag = reader.readSequence(); + if (argTag === 0) + continue; // indefinite length + if (argTag !== Ber.CONTEXT(0)) { + (0, DecodeResult_1.unknownContext)(errors, 'decode function content: arguments', argTag, options); + (0, DecodeResult_1.skipNext)(reader); + continue; + } + const argEl = (0, DecodeResult_1.appendErrors)((0, FunctionArgument_1.decodeFunctionArgument)(reader, options), errors); + args.push(argEl); + } + break; + case Ber.CONTEXT(3): + result = []; + reader.readSequence(Ber.BERDataTypes.SEQUENCE); + resOffset = reader.offset + reader.length; + while (reader.offset < resOffset) { + const resTag = reader.readSequence(); + if (resTag === 0) + continue; // indefinite length + if (resTag !== Ber.CONTEXT(0)) { + (0, DecodeResult_1.unknownContext)(errors, 'decode function content: result', resTag, options); + (0, DecodeResult_1.skipNext)(reader); + continue; + } + const resEl = (0, DecodeResult_1.appendErrors)((0, FunctionArgument_1.decodeFunctionArgument)(reader, options), errors); + result.push(resEl); + } + break; + case Ber.CONTEXT(4): + templateReference = reader.readRelativeOID(Ber.BERDataTypes.RELATIVE_OID); + break; + case 0: + break; // Idefinite length + default: + (0, DecodeResult_1.unknownContext)(errors, 'decode function content', tag, options); + (0, DecodeResult_1.skipNext)(reader); + break; + } + } + return (0, DecodeResult_1.makeResult)(new EmberFunction_1.EmberFunctionImpl(identifier, description, args, result, templateReference), errors); +} +exports.decodeFunctionContent = decodeFunctionContent; +//# sourceMappingURL=EmberFunction.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberFunction.js.map b/dist/encodings/ber/decoder/EmberFunction.js.map new file mode 100644 index 0000000..79a3a26 --- /dev/null +++ b/dist/encodings/ber/decoder/EmberFunction.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EmberFunction.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/EmberFunction.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberNode.d.ts b/dist/encodings/ber/decoder/EmberNode.d.ts new file mode 100644 index 0000000..6f1e05c --- /dev/null +++ b/dist/encodings/ber/decoder/EmberNode.d.ts @@ -0,0 +1,6 @@ +import * as Ber from '../../../Ber'; +import { EmberNode } from '../../../model/EmberNode'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export { decodeNode }; +declare function decodeNode(reader: Ber.Reader, options?: DecodeOptions): DecodeResult; +//# sourceMappingURL=EmberNode.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberNode.d.ts.map b/dist/encodings/ber/decoder/EmberNode.d.ts.map new file mode 100644 index 0000000..51ca2e7 --- /dev/null +++ b/dist/encodings/ber/decoder/EmberNode.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"EmberNode.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/EmberNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,SAAS,EAAiB,MAAM,0BAA0B,CAAA;AACnE,OAAO,EAAE,aAAa,EAAiB,YAAY,EAAwC,MAAM,gBAAgB,CAAA;AAGjH,OAAO,EAAE,UAAU,EAAE,CAAA;AAErB,iBAAS,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAE,aAA6B,GAAG,YAAY,CAAC,SAAS,CAAC,CA2CvG"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberNode.js b/dist/encodings/ber/decoder/EmberNode.js new file mode 100644 index 0000000..f639458 --- /dev/null +++ b/dist/encodings/ber/decoder/EmberNode.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeNode = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../../Ber")); +const EmberNode_1 = require("../../../model/EmberNode"); +const DecodeResult_1 = require("./DecodeResult"); +function decodeNode(reader, options = DecodeResult_1.defaultDecode) { + reader.readSequence(Ber.BERDataTypes.SET); + let identifier = undefined; + let description = undefined; + let isRoot = undefined; + let isOnline = undefined; + let schemaIdentifiers = undefined; + let templateReference = undefined; + const errors = []; + const endOffset = reader.offset + reader.length; + while (reader.offset < endOffset) { + const tag = reader.readSequence(); + switch (tag) { + case Ber.CONTEXT(0): + identifier = reader.readString(Ber.BERDataTypes.STRING); + break; + case Ber.CONTEXT(1): + description = reader.readString(Ber.BERDataTypes.STRING); + break; + case Ber.CONTEXT(2): + isRoot = reader.readBoolean(); + break; + case Ber.CONTEXT(3): + isOnline = reader.readBoolean(); + break; + case Ber.CONTEXT(4): + schemaIdentifiers = reader.readString(Ber.BERDataTypes.STRING); + break; + case Ber.CONTEXT(5): + templateReference = reader.readRelativeOID(Ber.BERDataTypes.RELATIVE_OID); + break; + case 0: + break; // indefinite length + default: + (0, DecodeResult_1.unknownContext)(errors, 'deocde node', tag, options); + (0, DecodeResult_1.skipNext)(reader); + break; + } + } + return (0, DecodeResult_1.makeResult)(new EmberNode_1.EmberNodeImpl(identifier, description, isRoot, isOnline, schemaIdentifiers, templateReference), errors); +} +exports.decodeNode = decodeNode; +//# sourceMappingURL=EmberNode.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/EmberNode.js.map b/dist/encodings/ber/decoder/EmberNode.js.map new file mode 100644 index 0000000..cfbcfcc --- /dev/null +++ b/dist/encodings/ber/decoder/EmberNode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EmberNode.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/EmberNode.ts"],"names":[],"mappings":";;;;AAAA,0DAAmC;AACnC,wDAAmE;AACnE,iDAAiH;AAKjH,SAAS,UAAU,CAAC,MAAkB,EAAE,UAAyB,4BAAa;IAC7E,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;IACzC,IAAI,UAAU,GAAuB,SAAS,CAAA;IAC9C,IAAI,WAAW,GAAuB,SAAS,CAAA;IAC/C,IAAI,MAAM,GAAwB,SAAS,CAAA;IAC3C,IAAI,QAAQ,GAAwB,SAAS,CAAA;IAC7C,IAAI,iBAAiB,GAAuB,SAAS,CAAA;IACrD,IAAI,iBAAiB,GAA4B,SAAS,CAAA;IAC1D,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC/C,OAAO,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;QACjC,QAAQ,GAAG,EAAE;YACZ,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;gBACvD,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;gBACxD,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;gBAC7B,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;gBAC/B,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;gBAC9D,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,iBAAiB,GAAG,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,CAAA;gBACzE,MAAK;YACN,KAAK,CAAC;gBACL,MAAK,CAAC,oBAAoB;YAC3B;gBACC,IAAA,6BAAc,EAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;gBACnD,IAAA,uBAAQ,EAAC,MAAM,CAAC,CAAA;gBAChB,MAAK;SACN;KACD;IACD,OAAO,IAAA,yBAAU,EAChB,IAAI,yBAAa,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,EAClG,MAAM,CACN,CAAA;AACF,CAAC;AA7CQ,gCAAU"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/FunctionArgument.d.ts b/dist/encodings/ber/decoder/FunctionArgument.d.ts new file mode 100644 index 0000000..3ccbc65 --- /dev/null +++ b/dist/encodings/ber/decoder/FunctionArgument.d.ts @@ -0,0 +1,6 @@ +import * as Ber from '../../../Ber'; +import { FunctionArgument } from '../../../model/FunctionArgument'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export { decodeFunctionArgument }; +declare function decodeFunctionArgument(reader: Ber.Reader, options?: DecodeOptions): DecodeResult; +//# sourceMappingURL=FunctionArgument.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/FunctionArgument.d.ts.map b/dist/encodings/ber/decoder/FunctionArgument.d.ts.map new file mode 100644 index 0000000..3f66202 --- /dev/null +++ b/dist/encodings/ber/decoder/FunctionArgument.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"FunctionArgument.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/FunctionArgument.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,gBAAgB,EAAwB,MAAM,iCAAiC,CAAA;AAIxF,OAAO,EACN,aAAa,EAEb,YAAY,EAMZ,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,sBAAsB,EAAE,CAAA;AAEjC,iBAAS,sBAAsB,CAC9B,MAAM,EAAE,GAAG,CAAC,MAAM,EAClB,OAAO,GAAE,aAA6B,GACpC,YAAY,CAAC,gBAAgB,CAAC,CAyBhC"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/FunctionArgument.js b/dist/encodings/ber/decoder/FunctionArgument.js new file mode 100644 index 0000000..afcfe53 --- /dev/null +++ b/dist/encodings/ber/decoder/FunctionArgument.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeFunctionArgument = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../../Ber")); +const FunctionArgument_1 = require("../../../model/FunctionArgument"); +const Parameter_1 = require("../../../model/Parameter"); +const constants_1 = require("../constants"); +const Parameter_2 = require("./Parameter"); +const DecodeResult_1 = require("./DecodeResult"); +function decodeFunctionArgument(reader, options = DecodeResult_1.defaultDecode) { + reader.readSequence(constants_1.FunctionArgumentBERID); + let type = null; + let name = undefined; + const errors = []; + const endOffset = reader.offset + reader.length; + while (reader.offset < endOffset) { + const tag = reader.readSequence(); + switch (tag) { + case Ber.CONTEXT(0): + type = (0, DecodeResult_1.appendErrors)((0, Parameter_2.readParameterType)(reader.readInt(), options), errors); + break; + case Ber.CONTEXT(1): + name = reader.readString(Ber.BERDataTypes.STRING); + break; + case 0: + break; // indefinite length + default: + (0, DecodeResult_1.unknownContext)(errors, 'decode function context', tag, options); + (0, DecodeResult_1.skipNext)(reader); + break; + } + } + type = (0, DecodeResult_1.check)(type, 'decode function argument', 'type', Parameter_1.ParameterType.Null, errors, options); + return (0, DecodeResult_1.makeResult)(new FunctionArgument_1.FunctionArgumentImpl(type, name), errors); +} +exports.decodeFunctionArgument = decodeFunctionArgument; +//# sourceMappingURL=FunctionArgument.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/FunctionArgument.js.map b/dist/encodings/ber/decoder/FunctionArgument.js.map new file mode 100644 index 0000000..7918a17 --- /dev/null +++ b/dist/encodings/ber/decoder/FunctionArgument.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FunctionArgument.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/FunctionArgument.ts"],"names":[],"mappings":";;;;AAAA,0DAAmC;AACnC,sEAAwF;AACxF,wDAAwD;AACxD,4CAAoD;AACpD,2CAA+C;AAC/C,iDASuB;AAIvB,SAAS,sBAAsB,CAC9B,MAAkB,EAClB,UAAyB,4BAAa;IAEtC,MAAM,CAAC,YAAY,CAAC,iCAAqB,CAAC,CAAA;IAC1C,IAAI,IAAI,GAAyB,IAAI,CAAA;IACrC,IAAI,IAAI,GAAuB,SAAS,CAAA;IACxC,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC/C,OAAO,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;QACjC,QAAQ,GAAG,EAAE;YACZ,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,IAAI,GAAG,IAAA,2BAAY,EAAC,IAAA,6BAAiB,EAAC,MAAM,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAA;gBACzE,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;gBACjD,MAAK;YACN,KAAK,CAAC;gBACL,MAAK,CAAC,oBAAoB;YAC3B;gBACC,IAAA,6BAAc,EAAC,MAAM,EAAE,yBAAyB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;gBAC/D,IAAA,uBAAQ,EAAC,MAAM,CAAC,CAAA;gBAChB,MAAK;SACN;KACD;IACD,IAAI,GAAG,IAAA,oBAAK,EAAC,IAAI,EAAE,0BAA0B,EAAE,MAAM,EAAE,yBAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IAC3F,OAAO,IAAA,yBAAU,EAAC,IAAI,uCAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAA;AAChE,CAAC;AA9BQ,wDAAsB"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Invocation.d.ts b/dist/encodings/ber/decoder/Invocation.d.ts new file mode 100644 index 0000000..16623a9 --- /dev/null +++ b/dist/encodings/ber/decoder/Invocation.d.ts @@ -0,0 +1,6 @@ +import * as Ber from '../../../Ber'; +import { Invocation } from '../../../model/Invocation'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export { decodeInvocation }; +declare function decodeInvocation(reader: Ber.Reader, options?: DecodeOptions): DecodeResult; +//# sourceMappingURL=Invocation.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Invocation.d.ts.map b/dist/encodings/ber/decoder/Invocation.d.ts.map new file mode 100644 index 0000000..9f04781 --- /dev/null +++ b/dist/encodings/ber/decoder/Invocation.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Invocation.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/Invocation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,UAAU,EAAkB,MAAM,2BAA2B,CAAA;AAGtE,OAAO,EAAE,aAAa,EAAiB,YAAY,EAAwC,MAAM,gBAAgB,CAAA;AAEjH,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAE3B,iBAAS,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAE,aAA6B,GAAG,YAAY,CAAC,UAAU,CAAC,CAmC9G"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Invocation.js b/dist/encodings/ber/decoder/Invocation.js new file mode 100644 index 0000000..fd43a79 --- /dev/null +++ b/dist/encodings/ber/decoder/Invocation.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeInvocation = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../../Ber")); +const Invocation_1 = require("../../../model/Invocation"); +const constants_1 = require("../constants"); +const DecodeResult_1 = require("./DecodeResult"); +function decodeInvocation(reader, options = DecodeResult_1.defaultDecode) { + reader.readSequence(constants_1.InvocationBERID); + let id = undefined; + const args = []; + let seqOffset; + const errors = []; + const endOffset = reader.offset + reader.length; + while (reader.offset < endOffset) { + const tag = reader.readSequence(); + switch (tag) { + case Ber.CONTEXT(0): + id = reader.readInt(); + break; + case Ber.CONTEXT(1): + reader.readSequence(Ber.BERDataTypes.SEQUENCE); + seqOffset = reader.offset + reader.length; + while (reader.offset < seqOffset) { + const tag = reader.readSequence(); + if (tag === Ber.CONTEXT(0)) { + args.push(reader.readValue()); + } + else { + (0, DecodeResult_1.unknownContext)(errors, 'decode invocation arguments', tag, options); + (0, DecodeResult_1.skipNext)(reader); + } + } + break; + case 0: + break; // indefinite length + default: + (0, DecodeResult_1.unknownContext)(errors, 'decode invocation', tag, options); + (0, DecodeResult_1.skipNext)(reader); + break; + } + } + return (0, DecodeResult_1.makeResult)(new Invocation_1.InvocationImpl(id, args), errors); +} +exports.decodeInvocation = decodeInvocation; +//# sourceMappingURL=Invocation.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Invocation.js.map b/dist/encodings/ber/decoder/Invocation.js.map new file mode 100644 index 0000000..3d52066 --- /dev/null +++ b/dist/encodings/ber/decoder/Invocation.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Invocation.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/Invocation.ts"],"names":[],"mappings":";;;;AAAA,0DAAmC;AACnC,0DAAsE;AAEtE,4CAA8C;AAC9C,iDAAiH;AAIjH,SAAS,gBAAgB,CAAC,MAAkB,EAAE,UAAyB,4BAAa;IACnF,MAAM,CAAC,YAAY,CAAC,2BAAe,CAAC,CAAA;IACpC,IAAI,EAAE,GAAuB,SAAS,CAAA;IACtC,MAAM,IAAI,GAA2B,EAAE,CAAA;IACvC,IAAI,SAAiB,CAAA;IACrB,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC/C,OAAO,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;QACjC,QAAQ,GAAG,EAAE;YACZ,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;gBACrB,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;gBAC9C,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;gBACzC,OAAO,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE;oBACjC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;oBACjC,IAAI,GAAG,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;wBAC3B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;qBAC7B;yBAAM;wBACN,IAAA,6BAAc,EAAC,MAAM,EAAE,6BAA6B,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;wBACnE,IAAA,uBAAQ,EAAC,MAAM,CAAC,CAAA;qBAChB;iBACD;gBACD,MAAK;YACN,KAAK,CAAC;gBACL,MAAK,CAAC,oBAAoB;YAC3B;gBACC,IAAA,6BAAc,EAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;gBACzD,IAAA,uBAAQ,EAAC,MAAM,CAAC,CAAA;gBAChB,MAAK;SACN;KACD;IACD,OAAO,IAAA,yBAAU,EAAC,IAAI,2BAAc,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAA;AACxD,CAAC;AArCQ,4CAAgB"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/InvocationResult.d.ts b/dist/encodings/ber/decoder/InvocationResult.d.ts new file mode 100644 index 0000000..bd21b55 --- /dev/null +++ b/dist/encodings/ber/decoder/InvocationResult.d.ts @@ -0,0 +1,5 @@ +import * as Ber from '../../../Ber'; +import { InvocationResult } from '../../../model/InvocationResult'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export declare function decodeInvocationResult(reader: Ber.Reader, options?: DecodeOptions): DecodeResult; +//# sourceMappingURL=InvocationResult.d.ts.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/InvocationResult.d.ts.map b/dist/encodings/ber/decoder/InvocationResult.d.ts.map new file mode 100644 index 0000000..522ed15 --- /dev/null +++ b/dist/encodings/ber/decoder/InvocationResult.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"InvocationResult.d.ts","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/InvocationResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,gBAAgB,EAAwB,MAAM,iCAAiC,CAAA;AAGxF,OAAO,EAAE,aAAa,EAAiB,YAAY,EAA+C,MAAM,gBAAgB,CAAA;AAExH,wBAAgB,sBAAsB,CACrC,MAAM,EAAE,GAAG,CAAC,MAAM,EAClB,OAAO,GAAE,aAA6B,GACpC,YAAY,CAAC,gBAAgB,CAAC,CA0ChC"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/InvocationResult.js b/dist/encodings/ber/decoder/InvocationResult.js new file mode 100644 index 0000000..d2bf140 --- /dev/null +++ b/dist/encodings/ber/decoder/InvocationResult.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeInvocationResult = void 0; +const tslib_1 = require("tslib"); +const Ber = tslib_1.__importStar(require("../../../Ber")); +const InvocationResult_1 = require("../../../model/InvocationResult"); +const constants_1 = require("../constants"); +const DecodeResult_1 = require("./DecodeResult"); +function decodeInvocationResult(reader, options = DecodeResult_1.defaultDecode) { + reader.readSequence(constants_1.InvocationResultBERID); + let id = null; + let success = undefined; + let result = undefined; + let seqOffset; + const errors = []; + const endOffset = reader.offset + reader.length; + while (reader.offset < endOffset) { + const tag = reader.readSequence(); + switch (tag) { + case Ber.CONTEXT(0): + id = reader.readInt(); + break; + case Ber.CONTEXT(1): + success = reader.readBoolean(); + break; + case Ber.CONTEXT(2): + result = []; + reader.readSequence(Ber.BERDataTypes.SEQUENCE); + seqOffset = reader.offset + reader.length; + while (reader.offset < seqOffset) { + const resTag = reader.readSequence(); + if (resTag === 0) + continue; + if (resTag === null || resTag !== Ber.CONTEXT(0)) { + (0, DecodeResult_1.unknownContext)(errors, 'decode invocation result: result', resTag, options); + (0, DecodeResult_1.skipNext)(reader); + continue; + } + result.push(reader.readValue()); + } + break; + case 0: + break; // indefinite length + default: + (0, DecodeResult_1.unknownContext)(errors, 'decode invocation result', tag, options); + (0, DecodeResult_1.skipNext)(reader); + break; + } + } + id = (0, DecodeResult_1.check)(id, 'decode invocation result', 'id', -1, errors, options); + return (0, DecodeResult_1.makeResult)(new InvocationResult_1.InvocationResultImpl(id, success, result), errors); +} +exports.decodeInvocationResult = decodeInvocationResult; +//# sourceMappingURL=InvocationResult.js.map \ No newline at end of file diff --git a/dist/encodings/ber/decoder/InvocationResult.js.map b/dist/encodings/ber/decoder/InvocationResult.js.map new file mode 100644 index 0000000..f133064 --- /dev/null +++ b/dist/encodings/ber/decoder/InvocationResult.js.map @@ -0,0 +1 @@ +{"version":3,"file":"InvocationResult.js","sourceRoot":"","sources":["../../../../src/encodings/ber/decoder/InvocationResult.ts"],"names":[],"mappings":";;;;AAAA,0DAAmC;AACnC,sEAAwF;AAExF,4CAAoD;AACpD,iDAAwH;AAExH,SAAgB,sBAAsB,CACrC,MAAkB,EAClB,UAAyB,4BAAa;IAEtC,MAAM,CAAC,YAAY,CAAC,iCAAqB,CAAC,CAAA;IAC1C,IAAI,EAAE,GAAkB,IAAI,CAAA;IAC5B,IAAI,OAAO,GAAwB,SAAS,CAAA;IAC5C,IAAI,MAAM,GAAuC,SAAS,CAAA;IAC1D,IAAI,SAAiB,CAAA;IACrB,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC/C,OAAO,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;QACjC,QAAQ,GAAG,EAAE;YACZ,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;gBACrB,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;gBAC9B,MAAK;YACN,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClB,MAAM,GAAG,EAAE,CAAA;gBACX,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;gBAC9C,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;gBACzC,OAAO,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE;oBACjC,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;oBACpC,IAAI,MAAM,KAAK,CAAC;wBAAE,SAAQ;oBAC1B,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;wBACjD,IAAA,6BAAc,EAAC,MAAM,EAAE,kCAAkC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;wBAC3E,IAAA,uBAAQ,EAAC,MAAM,CAAC,CAAA;wBAChB,SAAQ;qBACR;oBACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;iBAC/B;gBACD,MAAK;YACN,KAAK,CAAC;gBACL,MAAK,CAAC,oBAAoB;YAC3B;gBACC,IAAA,6BAAc,EAAC,MAAM,EAAE,0BAA0B,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;gBAChE,IAAA,uBAAQ,EAAC,MAAM,CAAC,CAAA;gBAChB,MAAK;SACN;KACD;IACD,EAAE,GAAG,IAAA,oBAAK,EAAC,EAAE,EAAE,0BAA0B,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACrE,OAAO,IAAA,yBAAU,EAAC,IAAI,uCAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAA;AACzE,CAAC;AA7CD,wDA6CC"} \ No newline at end of file diff --git a/dist/encodings/ber/decoder/Label.d.ts b/dist/encodings/ber/decoder/Label.d.ts new file mode 100644 index 0000000..f097c16 --- /dev/null +++ b/dist/encodings/ber/decoder/Label.d.ts @@ -0,0 +1,6 @@ +import * as Ber from '../../../Ber'; +import { Label } from '../../../model/Label'; +import { DecodeOptions, DecodeResult } from './DecodeResult'; +export { decodeLabel }; +declare function decodeLabel(reader: Ber.Reader, options?: DecodeOptions): DecodeResult