matterbridge 3.1.6 → 3.1.7-dev-20250723-8e073ce

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.
Files changed (241) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README-DOCKER.md +3 -3
  3. package/bin/mb_coap.js +2 -0
  4. package/bin/mb_mdns.js +2 -0
  5. package/dist/cli.js +2 -91
  6. package/dist/cliEmitter.js +0 -30
  7. package/dist/clusters/export.js +0 -2
  8. package/dist/defaultConfigSchema.js +0 -24
  9. package/dist/deviceManager.js +1 -94
  10. package/dist/devices/batteryStorage.js +1 -48
  11. package/dist/devices/dishwasher.js +3 -78
  12. package/dist/devices/evse.js +10 -74
  13. package/dist/devices/export.js +0 -2
  14. package/dist/devices/extractorHood.js +0 -42
  15. package/dist/devices/heatPump.js +2 -50
  16. package/dist/devices/laundryDryer.js +6 -83
  17. package/dist/devices/laundryWasher.js +7 -91
  18. package/dist/devices/roboticVacuumCleaner.js +7 -93
  19. package/dist/devices/solarPower.js +0 -38
  20. package/dist/devices/waterHeater.js +2 -82
  21. package/dist/dgram/coap.js +252 -0
  22. package/dist/dgram/dgram.js +2 -113
  23. package/dist/dgram/mb_coap.js +52 -0
  24. package/dist/dgram/mb_mdns.js +60 -0
  25. package/dist/dgram/mdns.js +135 -380
  26. package/dist/dgram/multicast.js +7 -64
  27. package/dist/dgram/unicast.js +0 -54
  28. package/dist/frontend.js +21 -435
  29. package/dist/globalMatterbridge.js +0 -47
  30. package/dist/helpers.js +0 -53
  31. package/dist/index.js +1 -30
  32. package/dist/logger/export.js +0 -1
  33. package/dist/matter/behaviors.js +0 -2
  34. package/dist/matter/clusters.js +0 -2
  35. package/dist/matter/devices.js +0 -2
  36. package/dist/matter/endpoints.js +0 -2
  37. package/dist/matter/export.js +0 -3
  38. package/dist/matter/types.js +0 -3
  39. package/dist/matterbridge.js +50 -804
  40. package/dist/matterbridgeAccessoryPlatform.js +0 -36
  41. package/dist/matterbridgeBehaviors.js +5 -65
  42. package/dist/matterbridgeDeviceTypes.js +15 -579
  43. package/dist/matterbridgeDynamicPlatform.js +0 -36
  44. package/dist/matterbridgeEndpoint.js +51 -1191
  45. package/dist/matterbridgeEndpointHelpers.js +13 -322
  46. package/dist/matterbridgePlatform.js +0 -233
  47. package/dist/matterbridgeTypes.js +0 -25
  48. package/dist/pluginManager.js +3 -249
  49. package/dist/shelly.js +7 -168
  50. package/dist/storage/export.js +0 -1
  51. package/dist/update.js +0 -54
  52. package/dist/utils/colorUtils.js +2 -263
  53. package/dist/utils/commandLine.js +0 -54
  54. package/dist/utils/copyDirectory.js +1 -38
  55. package/dist/utils/createDirectory.js +0 -33
  56. package/dist/utils/createZip.js +2 -47
  57. package/dist/utils/deepCopy.js +0 -39
  58. package/dist/utils/deepEqual.js +1 -72
  59. package/dist/utils/error.js +0 -41
  60. package/dist/utils/export.js +0 -1
  61. package/dist/utils/hex.js +0 -58
  62. package/dist/utils/isvalid.js +0 -101
  63. package/dist/utils/network.js +5 -81
  64. package/dist/utils/spawn.js +0 -40
  65. package/dist/utils/wait.js +9 -62
  66. package/npm-shrinkwrap.json +5 -3
  67. package/package.json +4 -3
  68. package/dist/cli.d.ts +0 -26
  69. package/dist/cli.d.ts.map +0 -1
  70. package/dist/cli.js.map +0 -1
  71. package/dist/cliEmitter.d.ts +0 -34
  72. package/dist/cliEmitter.d.ts.map +0 -1
  73. package/dist/cliEmitter.js.map +0 -1
  74. package/dist/clusters/export.d.ts +0 -2
  75. package/dist/clusters/export.d.ts.map +0 -1
  76. package/dist/clusters/export.js.map +0 -1
  77. package/dist/defaultConfigSchema.d.ts +0 -28
  78. package/dist/defaultConfigSchema.d.ts.map +0 -1
  79. package/dist/defaultConfigSchema.js.map +0 -1
  80. package/dist/deviceManager.d.ts +0 -112
  81. package/dist/deviceManager.d.ts.map +0 -1
  82. package/dist/deviceManager.js.map +0 -1
  83. package/dist/devices/batteryStorage.d.ts +0 -48
  84. package/dist/devices/batteryStorage.d.ts.map +0 -1
  85. package/dist/devices/batteryStorage.js.map +0 -1
  86. package/dist/devices/dishwasher.d.ts +0 -91
  87. package/dist/devices/dishwasher.d.ts.map +0 -1
  88. package/dist/devices/dishwasher.js.map +0 -1
  89. package/dist/devices/evse.d.ts +0 -75
  90. package/dist/devices/evse.d.ts.map +0 -1
  91. package/dist/devices/evse.js.map +0 -1
  92. package/dist/devices/export.d.ts +0 -11
  93. package/dist/devices/export.d.ts.map +0 -1
  94. package/dist/devices/export.js.map +0 -1
  95. package/dist/devices/extractorHood.d.ts +0 -46
  96. package/dist/devices/extractorHood.d.ts.map +0 -1
  97. package/dist/devices/extractorHood.js.map +0 -1
  98. package/dist/devices/heatPump.d.ts +0 -47
  99. package/dist/devices/heatPump.d.ts.map +0 -1
  100. package/dist/devices/heatPump.js.map +0 -1
  101. package/dist/devices/laundryDryer.d.ts +0 -87
  102. package/dist/devices/laundryDryer.d.ts.map +0 -1
  103. package/dist/devices/laundryDryer.js.map +0 -1
  104. package/dist/devices/laundryWasher.d.ts +0 -242
  105. package/dist/devices/laundryWasher.d.ts.map +0 -1
  106. package/dist/devices/laundryWasher.js.map +0 -1
  107. package/dist/devices/roboticVacuumCleaner.d.ts +0 -112
  108. package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
  109. package/dist/devices/roboticVacuumCleaner.js.map +0 -1
  110. package/dist/devices/solarPower.d.ts +0 -40
  111. package/dist/devices/solarPower.d.ts.map +0 -1
  112. package/dist/devices/solarPower.js.map +0 -1
  113. package/dist/devices/waterHeater.d.ts +0 -111
  114. package/dist/devices/waterHeater.d.ts.map +0 -1
  115. package/dist/devices/waterHeater.js.map +0 -1
  116. package/dist/dgram/dgram.d.ts +0 -140
  117. package/dist/dgram/dgram.d.ts.map +0 -1
  118. package/dist/dgram/dgram.js.map +0 -1
  119. package/dist/dgram/mdns.d.ts +0 -288
  120. package/dist/dgram/mdns.d.ts.map +0 -1
  121. package/dist/dgram/mdns.js.map +0 -1
  122. package/dist/dgram/multicast.d.ts +0 -65
  123. package/dist/dgram/multicast.d.ts.map +0 -1
  124. package/dist/dgram/multicast.js.map +0 -1
  125. package/dist/dgram/unicast.d.ts +0 -56
  126. package/dist/dgram/unicast.d.ts.map +0 -1
  127. package/dist/dgram/unicast.js.map +0 -1
  128. package/dist/frontend.d.ts +0 -304
  129. package/dist/frontend.d.ts.map +0 -1
  130. package/dist/frontend.js.map +0 -1
  131. package/dist/globalMatterbridge.d.ts +0 -59
  132. package/dist/globalMatterbridge.d.ts.map +0 -1
  133. package/dist/globalMatterbridge.js.map +0 -1
  134. package/dist/helpers.d.ts +0 -48
  135. package/dist/helpers.d.ts.map +0 -1
  136. package/dist/helpers.js.map +0 -1
  137. package/dist/index.d.ts +0 -33
  138. package/dist/index.d.ts.map +0 -1
  139. package/dist/index.js.map +0 -1
  140. package/dist/logger/export.d.ts +0 -2
  141. package/dist/logger/export.d.ts.map +0 -1
  142. package/dist/logger/export.js.map +0 -1
  143. package/dist/matter/behaviors.d.ts +0 -2
  144. package/dist/matter/behaviors.d.ts.map +0 -1
  145. package/dist/matter/behaviors.js.map +0 -1
  146. package/dist/matter/clusters.d.ts +0 -2
  147. package/dist/matter/clusters.d.ts.map +0 -1
  148. package/dist/matter/clusters.js.map +0 -1
  149. package/dist/matter/devices.d.ts +0 -2
  150. package/dist/matter/devices.d.ts.map +0 -1
  151. package/dist/matter/devices.js.map +0 -1
  152. package/dist/matter/endpoints.d.ts +0 -2
  153. package/dist/matter/endpoints.d.ts.map +0 -1
  154. package/dist/matter/endpoints.js.map +0 -1
  155. package/dist/matter/export.d.ts +0 -5
  156. package/dist/matter/export.d.ts.map +0 -1
  157. package/dist/matter/export.js.map +0 -1
  158. package/dist/matter/types.d.ts +0 -3
  159. package/dist/matter/types.d.ts.map +0 -1
  160. package/dist/matter/types.js.map +0 -1
  161. package/dist/matterbridge.d.ts +0 -460
  162. package/dist/matterbridge.d.ts.map +0 -1
  163. package/dist/matterbridge.js.map +0 -1
  164. package/dist/matterbridgeAccessoryPlatform.d.ts +0 -42
  165. package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
  166. package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
  167. package/dist/matterbridgeBehaviors.d.ts +0 -1351
  168. package/dist/matterbridgeBehaviors.d.ts.map +0 -1
  169. package/dist/matterbridgeBehaviors.js.map +0 -1
  170. package/dist/matterbridgeDeviceTypes.d.ts +0 -709
  171. package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
  172. package/dist/matterbridgeDeviceTypes.js.map +0 -1
  173. package/dist/matterbridgeDynamicPlatform.d.ts +0 -42
  174. package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
  175. package/dist/matterbridgeDynamicPlatform.js.map +0 -1
  176. package/dist/matterbridgeEndpoint.d.ts +0 -1328
  177. package/dist/matterbridgeEndpoint.d.ts.map +0 -1
  178. package/dist/matterbridgeEndpoint.js.map +0 -1
  179. package/dist/matterbridgeEndpointHelpers.d.ts +0 -3198
  180. package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
  181. package/dist/matterbridgeEndpointHelpers.js.map +0 -1
  182. package/dist/matterbridgePlatform.d.ts +0 -310
  183. package/dist/matterbridgePlatform.d.ts.map +0 -1
  184. package/dist/matterbridgePlatform.js.map +0 -1
  185. package/dist/matterbridgeTypes.d.ts +0 -195
  186. package/dist/matterbridgeTypes.d.ts.map +0 -1
  187. package/dist/matterbridgeTypes.js.map +0 -1
  188. package/dist/pluginManager.d.ts +0 -270
  189. package/dist/pluginManager.d.ts.map +0 -1
  190. package/dist/pluginManager.js.map +0 -1
  191. package/dist/shelly.d.ts +0 -174
  192. package/dist/shelly.d.ts.map +0 -1
  193. package/dist/shelly.js.map +0 -1
  194. package/dist/storage/export.d.ts +0 -2
  195. package/dist/storage/export.d.ts.map +0 -1
  196. package/dist/storage/export.js.map +0 -1
  197. package/dist/update.d.ts +0 -59
  198. package/dist/update.d.ts.map +0 -1
  199. package/dist/update.js.map +0 -1
  200. package/dist/utils/colorUtils.d.ts +0 -117
  201. package/dist/utils/colorUtils.d.ts.map +0 -1
  202. package/dist/utils/colorUtils.js.map +0 -1
  203. package/dist/utils/commandLine.d.ts +0 -59
  204. package/dist/utils/commandLine.d.ts.map +0 -1
  205. package/dist/utils/commandLine.js.map +0 -1
  206. package/dist/utils/copyDirectory.d.ts +0 -33
  207. package/dist/utils/copyDirectory.d.ts.map +0 -1
  208. package/dist/utils/copyDirectory.js.map +0 -1
  209. package/dist/utils/createDirectory.d.ts +0 -34
  210. package/dist/utils/createDirectory.d.ts.map +0 -1
  211. package/dist/utils/createDirectory.js.map +0 -1
  212. package/dist/utils/createZip.d.ts +0 -39
  213. package/dist/utils/createZip.d.ts.map +0 -1
  214. package/dist/utils/createZip.js.map +0 -1
  215. package/dist/utils/deepCopy.d.ts +0 -32
  216. package/dist/utils/deepCopy.d.ts.map +0 -1
  217. package/dist/utils/deepCopy.js.map +0 -1
  218. package/dist/utils/deepEqual.d.ts +0 -54
  219. package/dist/utils/deepEqual.d.ts.map +0 -1
  220. package/dist/utils/deepEqual.js.map +0 -1
  221. package/dist/utils/error.d.ts +0 -44
  222. package/dist/utils/error.d.ts.map +0 -1
  223. package/dist/utils/error.js.map +0 -1
  224. package/dist/utils/export.d.ts +0 -12
  225. package/dist/utils/export.d.ts.map +0 -1
  226. package/dist/utils/export.js.map +0 -1
  227. package/dist/utils/hex.d.ts +0 -49
  228. package/dist/utils/hex.d.ts.map +0 -1
  229. package/dist/utils/hex.js.map +0 -1
  230. package/dist/utils/isvalid.d.ts +0 -103
  231. package/dist/utils/isvalid.d.ts.map +0 -1
  232. package/dist/utils/isvalid.js.map +0 -1
  233. package/dist/utils/network.d.ts +0 -74
  234. package/dist/utils/network.d.ts.map +0 -1
  235. package/dist/utils/network.js.map +0 -1
  236. package/dist/utils/spawn.d.ts +0 -33
  237. package/dist/utils/spawn.d.ts.map +0 -1
  238. package/dist/utils/spawn.js.map +0 -1
  239. package/dist/utils/wait.d.ts +0 -56
  240. package/dist/utils/wait.d.ts.map +0 -1
  241. package/dist/utils/wait.js.map +0 -1
@@ -1,30 +1,5 @@
1
- /**
2
- * @description This file contains the class Mdns.
3
- * @file mdns.ts
4
- * @author Luca Liguori
5
- * @created 2025-03-22
6
- * @version 1.0.0
7
- * @license Apache-2.0
8
- *
9
- * Copyright 2025, 2026, 2027 Luca Liguori.
10
- *
11
- * Licensed under the Apache License, Version 2.0 (the "License");
12
- * you may not use this file except in compliance with the License.
13
- * You may obtain a copy of the License at
14
- *
15
- * http://www.apache.org/licenses/LICENSE-2.0
16
- *
17
- * Unless required by applicable law or agreed to in writing, software
18
- * distributed under the License is distributed on an "AS IS" BASIS,
19
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
- * See the License for the specific language governing permissions and
21
- * limitations under the License.
22
- */
23
- // AnsiLogger imports
24
1
  import { BLUE, CYAN, db, er, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
25
- // Matterbridge imports
26
- import { MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS, MDNS_MULTICAST_PORT, Multicast } from './multicast.js';
27
- // Node.js imports
2
+ import { Multicast } from './multicast.js';
28
3
  export var DnsRecordType;
29
4
  (function (DnsRecordType) {
30
5
  DnsRecordType[DnsRecordType["A"] = 1] = "A";
@@ -115,7 +90,6 @@ export var DnsRecordType;
115
90
  DnsRecordType[DnsRecordType["DOA"] = 259] = "DOA";
116
91
  DnsRecordType[DnsRecordType["AMTRELAY"] = 260] = "AMTRELAY";
117
92
  DnsRecordType[DnsRecordType["ZONEVERSION"] = 261] = "ZONEVERSION";
118
- // 262-32767 are unassigned/reserved
119
93
  DnsRecordType[DnsRecordType["TA"] = 32768] = "TA";
120
94
  DnsRecordType[DnsRecordType["DLV"] = 32769] = "DLV";
121
95
  })(DnsRecordType || (DnsRecordType = {}));
@@ -129,23 +103,11 @@ export var DnsClass;
129
103
  export var DnsClassFlag;
130
104
  (function (DnsClassFlag) {
131
105
  DnsClassFlag[DnsClassFlag["FLUSH"] = 32768] = "FLUSH";
132
- // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
133
106
  DnsClassFlag[DnsClassFlag["QU"] = 32768] = "QU";
134
107
  })(DnsClassFlag || (DnsClassFlag = {}));
135
108
  export class Mdns extends Multicast {
136
109
  deviceQueries = new Map();
137
110
  deviceResponses = new Map();
138
- /**
139
- * Creates an instance of the Mdns class.
140
- *
141
- * @param {string} name - The internal name of the mDNS server for the logs.
142
- * @param {string} multicastAddress - The multicast address for mDNS (i.e. 224.0.0.251 for udp4 or ff02::fb for udp6).
143
- * @param {number} multicastPort - The port for mDNS (i.e. 5353).
144
- * @param {('udp4' | 'udp6')} socketType - The type of socket to create (either 'udp4' or 'udp6').
145
- * @param {boolean} [reuseAddr] - Whether to reuse the address. Defaults to true.
146
- * @param {string} [interfaceName] - The optional name of the network interface to use.
147
- * @param {string} [interfaceAddress] - The optional IP address of the network interface to use.
148
- */
149
111
  constructor(name, multicastAddress, multicastPort, socketType, reuseAddr = true, interfaceName, interfaceAddress) {
150
112
  super(name, multicastAddress, multicastPort, socketType, reuseAddr, interfaceName, interfaceAddress);
151
113
  }
@@ -164,9 +126,9 @@ export class Mdns extends Multicast {
164
126
  this.onQuery(rinfo, result);
165
127
  }
166
128
  else {
167
- const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
168
- result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
169
- result.answers?.find((record) => record.type === 12 /* DnsRecordType.PTR */);
129
+ const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12) ||
130
+ result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12) ||
131
+ result.answers?.find((record) => record.type === 12);
170
132
  this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.data });
171
133
  this.onResponse(rinfo, result);
172
134
  }
@@ -176,28 +138,20 @@ export class Mdns extends Multicast {
176
138
  this.log.error(`Error decoding mDNS message: ${error instanceof Error ? error.message : error}`);
177
139
  }
178
140
  }
179
- /**
180
- * Decodes an mDNS message, including the header, question section, answer section,
181
- * authority section, and additional section.
182
- *
183
- * @param {Buffer} msg - The raw mDNS message buffer.
184
- * @returns {MdnsMessage} An object representing the decoded mDNS message.
185
- * @throws Error if the message is too short.
186
- */
187
141
  decodeMdnsMessage(msg) {
188
142
  if (msg.length < 12) {
189
143
  throw new Error('mDNS message too short');
190
144
  }
191
145
  const id = msg.readUInt16BE(0);
192
146
  const flags = msg.readUInt16BE(2);
193
- const qr = (flags & 0x8000) >> 15; // Bit 15: 0=query, 1=response.
194
- const opcode = (flags & 0x7800) >> 11; // Bits 14-11.
195
- const aa = Boolean(flags & 0x0400); // Bit 10.
196
- const tc = Boolean(flags & 0x0200); // Bit 9.
197
- const rd = Boolean(flags & 0x0100); // Bit 8.
198
- const ra = Boolean(flags & 0x0080); // Bit 7.
199
- const z = (flags & 0x0070) >> 4; // Bits 6-4.
200
- const rcode = flags & 0x000f; // Bits 3-0.
147
+ const qr = (flags & 0x8000) >> 15;
148
+ const opcode = (flags & 0x7800) >> 11;
149
+ const aa = Boolean(flags & 0x0400);
150
+ const tc = Boolean(flags & 0x0200);
151
+ const rd = Boolean(flags & 0x0100);
152
+ const ra = Boolean(flags & 0x0080);
153
+ const z = (flags & 0x0070) >> 4;
154
+ const rcode = flags & 0x000f;
201
155
  const qdCount = msg.readUInt16BE(4);
202
156
  const anCount = msg.readUInt16BE(6);
203
157
  const nsCount = msg.readUInt16BE(8);
@@ -222,7 +176,6 @@ export class Mdns extends Multicast {
222
176
  additionals: [],
223
177
  };
224
178
  let offset = 12;
225
- // Decode the question section.
226
179
  for (let i = 0; i < qdCount; i++) {
227
180
  const qnameResult = this.decodeDnsName(msg, offset);
228
181
  const qname = qnameResult.name;
@@ -233,19 +186,16 @@ export class Mdns extends Multicast {
233
186
  offset += 2;
234
187
  mdnsMessage.questions?.push({ name: qname, type: qtype, class: qclass });
235
188
  }
236
- // Decode the answer section.
237
189
  for (let i = 0; i < anCount; i++) {
238
190
  const rrResult = this.decodeResourceRecord(msg, offset);
239
191
  mdnsMessage.answers?.push(rrResult.record);
240
192
  offset = rrResult.newOffset;
241
193
  }
242
- // Decode the authority (NS) section.
243
194
  for (let i = 0; i < nsCount; i++) {
244
195
  const rrResult = this.decodeResourceRecord(msg, offset);
245
196
  mdnsMessage.authorities?.push(rrResult.record);
246
197
  offset = rrResult.newOffset;
247
198
  }
248
- // Decode the additional records section.
249
199
  for (let i = 0; i < arCount; i++) {
250
200
  const rrResult = this.decodeResourceRecord(msg, offset);
251
201
  mdnsMessage.additionals?.push(rrResult.record);
@@ -253,25 +203,15 @@ export class Mdns extends Multicast {
253
203
  }
254
204
  return mdnsMessage;
255
205
  }
256
- /**
257
- * Decodes a DNS name from a buffer, handling compression.
258
- *
259
- * @param {Buffer} msg - The full mDNS message buffer.
260
- * @param {number} offset - The offset at which the DNS name starts.
261
- * @returns {{ name: string; newOffset: number }} An object with the decoded name and the new offset.
262
- * @throws Error if the offset exceeds the buffer length or too many iterations are performed.
263
- */
264
206
  decodeDnsName(msg, offset) {
265
207
  const labels = [];
266
208
  let jumped = false;
267
209
  let originalOffset = offset;
268
- let iterations = 0; // Prevent infinite loops
210
+ let iterations = 0;
269
211
  while (true) {
270
- // Safety guard: prevent infinite loops in malformed messages.
271
212
  if (iterations++ > 1000) {
272
213
  throw new Error('Too many iterations while decoding DNS name. Possible malformed message.');
273
214
  }
274
- // Check that offset is within buffer bounds.
275
215
  if (offset >= msg.length) {
276
216
  throw new Error('Offset exceeds buffer length while decoding DNS name.');
277
217
  }
@@ -280,9 +220,7 @@ export class Mdns extends Multicast {
280
220
  offset++;
281
221
  break;
282
222
  }
283
- // Check for pointer (first two bits are 11)
284
223
  if ((len & 0xc0) === 0xc0) {
285
- // Ensure the pointer has two bytes available.
286
224
  if (offset + 1 >= msg.length) {
287
225
  throw new Error('Incomplete pointer encountered while decoding DNS name.');
288
226
  }
@@ -295,7 +233,6 @@ export class Mdns extends Multicast {
295
233
  continue;
296
234
  }
297
235
  offset++;
298
- // Check that the label length doesn't go beyond the buffer.
299
236
  if (offset + len > msg.length) {
300
237
  throw new Error('Label length exceeds buffer bounds while decoding DNS name.');
301
238
  }
@@ -304,15 +241,6 @@ export class Mdns extends Multicast {
304
241
  }
305
242
  return { name: labels.join('.'), newOffset: jumped ? originalOffset : offset };
306
243
  }
307
- /**
308
- * Encodes a domain name into the DNS label format.
309
- *
310
- * For example, "example.local" becomes:
311
- * [7] "example" [5] "local" [0]
312
- *
313
- * @param {string} name - The domain name to encode.
314
- * @returns {Buffer} The encoded domain name as a Buffer.
315
- */
316
244
  encodeDnsName(name) {
317
245
  const labels = name.split('.');
318
246
  const buffers = labels.map((label) => {
@@ -320,22 +248,12 @@ export class Mdns extends Multicast {
320
248
  lenBuf.writeUInt8(label.length, 0);
321
249
  return Buffer.concat([lenBuf, Buffer.from(label)]);
322
250
  });
323
- // Append the null byte to terminate the name.
324
251
  return Buffer.concat([...buffers, Buffer.from([0])]);
325
252
  }
326
- /**
327
- * Decodes a DNS resource record.
328
- *
329
- * @param {Buffer} msg - The full mDNS message buffer.
330
- * @param {number} offset - The offset at which the resource record starts.
331
- * @returns {{ record: MdnsRecord; newOffset: number }} An object containing the decoded record and the new offset.
332
- */
333
253
  decodeResourceRecord(msg, offset) {
334
- // Decode the NAME field (which may be compressed)
335
254
  const nameResult = this.decodeDnsName(msg, offset);
336
255
  const name = nameResult.name;
337
256
  offset = nameResult.newOffset;
338
- // Read TYPE (16 bits), CLASS (16 bits), TTL (32 bits), and RDLENGTH (16 bits)
339
257
  const type = msg.readUInt16BE(offset);
340
258
  offset += 2;
341
259
  const rrclass = msg.readUInt16BE(offset);
@@ -345,14 +263,12 @@ export class Mdns extends Multicast {
345
263
  const rdlength = msg.readUInt16BE(offset);
346
264
  offset += 2;
347
265
  let data = '';
348
- if (type === 12 /* DnsRecordType.PTR */) {
349
- // PTR record (type 12): decode its RDATA as a domain name.
266
+ if (type === 12) {
350
267
  const ptrResult = this.decodeDnsName(msg, offset);
351
268
  data = ptrResult.name;
352
269
  offset += rdlength;
353
270
  }
354
- else if (type === 16 /* DnsRecordType.TXT */) {
355
- // TXT record: may consist of one or more length-prefixed strings.
271
+ else if (type === 16) {
356
272
  const txtStrings = [];
357
273
  const end = offset + rdlength;
358
274
  while (offset < end) {
@@ -364,8 +280,7 @@ export class Mdns extends Multicast {
364
280
  }
365
281
  data = txtStrings.join(', ');
366
282
  }
367
- else if (type === 33 /* DnsRecordType.SRV */) {
368
- // SRV record (type === 33): consists of 2 bytes for priority, 2 for weight, 2 for port, followed by the target domain name.
283
+ else if (type === 33) {
369
284
  const priority = msg.readUInt16BE(offset);
370
285
  const weight = msg.readUInt16BE(offset + 2);
371
286
  const port = msg.readUInt16BE(offset + 4);
@@ -379,16 +294,13 @@ export class Mdns extends Multicast {
379
294
  });
380
295
  offset = srvTargetResult.newOffset;
381
296
  }
382
- else if (type === 1 /* DnsRecordType.A */) {
383
- // A record (type 1): an IPv4 address stored in 4 bytes.
297
+ else if (type === 1) {
384
298
  const ipBytes = msg.slice(offset, offset + 4);
385
299
  data = Array.from(ipBytes).join('.');
386
300
  offset += 4;
387
301
  }
388
- else if (type === 28 /* DnsRecordType.AAAA */) {
389
- // AAAA record (type 28): IPv6 address stored in 16 bytes.
302
+ else if (type === 28) {
390
303
  const ipBytes = msg.slice(offset, offset + 16);
391
- // Convert the 16 bytes into an IPv6 address string (colon-separated)
392
304
  const ipv6Parts = [];
393
305
  for (let i = 0; i < 16; i += 2) {
394
306
  ipv6Parts.push(ipBytes.readUInt16BE(i).toString(16));
@@ -396,14 +308,10 @@ export class Mdns extends Multicast {
396
308
  data = ipv6Parts.join(':');
397
309
  offset += 16;
398
310
  }
399
- else if (type === 47 /* DnsRecordType.NSEC */) {
400
- // NSEC record: RDATA consists of:
401
- // - Next Domain Name (in DNS label format)
402
- // - Type Bit Maps (variable length)
311
+ else if (type === 47) {
403
312
  const { name: nextDomain, newOffset } = this.decodeDnsName(msg, offset);
404
313
  const nextDomainLength = newOffset - offset;
405
314
  offset = newOffset;
406
- // Calculate the remaining length for the type bit maps.
407
315
  const bitmapLength = rdlength - nextDomainLength;
408
316
  const bitmapData = msg.slice(offset, offset + bitmapLength);
409
317
  const types = [];
@@ -430,7 +338,6 @@ export class Mdns extends Multicast {
430
338
  offset += bitmapLength;
431
339
  }
432
340
  else {
433
- // Fall back
434
341
  data = msg.slice(offset, offset + rdlength).toString('hex');
435
342
  offset += rdlength;
436
343
  }
@@ -439,28 +346,19 @@ export class Mdns extends Multicast {
439
346
  newOffset: offset,
440
347
  };
441
348
  }
442
- /**
443
- * Sends a DNS query with multiple questions.
444
- *
445
- * @param {Array<{ name: string; type: number; class: number; unicastResponse?: boolean }>} questions - Array of questions
446
- *
447
- * @remarks
448
- * Each question should have a name (e.g., "_http._tcp.local"), type (e.g., DnsRecordType.PTR), class (e.g., DnsClass.IN),
449
- * and an optional unicastResponse flag (this will add the DnsClassFlag.QU flag to the query).
450
- */
451
349
  sendQuery(questions) {
452
350
  const header = Buffer.alloc(12);
453
- header.writeUInt16BE(0, 0); // ID
454
- header.writeUInt16BE(0, 2); // Flags
455
- header.writeUInt16BE(questions.length, 4); // QDCOUNT
456
- header.writeUInt16BE(0, 6); // ANCOUNT
457
- header.writeUInt16BE(0, 8); // NSCOUNT
458
- header.writeUInt16BE(0, 10); // ARCOUNT
351
+ header.writeUInt16BE(0, 0);
352
+ header.writeUInt16BE(0, 2);
353
+ header.writeUInt16BE(questions.length, 4);
354
+ header.writeUInt16BE(0, 6);
355
+ header.writeUInt16BE(0, 8);
356
+ header.writeUInt16BE(0, 10);
459
357
  const questionBuffers = questions.map(({ name, type: qtype, class: qclass, unicastResponse = false }) => {
460
358
  const qname = this.encodeDnsName(name);
461
359
  const qfields = Buffer.alloc(4);
462
360
  qfields.writeUInt16BE(qtype, 0);
463
- qfields.writeUInt16BE(unicastResponse ? qclass | 32768 /* DnsClassFlag.QU */ : qclass, 2);
361
+ qfields.writeUInt16BE(unicastResponse ? qclass | 32768 : qclass, 2);
464
362
  return Buffer.concat([qname, qfields]);
465
363
  });
466
364
  const query = Buffer.concat([header, ...questionBuffers]);
@@ -480,46 +378,22 @@ export class Mdns extends Multicast {
480
378
  }
481
379
  });
482
380
  }
483
- /**
484
- * Constructs an mDNS response packet and sends it to the multicast address and port.
485
- *
486
- * @param {string} name - The domain name being responded to (e.g., "example.local").
487
- * @param {number} rtype - The response type (e.g., 1 for A, 28 for AAAA, etc.).
488
- * @param {number} rclass - The response class (typically 1 for IN).
489
- * @param {number} ttl - The time-to-live for the answer record.
490
- * @param {Buffer} rdata - The resource data for the response (e.g., 4 bytes for an A record IPv4 address).
491
- *
492
- * @example
493
- * const ptrRdata = mdnsIpv4.encodeDnsName('matterbridge._http._tcp.local');
494
- * mdnsIpv4.sendResponse('_http._tcp.local', DnsRecordType.PTR, DnsClass.IN, 120, ptrRdata);
495
- */
496
381
  sendResponse(name, rtype, rclass, ttl, rdata) {
497
- // Create a 12-byte DNS header.
498
382
  const header = Buffer.alloc(12);
499
- header.writeUInt16BE(0, 0); // ID is set to 0 in mDNS.
500
- // Set flags: QR (response) bit and AA (authoritative answer) bit.
383
+ header.writeUInt16BE(0, 0);
501
384
  header.writeUInt16BE(0x8400, 2);
502
- header.writeUInt16BE(0, 4); // QDCOUNT: 0 questions in response.
503
- header.writeUInt16BE(1, 6); // ANCOUNT: 1 answer record.
504
- header.writeUInt16BE(0, 8); // NSCOUNT: 0 authority records.
505
- header.writeUInt16BE(0, 10); // ARCOUNT: 0 additional records.
506
- // Encode the domain name in DNS label format.
385
+ header.writeUInt16BE(0, 4);
386
+ header.writeUInt16BE(1, 6);
387
+ header.writeUInt16BE(0, 8);
388
+ header.writeUInt16BE(0, 10);
507
389
  const aname = this.encodeDnsName(name);
508
- // Prepare the fixed part of the answer record:
509
- // - 2 bytes for qtype,
510
- // - 2 bytes for qclass,
511
- // - 4 bytes for TTL,
512
- // - 2 bytes for RDLENGTH (length of the rdata).
513
390
  const answerFixed = Buffer.alloc(10);
514
- answerFixed.writeUInt16BE(rtype, 0); // Record type.
515
- answerFixed.writeUInt16BE(rclass, 2); // Record class.
516
- answerFixed.writeUInt32BE(ttl, 4); // Time-to-live.
517
- answerFixed.writeUInt16BE(rdata.length, 8); // RDLENGTH.
518
- // Concatenate the answer: encoded name, fixed fields, and resource data.
391
+ answerFixed.writeUInt16BE(rtype, 0);
392
+ answerFixed.writeUInt16BE(rclass, 2);
393
+ answerFixed.writeUInt32BE(ttl, 4);
394
+ answerFixed.writeUInt16BE(rdata.length, 8);
519
395
  const answer = Buffer.concat([aname, answerFixed, rdata]);
520
- // Concatenate header and answer to form the complete mDNS response packet.
521
396
  const response = Buffer.concat([header, answer]);
522
- // Send the response packet via the socket.
523
397
  this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
524
398
  if (error) {
525
399
  this.log.error(`Dgram mDNS server failed to send response message for ${MAGENTA}${name}${er} type ${MAGENTA}${this.dnsTypeToString(rtype)}${er} class ${MAGENTA}${this.dnsResponseClassToString(rclass)}${er} ttl ${MAGENTA}${ttl}${er}: ${error instanceof Error ? error.message : error}`);
@@ -531,128 +405,116 @@ export class Mdns extends Multicast {
531
405
  }
532
406
  });
533
407
  }
534
- /**
535
- * Converts a DNS record type numeric value to its string representation.
536
- *
537
- * @param {number} type - The numeric DNS record type.
538
- * @returns {string} The string representation of the record type.
539
- */
540
408
  dnsTypeToString(type) {
541
409
  const typeMap = {
542
- [1 /* DnsRecordType.A */]: 'A',
543
- [2 /* DnsRecordType.NS */]: 'NS',
544
- [3 /* DnsRecordType.MD */]: 'MD',
545
- [4 /* DnsRecordType.MF */]: 'MF',
546
- [5 /* DnsRecordType.CNAME */]: 'CNAME',
547
- [6 /* DnsRecordType.SOA */]: 'SOA',
548
- [7 /* DnsRecordType.MB */]: 'MB',
549
- [8 /* DnsRecordType.MG */]: 'MG',
550
- [9 /* DnsRecordType.MR */]: 'MR',
551
- [10 /* DnsRecordType.NULL */]: 'NULL',
552
- [11 /* DnsRecordType.WKS */]: 'WKS',
553
- [12 /* DnsRecordType.PTR */]: 'PTR',
554
- [13 /* DnsRecordType.HINFO */]: 'HINFO',
555
- [14 /* DnsRecordType.MINFO */]: 'MINFO',
556
- [15 /* DnsRecordType.MX */]: 'MX',
557
- [16 /* DnsRecordType.TXT */]: 'TXT',
558
- [17 /* DnsRecordType.RP */]: 'RP',
559
- [18 /* DnsRecordType.AFSDB */]: 'AFSDB',
560
- [19 /* DnsRecordType.X25 */]: 'X25',
561
- [20 /* DnsRecordType.ISDN */]: 'ISDN',
562
- [21 /* DnsRecordType.RT */]: 'RT',
563
- [22 /* DnsRecordType.NSAP */]: 'NSAP',
564
- [23 /* DnsRecordType.NSAP_PTR */]: 'NSAP_PTR',
565
- [24 /* DnsRecordType.SIG */]: 'SIG',
566
- [25 /* DnsRecordType.KEY */]: 'KEY',
567
- [26 /* DnsRecordType.PX */]: 'PX',
568
- [27 /* DnsRecordType.GPOS */]: 'GPOS',
569
- [28 /* DnsRecordType.AAAA */]: 'AAAA',
570
- [29 /* DnsRecordType.LOC */]: 'LOC',
571
- [30 /* DnsRecordType.NXT */]: 'NXT',
572
- [31 /* DnsRecordType.EID */]: 'EID',
573
- [32 /* DnsRecordType.NIMLOC */]: 'NIMLOC',
574
- [33 /* DnsRecordType.SRV */]: 'SRV',
575
- [34 /* DnsRecordType.ATMA */]: 'ATMA',
576
- [35 /* DnsRecordType.NAPTR */]: 'NAPTR',
577
- [36 /* DnsRecordType.KX */]: 'KX',
578
- [37 /* DnsRecordType.CERT */]: 'CERT',
579
- [38 /* DnsRecordType.A6 */]: 'A6',
580
- [39 /* DnsRecordType.DNAME */]: 'DNAME',
581
- [40 /* DnsRecordType.SINK */]: 'SINK',
582
- [41 /* DnsRecordType.OPT */]: 'OPT',
583
- [42 /* DnsRecordType.APL */]: 'APL',
584
- [43 /* DnsRecordType.DS */]: 'DS',
585
- [44 /* DnsRecordType.SSHFP */]: 'SSHFP',
586
- [45 /* DnsRecordType.IPSECKEY */]: 'IPSECKEY',
587
- [46 /* DnsRecordType.RRSIG */]: 'RRSIG',
588
- [47 /* DnsRecordType.NSEC */]: 'NSEC',
589
- [48 /* DnsRecordType.DNSKEY */]: 'DNSKEY',
590
- [49 /* DnsRecordType.DHCID */]: 'DHCID',
591
- [50 /* DnsRecordType.NSEC3 */]: 'NSEC3',
592
- [51 /* DnsRecordType.NSEC3PARAM */]: 'NSEC3PARAM',
593
- [52 /* DnsRecordType.TLSA */]: 'TLSA',
594
- [53 /* DnsRecordType.SMIMEA */]: 'SMIMEA',
595
- [55 /* DnsRecordType.HIP */]: 'HIP',
596
- [56 /* DnsRecordType.NINFO */]: 'NINFO',
597
- [57 /* DnsRecordType.RKEY */]: 'RKEY',
598
- [58 /* DnsRecordType.TALINK */]: 'TALINK',
599
- [59 /* DnsRecordType.CDS */]: 'CDS',
600
- [60 /* DnsRecordType.CDNSKEY */]: 'CDNSKEY',
601
- [61 /* DnsRecordType.OPENPGPKEY */]: 'OPENPGPKEY',
602
- [62 /* DnsRecordType.CSYNC */]: 'CSYNC',
603
- [63 /* DnsRecordType.ZONEMD */]: 'ZONEMD',
604
- [64 /* DnsRecordType.SVCB */]: 'SVCB',
605
- [65 /* DnsRecordType.HTTPS */]: 'HTTPS',
606
- [99 /* DnsRecordType.SPF */]: 'SPF',
607
- [100 /* DnsRecordType.UINFO */]: 'UINFO',
608
- [101 /* DnsRecordType.UID */]: 'UID',
609
- [102 /* DnsRecordType.GID */]: 'GID',
610
- [103 /* DnsRecordType.UNSPEC */]: 'UNSPEC',
611
- [104 /* DnsRecordType.NID */]: 'NID',
612
- [105 /* DnsRecordType.L32 */]: 'L32',
613
- [106 /* DnsRecordType.L64 */]: 'L64',
614
- [107 /* DnsRecordType.LP */]: 'LP',
615
- [108 /* DnsRecordType.EUI48 */]: 'EUI48',
616
- [109 /* DnsRecordType.EUI64 */]: 'EUI64',
617
- [249 /* DnsRecordType.TKEY */]: 'TKEY',
618
- [250 /* DnsRecordType.TSIG */]: 'TSIG',
619
- [251 /* DnsRecordType.IXFR */]: 'IXFR',
620
- [252 /* DnsRecordType.AXFR */]: 'AXFR',
621
- [253 /* DnsRecordType.MAILB */]: 'MAILB',
622
- [254 /* DnsRecordType.MAILA */]: 'MAILA',
623
- [255 /* DnsRecordType.ANY */]: 'ANY',
624
- [256 /* DnsRecordType.URI */]: 'URI',
625
- [257 /* DnsRecordType.CAA */]: 'CAA',
626
- [258 /* DnsRecordType.AVC */]: 'AVC',
627
- [259 /* DnsRecordType.DOA */]: 'DOA',
628
- [260 /* DnsRecordType.AMTRELAY */]: 'AMTRELAY',
629
- [261 /* DnsRecordType.ZONEVERSION */]: 'ZONEVERSION',
630
- [32768 /* DnsRecordType.TA */]: 'TA',
631
- [32769 /* DnsRecordType.DLV */]: 'DLV',
410
+ [1]: 'A',
411
+ [2]: 'NS',
412
+ [3]: 'MD',
413
+ [4]: 'MF',
414
+ [5]: 'CNAME',
415
+ [6]: 'SOA',
416
+ [7]: 'MB',
417
+ [8]: 'MG',
418
+ [9]: 'MR',
419
+ [10]: 'NULL',
420
+ [11]: 'WKS',
421
+ [12]: 'PTR',
422
+ [13]: 'HINFO',
423
+ [14]: 'MINFO',
424
+ [15]: 'MX',
425
+ [16]: 'TXT',
426
+ [17]: 'RP',
427
+ [18]: 'AFSDB',
428
+ [19]: 'X25',
429
+ [20]: 'ISDN',
430
+ [21]: 'RT',
431
+ [22]: 'NSAP',
432
+ [23]: 'NSAP_PTR',
433
+ [24]: 'SIG',
434
+ [25]: 'KEY',
435
+ [26]: 'PX',
436
+ [27]: 'GPOS',
437
+ [28]: 'AAAA',
438
+ [29]: 'LOC',
439
+ [30]: 'NXT',
440
+ [31]: 'EID',
441
+ [32]: 'NIMLOC',
442
+ [33]: 'SRV',
443
+ [34]: 'ATMA',
444
+ [35]: 'NAPTR',
445
+ [36]: 'KX',
446
+ [37]: 'CERT',
447
+ [38]: 'A6',
448
+ [39]: 'DNAME',
449
+ [40]: 'SINK',
450
+ [41]: 'OPT',
451
+ [42]: 'APL',
452
+ [43]: 'DS',
453
+ [44]: 'SSHFP',
454
+ [45]: 'IPSECKEY',
455
+ [46]: 'RRSIG',
456
+ [47]: 'NSEC',
457
+ [48]: 'DNSKEY',
458
+ [49]: 'DHCID',
459
+ [50]: 'NSEC3',
460
+ [51]: 'NSEC3PARAM',
461
+ [52]: 'TLSA',
462
+ [53]: 'SMIMEA',
463
+ [55]: 'HIP',
464
+ [56]: 'NINFO',
465
+ [57]: 'RKEY',
466
+ [58]: 'TALINK',
467
+ [59]: 'CDS',
468
+ [60]: 'CDNSKEY',
469
+ [61]: 'OPENPGPKEY',
470
+ [62]: 'CSYNC',
471
+ [63]: 'ZONEMD',
472
+ [64]: 'SVCB',
473
+ [65]: 'HTTPS',
474
+ [99]: 'SPF',
475
+ [100]: 'UINFO',
476
+ [101]: 'UID',
477
+ [102]: 'GID',
478
+ [103]: 'UNSPEC',
479
+ [104]: 'NID',
480
+ [105]: 'L32',
481
+ [106]: 'L64',
482
+ [107]: 'LP',
483
+ [108]: 'EUI48',
484
+ [109]: 'EUI64',
485
+ [249]: 'TKEY',
486
+ [250]: 'TSIG',
487
+ [251]: 'IXFR',
488
+ [252]: 'AXFR',
489
+ [253]: 'MAILB',
490
+ [254]: 'MAILA',
491
+ [255]: 'ANY',
492
+ [256]: 'URI',
493
+ [257]: 'CAA',
494
+ [258]: 'AVC',
495
+ [259]: 'DOA',
496
+ [260]: 'AMTRELAY',
497
+ [261]: 'ZONEVERSION',
498
+ [32768]: 'TA',
499
+ [32769]: 'DLV',
632
500
  };
633
501
  return typeMap[type] ?? `TYPE${type}`;
634
502
  }
635
- /**
636
- * Converts a DNS response class numeric value to its string representation.
637
- *
638
- * @param {number} cls - The numeric DNS class.
639
- * @returns {string} The string representation of the DNS class.
640
- */
641
503
  dnsResponseClassToString(cls) {
642
- const isFlush = !!(cls & 32768 /* DnsClassFlag.FLUSH */);
504
+ const isFlush = !!(cls & 32768);
643
505
  const baseClass = cls & 0x7fff;
644
506
  let classStr;
645
507
  switch (baseClass) {
646
- case 1 /* DnsClass.IN */:
508
+ case 1:
647
509
  classStr = 'IN';
648
510
  break;
649
- case 3 /* DnsClass.CH */:
511
+ case 3:
650
512
  classStr = 'CH';
651
513
  break;
652
- case 4 /* DnsClass.HS */:
514
+ case 4:
653
515
  classStr = 'HS';
654
516
  break;
655
- case 255 /* DnsClass.ANY */:
517
+ case 255:
656
518
  classStr = 'ANY';
657
519
  break;
658
520
  default:
@@ -660,28 +522,21 @@ export class Mdns extends Multicast {
660
522
  }
661
523
  return isFlush ? `${classStr}|FLUSH` : classStr;
662
524
  }
663
- /**
664
- * Converts a DNS question class to a human-readable string.
665
- * Adds support for mDNS QU (unicast-response) bit.
666
- *
667
- * @param {number} cls - The numeric question class.
668
- * @returns {string} The string representation, e.g. "IN|QU"
669
- */
670
525
  dnsQuestionClassToString(cls) {
671
- const isQU = !!(cls & 32768 /* DnsClassFlag.QU */);
526
+ const isQU = !!(cls & 32768);
672
527
  const baseClass = cls & 0x7fff;
673
528
  let classStr;
674
529
  switch (baseClass) {
675
- case 1 /* DnsClass.IN */:
530
+ case 1:
676
531
  classStr = 'IN';
677
532
  break;
678
- case 3 /* DnsClass.CH */:
533
+ case 3:
679
534
  classStr = 'CH';
680
535
  break;
681
- case 4 /* DnsClass.HS */:
536
+ case 4:
682
537
  classStr = 'HS';
683
538
  break;
684
- case 255 /* DnsClass.ANY */:
539
+ case 255:
685
540
  classStr = 'ANY';
686
541
  break;
687
542
  default:
@@ -689,11 +544,6 @@ export class Mdns extends Multicast {
689
544
  }
690
545
  return isQU ? `${classStr}|QU` : classStr;
691
546
  }
692
- /**
693
- * Logs the decoded mDNS message header.
694
- *
695
- * @param {MdnsMessage} msg - The mDNS message header object.
696
- */
697
547
  logMdnsMessage(msg) {
698
548
  this.log.info(`Decoded mDNS message: ID ${MAGENTA}${msg.id}${nf}, QR ${GREEN}${msg.qr === 0 ? 'Query' : 'Response'}${nf}, OPCODE ${MAGENTA}${msg.opcode}${nf}, AA ${MAGENTA}${msg.aa}${nf}, TC ${MAGENTA}${msg.tc}${nf}, RD ${MAGENTA}${msg.rd}${nf}, RA ${MAGENTA}${msg.ra}${nf}, Z ${MAGENTA}${msg.z}${nf}, RCODE ${MAGENTA}${msg.rcode}${nf}, QDCount ${MAGENTA}${msg.qdCount}${nf}, ANCount ${MAGENTA}${msg.anCount}${nf}, NSCount ${MAGENTA}${msg.nsCount}${nf}, ARCount ${MAGENTA}${msg.arCount}${nf}`);
699
549
  msg.questions?.forEach((question) => {
@@ -710,14 +560,9 @@ export class Mdns extends Multicast {
710
560
  });
711
561
  this.log.info(`---\n`);
712
562
  }
713
- /**
714
- * Logs the discovered devices from the mDNS queries and responses.
715
- */
716
563
  logDevices() {
717
564
  this.log.info(`Discovered query devices: ${MAGENTA}${this.deviceQueries.size}${nf}`);
718
- // Collect devices into an array
719
565
  const deviceQueryArray = Array.from(this.deviceQueries.entries());
720
- // Sort the array by numeric value of the IP address
721
566
  deviceQueryArray.sort(([addressA], [addressB]) => {
722
567
  const partsA = addressA.split('.').map(Number);
723
568
  const partsB = addressB.split('.').map(Number);
@@ -726,17 +571,13 @@ export class Mdns extends Multicast {
726
571
  if (diff !== 0)
727
572
  return diff;
728
573
  }
729
- // istanbul ignore next
730
574
  return 0;
731
575
  });
732
- // Log the sorted devices
733
576
  deviceQueryArray.forEach(([rinfo, response]) => {
734
577
  this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf}`);
735
578
  });
736
579
  this.log.info(`Discovered response devices: ${MAGENTA}${this.deviceResponses.size}${nf}`);
737
- // Collect devices into an array
738
580
  const deviceResponseArray = Array.from(this.deviceResponses.entries());
739
- // Sort the array by numeric value of the IP address
740
581
  deviceResponseArray.sort(([addressA], [addressB]) => {
741
582
  const partsA = addressA.split(/[:.]/).map((part) => parseInt(part, 16));
742
583
  const partsB = addressB.split(/[:.]/).map((part) => parseInt(part, 16));
@@ -745,96 +586,10 @@ export class Mdns extends Multicast {
745
586
  if (diff !== 0)
746
587
  return diff;
747
588
  }
748
- // istanbul ignore next
749
589
  return 0;
750
590
  });
751
- // Log the sorted devices
752
591
  deviceResponseArray.forEach(([rinfo, response]) => {
753
592
  this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf} PTR ${GREEN}${response.dataPTR}${nf}`);
754
593
  });
755
594
  }
756
595
  }
757
- // CLI entry point for manual testing: node dist/dgram/mdns.js --mdns-udp4 --mdns-udp6 --mdns-query
758
- // istanbul ignore next if
759
- if (process.argv.includes('--mdns-udp4') || process.argv.includes('--mdns-udp6')) {
760
- // const mdnsIpv4 = new Mdns('mDNS Server udp4', MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_PORT, 'udp4', true, 'Loopback Pseudo-Interface 1', '127.0.0.1');
761
- // const mdnsIpv6 = new Mdns('mDNS Server udp6', MDNS_MULTICAST_IPV6_ADDRESS, MDNS_MULTICAST_PORT, 'udp6', true, 'Loopback Pseudo-Interface 1', '::1');
762
- const mdnsIpv4 = new Mdns('mDNS Server udp4', MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_PORT, 'udp4', true, undefined, '0.0.0.0');
763
- const mdnsIpv6 = new Mdns('mDNS Server udp6', MDNS_MULTICAST_IPV6_ADDRESS, MDNS_MULTICAST_PORT, 'udp6', true, undefined, '::');
764
- mdnsIpv6.listNetworkInterfaces();
765
- /**
766
- * Cleanup and log device information before exiting.
767
- */
768
- function cleanupAndLogAndExit() {
769
- if (process.argv.includes('--mdns-udp4'))
770
- mdnsIpv4.stop();
771
- if (process.argv.includes('--mdns-udp6'))
772
- mdnsIpv6.stop();
773
- if (process.argv.includes('--mdns-udp4'))
774
- mdnsIpv4.logDevices();
775
- if (process.argv.includes('--mdns-udp6'))
776
- mdnsIpv6.logDevices();
777
- // eslint-disable-next-line n/no-process-exit
778
- process.exit(0);
779
- }
780
- /**
781
- * Queries mDNS services over UDP IPv4 and sends a response for a specific service instance.
782
- * This function sends a query for Shelly, HTTP, and services, and responds with the appropriate PTR records.
783
- */
784
- const queryUdp4 = () => {
785
- mdnsIpv4.sendQuery([
786
- { name: '_matter._tcp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: false },
787
- { name: '_shelly._tcp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: false },
788
- { name: '_http._tcp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: false },
789
- { name: '_services._dns-sd._udp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: false },
790
- ]);
791
- const ptrRdata = mdnsIpv4.encodeDnsName('matterbridge._http._tcp.local');
792
- mdnsIpv4.sendResponse('_http._tcp.local', 12 /* DnsRecordType.PTR */, 1 /* DnsClass.IN */, 120, ptrRdata);
793
- };
794
- /**
795
- * Queries mDNS services over UDP IPv6 and sends a response for a specific service instance.
796
- * This function sends a query for Shelly, HTTP, and services, and responds with the appropriate PTR records.
797
- */
798
- const queryUdp6 = () => {
799
- mdnsIpv6.sendQuery([
800
- { name: '_matter._tcp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: true },
801
- { name: '_shelly._tcp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: true },
802
- { name: '_http._tcp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: true },
803
- { name: '_services._dns-sd._udp.local', type: 12 /* DnsRecordType.PTR */, class: 1 /* DnsClass.IN */, unicastResponse: true },
804
- ]);
805
- const ptrRdata = mdnsIpv6.encodeDnsName('matterbridge._http._tcp.local');
806
- mdnsIpv6.sendResponse('_http._tcp.local', 12 /* DnsRecordType.PTR */, 1 /* DnsClass.IN */, 120, ptrRdata);
807
- };
808
- // Handle Ctrl+C (SIGINT) to stop and log devices
809
- process.on('SIGINT', () => {
810
- cleanupAndLogAndExit();
811
- });
812
- if (process.argv.includes('--mdns-udp4')) {
813
- mdnsIpv4.start();
814
- mdnsIpv4.on('ready', (address) => {
815
- mdnsIpv4.log.info(`mdnsIpv4 server ready on ${address.family} ${address.address}:${address.port}`);
816
- if (!process.argv.includes('--mdns-query'))
817
- return; // Skip querying if --mdns-query is not specified
818
- queryUdp4();
819
- setInterval(() => {
820
- queryUdp4();
821
- }, 10000).unref();
822
- });
823
- }
824
- if (process.argv.includes('--mdns-udp6')) {
825
- mdnsIpv6.start();
826
- mdnsIpv6.on('ready', (address) => {
827
- mdnsIpv6.log.info(`mdnsIpv6 server ready on ${address.family} ${address.address}:${address.port}`);
828
- if (!process.argv.includes('--mdns-query'))
829
- return; // Skip querying if --mdns-query is not specified
830
- queryUdp6();
831
- setInterval(() => {
832
- queryUdp6();
833
- }, 10000).unref();
834
- });
835
- }
836
- setTimeout(() => {
837
- cleanupAndLogAndExit();
838
- }, 600000); // 10 minutes timeout to exit if no activity
839
- }
840
- //# sourceMappingURL=mdns.js.map