Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

knxultimate

Package Overview
Dependencies
Maintainers
0
Versions
82
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

knxultimate - npm Package Compare versions

Comparing version 4.0.0-beta.2 to 4.0.0-beta.3

test/dtp/dpt1.test.ts

27

build/KNXClient.d.ts

@@ -6,3 +6,3 @@ /// <reference types="node" />

import { KNXLoggerOptions } from './KnxLog';
import { KNXPacket } from './protocol';
import { KNXDescriptionResponse, KNXPacket } from './protocol';
import KNXRoutingIndication from './protocol/KNXRoutingIndication';

@@ -39,3 +39,4 @@ import KNXTunnelingRequest from './protocol/KNXTunnelingRequest';

ackReceived = "ackReceived",
close = "close"
close = "close",
descriptionResponse = "descriptionResponse"
}

@@ -53,2 +54,3 @@ export interface KNXClientEventCallbacks {

close: () => void;
descriptionResponse: (packet: KNXDescriptionResponse) => void;
}

@@ -69,2 +71,3 @@ export type KNXClientOptions = {

KNXQueueSendIntervalMilliseconds?: number;
sniffingMode?: boolean;
} & KNXLoggerOptions;

@@ -79,4 +82,13 @@ export declare function getDecodedKeyring(): string;

DISCONNECT = "disconnect",
DISCOVERY = "discovery"
DISCOVERY = "discovery",
GATEWAYDESCRIPTION = "GatewayDescription"
}
export type SnifferPacket = {
reqType?: string;
request?: string;
response?: string;
resType?: string;
deltaReq: number;
deltaRes?: number;
};
export default class KNXClient extends TypedEventEmitter<KNXClientEventCallbacks> {

@@ -104,3 +116,6 @@ private _channelID;

private queueLock;
constructor(options: KNXClientOptions);
private sniffingPackets;
private lastSnifferRequest;
constructor(options: KNXClientOptions, createSocket?: (client: KNXClient) => void);
private createSocket;
get channelID(): number;

@@ -127,2 +142,6 @@ get clearToSend(): boolean;

static discover(eth?: string | number, timeout?: number): Promise<string[]>;
isGatewayDescriptionRunning(): boolean;
startGatewayDescription(): void;
stopGatewayDescription(): void;
static getGatewayDescription(ipAddr: any, ipPort: any, eth?: string | number, timeout?: number): Promise<any[]>;
Connect(knxLayer?: TunnelTypes): void;

@@ -129,0 +148,0 @@ private closeSocket;

@@ -79,2 +79,3 @@ "use strict";

KNXClientEvents["close"] = "close";
KNXClientEvents["descriptionResponse"] = "descriptionResponse";
})(KNXClientEvents || (exports.KNXClientEvents = KNXClientEvents = {}));

@@ -110,5 +111,6 @@ const jKNXSecureKeyring = '';

