matterbridge 3.4.5-dev-20251224-1bb63cb → 3.4.5-dev-20251224-457def5

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/CHANGELOG.md CHANGED
@@ -34,9 +34,10 @@ Advantages:
34
34
 
35
35
  - [DevContainer]: Refactored Dev Container setup. The Matterbridge instance can now be paired on native Linux hosts or WSL 2 with Docker engine CLI integration. On Docker Desktop on Windows or macOS is not possible cause Docker Desktop runs inside a VM and not directly on the host so mDNS is not supported.
36
36
  - [DevContainer]: Since is now possible to pair from Dev Container, named volumes have been added to persist storage and plugins across rebuilds.
37
- - [mb_mdns]: Add query and advertise interval. Improved help for easy mDNS testing.
37
+ - [mb_mdns]: Added query and advertise interval. Improved help for easy mDNS testing.
38
38
  - [mb_mdns]: Advertise full DNS-SD record set (PTR/SRV/TXT/A/AAAA) for matterbridge.\_http.\_tcp.local on port 8283.
39
39
  - [mdns]: Added TXT/SRV/A/AAAA encoders into the Mdns class.
40
+ - [mb_mdns]: Added broadcast parameter to allow advertising when multicast is not available.
40
41
 
41
42
  ### Changed
42
43
 
@@ -1,5 +1,4 @@
1
1
  import { getIntParameter, getParameter, getStringArrayParameter, hasParameter } from '../utils/commandLine.js';
2
- import { getIpv4InterfaceAddress, getIpv6InterfaceAddress } from '../utils/network.js';
3
2
  import { MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS, MDNS_MULTICAST_PORT } from './multicast.js';
4
3
  import { Mdns } from './mdns.js';
5
4
  {
@@ -67,54 +66,9 @@ Examples:
67
66
  mdnsIpv6.logDevices();
68
67
  process.exit(0);
69
68
  }
70
- const queryUdp4 = () => {
71
- mdnsIpv4.log.info('Sending mDNS query for services...');
72
- mdnsIpv4.sendQuery([
73
- { name: '_matterc._udp.local', type: 12, class: 1, unicastResponse: false },
74
- { name: '_matter._tcp.local', type: 12, class: 1, unicastResponse: false },
75
- { name: '_shelly._tcp.local', type: 12, class: 1, unicastResponse: false },
76
- { name: '_http._tcp.local', type: 12, class: 1, unicastResponse: false },
77
- { name: '_services._dns-sd._udp.local', type: 12, class: 1, unicastResponse: false },
78
- ]);
79
- };
80
- const advertiseUdp4 = () => {
81
- mdnsIpv4.log.info('Sending mDNS advertisement for matterbridge service...');
82
- const serviceType = '_http._tcp.local';
83
- const instanceName = 'matterbridge._http._tcp.local';
84
- const hostName = 'matterbridge.local';
85
- const port = 8283;
86
- const ttl = 120;
87
- const ptrInstanceRdata = mdnsIpv4.encodeDnsName(instanceName);
88
- const ptrServiceTypeRdata = mdnsIpv4.encodeDnsName(serviceType);
89
- const srvRdata = mdnsIpv4.encodeSrvRdata(0, 0, port, hostName);
90
- const txtRdata = mdnsIpv4.encodeTxtRdata([`version=${pkg.version}`, 'path=/']);
91
- const answers = [
92
- { name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata: ptrServiceTypeRdata },
93
- { name: serviceType, rtype: 12, rclass: 1, ttl, rdata: ptrInstanceRdata },
94
- { name: instanceName, rtype: 33, rclass: 1 | 32768, ttl, rdata: srvRdata },
95
- { name: instanceName, rtype: 16, rclass: 1 | 32768, ttl, rdata: txtRdata },
96
- ];
97
- try {
98
- const ipv4 = getIpv4InterfaceAddress();
99
- if (ipv4 && ipv4 !== '0.0.0.0') {
100
- answers.push({ name: hostName, rtype: 1, rclass: 1 | 32768, ttl, rdata: mdnsIpv4.encodeA(ipv4) });
101
- }
102
- }
103
- catch {
104
- }
105
- try {
106
- const ipv6 = getIpv6InterfaceAddress();
107
- if (ipv6 && ipv6 !== '::') {
108
- answers.push({ name: hostName, rtype: 28, rclass: 1 | 32768, ttl, rdata: mdnsIpv4.encodeAAAA(ipv6) });
109
- }
110
- }
111
- catch {
112
- }
113
- mdnsIpv4.sendResponse(answers);
114
- };
115
- const queryUdp6 = () => {
116
- mdnsIpv6.log.info('Sending mDNS query for services...');
117
- mdnsIpv6.sendQuery([
69
+ const query = (mdns) => {
70
+ mdns.log.info('Sending mDNS query for services...');
71
+ mdns.sendQuery([
118
72
  { name: '_matterc._udp.local', type: 12, class: 1, unicastResponse: true },
119
73
  { name: '_matter._tcp.local', type: 12, class: 1, unicastResponse: true },
120
74
  { name: '_shelly._tcp.local', type: 12, class: 1, unicastResponse: true },
@@ -122,17 +76,17 @@ Examples:
122
76
  { name: '_services._dns-sd._udp.local', type: 12, class: 1, unicastResponse: true },
123
77
  ]);
124
78
  };
125
- const advertiseUdp6 = () => {
126
- mdnsIpv6.log.info('Sending mDNS advertisement for matterbridge service...');
79
+ const advertise = (mdns) => {
80
+ mdns.log.info('Sending mDNS advertisement for matterbridge service...');
127
81
  const serviceType = '_http._tcp.local';
128
82
  const instanceName = 'matterbridge._http._tcp.local';
129
83
  const hostName = 'matterbridge.local';
130
84
  const port = 8283;
131
85
  const ttl = 120;
132
- const ptrInstanceRdata = mdnsIpv6.encodeDnsName(instanceName);
133
- const ptrServiceTypeRdata = mdnsIpv6.encodeDnsName(serviceType);
134
- const srvRdata = mdnsIpv6.encodeSrvRdata(0, 0, port, hostName);
135
- const txtRdata = mdnsIpv6.encodeTxtRdata([`version=${pkg.version}`, 'path=/']);
86
+ const ptrInstanceRdata = mdns.encodeDnsName(instanceName);
87
+ const ptrServiceTypeRdata = mdns.encodeDnsName(serviceType);
88
+ const srvRdata = mdns.encodeSrvRdata(0, 0, port, hostName);
89
+ const txtRdata = mdns.encodeTxtRdata([`version=${pkg.version}`, 'path=/']);
136
90
  const answers = [
137
91
  { name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata: ptrServiceTypeRdata },
138
92
  { name: serviceType, rtype: 12, rclass: 1, ttl, rdata: ptrInstanceRdata },
@@ -140,22 +94,43 @@ Examples:
140
94
  { name: instanceName, rtype: 16, rclass: 1 | 32768, ttl, rdata: txtRdata },
141
95
  ];
142
96
  try {
143
- const ipv4 = getIpv4InterfaceAddress();
97
+ const ipv4 = mdns.getIpv4InterfaceAddress(mdns.interfaceName);
144
98
  if (ipv4) {
145
- answers.push({ name: hostName, rtype: 1, rclass: 1 | 32768, ttl, rdata: mdnsIpv6.encodeA(ipv4) });
99
+ answers.push({ name: hostName, rtype: 1, rclass: 1 | 32768, ttl, rdata: mdns.encodeA(ipv4) });
146
100
  }
147
101
  }
148
- catch {
102
+ catch (error) {
103
+ mdns.log.warn(`Error sending mDNS advertisement for matterbridge service A record: ${error.message}`);
149
104
  }
150
105
  try {
151
- const ipv6 = getIpv6InterfaceAddress();
106
+ const ipv6 = mdns.getIpv6InterfaceAddress(mdns.interfaceName);
152
107
  if (ipv6) {
153
- answers.push({ name: hostName, rtype: 28, rclass: 1 | 32768, ttl, rdata: mdnsIpv6.encodeAAAA(ipv6) });
108
+ answers.push({ name: hostName, rtype: 28, rclass: 1 | 32768, ttl, rdata: mdns.encodeAAAA(ipv6) });
154
109
  }
155
110
  }
156
- catch {
111
+ catch (error) {
112
+ mdns.log.warn(`Error sending mDNS advertisement for matterbridge service AAAA record: ${error.message}`);
113
+ }
114
+ const response = mdns.sendResponse(answers);
115
+ if (hasParameter('broadcast')) {
116
+ try {
117
+ const address = mdns.socketType === 'udp4' ? mdns.getIpv4InterfaceAddress(mdns.interfaceName) : mdns.getIpv6InterfaceAddress(mdns.interfaceName);
118
+ const mask = mdns.socketType === 'udp4' ? mdns.getNetmask(address) : undefined;
119
+ const broadcastAddress = mdns.socketType === 'udp4' ? mdns.getIpv4BroadcastAddress(address, mask) : mdns.getIpv6BroadcastAddress();
120
+ mdns.log.info(`Broadcasting mDNS advertisement for matterbridge service to ${broadcastAddress}...`);
121
+ mdns.socket.send(response, 0, response.length, mdns.multicastPort, broadcastAddress, (error) => {
122
+ if (error) {
123
+ mdns.log.error(`Error broadcasting mDNS advertisement: ${error.message}`);
124
+ }
125
+ else {
126
+ mdns.log.info(`mDNS advertisement broadcasted successfully to ${broadcastAddress}`);
127
+ }
128
+ });
129
+ }
130
+ catch (error) {
131
+ mdns.log.error(`Error broadcasting mDNS advertisement: ${error.message}`);
132
+ }
157
133
  }
158
- mdnsIpv6.sendResponse(answers);
159
134
  };
160
135
  process.on('SIGINT', () => {
161
136
  cleanupAndLogAndExit();
@@ -164,15 +139,15 @@ Examples:
164
139
  mdnsIpv4.on('ready', (address) => {
165
140
  mdnsIpv4.log.info(`mdnsIpv4 server ready on ${address.family} ${address.address}:${address.port}`);
166
141
  if (hasParameter('advertise')) {
167
- advertiseUdp4();
142
+ advertise(mdnsIpv4);
168
143
  setInterval(() => {
169
- advertiseUdp4();
144
+ advertise(mdnsIpv4);
170
145
  }, getIntParameter('advertise') || 10000).unref();
171
146
  }
172
147
  if (hasParameter('query')) {
173
- queryUdp4();
148
+ query(mdnsIpv4);
174
149
  setInterval(() => {
175
- queryUdp4();
150
+ query(mdnsIpv4);
176
151
  }, getIntParameter('query') || 10000).unref();
177
152
  }
178
153
  });
@@ -180,15 +155,15 @@ Examples:
180
155
  mdnsIpv6.on('ready', (address) => {
181
156
  mdnsIpv6.log.info(`mdnsIpv6 server ready on ${address.family} ${address.address}:${address.port}`);
182
157
  if (hasParameter('advertise')) {
183
- advertiseUdp6();
158
+ advertise(mdnsIpv6);
184
159
  setInterval(() => {
185
- advertiseUdp6();
160
+ advertise(mdnsIpv6);
186
161
  }, getIntParameter('advertise') || 10000).unref();
187
162
  }
188
163
  if (hasParameter('query')) {
189
- queryUdp6();
164
+ query(mdnsIpv6);
190
165
  setInterval(() => {
191
- queryUdp6();
166
+ query(mdnsIpv6);
192
167
  }, getIntParameter('query') || 10000).unref();
193
168
  }
194
169
  });
@@ -1,4 +1,5 @@
1
1
  import { BLUE, CYAN, db, er, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
2
+ import { hasParameter } from '../utils/commandLine.js';
2
3
  import { Multicast } from './multicast.js';
3
4
  export var DnsRecordType;
4
5
  (function (DnsRecordType) {
@@ -433,8 +434,10 @@ export class Mdns extends Multicast {
433
434
  return Buffer.concat([qname, qfields]);
434
435
  });
435
436
  const query = Buffer.concat([header, ...questionBuffers]);
436
- const decoded = this.decodeMdnsMessage(query);
437
- this.logMdnsMessage(decoded);
437
+ if (hasParameter('v') || hasParameter('verbose')) {
438
+ const decoded = this.decodeMdnsMessage(query);
439
+ this.logMdnsMessage(decoded);
440
+ }
438
441
  this.socket.send(query, 0, query.length, this.multicastPort, this.multicastAddress, (error) => {
439
442
  if (error) {
440
443
  this.log.error(`Dgram mDNS server failed to send query message: ${error.message}`);
@@ -448,6 +451,7 @@ export class Mdns extends Multicast {
448
451
  this.emit('sent', query, this.multicastAddress, this.multicastPort);
449
452
  }
450
453
  });
454
+ return query;
451
455
  }
452
456
  sendResponse(answers) {
453
457
  if (!Array.isArray(answers) || answers.length === 0) {
@@ -470,6 +474,10 @@ export class Mdns extends Multicast {
470
474
  return Buffer.concat([aname, answerFixed, rdata]);
471
475
  });
472
476
  const response = Buffer.concat([header, ...answerBuffers]);
477
+ if (hasParameter('v') || hasParameter('verbose')) {
478
+ const decoded = this.decodeMdnsMessage(response);
479
+ this.logMdnsMessage(decoded);
480
+ }
473
481
  this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
474
482
  if (error) {
475
483
  const items = answers.map((a) => `- name ${MAGENTA}${a.name}${er} type ${MAGENTA}${this.dnsTypeToString(a.rtype)}${er} class ${MAGENTA}${this.dnsResponseClassToString(a.rclass)}${er} ttl ${MAGENTA}${a.ttl}${er}`).join('\n');
@@ -482,6 +490,7 @@ export class Mdns extends Multicast {
482
490
  this.emit('sent', response, this.multicastAddress, this.multicastPort);
483
491
  }
484
492
  });
493
+ return response;
485
494
  }
486
495
  dnsTypeToString(type) {
487
496
  const typeMap = {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.4.5-dev-20251224-1bb63cb",
3
+ "version": "3.4.5-dev-20251224-457def5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.4.5-dev-20251224-1bb63cb",
9
+ "version": "3.4.5-dev-20251224-457def5",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.15.6",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.4.5-dev-20251224-1bb63cb",
3
+ "version": "3.4.5-dev-20251224-457def5",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",