matterbridge 3.4.5-dev-20251225-2f72161 → 3.4.5

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 (335) hide show
  1. package/CHANGELOG.md +5 -8
  2. package/dist/broadcastServer.d.ts +144 -0
  3. package/dist/broadcastServer.d.ts.map +1 -0
  4. package/dist/broadcastServer.js +117 -0
  5. package/dist/broadcastServer.js.map +1 -0
  6. package/dist/broadcastServerTypes.d.ts +841 -0
  7. package/dist/broadcastServerTypes.d.ts.map +1 -0
  8. package/dist/broadcastServerTypes.js +24 -0
  9. package/dist/broadcastServerTypes.js.map +1 -0
  10. package/dist/cli.d.ts +30 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +97 -1
  13. package/dist/cli.js.map +1 -0
  14. package/dist/cliEmitter.d.ts +50 -0
  15. package/dist/cliEmitter.d.ts.map +1 -0
  16. package/dist/cliEmitter.js +37 -0
  17. package/dist/cliEmitter.js.map +1 -0
  18. package/dist/cliHistory.d.ts +48 -0
  19. package/dist/cliHistory.d.ts.map +1 -0
  20. package/dist/cliHistory.js +38 -0
  21. package/dist/cliHistory.js.map +1 -0
  22. package/dist/clusters/export.d.ts +2 -0
  23. package/dist/clusters/export.d.ts.map +1 -0
  24. package/dist/clusters/export.js +2 -0
  25. package/dist/clusters/export.js.map +1 -0
  26. package/dist/deviceManager.d.ts +135 -0
  27. package/dist/deviceManager.d.ts.map +1 -0
  28. package/dist/deviceManager.js +113 -1
  29. package/dist/deviceManager.js.map +1 -0
  30. package/dist/devices/airConditioner.d.ts +98 -0
  31. package/dist/devices/airConditioner.d.ts.map +1 -0
  32. package/dist/devices/airConditioner.js +57 -0
  33. package/dist/devices/airConditioner.js.map +1 -0
  34. package/dist/devices/batteryStorage.d.ts +48 -0
  35. package/dist/devices/batteryStorage.d.ts.map +1 -0
  36. package/dist/devices/batteryStorage.js +48 -1
  37. package/dist/devices/batteryStorage.js.map +1 -0
  38. package/dist/devices/cooktop.d.ts +61 -0
  39. package/dist/devices/cooktop.d.ts.map +1 -0
  40. package/dist/devices/cooktop.js +56 -0
  41. package/dist/devices/cooktop.js.map +1 -0
  42. package/dist/devices/dishwasher.d.ts +71 -0
  43. package/dist/devices/dishwasher.d.ts.map +1 -0
  44. package/dist/devices/dishwasher.js +57 -0
  45. package/dist/devices/dishwasher.js.map +1 -0
  46. package/dist/devices/evse.d.ts +76 -0
  47. package/dist/devices/evse.d.ts.map +1 -0
  48. package/dist/devices/evse.js +74 -10
  49. package/dist/devices/evse.js.map +1 -0
  50. package/dist/devices/export.d.ts +17 -0
  51. package/dist/devices/export.d.ts.map +1 -0
  52. package/dist/devices/export.js +5 -0
  53. package/dist/devices/export.js.map +1 -0
  54. package/dist/devices/extractorHood.d.ts +46 -0
  55. package/dist/devices/extractorHood.d.ts.map +1 -0
  56. package/dist/devices/extractorHood.js +43 -0
  57. package/dist/devices/extractorHood.js.map +1 -0
  58. package/dist/devices/heatPump.d.ts +47 -0
  59. package/dist/devices/heatPump.d.ts.map +1 -0
  60. package/dist/devices/heatPump.js +50 -2
  61. package/dist/devices/heatPump.js.map +1 -0
  62. package/dist/devices/laundryDryer.d.ts +67 -0
  63. package/dist/devices/laundryDryer.d.ts.map +1 -0
  64. package/dist/devices/laundryDryer.js +62 -3
  65. package/dist/devices/laundryDryer.js.map +1 -0
  66. package/dist/devices/laundryWasher.d.ts +81 -0
  67. package/dist/devices/laundryWasher.d.ts.map +1 -0
  68. package/dist/devices/laundryWasher.js +70 -4
  69. package/dist/devices/laundryWasher.js.map +1 -0
  70. package/dist/devices/microwaveOven.d.ts +168 -0
  71. package/dist/devices/microwaveOven.d.ts.map +1 -0
  72. package/dist/devices/microwaveOven.js +88 -5
  73. package/dist/devices/microwaveOven.js.map +1 -0
  74. package/dist/devices/oven.d.ts +105 -0
  75. package/dist/devices/oven.d.ts.map +1 -0
  76. package/dist/devices/oven.js +85 -0
  77. package/dist/devices/oven.js.map +1 -0
  78. package/dist/devices/refrigerator.d.ts +118 -0
  79. package/dist/devices/refrigerator.d.ts.map +1 -0
  80. package/dist/devices/refrigerator.js +102 -0
  81. package/dist/devices/refrigerator.js.map +1 -0
  82. package/dist/devices/roboticVacuumCleaner.d.ts +112 -0
  83. package/dist/devices/roboticVacuumCleaner.d.ts.map +1 -0
  84. package/dist/devices/roboticVacuumCleaner.js +100 -9
  85. package/dist/devices/roboticVacuumCleaner.js.map +1 -0
  86. package/dist/devices/solarPower.d.ts +40 -0
  87. package/dist/devices/solarPower.d.ts.map +1 -0
  88. package/dist/devices/solarPower.js +38 -0
  89. package/dist/devices/solarPower.js.map +1 -0
  90. package/dist/devices/speaker.d.ts +87 -0
  91. package/dist/devices/speaker.d.ts.map +1 -0
  92. package/dist/devices/speaker.js +84 -0
  93. package/dist/devices/speaker.js.map +1 -0
  94. package/dist/devices/temperatureControl.d.ts +166 -0
  95. package/dist/devices/temperatureControl.d.ts.map +1 -0
  96. package/dist/devices/temperatureControl.js +24 -3
  97. package/dist/devices/temperatureControl.js.map +1 -0
  98. package/dist/devices/waterHeater.d.ts +111 -0
  99. package/dist/devices/waterHeater.d.ts.map +1 -0
  100. package/dist/devices/waterHeater.js +82 -2
  101. package/dist/devices/waterHeater.js.map +1 -0
  102. package/dist/dgram/coap.d.ts +205 -0
  103. package/dist/dgram/coap.d.ts.map +1 -0
  104. package/dist/dgram/coap.js +126 -13
  105. package/dist/dgram/coap.js.map +1 -0
  106. package/dist/dgram/dgram.d.ts +143 -0
  107. package/dist/dgram/dgram.d.ts.map +1 -0
  108. package/dist/dgram/dgram.js +121 -4
  109. package/dist/dgram/dgram.js.map +1 -0
  110. package/dist/dgram/mb_coap.d.ts +24 -0
  111. package/dist/dgram/mb_coap.d.ts.map +1 -0
  112. package/dist/dgram/mb_coap.js +41 -3
  113. package/dist/dgram/mb_coap.js.map +1 -0
  114. package/dist/dgram/mb_mdns.d.ts +24 -0
  115. package/dist/dgram/mb_mdns.d.ts.map +1 -0
  116. package/dist/dgram/mb_mdns.js +172 -172
  117. package/dist/dgram/mb_mdns.js.map +1 -0
  118. package/dist/dgram/mdns.d.ts +350 -0
  119. package/dist/dgram/mdns.d.ts.map +1 -0
  120. package/dist/dgram/mdns.js +358 -144
  121. package/dist/dgram/mdns.js.map +1 -0
  122. package/dist/dgram/mdnsReflectorClient.d.ts +39 -0
  123. package/dist/dgram/mdnsReflectorClient.d.ts.map +1 -0
  124. package/dist/dgram/mdnsReflectorClient.js +132 -0
  125. package/dist/dgram/mdnsReflectorClient.js.map +1 -0
  126. package/dist/dgram/mdnsReflectorServer.d.ts +54 -0
  127. package/dist/dgram/mdnsReflectorServer.d.ts.map +1 -0
  128. package/dist/dgram/mdnsReflectorServer.js +294 -0
  129. package/dist/dgram/mdnsReflectorServer.js.map +1 -0
  130. package/dist/dgram/mdnsReflectorTypes.d.ts +28 -0
  131. package/dist/dgram/mdnsReflectorTypes.d.ts.map +1 -0
  132. package/dist/dgram/mdnsReflectorTypes.js +28 -0
  133. package/dist/dgram/mdnsReflectorTypes.js.map +1 -0
  134. package/dist/dgram/multicast.d.ts +67 -0
  135. package/dist/dgram/multicast.d.ts.map +1 -0
  136. package/dist/dgram/multicast.js +62 -1
  137. package/dist/dgram/multicast.js.map +1 -0
  138. package/dist/dgram/unicast.d.ts +64 -0
  139. package/dist/dgram/unicast.d.ts.map +1 -0
  140. package/dist/dgram/unicast.js +64 -1
  141. package/dist/dgram/unicast.js.map +1 -0
  142. package/dist/frontend.d.ts +245 -0
  143. package/dist/frontend.d.ts.map +1 -0
  144. package/dist/frontend.js +485 -38
  145. package/dist/frontend.js.map +1 -0
  146. package/dist/frontendTypes.d.ts +529 -0
  147. package/dist/frontendTypes.d.ts.map +1 -0
  148. package/dist/frontendTypes.js +45 -0
  149. package/dist/frontendTypes.js.map +1 -0
  150. package/dist/helpers.d.ts +48 -0
  151. package/dist/helpers.d.ts.map +1 -0
  152. package/dist/helpers.js +53 -0
  153. package/dist/helpers.js.map +1 -0
  154. package/dist/index.d.ts +34 -0
  155. package/dist/index.d.ts.map +1 -0
  156. package/dist/index.js +25 -0
  157. package/dist/index.js.map +1 -0
  158. package/dist/jestutils/export.d.ts +2 -0
  159. package/dist/jestutils/export.d.ts.map +1 -0
  160. package/dist/jestutils/export.js +1 -0
  161. package/dist/jestutils/export.js.map +1 -0
  162. package/dist/jestutils/jestHelpers.d.ts +345 -0
  163. package/dist/jestutils/jestHelpers.d.ts.map +1 -0
  164. package/dist/jestutils/jestHelpers.js +371 -14
  165. package/dist/jestutils/jestHelpers.js.map +1 -0
  166. package/dist/logger/export.d.ts +2 -0
  167. package/dist/logger/export.d.ts.map +1 -0
  168. package/dist/logger/export.js +1 -0
  169. package/dist/logger/export.js.map +1 -0
  170. package/dist/matter/behaviors.d.ts +2 -0
  171. package/dist/matter/behaviors.d.ts.map +1 -0
  172. package/dist/matter/behaviors.js +2 -0
  173. package/dist/matter/behaviors.js.map +1 -0
  174. package/dist/matter/clusters.d.ts +2 -0
  175. package/dist/matter/clusters.d.ts.map +1 -0
  176. package/dist/matter/clusters.js +2 -0
  177. package/dist/matter/clusters.js.map +1 -0
  178. package/dist/matter/devices.d.ts +2 -0
  179. package/dist/matter/devices.d.ts.map +1 -0
  180. package/dist/matter/devices.js +2 -0
  181. package/dist/matter/devices.js.map +1 -0
  182. package/dist/matter/endpoints.d.ts +2 -0
  183. package/dist/matter/endpoints.d.ts.map +1 -0
  184. package/dist/matter/endpoints.js +2 -0
  185. package/dist/matter/endpoints.js.map +1 -0
  186. package/dist/matter/export.d.ts +5 -0
  187. package/dist/matter/export.d.ts.map +1 -0
  188. package/dist/matter/export.js +3 -0
  189. package/dist/matter/export.js.map +1 -0
  190. package/dist/matter/types.d.ts +3 -0
  191. package/dist/matter/types.d.ts.map +1 -0
  192. package/dist/matter/types.js +3 -0
  193. package/dist/matter/types.js.map +1 -0
  194. package/dist/matterNode.d.ts +342 -0
  195. package/dist/matterNode.d.ts.map +1 -0
  196. package/dist/matterNode.js +369 -8
  197. package/dist/matterNode.js.map +1 -0
  198. package/dist/matterbridge.d.ts +505 -0
  199. package/dist/matterbridge.d.ts.map +1 -0
  200. package/dist/matterbridge.js +824 -46
  201. package/dist/matterbridge.js.map +1 -0
  202. package/dist/matterbridgeAccessoryPlatform.d.ts +41 -0
  203. package/dist/matterbridgeAccessoryPlatform.d.ts.map +1 -0
  204. package/dist/matterbridgeAccessoryPlatform.js +38 -0
  205. package/dist/matterbridgeAccessoryPlatform.js.map +1 -0
  206. package/dist/matterbridgeBehaviors.d.ts +2404 -0
  207. package/dist/matterbridgeBehaviors.d.ts.map +1 -0
  208. package/dist/matterbridgeBehaviors.js +68 -5
  209. package/dist/matterbridgeBehaviors.js.map +1 -0
  210. package/dist/matterbridgeDeviceTypes.d.ts +698 -0
  211. package/dist/matterbridgeDeviceTypes.d.ts.map +1 -0
  212. package/dist/matterbridgeDeviceTypes.js +635 -14
  213. package/dist/matterbridgeDeviceTypes.js.map +1 -0
  214. package/dist/matterbridgeDynamicPlatform.d.ts +41 -0
  215. package/dist/matterbridgeDynamicPlatform.d.ts.map +1 -0
  216. package/dist/matterbridgeDynamicPlatform.js +38 -0
  217. package/dist/matterbridgeDynamicPlatform.js.map +1 -0
  218. package/dist/matterbridgeEndpoint.d.ts +1507 -0
  219. package/dist/matterbridgeEndpoint.d.ts.map +1 -0
  220. package/dist/matterbridgeEndpoint.js +1457 -53
  221. package/dist/matterbridgeEndpoint.js.map +1 -0
  222. package/dist/matterbridgeEndpointHelpers.d.ts +787 -0
  223. package/dist/matterbridgeEndpointHelpers.d.ts.map +1 -0
  224. package/dist/matterbridgeEndpointHelpers.js +483 -20
  225. package/dist/matterbridgeEndpointHelpers.js.map +1 -0
  226. package/dist/matterbridgeEndpointTypes.d.ts +166 -0
  227. package/dist/matterbridgeEndpointTypes.d.ts.map +1 -0
  228. package/dist/matterbridgeEndpointTypes.js +25 -0
  229. package/dist/matterbridgeEndpointTypes.js.map +1 -0
  230. package/dist/matterbridgePlatform.d.ts +539 -0
  231. package/dist/matterbridgePlatform.d.ts.map +1 -0
  232. package/dist/matterbridgePlatform.js +451 -1
  233. package/dist/matterbridgePlatform.js.map +1 -0
  234. package/dist/matterbridgeTypes.d.ts +252 -0
  235. package/dist/matterbridgeTypes.d.ts.map +1 -0
  236. package/dist/matterbridgeTypes.js +26 -0
  237. package/dist/matterbridgeTypes.js.map +1 -0
  238. package/dist/pluginManager.d.ts +372 -0
  239. package/dist/pluginManager.d.ts.map +1 -0
  240. package/dist/pluginManager.js +341 -5
  241. package/dist/pluginManager.js.map +1 -0
  242. package/dist/shelly.d.ts +181 -0
  243. package/dist/shelly.d.ts.map +1 -0
  244. package/dist/shelly.js +178 -7
  245. package/dist/shelly.js.map +1 -0
  246. package/dist/storage/export.d.ts +2 -0
  247. package/dist/storage/export.d.ts.map +1 -0
  248. package/dist/storage/export.js +1 -0
  249. package/dist/storage/export.js.map +1 -0
  250. package/dist/update.d.ts +84 -0
  251. package/dist/update.d.ts.map +1 -0
  252. package/dist/update.js +93 -1
  253. package/dist/update.js.map +1 -0
  254. package/dist/utils/colorUtils.d.ts +101 -0
  255. package/dist/utils/colorUtils.d.ts.map +1 -0
  256. package/dist/utils/colorUtils.js +97 -2
  257. package/dist/utils/colorUtils.js.map +1 -0
  258. package/dist/utils/commandLine.d.ts +66 -0
  259. package/dist/utils/commandLine.d.ts.map +1 -0
  260. package/dist/utils/commandLine.js +61 -1
  261. package/dist/utils/commandLine.js.map +1 -0
  262. package/dist/utils/copyDirectory.d.ts +35 -0
  263. package/dist/utils/copyDirectory.d.ts.map +1 -0
  264. package/dist/utils/copyDirectory.js +37 -0
  265. package/dist/utils/copyDirectory.js.map +1 -0
  266. package/dist/utils/createDirectory.d.ts +34 -0
  267. package/dist/utils/createDirectory.d.ts.map +1 -0
  268. package/dist/utils/createDirectory.js +33 -0
  269. package/dist/utils/createDirectory.js.map +1 -0
  270. package/dist/utils/createZip.d.ts +39 -0
  271. package/dist/utils/createZip.d.ts.map +1 -0
  272. package/dist/utils/createZip.js +47 -2
  273. package/dist/utils/createZip.js.map +1 -0
  274. package/dist/utils/deepCopy.d.ts +32 -0
  275. package/dist/utils/deepCopy.d.ts.map +1 -0
  276. package/dist/utils/deepCopy.js +39 -0
  277. package/dist/utils/deepCopy.js.map +1 -0
  278. package/dist/utils/deepEqual.d.ts +54 -0
  279. package/dist/utils/deepEqual.d.ts.map +1 -0
  280. package/dist/utils/deepEqual.js +72 -1
  281. package/dist/utils/deepEqual.js.map +1 -0
  282. package/dist/utils/error.d.ts +45 -0
  283. package/dist/utils/error.d.ts.map +1 -0
  284. package/dist/utils/error.js +42 -0
  285. package/dist/utils/error.js.map +1 -0
  286. package/dist/utils/export.d.ts +13 -0
  287. package/dist/utils/export.d.ts.map +1 -0
  288. package/dist/utils/export.js +1 -0
  289. package/dist/utils/export.js.map +1 -0
  290. package/dist/utils/format.d.ts +53 -0
  291. package/dist/utils/format.d.ts.map +1 -0
  292. package/dist/utils/format.js +49 -0
  293. package/dist/utils/format.js.map +1 -0
  294. package/dist/utils/hex.d.ts +89 -0
  295. package/dist/utils/hex.d.ts.map +1 -0
  296. package/dist/utils/hex.js +124 -0
  297. package/dist/utils/hex.js.map +1 -0
  298. package/dist/utils/inspector.d.ts +87 -0
  299. package/dist/utils/inspector.d.ts.map +1 -0
  300. package/dist/utils/inspector.js +69 -1
  301. package/dist/utils/inspector.js.map +1 -0
  302. package/dist/utils/isvalid.d.ts +103 -0
  303. package/dist/utils/isvalid.d.ts.map +1 -0
  304. package/dist/utils/isvalid.js +101 -0
  305. package/dist/utils/isvalid.js.map +1 -0
  306. package/dist/utils/network.d.ts +117 -0
  307. package/dist/utils/network.d.ts.map +1 -0
  308. package/dist/utils/network.js +103 -5
  309. package/dist/utils/network.js.map +1 -0
  310. package/dist/utils/spawn.d.ts +33 -0
  311. package/dist/utils/spawn.d.ts.map +1 -0
  312. package/dist/utils/spawn.js +71 -1
  313. package/dist/utils/spawn.js.map +1 -0
  314. package/dist/utils/tracker.d.ts +108 -0
  315. package/dist/utils/tracker.d.ts.map +1 -0
  316. package/dist/utils/tracker.js +64 -1
  317. package/dist/utils/tracker.js.map +1 -0
  318. package/dist/utils/wait.d.ts +54 -0
  319. package/dist/utils/wait.d.ts.map +1 -0
  320. package/dist/utils/wait.js +60 -8
  321. package/dist/utils/wait.js.map +1 -0
  322. package/dist/workerGlobalPrefix.d.ts +25 -0
  323. package/dist/workerGlobalPrefix.d.ts.map +1 -0
  324. package/dist/workerGlobalPrefix.js +37 -5
  325. package/dist/workerGlobalPrefix.js.map +1 -0
  326. package/dist/workerTypes.d.ts +52 -0
  327. package/dist/workerTypes.d.ts.map +1 -0
  328. package/dist/workerTypes.js +24 -0
  329. package/dist/workerTypes.js.map +1 -0
  330. package/dist/workers.d.ts +69 -0
  331. package/dist/workers.d.ts.map +1 -0
  332. package/dist/workers.js +68 -4
  333. package/dist/workers.js.map +1 -0
  334. package/npm-shrinkwrap.json +2 -2
  335. package/package.json +2 -1