KNXTimer["DISCOVERY"] = "discovery";
KNXTimer["GATEWAYDESCRIPTION"] = "GatewayDescription";
})(KNXTimer || (exports.KNXTimer = KNXTimer = {}));
class KNXClient extends TypedEmitter_1.TypedEventEmitter {
constructor(options) {
constructor(options, createSocket) {
super();

@@ -128,2 +130,3 @@ this._clearToSend = false;

this._options = options;
this.sniffingPackets = [];
this.sysLogger = KnxLog_1.default.get({

@@ -168,8 +171,22 @@ loglevel: this._options.loglevel,

}
if (createSocket) {
createSocket(this);
}
else {
this.createSocket();
}
}
createSocket() {
if (this._options.hostProtocol === 'TunnelUDP') {
this._clientSocket = dgram_1.default.createSocket({
type: 'udp4',
reuseAddr: false,
reuseAddr: true,
});
this._clientSocket.bind({ port: null, address: this._options.localIPAddress }, () => {
this._clientSocket.on(SocketEvents.message, this.processInboundMessage.bind(this));
this._clientSocket.on(SocketEvents.error, (error) => this.emit(KNXClientEvents.error, error));
this._clientSocket.on(SocketEvents.close, () => this.emit(KNXClientEvents.close));
this._clientSocket.bind({
port: this._peerPort,
address: this._options.localIPAddress,
}, () => {
try {

@@ -186,5 +203,2 @@ ;

});
this._clientSocket.on(SocketEvents.message, this.processInboundMessage.bind(this));
this._clientSocket.on(SocketEvents.error, (error) => this.emit(KNXClientEvents.error, error));
this._clientSocket.on(SocketEvents.close, () => this.emit(KNXClientEvents.close));
}

@@ -209,6 +223,6 @@ else if (this._options.hostProtocol === 'TunnelTCP') {

this._clientSocket.bind(this._peerPort, () => {
const client = this._clientSocket;
try {
client.setMulticastTTL(250);
client.setMulticastInterface(this._options.localIPAddress);
;
this._clientSocket.setMulticastTTL(250);
this._clientSocket.setMulticastInterface(this._options.localIPAddress);
}

@@ -220,3 +234,4 @@ catch (error) {

try {
client.addMembership(this._peerHost, this._options.localIPAddress);
;
this._clientSocket.addMembership(this._peerHost, this._options.localIPAddress);
}

@@ -300,3 +315,3 @@ catch (err) {

processKnxPacketQueueItem(_knxPacket) {
this.sysLogger.debug(`KNXClient: processKnxPacketQueueItem: Processing queued KNX. commandQueue.length: ${this.commandQueue.length} ${_knxPacket.header.service_type}`);
this.sysLogger.debug(`KNXClient: processKnxPacketQueueItem: Processing queued KNX. commandQueue.length: ${this.commandQueue.length} ${_knxPacket.header.service_type} ${JSON.stringify(_knxPacket)}`);
if (_knxPacket instanceof KNXConnectRequest_1.default) {

@@ -383,2 +398,13 @@ this.sysLogger.debug(`Sending KNX packet: ${_knxPacket.constructor.name} Host:${this._peerHost}:${this._peerPort}`);

};
if (this._options.sniffingMode) {
const buffer = _knxPacket.toBuffer();
this.sniffingPackets.push({
reqType: _knxPacket.constructor.name,
request: buffer.toString('hex'),
deltaReq: this.lastSnifferRequest
? Date.now() - this.lastSnifferRequest
: 0,
});
this.lastSnifferRequest = Date.now();
}
if (_priority) {

@@ -590,3 +616,3 @@ this.commandQueue.push(toBeAdded);

const discovered = [];
client.on(KNXClientEvents.discover, (host) => {
client.on(KNXClientEvents.discover, (host, header, searchResponse) => {
discovered.push(host);

@@ -599,2 +625,36 @@ });

}
isGatewayDescriptionRunning() {
return this.timers.has(KNXTimer.GATEWAYDESCRIPTION);
}
startGatewayDescription() {
this._clearToSend = true;
if (this.isGatewayDescriptionRunning()) {
throw new Error('GatewayDescription gather is already running');
}
this.setTimer(KNXTimer.GATEWAYDESCRIPTION, () => { }, 1000 * KNXConstants_1.KNX_CONSTANTS.SEARCH_TIMEOUT);
this.sendDescriptionRequestMessage();
}
stopGatewayDescription() {
this.clearTimer(KNXTimer.GATEWAYDESCRIPTION);
}
static async getGatewayDescription(ipAddr, ipPort, eth, timeout = 5000) {
if (typeof eth === 'number') {
timeout = eth;
eth = undefined;
}
const client = new KNXClient({
ipAddr,
ipPort,
interface: eth,
hostProtocol: 'TunnelUDP',
});
const descriptions = [];
client.on(KNXClientEvents.descriptionResponse, (searchResponse) => {
descriptions.push(searchResponse);
});
client.startGatewayDescription();
await (0, utils_1.wait)(timeout);
await client.Disconnect();
return descriptions;
}
Connect(knxLayer = TunnelCRI_1.TunnelTypes.TUNNEL_LINKLAYER) {

@@ -620,7 +680,7 @@ if (this._clientSocket === null) {

const timeoutError = new Error(`Connection timeout to ${this._peerHost}:${this._peerPort}`);
this._awaitingResponseType = KNXConstants_1.KNX_CONSTANTS.CONNECT_RESPONSE;
this._clientTunnelSeqNumber = -1;
this.setTimer(KNXTimer.CONNECTION, () => {
this.emit(KNXClientEvents.error, timeoutError);
}, 1000 * KNXConstants_1.KNX_CONSTANTS.CONNECT_REQUEST_TIMEOUT);
this._awaitingResponseType = KNXConstants_1.KNX_CONSTANTS.CONNECT_RESPONSE;
this._clientTunnelSeqNumber = -1;
this.setTimer(KNXTimer.CONNECT_REQUEST, () => {

@@ -691,2 +751,6 @@ this.sendConnectRequestMessage(new TunnelCRI_1.default(knxLayer));

}
if (this._options.sniffingMode) {
console.log('Sniffing mode is enabled. Dumping sniffing buffers...');
console.log(this.sniffingPackets);
}
}

@@ -768,6 +832,25 @@ isConnected() {

sProcessInboundLog += ` srcAddress: ${JSON.stringify(rinfo)}`;
this.sysLogger.debug(`Received KNX packet: _processInboundMessage, ${sProcessInboundLog} ChannelID:${this._channelID}` ||
this.sysLogger.debug(`KNXEngine: processInboundMessage prior to processing: ${sProcessInboundLog} ChannelID:${this._channelID}` ||
`??` +
` Host:${this._options.ipAddr}:${this._options.ipPort}`);
const { knxHeader, knxMessage } = KNXProtocol_1.default.parseMessage(msg);
this.sysLogger.debug(`KNXEngine: processInboundMessage after processing, header: ${JSON.stringify(knxHeader)} knxMessage: ${JSON.stringify(knxMessage)} Host:${this._options.ipAddr}:${this._options.ipPort}`);
if (this._options.sniffingMode) {
const lastEntry = this.sniffingPackets[this.sniffingPackets.length - 1];
if (lastEntry) {
if (lastEntry.response) {
this.sniffingPackets.push({
reqType: knxMessage.constructor.name,
response: msg.toString('hex'),
deltaReq: Date.now() - this.lastSnifferRequest,
});
}
else {
lastEntry.response = msg.toString('hex');
lastEntry.resType = knxMessage.constructor.name;
lastEntry.deltaRes =
Date.now() - this.lastSnifferRequest;
}
}
}
if (knxHeader.service_type === KNXConstants_1.KNX_CONSTANTS.ROUTING_LOST_MESSAGE) {

@@ -786,2 +869,7 @@ this.emit(KNXClientEvents.error, new Error('ROUTING_LOST_MESSAGE'));

}
else if (knxHeader.service_type === KNXConstants_1.KNX_CONSTANTS.DESCRIPTION_RESPONSE) {
const knxDescriptionResponse = knxMessage;
this.sysLogger.debug(`Received KNX packet: TUNNELING: DESCRIPTION_RESPONSE, ChannelID:${this._channelID} DescriptionResponse:${JSON.stringify(knxDescriptionResponse)} Host:${this._options.ipAddr}:${this._options.ipPort}`);
this.emit(KNXClientEvents.descriptionResponse, knxDescriptionResponse);
}
else if (knxHeader.service_type === KNXConstants_1.KNX_CONSTANTS.CONNECT_RESPONSE) {

@@ -788,0 +876,0 @@ if (this._connectionState === ConncetionState.CONNECTING) {

2

build/protocol/HPAI.js

@@ -75,3 +75,3 @@ "use strict";

}
const port = buffer.readUInt8(offset);
const port = buffer.readUInt16BE(offset);
const host = ip.join('.');

@@ -78,0 +78,0 @@ return new HPAI(host, port, protocol);

@@ -12,6 +12,19 @@ "use strict";

const candidateInterfaces = {};
const interfaces = os_1.default.networkInterfaces();
let interfaces = os_1.default.networkInterfaces();
if (process.env.CI) {
interfaces = {
eth0: [
{
address: '192.168.1.58',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: false,
cidr: '192.168.1.58/24',
},
],
};
}
for (const iface in interfaces) {
for (const key in interfaces[iface]) {
const intf = interfaces[iface][key];
for (const intf of interfaces[iface]) {
try {

@@ -18,0 +31,0 @@ KnxLog_1.default.get().debug('ipAddressHelper.js: parsing interface: %s (%j)', iface, intf);

# [4.0.0-beta.3](https://github.com/Supergiovane/KNXUltimate/compare/v4.0.0-beta.2...v4.0.0-beta.3) (2024-11-15)
### Bug Fixes
* fix missing "test" folder ([821e398](https://github.com/Supergiovane/KNXUltimate/commit/821e39820f936e3b568c05573565a0dc8be1cbb3))
* removed the "test" folder from the include array ([742a028](https://github.com/Supergiovane/KNXUltimate/commit/742a028fec4a122f7d049c766b819ba6fc5308bf))
* the tunnel socket creation function (createSocket), adding reusable option and specifying the port. This will likely prevent some UDP packets not arriving at the socket, due to operating system routing restrictions. ([3fdd938](https://github.com/Supergiovane/KNXUltimate/commit/3fdd9383191bd3a842bf165448714784fc89a52b))
### Features
* added getGatewayDescription method, to gather infos of the connected gateway ([88b883a](https://github.com/Supergiovane/KNXUltimate/commit/88b883a5226cddbeea22864a2c848a249b7b6789))
* added the gatewaydescription.ts sample ([41b1f66](https://github.com/Supergiovane/KNXUltimate/commit/41b1f66679098f9c61fa162640ca83fdc887e585))
* added the KNX/IP Gateway description gatherer, wich contains the gateway's name, tunneling/routing modes etc.. ([f99170f](https://github.com/Supergiovane/KNXUltimate/commit/f99170ff63216ec0453a21aa51106c23dc622974))
# [4.0.0-beta.2](https://github.com/Supergiovane/KNXUltimate/compare/v4.0.0-beta.1...v4.0.0-beta.2) (2024-10-17)

@@ -4,0 +20,0 @@

{
"name": "knxultimate",
"description": "KNX IP protocol implementation for Node. This is the ENGINE of Node-Red KNX-Ultimate node.",
"version": "4.0.0-beta.2",
"version": "4.0.0-beta.3",
"main": "./build/index.js",
"engines": {
"node": ">=14"
"node": ">=16"
},

@@ -16,5 +16,7 @@ "private": false,

"build": "tsc -p tsconfig.build.json",
"buildexamples": "tsc -p tsconfig.examples.json",
"lint": "eslint --ext .ts .",
"lint-fix": "eslint --fix --ext .ts .",
"test": "tsc -p tsconfig.test.json && node --test build/test",
"test": "node -r esbuild-register --test test/**/*.test.ts",
"test:coverage": "nyc npm run test",
"test-connection": "",

@@ -57,9 +59,14 @@ "release": "read -p 'GITHUB_TOKEN: ' GITHUB_TOKEN && export GITHUB_TOKEN=$GITHUB_TOKEN && release-it",

"email": "maxsupergiovane@icloud.com"
},
}
],
"contributors": [
{
"name": "Daniel Lando",
"email": "daniel.sorridi@gmail.com"
},
{
"name": "Andrea Zanetti",
"email": "zanetti.sw@gmail.com"
}
],
"contributors": [],
"keywords": [

@@ -83,6 +90,7 @@ "knx",

"@types/node": "^20.12.7",
"@types/sinon": "^17.0.3",
"@types/xml2js": "^0.4.14",
"@typescript-eslint/eslint-plugin": "^7.7.0",
"@typescript-eslint/parser": "^7.7.0",
"esbuild-register": "^3.5.0",
"esbuild-register": "^3.6.0",
"eslint": "^8.57.0",

@@ -94,6 +102,8 @@ "eslint-config-airbnb-base": "^15.0.0",

"eslint-plugin-prettier": "^5.1.3",
"nyc": "^17.1.0",
"prettier": "^3.2.5",
"release-it": "^17.2.0",
"sinon": "^19.0.2",
"typescript": "^5.4.5"
}
}

@@ -76,2 +76,4 @@ ![Logo](img/logo-big.png)

| .read (GA) | Sends a READ telegram to the BUS. **GA** is the group address (for example "0/0/1"). |
| . discover() | Sends a discover request on the KNX default multicast port and returns the results as an array. This is an async method. See the example in the **examples** folder |
| .getGatewayDescription() | Sends a gateway description request. It works after an established connection. The async results will be sent to the *descriptionResponse* event. There is an example in the **examples** folder named **gatewaydescription.ts** . |

@@ -96,4 +98,6 @@ | Property | Description |

| close | The main KNXUltimate socket has been closed. |
| error | KNXUltimate has raised an error. The error description is provided as well. |
| error | KNXUltimate has raised an error. The error description is provided as well. |
| descriptionResponse | Gather the *getGatewayDescription* responses. There is an example in the **examples** folder named **gatewaydescription.ts** . |
## DECONDING THE TELEGRAMS FROM BUS

@@ -120,2 +124,3 @@

- [test-toggle](./examples/test-toggle.ts) - An interactive example that shows how to toggle a switch on/off. **WARNING** this sends data to your KNX BUS!
- [gatewaydescription](./examples/gatewaydescription.ts) - Discover all gateways on your network and shows the details (name, mac address, etc...).

@@ -122,0 +127,0 @@ <br/>

/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable no-multi-assign */
/* node:coverage disable */
const _0 = new Uint8Array(16)

@@ -4,0 +5,0 @@ const _9 = new Uint8Array(32)

@@ -1,2 +0,1 @@

// Made with love by Supergiovane
import dgram, { RemoteInfo, Socket as UDPSocket } from 'dgram'

@@ -18,3 +17,3 @@ import net, { Socket as TCPSocket } from 'net'

import KnxLog, { KNXLoggerOptions } from './KnxLog'
import { KNXPacket } from './protocol'
import { KNXDescriptionResponse, KNXPacket } from './protocol'
import KNXRoutingIndication from './protocol/KNXRoutingIndication'

@@ -59,2 +58,3 @@ import KNXConnectRequest from './protocol/KNXConnectRequest'

close = 'close',
descriptionResponse = 'descriptionResponse',
}

@@ -80,2 +80,3 @@

close: () => void
descriptionResponse: (packet: KNXDescriptionResponse) => void
}

@@ -112,2 +113,4 @@

KNXQueueSendIntervalMilliseconds?: number
/** Enables sniffing mode to monitor KNX */
sniffingMode?: boolean
} & KNXLoggerOptions

@@ -150,4 +153,17 @@

DISCOVERY = 'discovery',
/** Waits for the gateway description gather responses */
GATEWAYDESCRIPTION = 'GatewayDescription',
}
export type SnifferPacket = {
reqType?: string
request?: string
response?: string
resType?: string
/** Time in ms between this request and the previous */
deltaReq: number
/** Time in ms between the request and the response */
deltaRes?: number
}
interface KNXQueueItem {

@@ -202,3 +218,10 @@ knxPacket: KNXPacket

constructor(options: KNXClientOptions) {
private sniffingPackets: SnifferPacket[]
private lastSnifferRequest: number
constructor(
options: KNXClientOptions,
createSocket?: (client: KNXClient) => void,
) {
super()

@@ -220,2 +243,4 @@ this.timers = new Map()

this.sniffingPackets = []
this.sysLogger = KnxLog.get({

@@ -252,3 +277,3 @@ loglevel: this._options.loglevel,

// add an empty error listener, without this
// every "error" emitted would throw an unhandled exception
// every "error" emitted throws an unhandled exception
this.on('error', (error) => {

@@ -273,10 +298,30 @@ this.sysLogger.error(error.stack)

if (createSocket) {
createSocket(this)
} else {
this.createSocket()
}
}
private createSocket() {
if (this._options.hostProtocol === 'TunnelUDP') {
this._clientSocket = dgram.createSocket({
type: 'udp4',
reuseAddr: false,
reuseAddr: true,
}) as UDPSocket
// this._clientSocket.removeAllListeners()
this._clientSocket.on(
SocketEvents.message,
this.processInboundMessage.bind(this),
)
this._clientSocket.on(SocketEvents.error, (error) =>
this.emit(KNXClientEvents.error, error),
)
this._clientSocket.on(SocketEvents.close, () =>
this.emit(KNXClientEvents.close),
)
this._clientSocket.bind(
{ port: null, address: this._options.localIPAddress },
{
port: this._peerPort,
address: this._options.localIPAddress,
},
() => {

@@ -297,12 +342,2 @@ try {

)
this._clientSocket.on(
SocketEvents.message,
this.processInboundMessage.bind(this),
)
this._clientSocket.on(SocketEvents.error, (error) =>
this.emit(KNXClientEvents.error, error),
)
this._clientSocket.on(SocketEvents.close, () =>
this.emit(KNXClientEvents.close),
)
} else if (this._options.hostProtocol === 'TunnelTCP') {

@@ -338,6 +373,7 @@ this._clientSocket = new net.Socket()

this._clientSocket.bind(this._peerPort, () => {
const client = this._clientSocket as UDPSocket
try {
client.setMulticastTTL(250)
client.setMulticastInterface(this._options.localIPAddress)
;(this._clientSocket as UDPSocket).setMulticastTTL(250)
;(this._clientSocket as UDPSocket).setMulticastInterface(
this._options.localIPAddress,
)
} catch (error) {

@@ -350,3 +386,3 @@ this.sysLogger.error(

try {
client.addMembership(
;(this._clientSocket as UDPSocket).addMembership(
this._peerHost,

@@ -467,7 +503,4 @@ this._options.localIPAddress,

private processKnxPacketQueueItem(_knxPacket: KNXPacket) {
// await new Promise((f) => {
// setTimeout(f, 2000)
// }) // For debugging
this.sysLogger.debug(
`KNXClient: processKnxPacketQueueItem: Processing queued KNX. commandQueue.length: ${this.commandQueue.length} ${_knxPacket.header.service_type}`,
`KNXClient: processKnxPacketQueueItem: Processing queued KNX. commandQueue.length: ${this.commandQueue.length} ${_knxPacket.header.service_type} ${JSON.stringify(_knxPacket)}`,
)

@@ -612,2 +645,16 @@ if (_knxPacket instanceof KNXConnectRequest) {

}
if (this._options.sniffingMode) {
const buffer = _knxPacket.toBuffer()
this.sniffingPackets.push({
reqType: _knxPacket.constructor.name,
request: buffer.toString('hex'),
deltaReq: this.lastSnifferRequest
? Date.now() - this.lastSnifferRequest
: 0,
})
this.lastSnifferRequest = Date.now()
}
if (_priority) {

@@ -753,3 +800,3 @@ this.commandQueue.push(toBeAdded) // Put the item as first to be sent.

this.send(knxPacketRequest, undefined, false, this.getSeqNumber())
// 06/12/2021 Multivast automaticalli echoes telegrams
// 06/12/2021 Multivast automatically echoes telegrams
} else {

@@ -1002,3 +1049,3 @@ // Tunneling

* Send a search request message to the KNX bus and wait for responses
* Set _clearToSend to true to allow the discovery packet to process. Initially set to false to prevent premature sends.
* Set _clearToSend to true to allow the discovery packet to process. Initially set to false to prevent premature sends!
*/

@@ -1041,3 +1088,3 @@ startDiscovery() {

client.on(KNXClientEvents.discover, (host) => {
client.on(KNXClientEvents.discover, (host, header, searchResponse) => {
discovered.push(host)

@@ -1054,14 +1101,69 @@ })

// getDescription(host, port) {
// if (this._clientSocket == null) {
// throw new Error('No client socket defined');
// }
// this._connectionTimeoutTimer = setTimeout(() => {
// this._connectionTimeoutTimer = null;
// }, 1000 * KNX_CONSTANTS.DEVICE_CONFIGURATION_REQUEST_TIMEOUT);
// this._awaitingResponseType = KNX_CONSTANTS.DESCRIPTION_RESPONSE;
// this._sendDescriptionRequestMessage(host, port);
// }
/**
* Returns true if the gw description's gatherer is running
*/
isGatewayDescriptionRunning() {
return this.timers.has(KNXTimer.GATEWAYDESCRIPTION)
}
/**
* Send a get description message to the KNX bus and wait for responses
* Set _clearToSend to true to allow the gatherer packet to process. Initially set to false to prevent premature sends.
*/
startGatewayDescription() {
this._clearToSend = true
if (this.isGatewayDescriptionRunning()) {
throw new Error('GatewayDescription gather is already running')
}
this.setTimer(
KNXTimer.GATEWAYDESCRIPTION,
() => {},
1000 * KNX_CONSTANTS.SEARCH_TIMEOUT,
)
this.sendDescriptionRequestMessage()
}
/**
* Stop the process
*/
stopGatewayDescription() {
this.clearTimer(KNXTimer.GATEWAYDESCRIPTION)
}
/**
* Returns an array of "search_responses" from the KNX interfaces in the format of a KNX descriptionResponse
*/
public static async getGatewayDescription(
ipAddr,
ipPort,
eth?: string | number,
timeout = 5000,
) {
if (typeof eth === 'number') {
timeout = eth
eth = undefined
}
const client = new KNXClient({
ipAddr,
ipPort,
interface: eth as string,
hostProtocol: 'TunnelUDP',
})
const descriptions = []
client.on(KNXClientEvents.descriptionResponse, (searchResponse) => {
descriptions.push(searchResponse)
})
client.startGatewayDescription()
await wait(timeout)
await client.Disconnect()
return descriptions
}
/**
* Connect to the KNX bus

@@ -1098,2 +1200,4 @@ */

)
this._awaitingResponseType = KNX_CONSTANTS.CONNECT_RESPONSE
this._clientTunnelSeqNumber = -1
this.setTimer(

@@ -1106,4 +1210,2 @@ KNXTimer.CONNECTION,

)
this._awaitingResponseType = KNX_CONSTANTS.CONNECT_RESPONSE
this._clientTunnelSeqNumber = -1
// 27/06/2023, leave some time to the dgram, to do the bind and read local ip and local port

@@ -1118,11 +1220,3 @@ this.setTimer(

} else if (this._options.hostProtocol === 'TunnelTCP') {
// TCP
// const timeoutError = new Error(
// `Connection timeout to ${this._peerHost}:${this._peerPort}`,
// )
this._clientSocket.connect(this._peerPort, this._peerHost, () => {
// this._timer = setTimeout(() => {
// this._timer = null;
// this.emit(KNXClientEvents.error, timeoutError);
// }, 1000 * KNX_CONSTANTS.CONNECT_REQUEST_TIMEOUT);
this._awaitingResponseType = KNX_CONSTANTS.CONNECT_RESPONSE

@@ -1218,2 +1312,7 @@ this._clientTunnelSeqNumber = 0

}
if (this._options.sniffingMode) {
console.log('Sniffing mode is enabled. Dumping sniffing buffers...')
console.log(this.sniffingPackets)
}
}

@@ -1264,6 +1363,2 @@

// const timeoutError = new Error(
// `HeartBeat failure with ${this._peerHost}:${this._peerPort}`,
// )
const deadError = new Error(

@@ -1326,5 +1421,2 @@ `Connection dead with ${this._peerHost}:${this._peerPort}`,

// _keyFromCEMIMessage(cEMIMessage) {
// return cEMIMessage.dstAddress.toString();
// }
/**

@@ -1392,3 +1484,2 @@ * Setup a timer while waiting for an ACK of `knxTunnelingRequest`

let sProcessInboundLog = ''
try {

@@ -1399,3 +1490,3 @@ // Composing debug string

this.sysLogger.debug(
`Received KNX packet: _processInboundMessage, ${sProcessInboundLog} ChannelID:${this._channelID}` ||
`KNXEngine: processInboundMessage prior to processing: ${sProcessInboundLog} ChannelID:${this._channelID}` ||
`??` +

@@ -1406,6 +1497,26 @@ ` Host:${this._options.ipAddr}:${this._options.ipPort}`,

// BUGFIXING https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/162
// msg = Buffer.from("0610053000102900b06011fe11150080","hex");
const { knxHeader, knxMessage } = KNXProtocol.parseMessage(msg)
this.sysLogger.debug(
`KNXEngine: processInboundMessage after processing, header: ${JSON.stringify(knxHeader)} knxMessage: ${JSON.stringify(knxMessage)} Host:${this._options.ipAddr}:${this._options.ipPort}`,
)
if (this._options.sniffingMode) {
const lastEntry =
this.sniffingPackets[this.sniffingPackets.length - 1]
if (lastEntry) {
// last entry already has a response, so create a new entry
if (lastEntry.response) {
this.sniffingPackets.push({
reqType: knxMessage.constructor.name,
response: msg.toString('hex'),
deltaReq: Date.now() - this.lastSnifferRequest,
})
} else {
lastEntry.response = msg.toString('hex')
lastEntry.resType = knxMessage.constructor.name
lastEntry.deltaRes =
Date.now() - this.lastSnifferRequest
}
}
}
// 26/12/2021 ROUTING LOST MESSAGE OR BUSY

@@ -1436,2 +1547,15 @@ if (knxHeader.service_type === KNX_CONSTANTS.ROUTING_LOST_MESSAGE) {

} else if (
knxHeader.service_type === KNX_CONSTANTS.DESCRIPTION_RESPONSE
) {
const knxDescriptionResponse =
knxMessage as KNXDescriptionResponse
this.sysLogger.debug(
`Received KNX packet: TUNNELING: DESCRIPTION_RESPONSE, ChannelID:${this._channelID} DescriptionResponse:${JSON.stringify(knxDescriptionResponse)} Host:${this._options.ipAddr}:${this._options.ipPort}`,
)
this.emit(
KNXClientEvents.descriptionResponse,
knxDescriptionResponse,
)
} else if (
knxHeader.service_type === KNX_CONSTANTS.CONNECT_RESPONSE

@@ -1528,5 +1652,2 @@ ) {

}
// 26/12/2021 send the ACK if the server requestet that
// Then REMOVED, because some interfaces sets the "ack request" always to 0 even if it needs ack.
// if (knxMessage.cEMIMessage.control.ack){
try {

@@ -1691,7 +1812,2 @@ const knxTunnelAck = KNXProtocol.newKNXTunnelingACK(

)
// try {
// 05/01/2022 Avoid disconnecting, because there are many bugged knx gateways out there!
// this.emit(KNXClientEvents.error, e);
// this._setDisconnected();
// } catch (error) {}
}

@@ -1725,8 +1841,2 @@ }

private sendConnectRequestMessage(cri: TunnelCRI) {
// try {
// const oHPAI = new HPAI(this._options.localSocketAddress.address, this._options.localSocketAddress.port, this._options.hostProtocol === 'TunnelTCP' ? KNX_CONSTANTS.IPV4_TCP : KNX_CONSTANTS.IPV4_UDP)
// this.send(KNXProtocol.newKNXConnectRequest(cri, null, oHPAI))
// } catch (error) {
// this.send(KNXProtocol.newKNXConnectRequest(cri))
// }
this.send(

@@ -1741,8 +1851,2 @@ KNXProtocol.newKNXConnectRequest(cri),

private sendConnectionStateRequestMessage(channelID: number) {
// try {
// const oHPAI = new HPAI.HPAI(this._options.localSocketAddress.address, this._options.localSocketAddress.port, this._options.hostProtocol === 'TunnelTCP' ? KNX_CONSTANTS.IPV4_TCP : KNX_CONSTANTS.IPV4_UDP)
// this.send(KNXProtocol.newKNXConnectionStateRequest(channelID, oHPAI))
// } catch (error) {
// this.send(KNXProtocol.newKNXConnectionStateRequest(channelID))
// }
this.send(

@@ -1757,8 +1861,2 @@ KNXProtocol.newKNXConnectionStateRequest(channelID),

private sendDisconnectRequestMessage(channelID: number) {
// try {
// const oHPAI = new HPAI.HPAI(this._options.localSocketAddress.address, this._options.localSocketAddress.port, this._options.hostProtocol === 'TunnelTCP' ? KNX_CONSTANTS.IPV4_TCP : KNX_CONSTANTS.IPV4_UDP)
// this.send(KNXProtocol.newKNXDisconnectRequest(channelID, oHPAI))
// } catch (error) {
// this.send(KNXProtocol.newKNXDisconnectRequest(channelID))
// }
this.send(

@@ -1765,0 +1863,0 @@ KNXProtocol.newKNXDisconnectRequest(channelID),

@@ -105,3 +105,3 @@ import { KNX_CONSTANTS } from './KNXConstants'

}
const port = buffer.readUInt8(offset)
const port = buffer.readUInt16BE(offset)
const host = ip.join('.')

@@ -108,0 +108,0 @@ return new HPAI(host, port, protocol)

@@ -7,6 +7,23 @@ import { hasProp } from '../utils'

const candidateInterfaces: { [key: string]: NetworkInterfaceInfo } = {}
const interfaces = os.networkInterfaces()
let interfaces: Record<string, NetworkInterfaceInfo[]> =
os.networkInterfaces()
if (process.env.CI) {
// create a fake interface for CI
interfaces = {
eth0: [
{
address: '192.168.1.58',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: false,
cidr: '192.168.1.58/24',
},
],
}
}
for (const iface in interfaces) {
for (const key in interfaces[iface]) {
const intf = interfaces[iface][key]
for (const intf of interfaces[iface]) {
try {

@@ -54,2 +71,3 @@ KnxLog.get().debug(

)
const candidateInterfaces = getIPv4Interfaces()

@@ -56,0 +74,0 @@ if (_interface !== '') {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc