@matterbridge/core 3.5.4-dev-20260211-c4f9359 → 3.5.4-dev-20260211-520e349
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/frontend.js +24 -42
- package/dist/jestutils/jestHelpers.js +2 -2
- package/package.json +5 -5
- package/dist/mb_coap.d.ts +0 -1
- package/dist/mb_coap.js +0 -51
- package/dist/mb_health.d.ts +0 -10
- package/dist/mb_health.js +0 -77
- package/dist/mb_mdns.d.ts +0 -1
- package/dist/mb_mdns.js +0 -227
package/dist/frontend.js
CHANGED
|
@@ -206,27 +206,18 @@ export class Frontend extends EventEmitter {
|
|
|
206
206
|
this.emit('server_error', error);
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
|
-
|
|
210
|
-
this.httpServer
|
|
211
|
-
|
|
212
|
-
this.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
if (this.matterbridge.systemInformation.ipv4Address !== '' && !getParameter('bind'))
|
|
223
|
-
this.log.info(`The frontend http server is listening on ${UNDERLINE}http://${this.matterbridge.systemInformation.ipv4Address}:${this.port}${UNDERLINEOFF}${rs}`);
|
|
224
|
-
if (this.matterbridge.systemInformation.ipv6Address !== '' && !getParameter('bind'))
|
|
225
|
-
this.log.info(`The frontend http server is listening on ${UNDERLINE}http://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
|
|
226
|
-
this.listening = true;
|
|
227
|
-
this.emit('server_listening', 'http', this.port);
|
|
228
|
-
});
|
|
229
|
-
}
|
|
209
|
+
this.httpServer.listen(this.port, getParameter('bind'), () => {
|
|
210
|
+
const addr = this.httpServer?.address();
|
|
211
|
+
if (addr && typeof addr !== 'string') {
|
|
212
|
+
this.log.info(`The frontend http server is bound to ${addr.family} ${addr.address}:${addr.port}`);
|
|
213
|
+
}
|
|
214
|
+
if (this.matterbridge.systemInformation.ipv4Address !== '' && !getParameter('bind'))
|
|
215
|
+
this.log.info(`The frontend http server is listening on ${UNDERLINE}http://${this.matterbridge.systemInformation.ipv4Address}:${this.port}${UNDERLINEOFF}${rs}`);
|
|
216
|
+
if (this.matterbridge.systemInformation.ipv6Address !== '' && !getParameter('bind'))
|
|
217
|
+
this.log.info(`The frontend http server is listening on ${UNDERLINE}http://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
|
|
218
|
+
this.listening = true;
|
|
219
|
+
this.emit('server_listening', 'http', this.port);
|
|
220
|
+
});
|
|
230
221
|
this.httpServer.on('upgrade', async (req, socket, head) => {
|
|
231
222
|
try {
|
|
232
223
|
if ((req.headers.upgrade || '').toLowerCase() !== 'websocket') {
|
|
@@ -344,27 +335,18 @@ export class Frontend extends EventEmitter {
|
|
|
344
335
|
this.emit('server_error', error);
|
|
345
336
|
return;
|
|
346
337
|
}
|
|
347
|
-
|
|
348
|
-
this.httpsServer
|
|
349
|
-
|
|
350
|
-
this.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
if (this.matterbridge.systemInformation.ipv4Address !== '' && !getParameter('bind'))
|
|
361
|
-
this.log.info(`The frontend https server is listening on ${UNDERLINE}https://${this.matterbridge.systemInformation.ipv4Address}:${this.port}${UNDERLINEOFF}${rs}`);
|
|
362
|
-
if (this.matterbridge.systemInformation.ipv6Address !== '' && !getParameter('bind'))
|
|
363
|
-
this.log.info(`The frontend https server is listening on ${UNDERLINE}https://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
|
|
364
|
-
this.listening = true;
|
|
365
|
-
this.emit('server_listening', 'https', this.port);
|
|
366
|
-
});
|
|
367
|
-
}
|
|
338
|
+
this.httpsServer.listen(this.port, getParameter('bind'), () => {
|
|
339
|
+
const addr = this.httpsServer?.address();
|
|
340
|
+
if (addr && typeof addr !== 'string') {
|
|
341
|
+
this.log.info(`The frontend https server is bound to ${addr.family} ${addr.address}:${addr.port}`);
|
|
342
|
+
}
|
|
343
|
+
if (this.matterbridge.systemInformation.ipv4Address !== '' && !getParameter('bind'))
|
|
344
|
+
this.log.info(`The frontend https server is listening on ${UNDERLINE}https://${this.matterbridge.systemInformation.ipv4Address}:${this.port}${UNDERLINEOFF}${rs}`);
|
|
345
|
+
if (this.matterbridge.systemInformation.ipv6Address !== '' && !getParameter('bind'))
|
|
346
|
+
this.log.info(`The frontend https server is listening on ${UNDERLINE}https://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
|
|
347
|
+
this.listening = true;
|
|
348
|
+
this.emit('server_listening', 'https', this.port);
|
|
349
|
+
});
|
|
368
350
|
this.httpsServer.on('upgrade', async (req, socket, head) => {
|
|
369
351
|
try {
|
|
370
352
|
if ((req.headers.upgrade || '').toLowerCase() !== 'websocket') {
|
|
@@ -244,10 +244,11 @@ export async function stopMatterbridge(cleanupPause = 10, destroyPause = 250) {
|
|
|
244
244
|
await destroyMatterbridgeEnvironment(cleanupPause, destroyPause);
|
|
245
245
|
}
|
|
246
246
|
export async function createMatterbridgeEnvironment(name) {
|
|
247
|
+
log = new AnsiLogger({ logName: name, logTimestampFormat: 4, logLevel: "debug" });
|
|
247
248
|
matterbridge = await Matterbridge.loadInstance(false);
|
|
248
249
|
expect(matterbridge).toBeDefined();
|
|
249
250
|
expect(matterbridge).toBeInstanceOf(Matterbridge);
|
|
250
|
-
matterbridge.matterbridgeVersion = '3.5.
|
|
251
|
+
matterbridge.matterbridgeVersion = '3.5.4';
|
|
251
252
|
matterbridge.bridgeMode = 'bridge';
|
|
252
253
|
matterbridge.rootDirectory = path.join('jest', name);
|
|
253
254
|
matterbridge.homeDirectory = path.join('jest', name);
|
|
@@ -255,7 +256,6 @@ export async function createMatterbridgeEnvironment(name) {
|
|
|
255
256
|
matterbridge.matterbridgePluginDirectory = path.join('jest', name, 'Matterbridge');
|
|
256
257
|
matterbridge.matterbridgeCertDirectory = path.join('jest', name, '.mattercert');
|
|
257
258
|
matterbridge.log.logLevel = "debug";
|
|
258
|
-
log = new AnsiLogger({ logName: name, logTimestampFormat: 4, logLevel: "debug" });
|
|
259
259
|
frontend = matterbridge.frontend;
|
|
260
260
|
plugins = matterbridge.plugins;
|
|
261
261
|
devices = matterbridge.devices;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.5.4-dev-20260211-
|
|
3
|
+
"version": "3.5.4-dev-20260211-520e349",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -126,10 +126,10 @@
|
|
|
126
126
|
},
|
|
127
127
|
"dependencies": {
|
|
128
128
|
"@matter/main": "0.16.8",
|
|
129
|
-
"@matterbridge/dgram": "3.5.4-dev-20260211-
|
|
130
|
-
"@matterbridge/thread": "3.5.4-dev-20260211-
|
|
131
|
-
"@matterbridge/types": "3.5.4-dev-20260211-
|
|
132
|
-
"@matterbridge/utils": "3.5.4-dev-20260211-
|
|
129
|
+
"@matterbridge/dgram": "3.5.4-dev-20260211-520e349",
|
|
130
|
+
"@matterbridge/thread": "3.5.4-dev-20260211-520e349",
|
|
131
|
+
"@matterbridge/types": "3.5.4-dev-20260211-520e349",
|
|
132
|
+
"@matterbridge/utils": "3.5.4-dev-20260211-520e349",
|
|
133
133
|
"archiver": "7.0.1",
|
|
134
134
|
"express": "5.2.1",
|
|
135
135
|
"glob": "13.0.1",
|
package/dist/mb_coap.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/mb_coap.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { COAP_MULTICAST_IPV4_ADDRESS, COAP_MULTICAST_IPV6_ADDRESS, COAP_MULTICAST_PORT, Coap, COAP_OPTION_URI_PATH } from '@matterbridge/dgram';
|
|
2
|
-
{
|
|
3
|
-
const coapIpv4 = new Coap('CoAP Server udp4', COAP_MULTICAST_IPV4_ADDRESS, COAP_MULTICAST_PORT, 'udp4', true);
|
|
4
|
-
const coapIpv6 = new Coap('CoAP Server udp6', COAP_MULTICAST_IPV6_ADDRESS, COAP_MULTICAST_PORT, 'udp6', true);
|
|
5
|
-
coapIpv4.listNetworkInterfaces();
|
|
6
|
-
function cleanupAndLogAndExit() {
|
|
7
|
-
if (process.argv.includes('--coap-udp4'))
|
|
8
|
-
coapIpv4.stop();
|
|
9
|
-
if (process.argv.includes('--coap-udp6'))
|
|
10
|
-
coapIpv6.stop();
|
|
11
|
-
process.exit(0);
|
|
12
|
-
}
|
|
13
|
-
const requestUdp4 = () => {
|
|
14
|
-
coapIpv4.sendRequest(32000, [
|
|
15
|
-
{ number: COAP_OPTION_URI_PATH, value: Buffer.from('cit') },
|
|
16
|
-
{ number: COAP_OPTION_URI_PATH, value: Buffer.from('d') },
|
|
17
|
-
], {}, undefined, COAP_MULTICAST_IPV4_ADDRESS, COAP_MULTICAST_PORT);
|
|
18
|
-
};
|
|
19
|
-
const requestUdp6 = () => {
|
|
20
|
-
coapIpv6.sendRequest(32000, [
|
|
21
|
-
{ number: COAP_OPTION_URI_PATH, value: Buffer.from('cit') },
|
|
22
|
-
{ number: COAP_OPTION_URI_PATH, value: Buffer.from('d') },
|
|
23
|
-
], {}, undefined, COAP_MULTICAST_IPV6_ADDRESS, COAP_MULTICAST_PORT);
|
|
24
|
-
};
|
|
25
|
-
process.on('SIGINT', () => {
|
|
26
|
-
cleanupAndLogAndExit();
|
|
27
|
-
});
|
|
28
|
-
coapIpv4.start();
|
|
29
|
-
coapIpv4.on('ready', (address) => {
|
|
30
|
-
coapIpv4.log.info(`coapIpv4 server ready on ${address.family} ${address.address}:${address.port}`);
|
|
31
|
-
if (!process.argv.includes('--coap-request'))
|
|
32
|
-
return;
|
|
33
|
-
requestUdp4();
|
|
34
|
-
setInterval(() => {
|
|
35
|
-
requestUdp4();
|
|
36
|
-
}, 10000).unref();
|
|
37
|
-
});
|
|
38
|
-
coapIpv6.start();
|
|
39
|
-
coapIpv6.on('ready', (address) => {
|
|
40
|
-
coapIpv6.log.info(`coapIpv6 server ready on ${address.family} ${address.address}:${address.port}`);
|
|
41
|
-
if (!process.argv.includes('--coap-request'))
|
|
42
|
-
return;
|
|
43
|
-
requestUdp6();
|
|
44
|
-
setInterval(() => {
|
|
45
|
-
requestUdp6();
|
|
46
|
-
}, 10000).unref();
|
|
47
|
-
});
|
|
48
|
-
setTimeout(() => {
|
|
49
|
-
cleanupAndLogAndExit();
|
|
50
|
-
}, 600000);
|
|
51
|
-
}
|
package/dist/mb_health.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare function checkHealth(url: string, timeoutMs: number): Promise<boolean>;
|
|
2
|
-
export declare function fetchHealth(url: string, timeoutMs: number): Promise<{
|
|
3
|
-
ok: boolean;
|
|
4
|
-
statusCode: number;
|
|
5
|
-
body: string;
|
|
6
|
-
json?: unknown;
|
|
7
|
-
}>;
|
|
8
|
-
export declare function mbHealthExitCode(url: string, timeoutMs: number): Promise<number>;
|
|
9
|
-
export declare function mbHealthCli(url: string, timeoutMs: number, exitFn?: (code: number) => never | void): Promise<void>;
|
|
10
|
-
export declare function mbHealthMain(exitFn?: (code: number) => never | void): Promise<void>;
|
package/dist/mb_health.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import http from 'node:http';
|
|
2
|
-
import https from 'node:https';
|
|
3
|
-
export function checkHealth(url, timeoutMs) {
|
|
4
|
-
return fetchHealth(url, timeoutMs)
|
|
5
|
-
.then(({ ok }) => ok)
|
|
6
|
-
.catch(() => false);
|
|
7
|
-
}
|
|
8
|
-
export function fetchHealth(url, timeoutMs) {
|
|
9
|
-
return new Promise((resolve) => {
|
|
10
|
-
const parsedUrl = new URL(url);
|
|
11
|
-
const requestImpl = parsedUrl.protocol === 'https:' ? https : http;
|
|
12
|
-
const request = requestImpl.request({
|
|
13
|
-
protocol: parsedUrl.protocol,
|
|
14
|
-
hostname: parsedUrl.hostname,
|
|
15
|
-
port: parsedUrl.port,
|
|
16
|
-
path: parsedUrl.pathname + parsedUrl.search,
|
|
17
|
-
method: 'GET',
|
|
18
|
-
headers: {
|
|
19
|
-
'cache-control': 'no-store',
|
|
20
|
-
'accept': 'application/json',
|
|
21
|
-
},
|
|
22
|
-
}, (response) => {
|
|
23
|
-
const chunks = [];
|
|
24
|
-
response.on('data', (chunk) => {
|
|
25
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
26
|
-
});
|
|
27
|
-
response.on('end', () => {
|
|
28
|
-
const statusCode = response.statusCode ?? 0;
|
|
29
|
-
const ok = statusCode >= 200 && statusCode < 300;
|
|
30
|
-
const body = Buffer.concat(chunks).toString('utf8');
|
|
31
|
-
let json;
|
|
32
|
-
try {
|
|
33
|
-
if (body.trim().length > 0)
|
|
34
|
-
json = JSON.parse(body);
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
json = undefined;
|
|
38
|
-
}
|
|
39
|
-
resolve({ ok, statusCode, body, json });
|
|
40
|
-
});
|
|
41
|
-
response.on('error', () => {
|
|
42
|
-
resolve({ ok: false, statusCode: response.statusCode ?? 0, body: '' });
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
request.on('error', () => resolve({ ok: false, statusCode: 0, body: '' }));
|
|
46
|
-
request.setTimeout(timeoutMs, () => {
|
|
47
|
-
request.destroy();
|
|
48
|
-
resolve({ ok: false, statusCode: 0, body: '' });
|
|
49
|
-
});
|
|
50
|
-
request.end();
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
export async function mbHealthExitCode(url, timeoutMs) {
|
|
54
|
-
try {
|
|
55
|
-
const { ok } = await fetchHealth(url, timeoutMs);
|
|
56
|
-
return ok ? 0 : 1;
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
return 1;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
export async function mbHealthCli(url, timeoutMs, exitFn = process.exit) {
|
|
63
|
-
const { ok, statusCode, body, json } = await fetchHealth(url, timeoutMs);
|
|
64
|
-
if (json !== undefined) {
|
|
65
|
-
console.log(JSON.stringify(json, null, 2));
|
|
66
|
-
}
|
|
67
|
-
else if (body) {
|
|
68
|
-
console.log(body);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
console.log(JSON.stringify({ ok, statusCode }, null, 2));
|
|
72
|
-
}
|
|
73
|
-
exitFn(ok ? 0 : 1);
|
|
74
|
-
}
|
|
75
|
-
export async function mbHealthMain(exitFn = process.exit) {
|
|
76
|
-
await mbHealthCli('http://localhost:8283/health', 5000, exitFn);
|
|
77
|
-
}
|
package/dist/mb_mdns.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/mb_mdns.js
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import { MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS, MDNS_MULTICAST_PORT, Mdns } from '@matterbridge/dgram';
|
|
3
|
-
import { getIntParameter, getParameter, getStringArrayParameter, hasParameter } from '@matterbridge/utils';
|
|
4
|
-
{
|
|
5
|
-
if (hasParameter('h') || hasParameter('help')) {
|
|
6
|
-
console.log(`Copyright (c) Matterbridge. All rights reserved. Version 1.0.0.\n`);
|
|
7
|
-
console.log(`Usage: mb_mdns [options...]
|
|
8
|
-
|
|
9
|
-
If no command line is provided, mb_mdns shows all incoming mDNS records on all interfaces (0.0.0.0 and ::).
|
|
10
|
-
|
|
11
|
-
Options:
|
|
12
|
-
-h, --help Show this help message and exit.
|
|
13
|
-
--interfaceName <name> Network interface name to bind to (default all interfaces).
|
|
14
|
-
--ipv4InterfaceAddress <address> IPv4 address of the network interface to bind to (default: 0.0.0.0).
|
|
15
|
-
--ipv6InterfaceAddress <address> IPv6 address of the network interface to bind to (default: ::).
|
|
16
|
-
--outgoingIpv4InterfaceAddress <address> Outgoing IPv4 address of the network interface (default first external address).
|
|
17
|
-
--outgoingIpv6InterfaceAddress <address> Outgoing IPv6 address of the network interface (default first external address).
|
|
18
|
-
--advertise <interval> Enable matterbridge mDNS advertisement each ms (default interval: 10000ms).
|
|
19
|
-
--query <interval> Enable common mDNS services query each ms (default interval: 10000ms).
|
|
20
|
-
--filter <string...> Filter strings to match in the mDNS record name (default: no filter).
|
|
21
|
-
--ip-filter <string...> Filter strings to match in the mDNS sender ip address (default: no filter).
|
|
22
|
-
--noIpv4 Disable IPv4 mDNS server (default: enabled).
|
|
23
|
-
--noIpv6 Disable IPv6 mDNS server (default: enabled).
|
|
24
|
-
--no-timeout Disable automatic timeout of 10 minutes. Reflector mode disables timeout automatically.
|
|
25
|
-
-d, --debug Enable debug logging (default: disabled).
|
|
26
|
-
-v, --verbose Enable verbose logging (default: disabled).
|
|
27
|
-
-s, --silent Enable silent mode, only log notices, warnings and errors.
|
|
28
|
-
|
|
29
|
-
Examples:
|
|
30
|
-
# Listen for Matter device commissioner service records only on eth0 interface
|
|
31
|
-
mb_mdns --interfaceName eth0 --filter _matterc._udp
|
|
32
|
-
|
|
33
|
-
# Listen for Matter device discovery service records only on eth0 interface
|
|
34
|
-
mb_mdns --interfaceName eth0 --filter _matter._tcp
|
|
35
|
-
|
|
36
|
-
# Listen for Matter commissioner and discovery service records on all interfaces
|
|
37
|
-
mb_mdns --filter _matterc._udp _matter._tcp
|
|
38
|
-
|
|
39
|
-
# Listen for Matter commissioner and discovery service records on all interfaces from specific ipv4 and ipv6 ips
|
|
40
|
-
mb_mdns --filter _matterc._udp _matter._tcp --ip-filter 192.168.69.20 fe80::1077:2e0d:2c91:aa90
|
|
41
|
-
|
|
42
|
-
# Query for mDNS devices every 10s on a specific interface
|
|
43
|
-
mb_mdns --interfaceName eth0 --query
|
|
44
|
-
|
|
45
|
-
# Advertise _matterbridge._tcp.local every 5s with filter
|
|
46
|
-
mb_mdns --advertise 5000 --filter _matterbridge._tcp.local
|
|
47
|
-
|
|
48
|
-
# Query each 5s and listen for _matterbridge._tcp.local service records
|
|
49
|
-
mb_mdns --query 5000 --filter _matterbridge._tcp.local
|
|
50
|
-
`);
|
|
51
|
-
process.exit(0);
|
|
52
|
-
}
|
|
53
|
-
const { default: pkg } = await import('../package.json', { with: { type: 'json' } });
|
|
54
|
-
let mdnsIpv4QueryInterval;
|
|
55
|
-
let mdnsIpv6QueryInterval;
|
|
56
|
-
let mdnsIpv4AdvertiseInterval;
|
|
57
|
-
let mdnsIpv6AdvertiseInterval;
|
|
58
|
-
let mdnsIpv4 = undefined;
|
|
59
|
-
let mdnsIpv6 = undefined;
|
|
60
|
-
async function cleanupAndLogAndExit() {
|
|
61
|
-
clearInterval(mdnsIpv4QueryInterval);
|
|
62
|
-
clearInterval(mdnsIpv6QueryInterval);
|
|
63
|
-
clearInterval(mdnsIpv4AdvertiseInterval);
|
|
64
|
-
clearInterval(mdnsIpv6AdvertiseInterval);
|
|
65
|
-
if (hasParameter('advertise')) {
|
|
66
|
-
if (mdnsIpv4)
|
|
67
|
-
advertise(mdnsIpv4, 0);
|
|
68
|
-
if (mdnsIpv6)
|
|
69
|
-
advertise(mdnsIpv6, 0);
|
|
70
|
-
}
|
|
71
|
-
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
72
|
-
mdnsIpv4?.stop();
|
|
73
|
-
mdnsIpv6?.stop();
|
|
74
|
-
mdnsIpv4?.logDevices();
|
|
75
|
-
mdnsIpv6?.logDevices();
|
|
76
|
-
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
77
|
-
}
|
|
78
|
-
const query = (mdns) => {
|
|
79
|
-
mdns.log.info('Sending mDNS query for common services...');
|
|
80
|
-
try {
|
|
81
|
-
mdns.sendQuery([
|
|
82
|
-
{ name: '_matterc._udp.local', type: 12, class: 1, unicastResponse: true },
|
|
83
|
-
{ name: '_matter._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
84
|
-
{ name: '_matterbridge._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
85
|
-
{ name: '_home-assistant._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
86
|
-
{ name: '_shelly._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
87
|
-
{ name: '_mqtt._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
88
|
-
{ name: '_http._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
89
|
-
{ name: '_googlecast._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
90
|
-
{ name: '_airplay._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
91
|
-
{ name: '_amzn-alexa._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
92
|
-
{ name: '_companion-link._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
93
|
-
{ name: '_hap._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
94
|
-
{ name: '_hap._udp.local', type: 12, class: 1, unicastResponse: true },
|
|
95
|
-
{ name: '_ipp._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
96
|
-
{ name: '_ipps._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
97
|
-
{ name: '_meshcop._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
98
|
-
{ name: '_printer._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
99
|
-
{ name: '_raop._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
100
|
-
{ name: '_sleep-proxy._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
101
|
-
{ name: '_ssh._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
102
|
-
{ name: '_services._dns-sd._udp.local', type: 12, class: 1, unicastResponse: true },
|
|
103
|
-
]);
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
mdns.log.error(`Error sending mDNS query: ${error.message}`);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const advertise = (mdns, ttl = 120) => {
|
|
110
|
-
mdns.log.info(`Sending mDNS advertisement for matterbridge service with TTL ${ttl ? ttl.toString() : 'goodbye'}...`);
|
|
111
|
-
const httpServiceType = '_http._tcp.local';
|
|
112
|
-
const matterbridgeServiceType = '_matterbridge._tcp.local';
|
|
113
|
-
const httpInstanceName = 'matterbridge._http._tcp.local';
|
|
114
|
-
const matterbridgeInstanceName = 'matterbridge._matterbridge._tcp.local';
|
|
115
|
-
const hostName = 'matterbridge.local';
|
|
116
|
-
const port = 8283;
|
|
117
|
-
const ptrHttpServiceTypeRdata = mdns.encodeDnsName(httpServiceType);
|
|
118
|
-
const ptrMatterbridgeServiceTypeRdata = mdns.encodeDnsName(matterbridgeServiceType);
|
|
119
|
-
const ptrHttpInstanceRdata = mdns.encodeDnsName(httpInstanceName);
|
|
120
|
-
const ptrMatterbridgeInstanceRdata = mdns.encodeDnsName(matterbridgeInstanceName);
|
|
121
|
-
const srvRdata = mdns.encodeSrvRdata(0, 0, port, hostName);
|
|
122
|
-
const txtRdata = mdns.encodeTxtRdata([`version=${pkg.version}`, 'path=/']);
|
|
123
|
-
const answers = [
|
|
124
|
-
{ name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata: ptrHttpServiceTypeRdata },
|
|
125
|
-
{ name: httpServiceType, rtype: 12, rclass: 1, ttl, rdata: ptrHttpInstanceRdata },
|
|
126
|
-
{ name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata: ptrMatterbridgeServiceTypeRdata },
|
|
127
|
-
{ name: matterbridgeServiceType, rtype: 12, rclass: 1, ttl, rdata: ptrMatterbridgeInstanceRdata },
|
|
128
|
-
{ name: httpInstanceName, rtype: 33, rclass: 1 | 32768, ttl, rdata: srvRdata },
|
|
129
|
-
{ name: matterbridgeInstanceName, rtype: 33, rclass: 1 | 32768, ttl, rdata: srvRdata },
|
|
130
|
-
{ name: httpInstanceName, rtype: 16, rclass: 1 | 32768, ttl, rdata: txtRdata },
|
|
131
|
-
{ name: matterbridgeInstanceName, rtype: 16, rclass: 1 | 32768, ttl, rdata: txtRdata },
|
|
132
|
-
];
|
|
133
|
-
const interfaces = os.networkInterfaces();
|
|
134
|
-
let interfaceInfos = mdns.interfaceName ? interfaces[mdns.interfaceName] : undefined;
|
|
135
|
-
if (!interfaceInfos) {
|
|
136
|
-
interfaceInfos = [];
|
|
137
|
-
for (const name of Object.keys(interfaces)) {
|
|
138
|
-
const infos = interfaces[name];
|
|
139
|
-
if (infos && infos.length > 0 && !infos[0].internal) {
|
|
140
|
-
interfaceInfos.push(...infos);
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
for (const info of interfaceInfos) {
|
|
146
|
-
if (info.family === 'IPv4' && !info.internal) {
|
|
147
|
-
const ipv4 = info.address;
|
|
148
|
-
answers.push({ name: hostName, rtype: 1, rclass: 1 | 32768, ttl, rdata: mdns.encodeA(ipv4) });
|
|
149
|
-
}
|
|
150
|
-
else if (info.family === 'IPv6' && !info.internal) {
|
|
151
|
-
const ipv6 = info.address;
|
|
152
|
-
answers.push({ name: hostName, rtype: 28, rclass: 1 | 32768, ttl, rdata: mdns.encodeAAAA(ipv6) });
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
try {
|
|
156
|
-
mdns.sendResponse(answers);
|
|
157
|
-
}
|
|
158
|
-
catch (error) {
|
|
159
|
-
mdns.log.error(`Error sending mDNS advertisement: ${error.message}`);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
if (!hasParameter('noIpv4')) {
|
|
163
|
-
mdnsIpv4 = new Mdns('mDNS Server udp4', MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_PORT, 'udp4', true, getParameter('interfaceName'), getParameter('ipv4InterfaceAddress') || '0.0.0.0', getParameter('outgoingIpv4InterfaceAddress'));
|
|
164
|
-
if (hasParameter('v') || hasParameter('verbose'))
|
|
165
|
-
mdnsIpv4.listNetworkInterfaces();
|
|
166
|
-
const filters = getStringArrayParameter('filter');
|
|
167
|
-
if (filters)
|
|
168
|
-
mdnsIpv4.filters.push(...filters);
|
|
169
|
-
const ipFilters = getStringArrayParameter('ip-filter');
|
|
170
|
-
if (ipFilters)
|
|
171
|
-
mdnsIpv4.ipFilters.push(...ipFilters);
|
|
172
|
-
mdnsIpv4.on('error', (err) => {
|
|
173
|
-
mdnsIpv4?.log.error(`mDNS udp4 Server error: ${err.message}\n${err.stack}`);
|
|
174
|
-
});
|
|
175
|
-
mdnsIpv4.start();
|
|
176
|
-
mdnsIpv4.on('ready', (address) => {
|
|
177
|
-
mdnsIpv4?.socket.setMulticastLoopback(false);
|
|
178
|
-
mdnsIpv4?.log.info(`mdnsIpv4 server ready on ${address.family} ${address.address}:${address.port}`);
|
|
179
|
-
if (hasParameter('advertise')) {
|
|
180
|
-
advertise(mdnsIpv4);
|
|
181
|
-
mdnsIpv4AdvertiseInterval = setInterval(() => advertise(mdnsIpv4), getIntParameter('advertise') || 10000).unref();
|
|
182
|
-
}
|
|
183
|
-
if (hasParameter('query')) {
|
|
184
|
-
query(mdnsIpv4);
|
|
185
|
-
mdnsIpv4QueryInterval = setInterval(() => query(mdnsIpv4), getIntParameter('query') || 10000).unref();
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
if (!hasParameter('noIpv6')) {
|
|
190
|
-
mdnsIpv6 = new Mdns('mDNS Server udp6', MDNS_MULTICAST_IPV6_ADDRESS, MDNS_MULTICAST_PORT, 'udp6', true, getParameter('interfaceName'), getParameter('ipv6InterfaceAddress') || '::', getParameter('outgoingIpv6InterfaceAddress'));
|
|
191
|
-
if (hasParameter('v') || hasParameter('verbose'))
|
|
192
|
-
mdnsIpv6.listNetworkInterfaces();
|
|
193
|
-
const filters = getStringArrayParameter('filter');
|
|
194
|
-
if (filters)
|
|
195
|
-
mdnsIpv6.filters.push(...filters);
|
|
196
|
-
const ipFilters = getStringArrayParameter('ip-filter');
|
|
197
|
-
if (ipFilters)
|
|
198
|
-
mdnsIpv6.ipFilters.push(...ipFilters);
|
|
199
|
-
mdnsIpv6.on('error', (err) => {
|
|
200
|
-
mdnsIpv6?.log.error(`mDNS udp6 Server error: ${err.message}\n${err.stack}`);
|
|
201
|
-
});
|
|
202
|
-
mdnsIpv6.start();
|
|
203
|
-
mdnsIpv6.on('ready', (address) => {
|
|
204
|
-
mdnsIpv6?.socket.setMulticastLoopback(false);
|
|
205
|
-
mdnsIpv6?.log.info(`mdnsIpv6 server ready on ${address.family} ${address.address}:${address.port}`);
|
|
206
|
-
if (hasParameter('advertise')) {
|
|
207
|
-
advertise(mdnsIpv6);
|
|
208
|
-
mdnsIpv6AdvertiseInterval = setInterval(() => advertise(mdnsIpv6), getIntParameter('advertise') || 10000).unref();
|
|
209
|
-
}
|
|
210
|
-
if (hasParameter('query')) {
|
|
211
|
-
query(mdnsIpv6);
|
|
212
|
-
mdnsIpv6QueryInterval = setInterval(() => query(mdnsIpv6), getIntParameter('query') || 10000).unref();
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
process.on('SIGINT', async () => {
|
|
217
|
-
await cleanupAndLogAndExit();
|
|
218
|
-
});
|
|
219
|
-
process.on('SIGTERM', async () => {
|
|
220
|
-
await cleanupAndLogAndExit();
|
|
221
|
-
});
|
|
222
|
-
if (!hasParameter('no-timeout')) {
|
|
223
|
-
setTimeout(async () => {
|
|
224
|
-
await cleanupAndLogAndExit();
|
|
225
|
-
}, 600000).unref();
|
|
226
|
-
}
|
|
227
|
-
}
|