@@ -1,5 +1,30 @@
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
1
24
  import { BLUE, CYAN, db, er, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
25
+ // Utils imports
2
26
  import { hasParameter } from '../utils/commandLine.js';
27
+ // Net imports
3
28
  import { Multicast } from './multicast.js';
4
29
  export var DnsRecordType;
5
30
  (function (DnsRecordType) {
@@ -91,6 +116,7 @@ export var DnsRecordType;
91
116
  DnsRecordType[DnsRecordType["DOA"] = 259] = "DOA";
92
117
  DnsRecordType[DnsRecordType["AMTRELAY"] = 260] = "AMTRELAY";
93
118
  DnsRecordType[DnsRecordType["ZONEVERSION"] = 261] = "ZONEVERSION";
119
+ // 262-32767 are unassigned/reserved
94
120
  DnsRecordType[DnsRecordType["TA"] = 32768] = "TA";
95
121
  DnsRecordType[DnsRecordType["DLV"] = 32769] = "DLV";
96
122
  })(DnsRecordType || (DnsRecordType = {}));
@@ -104,12 +130,25 @@ export var DnsClass;
104
130
  export var DnsClassFlag;
105
131
  (function (DnsClassFlag) {
106
132
  DnsClassFlag[DnsClassFlag["FLUSH"] = 32768] = "FLUSH";
133
+ // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
107
134
  DnsClassFlag[DnsClassFlag["QU"] = 32768] = "QU";
108
135
  })(DnsClassFlag || (DnsClassFlag = {}));
109
136
  export class Mdns extends Multicast {
110
137
  deviceQueries = new Map();
111
138
  deviceResponses = new Map();
112
139
  filters = [];
140
+ /**
141
+ * Creates an instance of the Mdns class.
142
+ *
143
+ * @param {string} name - The internal name of the mDNS server for the logs.
144
+ * @param {string} multicastAddress - The multicast address for mDNS (i.e. 224.0.0.251 for udp4 or ff02::fb for udp6).
145
+ * @param {number} multicastPort - The port for mDNS (i.e. 5353).
146
+ * @param {('udp4' | 'udp6')} socketType - The type of socket to create (either 'udp4' or 'udp6').
147
+ * @param {boolean} [reuseAddr] - Whether to reuse the address. Defaults to true.
148
+ * @param {string} [interfaceName] - The optional name of the network interface to use.
149
+ * @param {string} [interfaceAddress] - The optional IP address of the network interface to use.
150
+ * @param {string} [outgoingInterfaceAddress] - The address of the outgoing network interface.
151
+ */
113
152
  constructor(name, multicastAddress, multicastPort, socketType, reuseAddr = true, interfaceName, interfaceAddress, outgoingInterfaceAddress) {
114
153
  super(name, multicastAddress, multicastPort, socketType, reuseAddr, interfaceName, interfaceAddress, outgoingInterfaceAddress);
115
154
  }
@@ -129,16 +168,17 @@ export class Mdns extends Multicast {
129
168
  this.onQuery(rinfo, result);
130
169
  }
131
170
  else {
132
- const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12) ||
133
- result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12) ||
134
- result.answers?.find((record) => record.type === 12) ||
135
- result.answers?.find((record) => record.type === 16) ||
171
+ const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
172
+ result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
173
+ result.answers?.find((record) => record.type === 12 /* DnsRecordType.PTR */) ||
174
+ result.answers?.find((record) => record.type === 16 /* DnsRecordType.TXT */) ||
136
175
  result.answers
137
176
  ? result.answers[0]
138
- : undefined;
139
- this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 ? ptr?.data : ptr?.name });
177
+ : undefined; // Fallback to the first answer if no PTR or TXT found
178
+ this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 /* DnsRecordType.PTR */ ? ptr?.data : ptr?.name });
140
179
  this.onResponse(rinfo, result);
141
180
  }
181
+ // Apply filters if any
142
182
  if (this.filters.length > 0) {
143
183
  this.log.debug(`mDNS message filtered out by filters: ${this.filters.join(', ')}`);
144
184
  for (const filter of this.filters) {
@@ -160,20 +200,28 @@ export class Mdns extends Multicast {
160
200
  this.log.error(`Error decoding mDNS message: ${error instanceof Error ? error.message : error}`);
161
201
  }
162
202
  }
203
+ /**
204
+ * Decodes an mDNS message, including the header, question section, answer section,
205
+ * authority section, and additional section.
206
+ *
207
+ * @param {Buffer} msg - The raw mDNS message buffer.
208
+ * @returns {MdnsMessage} An object representing the decoded mDNS message.
209
+ * @throws {Error} if the message is too short.
210
+ */
163
211
  decodeMdnsMessage(msg) {
164
212
  if (msg.length < 12) {
165
213
  throw new Error('mDNS message too short');
166
214
  }
167
215
  const id = msg.readUInt16BE(0);
168
216
  const flags = msg.readUInt16BE(2);
169
- const qr = (flags & 0x8000) >> 15;
170
- const opcode = (flags & 0x7800) >> 11;
171
- const aa = Boolean(flags & 0x0400);
172
- const tc = Boolean(flags & 0x0200);
173
- const rd = Boolean(flags & 0x0100);
174
- const ra = Boolean(flags & 0x0080);
175
- const z = (flags & 0x0070) >> 4;
176
- const rcode = flags & 0x000f;
217
+ const qr = (flags & 0x8000) >> 15; // Bit 15: 0=query, 1=response.
218
+ const opcode = (flags & 0x7800) >> 11; // Bits 14-11.
219
+ const aa = Boolean(flags & 0x0400); // Bit 10.
220
+ const tc = Boolean(flags & 0x0200); // Bit 9.
221
+ const rd = Boolean(flags & 0x0100); // Bit 8.
222
+ const ra = Boolean(flags & 0x0080); // Bit 7.
223
+ const z = (flags & 0x0070) >> 4; // Bits 6-4.
224
+ const rcode = flags & 0x000f; // Bits 3-0.
177
225
  const qdCount = msg.readUInt16BE(4);
178
226
  const anCount = msg.readUInt16BE(6);
179
227
  const nsCount = msg.readUInt16BE(8);
@@ -198,6 +246,7 @@ export class Mdns extends Multicast {
198
246
  additionals: [],
199
247
  };
200
248
  let offset = 12;
249
+ // Decode the question section.
201
250
  for (let i = 0; i < qdCount; i++) {
202
251
  const qnameResult = this.decodeDnsName(msg, offset);
203
252
  const qname = qnameResult.name;
@@ -208,16 +257,19 @@ export class Mdns extends Multicast {
208
257
  offset += 2;
209
258
  mdnsMessage.questions?.push({ name: qname, type: qtype, class: qclass });
210
259
  }
260
+ // Decode the answer section.
211
261
  for (let i = 0; i < anCount; i++) {
212
262
  const rrResult = this.decodeResourceRecord(msg, offset);
213
263
  mdnsMessage.answers?.push(rrResult.record);
214
264
  offset = rrResult.newOffset;
215
265
  }
266
+ // Decode the authority (NS) section.
216
267
  for (let i = 0; i < nsCount; i++) {
217
268
  const rrResult = this.decodeResourceRecord(msg, offset);
218
269
  mdnsMessage.authorities?.push(rrResult.record);
219
270
  offset = rrResult.newOffset;
220
271
  }
272
+ // Decode the additional records section.
221
273
  for (let i = 0; i < arCount; i++) {
222
274
  const rrResult = this.decodeResourceRecord(msg, offset);
223
275
  mdnsMessage.additionals?.push(rrResult.record);
@@ -225,15 +277,25 @@ export class Mdns extends Multicast {
225
277
  }
226
278
  return mdnsMessage;
227
279
  }
280
+ /**
281
+ * Decodes a DNS name from a buffer, handling compression.
282
+ *
283
+ * @param {Buffer} msg - The full mDNS message buffer.
284
+ * @param {number} offset - The offset at which the DNS name starts.
285
+ * @returns {{ name: string; newOffset: number }} An object with the decoded name and the new offset.
286
+ * @throws {Error} if the offset exceeds the buffer length or too many iterations are performed.
287
+ */
228
288
  decodeDnsName(msg, offset) {
229
289
  const labels = [];
230
290
  let jumped = false;
231
291
  let originalOffset = offset;
232
- let iterations = 0;
292
+ let iterations = 0; // Prevent infinite loops
233
293
  while (true) {
294
+ // Safety guard: prevent infinite loops in malformed messages.
234
295
  if (iterations++ > 1000) {
235
296
  throw new Error('Too many iterations while decoding DNS name. Possible malformed message.');
236
297
  }
298
+ // Check that offset is within buffer bounds.
237
299
  if (offset >= msg.length) {
238
300
  throw new Error('Offset exceeds buffer length while decoding DNS name.');
239
301
  }
@@ -242,7 +304,9 @@ export class Mdns extends Multicast {
242
304
  offset++;
243
305
  break;
244
306
  }
307
+ // Check for pointer (first two bits are 11)
245
308
  if ((len & 0xc0) === 0xc0) {
309
+ // Ensure the pointer has two bytes available.
246
310
  if (offset + 1 >= msg.length) {
247
311
  throw new Error('Incomplete pointer encountered while decoding DNS name.');
248
312
  }
@@ -255,6 +319,7 @@ export class Mdns extends Multicast {
255
319
  continue;
256
320
  }
257
321
  offset++;
322
+ // Check that the label length doesn't go beyond the buffer.
258
323
  if (offset + len > msg.length) {
259
324
  throw new Error('Label length exceeds buffer bounds while decoding DNS name.');
260
325
  }
@@ -263,6 +328,15 @@ export class Mdns extends Multicast {
263
328
  }
264
329
  return { name: labels.join('.'), newOffset: jumped ? originalOffset : offset };
265
330
  }
331
+ /**
332
+ * Encodes a domain name into the DNS label format.
333
+ *
334
+ * For example, "example.local" becomes:
335
+ * [7] "example" [5] "local" [0]
336
+ *
337
+ * @param {string} name - The domain name to encode.
338
+ * @returns {Buffer} The encoded domain name as a Buffer.
339
+ */
266
340
  encodeDnsName(name) {
267
341
  const labels = name.split('.');
268
342
  const buffers = labels.map((label) => {
@@ -270,8 +344,25 @@ export class Mdns extends Multicast {
270
344
  lenBuf.writeUInt8(label.length, 0);
271
345
  return Buffer.concat([lenBuf, Buffer.from(label)]);
272
346
  });
347
+ // Append the null byte to terminate the name.
273
348
  return Buffer.concat([...buffers, Buffer.from([0])]);
274
349
  }
350
+ /**
351
+ * Encodes TXT record RDATA.
352
+ *
353
+ * In DNS/mDNS, TXT RDATA is a sequence of one or more <character-string>,
354
+ * each encoded as: [length byte][UTF-8 bytes].
355
+ *
356
+ * @param {string[]} txt - Array of TXT entries, e.g. ["key=value", "path=/"].
357
+ * @returns {Buffer} Encoded TXT RDATA.
358
+ * @throws {Error} If any entry exceeds 255 bytes.
359
+ *
360
+ * @example
361
+ * const txtRdata = mdns.encodeTxtRdata(['txtvers=1', 'path=/']);
362
+ * mdns.sendResponse([
363
+ * { name: 'example._http._tcp.local', rtype: DnsRecordType.TXT, rclass: DnsClass.IN | DnsClassFlag.FLUSH, ttl: 120, rdata: txtRdata },
364
+ * ]);
365
+ */
275
366
  encodeTxtRdata(txt) {
276
367
  const parts = txt.map((entry) => {
277
368
  const value = Buffer.from(entry, 'utf8');
@@ -281,6 +372,21 @@ export class Mdns extends Multicast {
281
372
  });
282
373
  return Buffer.concat(parts);
283
374
  }
375
+ /**
376
+ * Encodes SRV record RDATA.
377
+ *
378
+ * SRV RDATA layout (RFC 2782):
379
+ * - priority (2 bytes)
380
+ * - weight (2 bytes)
381
+ * - port (2 bytes)
382
+ * - target (DNS name)
383
+ *
384
+ * @param {number} priority - SRV priority.
385
+ * @param {number} weight - SRV weight.
386
+ * @param {number} port - Service port.
387
+ * @param {string} target - Target hostname (e.g. "matterbridge.local").
388
+ * @returns {Buffer} Encoded SRV RDATA.
389
+ */
284
390
  encodeSrvRdata(priority, weight, port, target) {
285
391
  const fixed = Buffer.alloc(6);
286
392
  fixed.writeUInt16BE(priority, 0);
@@ -288,6 +394,13 @@ export class Mdns extends Multicast {
288
394
  fixed.writeUInt16BE(port, 4);
289
395
  return Buffer.concat([fixed, this.encodeDnsName(target)]);
290
396
  }
397
+ /**
398
+ * Encodes an IPv4 address for an A record RDATA (4 bytes).
399
+ *
400
+ * @param {string} ipv4 - IPv4 address, e.g. "192.168.1.10".
401
+ * @returns {Buffer} 4-byte buffer.
402
+ * @throws {Error} If the address is not a valid dotted-quad.
403
+ */
291
404
  encodeA(ipv4) {
292
405
  const parts = ipv4.split('.').map((p) => Number(p));
293
406
  if (parts.length !== 4 || parts.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) {
@@ -295,8 +408,19 @@ export class Mdns extends Multicast {
295
408
  }
296
409
  return Buffer.from(parts);
297
410
  }
411
+ /**
412
+ * Encodes an IPv6 address for an AAAA record RDATA (16 bytes).
413
+ *
414
+ * Supports the "::" zero-compression form and ignores an optional scope id
415
+ * suffix (e.g. "fe80::1%12" or "fe80::1%eth0").
416
+ *
417
+ * @param {string} ipv6WithOptionalScope - IPv6 address (optionally with scope id).
418
+ * @returns {Buffer} 16-byte buffer.
419
+ * @throws {Error} If the address is not a valid IPv6 literal.
420
+ */
298
421
  encodeAAAA(ipv6WithOptionalScope) {
299
422
  const ipv6 = ipv6WithOptionalScope.split('%')[0];
423
+ // Expand IPv6 to 8 groups of 16-bit words.
300
424
  const [left, right] = ipv6.split('::');
301
425
  const leftParts = left ? left.split(':').filter(Boolean) : [];
302
426
  const rightParts = right ? right.split(':').filter(Boolean) : [];
@@ -322,10 +446,19 @@ export class Mdns extends Multicast {
322
446
  return [(word >> 8) & 0xff, word & 0xff];
323
447
  }));
324
448
  }
449
+ /**
450
+ * Decodes a DNS resource record.
451
+ *
452
+ * @param {Buffer} msg - The full mDNS message buffer.
453
+ * @param {number} offset - The offset at which the resource record starts.
454
+ * @returns {{ record: MdnsRecord; newOffset: number }} An object containing the decoded record and the new offset.
455
+ */
325
456
  decodeResourceRecord(msg, offset) {
457
+ // Decode the NAME field (which may be compressed)
326
458
  const nameResult = this.decodeDnsName(msg, offset);
327
459
  const name = nameResult.name;
328
460
  offset = nameResult.newOffset;
461
+ // Read TYPE (16 bits), CLASS (16 bits), TTL (32 bits), and RDLENGTH (16 bits)
329
462
  const type = msg.readUInt16BE(offset);
330
463
  offset += 2;
331
464
  const rrclass = msg.readUInt16BE(offset);
@@ -335,12 +468,14 @@ export class Mdns extends Multicast {
335
468
  const rdlength = msg.readUInt16BE(offset);
336
469
  offset += 2;
337
470
  let data = '';
338
- if (type === 12) {
471
+ if (type === 12 /* DnsRecordType.PTR */) {
472
+ // PTR record (type 12): decode its RDATA as a domain name.
339
473
  const ptrResult = this.decodeDnsName(msg, offset);
340
474
  data = ptrResult.name;
341
475
  offset += rdlength;
342
476
  }
343
- else if (type === 16) {
477
+ else if (type === 16 /* DnsRecordType.TXT */) {
478
+ // TXT record: may consist of one or more length-prefixed strings.
344
479
  const txtStrings = [];
345
480
  const end = offset + rdlength;
346
481
  while (offset < end) {
@@ -352,7 +487,8 @@ export class Mdns extends Multicast {
352
487
  }
353
488
  data = txtStrings.join(', ');
354
489
  }
355
- else if (type === 33) {
490
+ else if (type === 33 /* DnsRecordType.SRV */) {
491
+ // SRV record (type === 33): consists of 2 bytes for priority, 2 for weight, 2 for port, followed by the target domain name.
356
492
  const priority = msg.readUInt16BE(offset);
357
493
  const weight = msg.readUInt16BE(offset + 2);
358
494
  const port = msg.readUInt16BE(offset + 4);
@@ -366,13 +502,16 @@ export class Mdns extends Multicast {
366
502
  });
367
503
  offset = srvTargetResult.newOffset;
368
504
  }
369
- else if (type === 1) {
505
+ else if (type === 1 /* DnsRecordType.A */) {
506
+ // A record (type 1): an IPv4 address stored in 4 bytes.
370
507
  const ipBytes = msg.slice(offset, offset + 4);
371
508
  data = Array.from(ipBytes).join('.');
372
509
  offset += 4;
373
510
  }
374
- else if (type === 28) {
511
+ else if (type === 28 /* DnsRecordType.AAAA */) {
512
+ // AAAA record (type 28): IPv6 address stored in 16 bytes.
375
513
  const ipBytes = msg.slice(offset, offset + 16);
514
+ // Convert the 16 bytes into an IPv6 address string (colon-separated)
376
515
  const ipv6Parts = [];
377
516
  for (let i = 0; i < 16; i += 2) {
378
517
  ipv6Parts.push(ipBytes.readUInt16BE(i).toString(16));
@@ -380,10 +519,14 @@ export class Mdns extends Multicast {
380
519
  data = ipv6Parts.join(':');
381
520
  offset += 16;
382
521
  }
383
- else if (type === 47) {
522
+ else if (type === 47 /* DnsRecordType.NSEC */) {
523
+ // NSEC record: RDATA consists of:
524
+ // - Next Domain Name (in DNS label format)
525
+ // - Type Bit Maps (variable length)
384
526
  const { name: nextDomain, newOffset } = this.decodeDnsName(msg, offset);
385
527
  const nextDomainLength = newOffset - offset;
386
528
  offset = newOffset;
529
+ // Calculate the remaining length for the type bit maps.
387
530
  const bitmapLength = rdlength - nextDomainLength;
388
531
  const bitmapData = msg.slice(offset, offset + bitmapLength);
389
532
  const types = [];
@@ -410,6 +553,7 @@ export class Mdns extends Multicast {
410
553
  offset += bitmapLength;
411
554
  }
412
555
  else {
556
+ // Fall back
413
557
  data = msg.slice(offset, offset + rdlength).toString('hex');
414
558
  offset += rdlength;
415
559
  }
@@ -418,19 +562,30 @@ export class Mdns extends Multicast {
418
562
  newOffset: offset,
419
563
  };
420
564
  }
565
+ /**
566
+ * Sends a DNS query with multiple questions.
567
+ *
568
+ * @param {Array<{ name: string; type: number; class: number; unicastResponse?: boolean }>} questions - Array of questions
569
+ * to include in the query.
570
+ * @returns {Buffer<ArrayBuffer>} The constructed query buffer.
571
+ *
572
+ * @remarks
573
+ * Each question should have a name (e.g., "_http._tcp.local"), type (e.g., DnsRecordType.PTR), class (e.g., DnsClass.IN),
574
+ * and an optional unicastResponse flag (this will add the DnsClassFlag.QU flag to the query).
575
+ */
421
576
  sendQuery(questions) {
422
577
  const header = Buffer.alloc(12);
423
- header.writeUInt16BE(0, 0);
424
- header.writeUInt16BE(0, 2);
425
- header.writeUInt16BE(questions.length, 4);
426
- header.writeUInt16BE(0, 6);
427
- header.writeUInt16BE(0, 8);
428
- header.writeUInt16BE(0, 10);
578
+ header.writeUInt16BE(0, 0); // ID
579
+ header.writeUInt16BE(0, 2); // Flags
580
+ header.writeUInt16BE(questions.length, 4); // QDCOUNT
581
+ header.writeUInt16BE(0, 6); // ANCOUNT
582
+ header.writeUInt16BE(0, 8); // NSCOUNT
583
+ header.writeUInt16BE(0, 10); // ARCOUNT
429
584
  const questionBuffers = questions.map(({ name, type: qtype, class: qclass, unicastResponse = false }) => {
430
585
  const qname = this.encodeDnsName(name);
431
586
  const qfields = Buffer.alloc(4);
432
587
  qfields.writeUInt16BE(qtype, 0);
433
- qfields.writeUInt16BE(unicastResponse ? qclass | 32768 : qclass, 2);
588
+ qfields.writeUInt16BE(unicastResponse ? qclass | 32768 /* DnsClassFlag.QU */ : qclass, 2);
434
589
  return Buffer.concat([qname, qfields]);
435
590
  });
436
591
  const query = Buffer.concat([header, ...questionBuffers]);
@@ -453,31 +608,52 @@ export class Mdns extends Multicast {
453
608
  });
454
609
  return query;
455
610
  }
611
+ /**
612
+ * Constructs an mDNS response packet and sends it to the multicast address and port.
613
+ *
614
+ * @param {Array<{ name: string; rtype: number; rclass: number; ttl: number; rdata: Buffer }>} answers - Array of answer records.
615
+ * @returns {Buffer<ArrayBuffer>} The constructed response buffer.
616
+ *
617
+ * @example
618
+ * const ptrRdata = mdnsIpv4.encodeDnsName('matterbridge._http._tcp.local');
619
+ * mdnsIpv4.sendResponse([{ name: '_http._tcp.local', rtype: DnsRecordType.PTR, rclass: DnsClass.IN, ttl: 120, rdata: ptrRdata }]);
620
+ */
456
621
  sendResponse(answers) {
457
622
  if (!Array.isArray(answers) || answers.length === 0) {
458
623
  throw new Error('sendResponse requires a non-empty answers array');
459
624
  }
625
+ // Create a 12-byte DNS header.
460
626
  const header = Buffer.alloc(12);
461
- header.writeUInt16BE(0, 0);
627
+ header.writeUInt16BE(0, 0); // ID is set to 0 in mDNS.
628
+ // Set flags: QR (response) bit and AA (authoritative answer) bit.
462
629
  header.writeUInt16BE(0x8400, 2);
463
- header.writeUInt16BE(0, 4);
464
- header.writeUInt16BE(answers.length, 6);
465
- header.writeUInt16BE(0, 8);
466
- header.writeUInt16BE(0, 10);
630
+ header.writeUInt16BE(0, 4); // QDCOUNT: 0 questions in response.
631
+ header.writeUInt16BE(answers.length, 6); // ANCOUNT: number of answer records.
632
+ header.writeUInt16BE(0, 8); // NSCOUNT: 0 authority records.
633
+ header.writeUInt16BE(0, 10); // ARCOUNT: 0 additional records.
467
634
  const answerBuffers = answers.map(({ name, rtype, rclass, ttl, rdata }) => {
635
+ // Encode the domain name in DNS label format.
468
636
  const aname = this.encodeDnsName(name);
637
+ // Prepare the fixed part of the answer record:
638
+ // - 2 bytes for qtype,
639
+ // - 2 bytes for qclass,
640
+ // - 4 bytes for TTL,
641
+ // - 2 bytes for RDLENGTH (length of the rdata).
469
642
  const answerFixed = Buffer.alloc(10);
470
- answerFixed.writeUInt16BE(rtype, 0);
471
- answerFixed.writeUInt16BE(rclass, 2);
472
- answerFixed.writeUInt32BE(ttl, 4);
473
- answerFixed.writeUInt16BE(rdata.length, 8);
643
+ answerFixed.writeUInt16BE(rtype, 0); // Record type.
644
+ answerFixed.writeUInt16BE(rclass, 2); // Record class.
645
+ answerFixed.writeUInt32BE(ttl, 4); // Time-to-live.
646
+ answerFixed.writeUInt16BE(rdata.length, 8); // RDLENGTH.
647
+ // Concatenate the answer: encoded name, fixed fields, and resource data.
474
648
  return Buffer.concat([aname, answerFixed, rdata]);
475
649
  });
650
+ // Concatenate header and answers to form the complete mDNS response packet.
476
651
  const response = Buffer.concat([header, ...answerBuffers]);
477
652
  if (hasParameter('v') || hasParameter('verbose')) {
478
653
  const decoded = this.decodeMdnsMessage(response);
479
654
  this.logMdnsMessage(decoded);
480
655
  }
656
+ // Send the response packet via the socket.
481
657
  this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
482
658
  if (error) {
483
659
  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');
@@ -492,116 +668,128 @@ export class Mdns extends Multicast {
492
668
  });
493
669
  return response;
494
670
  }
671
+ /**
672
+ * Converts a DNS record type numeric value to its string representation.
673
+ *
674
+ * @param {number} type - The numeric DNS record type.
675
+ * @returns {string} The string representation of the record type.
676
+ */
495
677
  dnsTypeToString(type) {
496
678
  const typeMap = {
497
- [1]: 'A',
498
- [2]: 'NS',
499
- [3]: 'MD',
500
- [4]: 'MF',
501
- [5]: 'CNAME',
502
- [6]: 'SOA',
503
- [7]: 'MB',
504
- [8]: 'MG',
505
- [9]: 'MR',
506
- [10]: 'NULL',
507
- [11]: 'WKS',
508
- [12]: 'PTR',
509
- [13]: 'HINFO',
510
- [14]: 'MINFO',
511
- [15]: 'MX',
512
- [16]: 'TXT',
513
- [17]: 'RP',
514
- [18]: 'AFSDB',
515
- [19]: 'X25',
516
- [20]: 'ISDN',
517
- [21]: 'RT',
518
- [22]: 'NSAP',
519
- [23]: 'NSAP_PTR',
520
- [24]: 'SIG',
521
- [25]: 'KEY',
522
- [26]: 'PX',
523
- [27]: 'GPOS',
524
- [28]: 'AAAA',
525
- [29]: 'LOC',
526
- [30]: 'NXT',
527
- [31]: 'EID',
528
- [32]: 'NIMLOC',
529
- [33]: 'SRV',
530
- [34]: 'ATMA',
531
- [35]: 'NAPTR',
532
- [36]: 'KX',
533
- [37]: 'CERT',
534
- [38]: 'A6',
535
- [39]: 'DNAME',
536
- [40]: 'SINK',
537
- [41]: 'OPT',
538
- [42]: 'APL',
539
- [43]: 'DS',
540
- [44]: 'SSHFP',
541
- [45]: 'IPSECKEY',
542
- [46]: 'RRSIG',
543
- [47]: 'NSEC',
544
- [48]: 'DNSKEY',
545
- [49]: 'DHCID',
546
- [50]: 'NSEC3',
547
- [51]: 'NSEC3PARAM',
548
- [52]: 'TLSA',
549
- [53]: 'SMIMEA',
550
- [55]: 'HIP',
551
- [56]: 'NINFO',
552
- [57]: 'RKEY',
553
- [58]: 'TALINK',
554
- [59]: 'CDS',
555
- [60]: 'CDNSKEY',
556
- [61]: 'OPENPGPKEY',
557
- [62]: 'CSYNC',
558
- [63]: 'ZONEMD',
559
- [64]: 'SVCB',
560
- [65]: 'HTTPS',
561
- [99]: 'SPF',
562
- [100]: 'UINFO',
563
- [101]: 'UID',
564
- [102]: 'GID',
565
- [103]: 'UNSPEC',
566
- [104]: 'NID',
567
- [105]: 'L32',
568
- [106]: 'L64',
569
- [107]: 'LP',
570
- [108]: 'EUI48',
571
- [109]: 'EUI64',
572
- [249]: 'TKEY',
573
- [250]: 'TSIG',
574
- [251]: 'IXFR',
575
- [252]: 'AXFR',
576
- [253]: 'MAILB',
577
- [254]: 'MAILA',
578
- [255]: 'ANY',
579
- [256]: 'URI',
580
- [257]: 'CAA',
581
- [258]: 'AVC',
582
- [259]: 'DOA',
583
- [260]: 'AMTRELAY',
584
- [261]: 'ZONEVERSION',
585
- [32768]: 'TA',
586
- [32769]: 'DLV',
679
+ [1 /* DnsRecordType.A */]: 'A',
680
+ [2 /* DnsRecordType.NS */]: 'NS',
681
+ [3 /* DnsRecordType.MD */]: 'MD',
682
+ [4 /* DnsRecordType.MF */]: 'MF',
683
+ [5 /* DnsRecordType.CNAME */]: 'CNAME',
684
+ [6 /* DnsRecordType.SOA */]: 'SOA',
685
+ [7 /* DnsRecordType.MB */]: 'MB',
686
+ [8 /* DnsRecordType.MG */]: 'MG',
687
+ [9 /* DnsRecordType.MR */]: 'MR',
688
+ [10 /* DnsRecordType.NULL */]: 'NULL',
689
+ [11 /* DnsRecordType.WKS */]: 'WKS',
690
+ [12 /* DnsRecordType.PTR */]: 'PTR',
691
+ [13 /* DnsRecordType.HINFO */]: 'HINFO',
692
+ [14 /* DnsRecordType.MINFO */]: 'MINFO',
693
+ [15 /* DnsRecordType.MX */]: 'MX',
694
+ [16 /* DnsRecordType.TXT */]: 'TXT',
695
+ [17 /* DnsRecordType.RP */]: 'RP',
696
+ [18 /* DnsRecordType.AFSDB */]: 'AFSDB',
697
+ [19 /* DnsRecordType.X25 */]: 'X25',
698
+ [20 /* DnsRecordType.ISDN */]: 'ISDN',
699
+ [21 /* DnsRecordType.RT */]: 'RT',
700
+ [22 /* DnsRecordType.NSAP */]: 'NSAP',
701
+ [23 /* DnsRecordType.NSAP_PTR */]: 'NSAP_PTR',
702
+ [24 /* DnsRecordType.SIG */]: 'SIG',
703
+ [25 /* DnsRecordType.KEY */]: 'KEY',
704
+ [26 /* DnsRecordType.PX */]: 'PX',
705
+ [27 /* DnsRecordType.GPOS */]: 'GPOS',
706
+ [28 /* DnsRecordType.AAAA */]: 'AAAA',
707
+ [29 /* DnsRecordType.LOC */]: 'LOC',
708
+ [30 /* DnsRecordType.NXT */]: 'NXT',
709
+ [31 /* DnsRecordType.EID */]: 'EID',
710
+ [32 /* DnsRecordType.NIMLOC */]: 'NIMLOC',
711
+ [33 /* DnsRecordType.SRV */]: 'SRV',
712
+ [34 /* DnsRecordType.ATMA */]: 'ATMA',
713
+ [35 /* DnsRecordType.NAPTR */]: 'NAPTR',
714
+ [36 /* DnsRecordType.KX */]: 'KX',
715
+ [37 /* DnsRecordType.CERT */]: 'CERT',
716
+ [38 /* DnsRecordType.A6 */]: 'A6',
717
+ [39 /* DnsRecordType.DNAME */]: 'DNAME',
718
+ [40 /* DnsRecordType.SINK */]: 'SINK',
719
+ [41 /* DnsRecordType.OPT */]: 'OPT',
720
+ [42 /* DnsRecordType.APL */]: 'APL',
721
+ [43 /* DnsRecordType.DS */]: 'DS',
722
+ [44 /* DnsRecordType.SSHFP */]: 'SSHFP',
723
+ [45 /* DnsRecordType.IPSECKEY */]: 'IPSECKEY',
724
+ [46 /* DnsRecordType.RRSIG */]: 'RRSIG',
725
+ [47 /* DnsRecordType.NSEC */]: 'NSEC',
726
+ [48 /* DnsRecordType.DNSKEY */]: 'DNSKEY',
727
+ [49 /* DnsRecordType.DHCID */]: 'DHCID',
728
+ [50 /* DnsRecordType.NSEC3 */]: 'NSEC3',
729
+ [51 /* DnsRecordType.NSEC3PARAM */]: 'NSEC3PARAM',
730
+ [52 /* DnsRecordType.TLSA */]: 'TLSA',
731
+ [53 /* DnsRecordType.SMIMEA */]: 'SMIMEA',
732
+ [55 /* DnsRecordType.HIP */]: 'HIP',
733
+ [56 /* DnsRecordType.NINFO */]: 'NINFO',
734
+ [57 /* DnsRecordType.RKEY */]: 'RKEY',
735
+ [58 /* DnsRecordType.TALINK */]: 'TALINK',
736
+ [59 /* DnsRecordType.CDS */]: 'CDS',
737
+ [60 /* DnsRecordType.CDNSKEY */]: 'CDNSKEY',
738
+ [61 /* DnsRecordType.OPENPGPKEY */]: 'OPENPGPKEY',
739
+ [62 /* DnsRecordType.CSYNC */]: 'CSYNC',
740
+ [63 /* DnsRecordType.ZONEMD */]: 'ZONEMD',
741
+ [64 /* DnsRecordType.SVCB */]: 'SVCB',
742
+ [65 /* DnsRecordType.HTTPS */]: 'HTTPS',
743
+ [99 /* DnsRecordType.SPF */]: 'SPF',
744
+ [100 /* DnsRecordType.UINFO */]: 'UINFO',
745
+ [101 /* DnsRecordType.UID */]: 'UID',
746
+ [102 /* DnsRecordType.GID */]: 'GID',
747
+ [103 /* DnsRecordType.UNSPEC */]: 'UNSPEC',
748
+ [104 /* DnsRecordType.NID */]: 'NID',
749
+ [105 /* DnsRecordType.L32 */]: 'L32',
750
+ [106 /* DnsRecordType.L64 */]: 'L64',
751
+ [107 /* DnsRecordType.LP */]: 'LP',
752
+ [108 /* DnsRecordType.EUI48 */]: 'EUI48',
753
+ [109 /* DnsRecordType.EUI64 */]: 'EUI64',
754
+ [249 /* DnsRecordType.TKEY */]: 'TKEY',
755
+ [250 /* DnsRecordType.TSIG */]: 'TSIG',
756
+ [251 /* DnsRecordType.IXFR */]: 'IXFR',
757
+ [252 /* DnsRecordType.AXFR */]: 'AXFR',
758
+ [253 /* DnsRecordType.MAILB */]: 'MAILB',
759
+ [254 /* DnsRecordType.MAILA */]: 'MAILA',
760
+ [255 /* DnsRecordType.ANY */]: 'ANY',
761
+ [256 /* DnsRecordType.URI */]: 'URI',
762
+ [257 /* DnsRecordType.CAA */]: 'CAA',
763
+ [258 /* DnsRecordType.AVC */]: 'AVC',
764
+ [259 /* DnsRecordType.DOA */]: 'DOA',
765
+ [260 /* DnsRecordType.AMTRELAY */]: 'AMTRELAY',
766
+ [261 /* DnsRecordType.ZONEVERSION */]: 'ZONEVERSION',
767
+ [32768 /* DnsRecordType.TA */]: 'TA',
768
+ [32769 /* DnsRecordType.DLV */]: 'DLV',
587
769
  };
588
770
  return typeMap[type] ?? `TYPE${type}`;
589
771
  }
772
+ /**
773
+ * Converts a DNS response class numeric value to its string representation.
774
+ *
775
+ * @param {number} cls - The numeric DNS class.
776
+ * @returns {string} The string representation of the DNS class.
777
+ */
590
778
  dnsResponseClassToString(cls) {
591
- const isFlush = !!(cls & 32768);
779
+ const isFlush = !!(cls & 32768 /* DnsClassFlag.FLUSH */);
592
780
  const baseClass = cls & 0x7fff;
593
781
  let classStr;
594
782
  switch (baseClass) {
595
- case 1:
783
+ case 1 /* DnsClass.IN */:
596
784
  classStr = 'IN';
597
785
  break;
598
- case 3:
786
+ case 3 /* DnsClass.CH */:
599
787
  classStr = 'CH';
600
788
  break;
601
- case 4:
789
+ case 4 /* DnsClass.HS */:
602
790
  classStr = 'HS';
603
791
  break;
604
- case 255:
792
+ case 255 /* DnsClass.ANY */:
605
793
  classStr = 'ANY';
606
794
  break;
607
795
  default:
@@ -609,21 +797,28 @@ export class Mdns extends Multicast {
609
797
  }
610
798
  return isFlush ? `${classStr}|FLUSH` : classStr;
611
799
  }
800
+ /**
801
+ * Converts a DNS question class to a human-readable string.
802
+ * Adds support for mDNS QU (unicast-response) bit.
803
+ *
804
+ * @param {number} cls - The numeric question class.
805
+ * @returns {string} The string representation, e.g. "IN|QU"
806
+ */
612
807
  dnsQuestionClassToString(cls) {
613
- const isQU = !!(cls & 32768);
808
+ const isQU = !!(cls & 32768 /* DnsClassFlag.QU */);
614
809
  const baseClass = cls & 0x7fff;
615
810
  let classStr;
616
811
  switch (baseClass) {
617
- case 1:
812
+ case 1 /* DnsClass.IN */:
618
813
  classStr = 'IN';
619
814
  break;
620
- case 3:
815
+ case 3 /* DnsClass.CH */:
621
816
  classStr = 'CH';
622
817
  break;
623
- case 4:
818
+ case 4 /* DnsClass.HS */:
624
819
  classStr = 'HS';
625
820
  break;
626
- case 255:
821
+ case 255 /* DnsClass.ANY */:
627
822
  classStr = 'ANY';
628
823
  break;
629
824
  default:
@@ -631,25 +826,37 @@ export class Mdns extends Multicast {
631
826
  }
632
827
  return isQU ? `${classStr}|QU` : classStr;
633
828
  }
634
- logMdnsMessage(msg) {
635
- 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}`);
829
+ /**
830
+ * Logs the decoded mDNS message header.
831
+ *
832
+ * @param {MdnsMessage} msg - The mDNS message header object.
833
+ * @param {AnsiLogger} [log] - The logger to use (defaults to this.log).
834
+ * @param {string} [text] - Optional additional text to include in the log.
835
+ */
836
+ logMdnsMessage(msg, log = this.log, text = 'Decoded mDNS message') {
837
+ log.info(`${text}: 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}`);
636
838
  msg.questions?.forEach((question) => {
637
- this.log.info(`Question: ${CYAN}${question.name}${nf} type ${idn}${this.dnsTypeToString(question.type)}${rs}${nf} class ${CYAN}${this.dnsQuestionClassToString(question.class)}${nf}`);
839
+ log.info(`Question: ${CYAN}${question.name}${nf} type ${idn}${this.dnsTypeToString(question.type)}${rs}${nf} class ${CYAN}${this.dnsQuestionClassToString(question.class)}${nf}`);
638
840
  });
639
841
  msg.answers?.forEach((answer) => {
640
- this.log.info(`Answer: ${CYAN}${answer.name}${nf} type ${idn}${this.dnsTypeToString(answer.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(answer.class)}${nf} ttl ${CYAN}${answer.ttl}${nf} data ${CYAN}${answer.data}${nf}`);
842
+ log.info(`Answer: ${CYAN}${answer.name}${nf} type ${idn}${this.dnsTypeToString(answer.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(answer.class)}${nf} ttl ${CYAN}${answer.ttl}${nf} data ${CYAN}${answer.data}${nf}`);
641
843
  });
642
844
  msg.authorities?.forEach((authority) => {
643
- this.log.info(`Authority: ${CYAN}${authority.name}${nf} type ${idn}${this.dnsTypeToString(authority.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(authority.class)}${nf} ttl ${CYAN}${authority.ttl}${nf} data ${CYAN}${authority.data}${nf}`);
845
+ log.info(`Authority: ${CYAN}${authority.name}${nf} type ${idn}${this.dnsTypeToString(authority.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(authority.class)}${nf} ttl ${CYAN}${authority.ttl}${nf} data ${CYAN}${authority.data}${nf}`);
644
846
  });
645
847
  msg.additionals?.forEach((additional) => {
646
- this.log.info(`Additional: ${CYAN}${additional.name}${nf} type ${idn}${this.dnsTypeToString(additional.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(additional.class)}${nf} ttl ${CYAN}${additional.ttl}${nf} data ${CYAN}${additional.data}${nf}`);
848
+ log.info(`Additional: ${CYAN}${additional.name}${nf} type ${idn}${this.dnsTypeToString(additional.type)}${rs}${nf} class ${CYAN}${this.dnsResponseClassToString(additional.class)}${nf} ttl ${CYAN}${additional.ttl}${nf} data ${CYAN}${additional.data}${nf}`);
647
849
  });
648
- this.log.info(`---\n`);
850
+ log.info(`---\n`);
649
851
  }
852
+ /**
853
+ * Logs the discovered devices from the mDNS queries and responses.
854
+ */
650
855
  logDevices() {
651
856
  this.log.info(`Discovered query devices: ${MAGENTA}${this.deviceQueries.size}${nf}`);
857
+ // Collect devices into an array
652
858
  const deviceQueryArray = Array.from(this.deviceQueries.entries());
859
+ // Sort the array by numeric value of the IP address
653
860
  deviceQueryArray.sort(([addressA], [addressB]) => {
654
861
  const partsA = addressA.split('.').map(Number);
655
862
  const partsB = addressB.split('.').map(Number);
@@ -658,13 +865,17 @@ export class Mdns extends Multicast {
658
865
  if (diff !== 0)
659
866
  return diff;
660
867
  }
868
+ // istanbul ignore next
661
869
  return 0;
662
870
  });
871
+ // Log the sorted devices
663
872
  deviceQueryArray.forEach(([rinfo, response]) => {
664
873
  this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf}`);
665
874
  });
666
875
  this.log.info(`Discovered response devices: ${MAGENTA}${this.deviceResponses.size}${nf}`);
876
+ // Collect devices into an array
667
877
  const deviceResponseArray = Array.from(this.deviceResponses.entries());
878
+ // Sort the array by numeric value of the IP address
668
879
  deviceResponseArray.sort(([addressA], [addressB]) => {
669
880
  const partsA = addressA.split(/[:.]/).map((part) => parseInt(part, 16));
670
881
  const partsB = addressB.split(/[:.]/).map((part) => parseInt(part, 16));
@@ -673,10 +884,13 @@ export class Mdns extends Multicast {
673
884
  if (diff !== 0)
674
885
  return diff;
675
886
  }
887
+ // istanbul ignore next
676
888
  return 0;
677
889
  });
890
+ // Log the sorted devices
678
891
  deviceResponseArray.forEach(([rinfo, response]) => {
679
892
  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}`);
680
893
  });
681
894
  }
682
895
  }
896
+ //# sourceMappingURL=mdns.js.map