@homebridge-plugins/homebridge-ewelink 12.3.3

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 (113) hide show
  1. package/CHANGELOG.md +1363 -0
  2. package/LICENSE +21 -0
  3. package/README.md +68 -0
  4. package/config.schema.json +1757 -0
  5. package/eslint.config.js +15 -0
  6. package/lib/connection/api.js +508 -0
  7. package/lib/connection/http.js +304 -0
  8. package/lib/connection/lan.js +318 -0
  9. package/lib/connection/ws.js +414 -0
  10. package/lib/device/curtain.js +324 -0
  11. package/lib/device/diffuser.js +473 -0
  12. package/lib/device/fan.js +349 -0
  13. package/lib/device/group.js +106 -0
  14. package/lib/device/humidifier.js +199 -0
  15. package/lib/device/index.js +61 -0
  16. package/lib/device/light-cct.js +333 -0
  17. package/lib/device/light-dimmer.js +257 -0
  18. package/lib/device/light-rgb-cct.js +809 -0
  19. package/lib/device/light-rgb.js +272 -0
  20. package/lib/device/motor.js +363 -0
  21. package/lib/device/outlet-multi.js +417 -0
  22. package/lib/device/outlet-single-inched.js +409 -0
  23. package/lib/device/outlet-single.js +384 -0
  24. package/lib/device/panel.js +382 -0
  25. package/lib/device/rf-bridge.js +321 -0
  26. package/lib/device/rf-button.js +125 -0
  27. package/lib/device/rf-sensor.js +173 -0
  28. package/lib/device/sensor-ambient.js +311 -0
  29. package/lib/device/sensor-contact.js +140 -0
  30. package/lib/device/sensor-temp-humi.js +182 -0
  31. package/lib/device/simulation/blind.js +253 -0
  32. package/lib/device/simulation/cooler.js +312 -0
  33. package/lib/device/simulation/door.js +253 -0
  34. package/lib/device/simulation/doorbell.js +190 -0
  35. package/lib/device/simulation/garage-eachen.js +235 -0
  36. package/lib/device/simulation/garage-four.js +176 -0
  37. package/lib/device/simulation/garage-od-switch.js +36 -0
  38. package/lib/device/simulation/garage-one.js +395 -0
  39. package/lib/device/simulation/garage-two.js +394 -0
  40. package/lib/device/simulation/gate-one.js +327 -0
  41. package/lib/device/simulation/heater.js +389 -0
  42. package/lib/device/simulation/index.js +75 -0
  43. package/lib/device/simulation/light-fan.js +258 -0
  44. package/lib/device/simulation/lock-eachen.js +163 -0
  45. package/lib/device/simulation/lock-one.js +366 -0
  46. package/lib/device/simulation/p-button.js +223 -0
  47. package/lib/device/simulation/purifier.js +289 -0
  48. package/lib/device/simulation/rf-blind.js +192 -0
  49. package/lib/device/simulation/rf-door.js +180 -0
  50. package/lib/device/simulation/rf-window.js +180 -0
  51. package/lib/device/simulation/sensor-hidden.js +105 -0
  52. package/lib/device/simulation/sensor-leak.js +123 -0
  53. package/lib/device/simulation/sensor-visible.js +231 -0
  54. package/lib/device/simulation/sensor.js +300 -0
  55. package/lib/device/simulation/switch-valve.js +351 -0
  56. package/lib/device/simulation/tap-one.js +283 -0
  57. package/lib/device/simulation/tap-two.js +266 -0
  58. package/lib/device/simulation/th-cooler.js +443 -0
  59. package/lib/device/simulation/th-dehumidifier.js +424 -0
  60. package/lib/device/simulation/th-heater.js +449 -0
  61. package/lib/device/simulation/th-humidifier.js +424 -0
  62. package/lib/device/simulation/th-thermostat.js +611 -0
  63. package/lib/device/simulation/tv.js +252 -0
  64. package/lib/device/simulation/valve-four.js +232 -0
  65. package/lib/device/simulation/valve-one.js +345 -0
  66. package/lib/device/simulation/valve-two.js +340 -0
  67. package/lib/device/simulation/window.js +253 -0
  68. package/lib/device/switch-man.js +106 -0
  69. package/lib/device/switch-mate.js +82 -0
  70. package/lib/device/switch-multi.js +411 -0
  71. package/lib/device/switch-single-inched.js +332 -0
  72. package/lib/device/switch-single.js +307 -0
  73. package/lib/device/template.js +43 -0
  74. package/lib/device/thermostat.js +286 -0
  75. package/lib/device/zigbee/index.js +27 -0
  76. package/lib/device/zigbee/light-cct.js +263 -0
  77. package/lib/device/zigbee/light-dimmer.js +148 -0
  78. package/lib/device/zigbee/light-rgb-cct.js +400 -0
  79. package/lib/device/zigbee/motor.js +301 -0
  80. package/lib/device/zigbee/sensor-ambient.js +177 -0
  81. package/lib/device/zigbee/sensor-contact.js +137 -0
  82. package/lib/device/zigbee/sensor-leak.js +119 -0
  83. package/lib/device/zigbee/sensor-motion.js +119 -0
  84. package/lib/device/zigbee/sensor-occupancy.js +119 -0
  85. package/lib/device/zigbee/sensor-smoke.js +96 -0
  86. package/lib/device/zigbee/switch-stateless.js +104 -0
  87. package/lib/device/zigbee/thermostat.js +323 -0
  88. package/lib/fakegato/LICENSE +21 -0
  89. package/lib/fakegato/fakegato-history.js +813 -0
  90. package/lib/fakegato/fakegato-storage.js +108 -0
  91. package/lib/fakegato/fakegato-timer.js +125 -0
  92. package/lib/fakegato/uuid.js +27 -0
  93. package/lib/homebridge-ui/public/index.html +365 -0
  94. package/lib/homebridge-ui/server.js +46 -0
  95. package/lib/index.js +7 -0
  96. package/lib/node-dns-sd/LICENSE +21 -0
  97. package/lib/node-dns-sd/README.md +613 -0
  98. package/lib/node-dns-sd/lib/dns-sd-classes.json +6 -0
  99. package/lib/node-dns-sd/lib/dns-sd-composer.js +83 -0
  100. package/lib/node-dns-sd/lib/dns-sd-parser.js +344 -0
  101. package/lib/node-dns-sd/lib/dns-sd-types.json +52 -0
  102. package/lib/node-dns-sd/lib/dns-sd.js +580 -0
  103. package/lib/platform.js +2156 -0
  104. package/lib/utils/colour.js +552 -0
  105. package/lib/utils/constants.js +589 -0
  106. package/lib/utils/custom-chars.js +33 -0
  107. package/lib/utils/eve-chars.js +130 -0
  108. package/lib/utils/functions.js +42 -0
  109. package/lib/utils/lang-en.js +160 -0
  110. package/lib/utils/lang-fr.js +163 -0
  111. package/lib/utils/lang-th.js +160 -0
  112. package/lib/utils/lang.js +5 -0
  113. package/package.json +75 -0
@@ -0,0 +1,580 @@
1
+ /* ------------------------------------------------------------------
2
+ * node-dns-sd - dns-sd.js
3
+ *
4
+ * Copyright (c) 2018 - 2020, Futomi Hatano, All rights reserved.
5
+ * Released under the MIT license
6
+ * Date: 2020-09-30
7
+ * ---------------------------------------------------------------- */
8
+
9
+ import mDgram from 'node:dgram'
10
+ import mOs from 'node:os'
11
+ import mDnsSdComposer from './dns-sd-composer.js'
12
+ import mDnsSdParser from './dns-sd-parser.js'
13
+
14
+ /* ------------------------------------------------------------------
15
+ * Constructor: DnsSd()
16
+ * ---------------------------------------------------------------- */
17
+ const DnsSd = function () {
18
+ // Public
19
+ this.ondata = () => { }
20
+
21
+ // Private
22
+ this._MULTICAST_ADDR = '224.0.0.251'
23
+ this._UDP_PORT = 5353
24
+ this._DISCOVERY_WAIT_DEFAULT = 3 // sec
25
+
26
+ this._udp = null
27
+ this._source_address_list = []
28
+ this._discovered_devices = {}
29
+ this._is_discovering = false
30
+ this._is_monitoring = false
31
+ this._is_listening = false
32
+ this._onreceive = () => { }
33
+ }
34
+
35
+ /* ------------------------------------------------------------------
36
+ * Method: discover(params)
37
+ * - params | Object | Required |
38
+ * - name | String or | Required | Servcie name.(e.g., "_googlecast._tcp.local")
39
+ * | Array | |
40
+ * - type | String | Optional | Query Type (e.g., "PTR"). The default value is "*".
41
+ * - key | String | Optional | "address" (default) or "fqdn".
42
+ * | | | - "address": IP address based discovery
43
+ * | | | - "fqdn": FQDN (service) based discovery
44
+ * - wait | Integer | Optional | Duration of monitoring. The default value is 3 (sec).
45
+ * - quick | Boolean | Optional | If `true`, this method returns immediately after
46
+ * | | | a device was found ignoring the value of the `wait`.
47
+ * | | | The default value is `false`.
48
+ * - filter | String or | Optional | If specified as a string, this method discovers only
49
+ * | Function | | devices which the string is found in the `fqdn`,
50
+ * | | | `address`, `modelName` or `familyName`.
51
+ * | | | If specified as a function, this method discovers
52
+ * | | | only devices for which the function returns `true`.
53
+ * ---------------------------------------------------------------- */
54
+ DnsSd.prototype.discover = function (params) {
55
+ const promise = new Promise((resolve, reject) => {
56
+ if (this._is_discovering === true) {
57
+ reject(new Error('The discovery process is running.'))
58
+ return
59
+ }
60
+ // Check the parameters
61
+ const res = this._checkDiscoveryParameters(params)
62
+ if (res.error) {
63
+ reject(res.error)
64
+ return
65
+ }
66
+ const device_list = []
67
+ this._startListening().then(() => this._startDiscovery(res.params)).then(() => {
68
+ for (const addr in this._discovered_devices) {
69
+ const device = this._discovered_devices[addr]
70
+ device_list.push(device)
71
+ }
72
+ this._stopDiscovery().then(() => {
73
+ resolve(device_list)
74
+ })
75
+ }).catch((error) => {
76
+ this._stopDiscovery().then(() => {
77
+ reject(error)
78
+ })
79
+ })
80
+ })
81
+ return promise
82
+ }
83
+
84
+ DnsSd.prototype._createDeviceObject = function (packet) {
85
+ const o = {}
86
+
87
+ const trecs = {};
88
+ ['answers', 'authorities', 'additionals'].forEach((k) => {
89
+ packet[k].forEach((r) => {
90
+ const { type } = r
91
+ if (!trecs[type]) {
92
+ trecs[type] = []
93
+ }
94
+ trecs[type].push(r)
95
+ })
96
+ })
97
+
98
+ o.address = null
99
+ if (trecs.A) {
100
+ o.address = trecs.A[0].rdata
101
+ }
102
+ if (!o.address) {
103
+ o.address = packet.address
104
+ }
105
+
106
+ o.fqdn = null
107
+ if (trecs.PTR) {
108
+ const rec = trecs.PTR[0]
109
+ o.fqdn = rec.rdata
110
+ }
111
+
112
+ o.modelName = null
113
+ o.familyName = null
114
+ if (trecs.TXT && trecs.TXT[0] && trecs.TXT[0].rdata) {
115
+ const r = trecs.TXT[0]
116
+ const d = r.rdata || {}
117
+ const name = r.name || ''
118
+ if (/Apple TV/.test(name)) {
119
+ o.modelName = 'Apple TV'
120
+ if (trecs.TXT) {
121
+ for (let i = 0; i < trecs.TXT.length; i += 1) {
122
+ const r = trecs.TXT[i]
123
+ if ((/_device-info/).test(r.name) && r.rdata && r.rdata.model) {
124
+ o.modelName = `Apple TV ${r.rdata.model}`
125
+ break
126
+ }
127
+ }
128
+ }
129
+ } else if (/_googlecast/.test(name)) {
130
+ o.modelName = d.md || null
131
+ o.familyName = d.fn || null
132
+ } else if (/Philips hue/.test(name)) {
133
+ o.modelName = 'Philips hue'
134
+ if (d.md) {
135
+ o.modelName += ` ${d.md}`
136
+ }
137
+ } else if (/Canon/.test(name)) {
138
+ o.modelName = d.ty || null
139
+ }
140
+ }
141
+ if (!o.modelName) {
142
+ if (trecs.A && trecs.A[0]) {
143
+ const r = trecs.A[0]
144
+ const { name } = r
145
+ if (/Apple-TV/.test(name)) {
146
+ o.modelName = 'Apple TV'
147
+ } else if (/iPad/.test(name)) {
148
+ o.modelName = 'iPad'
149
+ }
150
+ }
151
+ }
152
+
153
+ if (!o.modelName) {
154
+ if (o.fqdn) {
155
+ const hostname = (o.fqdn.split('.')).shift()
156
+ if (hostname && / /.test(hostname)) {
157
+ o.modelName = hostname
158
+ }
159
+ }
160
+ }
161
+
162
+ o.service = null
163
+ if (trecs.SRV) {
164
+ const rec = trecs.SRV[0]
165
+ const name_parts = rec.name.split('.')
166
+ name_parts.reverse()
167
+ o.service = {
168
+ port: rec.rdata.port,
169
+ protocol: name_parts[1].replace(/^_/, ''),
170
+ type: name_parts[2].replace(/^_/, ''),
171
+ }
172
+ }
173
+
174
+ o.packet = packet
175
+ return o
176
+ }
177
+
178
+ DnsSd.prototype._checkDiscoveryParameters = function (params) {
179
+ const p = {}
180
+ if (params) {
181
+ if (typeof (params) !== 'object') {
182
+ return { error: new Error('The argument `params` is invalid.') }
183
+ }
184
+ } else {
185
+ return { error: new Error('The argument `params` is required.') }
186
+ }
187
+
188
+ if ('name' in params) {
189
+ const v = params.name
190
+ if (typeof (v) === 'string') {
191
+ if (v === '') {
192
+ return { error: new Error('The `name` must be an non-empty string.') }
193
+ }
194
+ p.name = [v]
195
+ } else if (Array.isArray(v)) {
196
+ if (v.length === 0) {
197
+ return { error: new Error('The `name` must be a non-empty array.') }
198
+ }
199
+ if (v.length > 255) {
200
+ return { error: new Error('The `name` can include up to 255 elements.') }
201
+ }
202
+ let err = null
203
+ const list = []
204
+ for (let i = 0; i < v.length; i += 1) {
205
+ if (typeof (v[i]) === 'string' && v[i] !== '') {
206
+ list.push(v[i])
207
+ } else {
208
+ err = new Error('The `name` must be an Array object including non-empty strings.')
209
+ break
210
+ }
211
+ }
212
+ if (err) {
213
+ return { error: err }
214
+ }
215
+ p.name = list
216
+ } else {
217
+ return { error: new Error('The `name` must be a string or an Array object.') }
218
+ }
219
+ } else {
220
+ return { error: new Error('The `name` is required.') }
221
+ }
222
+
223
+ if ('type' in params) {
224
+ const v = params.type
225
+ if (typeof (v) !== 'string' || !(/^[a-z0-9]{1,10}$/i.test(v) || v === '*')) {
226
+ return { error: new Error('The `type` is invalid.') }
227
+ }
228
+ p.type = v.toUpperCase()
229
+ }
230
+
231
+ if ('key' in params) {
232
+ let v = params.key
233
+ if (typeof (v) !== 'string' || !/^(?:address|fqdn)$/.test(v)) {
234
+ return { error: new Error('The `key` is invalid.') }
235
+ }
236
+ if (!v) {
237
+ v = 'address'
238
+ }
239
+ p.key = v
240
+ }
241
+
242
+ if ('wait' in params) {
243
+ const v = params.wait
244
+ if (typeof (v) !== 'number' || v <= 0 || v % 1 !== 0) {
245
+ return { error: new Error('The `wait` is invalid.') }
246
+ }
247
+ p.wait = v
248
+ }
249
+
250
+ if ('quick' in params) {
251
+ const v = params.quick
252
+ if (typeof (v) !== 'boolean') {
253
+ return { error: new Error('The `quick` must be a boolean.') }
254
+ }
255
+ p.quick = v
256
+ } else {
257
+ p.quick = false
258
+ }
259
+
260
+ if ('filter' in params) {
261
+ const v = params.filter
262
+ if (typeof (v) !== 'string' && typeof (v) !== 'function') {
263
+ return { error: new Error('The `filter` must be a string.') }
264
+ }
265
+ if (v) {
266
+ p.filter = v
267
+ }
268
+ }
269
+
270
+ return { params: p }
271
+ }
272
+
273
+ DnsSd.prototype._startDiscovery = function (params) {
274
+ const promise = new Promise((resolve, reject) => {
275
+ this._discovered_devices = {}
276
+ this._is_discovering = true
277
+ const wait = (params && params.wait) ? params.wait : this._DISCOVERY_WAIT_DEFAULT
278
+ // Create a request packet
279
+ const buf = mDnsSdComposer.compose({
280
+ name: params.name,
281
+ type: params.type,
282
+ })
283
+
284
+ // Timer
285
+ let send_timer = null
286
+ let wait_timer = null
287
+
288
+ const clearTimer = () => {
289
+ if (send_timer) {
290
+ clearTimeout(send_timer)
291
+ send_timer = null
292
+ }
293
+ if (wait_timer) {
294
+ clearTimeout(wait_timer)
295
+ wait_timer = null
296
+ }
297
+ this._onreceive = () => { }
298
+ }
299
+
300
+ wait_timer = setTimeout(() => {
301
+ clearTimer()
302
+ resolve()
303
+ }, wait * 1000)
304
+
305
+ const { quick } = params
306
+ let { key } = params
307
+ if (!key) {
308
+ key = 'address'
309
+ }
310
+ this._onreceive = (addr, packet) => {
311
+ if (!this._isTargettedDevice(packet, params.name)) {
312
+ return
313
+ }
314
+ const device = this._createDeviceObject(packet)
315
+ if (!this._evaluateDeviceFilter(device, params.filter)) {
316
+ return
317
+ }
318
+ if (key === 'fqdn') {
319
+ const { fqdn } = device
320
+ this._discovered_devices[fqdn] = device
321
+ } else {
322
+ this._discovered_devices[addr] = device
323
+ }
324
+ if (quick) {
325
+ clearTimer()
326
+ resolve()
327
+ }
328
+ }
329
+
330
+ // Send a packet
331
+ let send_num = 0
332
+ const sendQueryPacket = () => {
333
+ this._udp.send(buf, 0, buf.length, this._UDP_PORT, this._MULTICAST_ADDR, (error) => {
334
+ if (error) {
335
+ clearTimer()
336
+ reject(error)
337
+ } else {
338
+ send_num++
339
+ if (send_num < 3) {
340
+ send_timer = setTimeout(() => {
341
+ sendQueryPacket()
342
+ }, 1000)
343
+ } else {
344
+ send_timer = null
345
+ }
346
+ }
347
+ })
348
+ }
349
+ sendQueryPacket()
350
+ })
351
+ return promise
352
+ }
353
+
354
+ DnsSd.prototype._isTargettedDevice = function (packet, name_list) {
355
+ let hit = false
356
+ packet.answers.forEach((ans) => {
357
+ const { name } = ans
358
+ if (name && name_list.includes(name)) {
359
+ hit = true
360
+ }
361
+ })
362
+ return hit
363
+ }
364
+
365
+ DnsSd.prototype._evaluateDeviceFilter = function (device, filter) {
366
+ if (filter) {
367
+ const filter_type = typeof (filter)
368
+ if (filter_type === 'string') {
369
+ return this._evaluateDeviceFilterString(device, filter)
370
+ }
371
+ if (filter_type === 'function') {
372
+ return this._evaluateDeviceFilterFunction(device, filter)
373
+ }
374
+ return false
375
+ }
376
+ return true
377
+ }
378
+
379
+ DnsSd.prototype._evaluateDeviceFilterString = function (device, filter) {
380
+ if (device.fqdn && device.fqdn.includes(filter)) {
381
+ return true
382
+ }
383
+ if (device.address && device.address.includes(filter)) {
384
+ return true
385
+ }
386
+ if (device.modelName && device.modelName.includes(filter)) {
387
+ return true
388
+ }
389
+ if (device.familyName && device.familyName.includes(filter)) {
390
+ return true
391
+ }
392
+ return false
393
+ }
394
+
395
+ DnsSd.prototype._evaluateDeviceFilterFunction = function (device, filter) {
396
+ let res = false
397
+ try {
398
+ res = filter(device)
399
+ } catch (e) { }
400
+ res = !!res
401
+ return res
402
+ }
403
+
404
+ DnsSd.prototype._stopDiscovery = function () {
405
+ const promise = new Promise((resolve) => {
406
+ this._discovered_devices = {}
407
+ this._is_discovering = false
408
+ this._stopListening().then(() => {
409
+ resolve()
410
+ }).catch(() => {
411
+ resolve()
412
+ })
413
+ })
414
+ return promise
415
+ }
416
+
417
+ DnsSd.prototype._addMembership = function () {
418
+ this._source_address_list.forEach((netif) => {
419
+ try {
420
+ this._udp.addMembership(this._MULTICAST_ADDR, netif)
421
+ } catch (e) {
422
+ // eslint-disable-next-line no-console
423
+ console.log(`Catching error on address already in use: ${JSON.stringify(e)}`)
424
+ }
425
+ })
426
+ }
427
+
428
+ DnsSd.prototype._dropMembership = function () {
429
+ this._source_address_list.forEach((netif) => {
430
+ try {
431
+ this._udp.dropMembership(this._MULTICAST_ADDR, netif)
432
+ } catch (e) {
433
+ // eslint-disable-next-line no-console
434
+ console.log(`Catching error on dropMembership: ${JSON.stringify(e)}`)
435
+ }
436
+ })
437
+ }
438
+
439
+ DnsSd.prototype._getSourceAddressList = function () {
440
+ const list = []
441
+ const netifs = mOs.networkInterfaces()
442
+ for (const dev in netifs) {
443
+ netifs[dev].forEach((info) => {
444
+ if (info.family === 'IPv4' && info.internal === false) {
445
+ const m = info.address.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/)
446
+ if (m) {
447
+ list.push(m[1])
448
+ }
449
+ }
450
+ })
451
+ }
452
+ return list
453
+ }
454
+
455
+ /* ------------------------------------------------------------------
456
+ * Method: startMonitoring()
457
+ * ---------------------------------------------------------------- */
458
+ DnsSd.prototype.startMonitoring = function () {
459
+ const promise = new Promise((resolve, reject) => {
460
+ if (this._is_monitoring === true) {
461
+ resolve()
462
+ return
463
+ }
464
+ this._startListening().then(() => {
465
+ this._is_monitoring = true
466
+ resolve()
467
+ }).catch((error) => {
468
+ this._is_monitoring = false
469
+ this._stopListening().then(() => {
470
+ reject(error)
471
+ })
472
+ })
473
+ })
474
+ return promise
475
+ }
476
+
477
+ /* ------------------------------------------------------------------
478
+ * Method: stopMonitoring()
479
+ * ---------------------------------------------------------------- */
480
+ DnsSd.prototype.stopMonitoring = function () {
481
+ return new Promise((resolve) => {
482
+ this._is_monitoring = false
483
+ this._stopListening().then(() => {
484
+ resolve()
485
+ }).catch(() => {
486
+ resolve()
487
+ })
488
+ })
489
+ }
490
+
491
+ DnsSd.prototype._startListening = function () {
492
+ const promise = new Promise((resolve, reject) => {
493
+ if (this._is_listening === true) {
494
+ resolve()
495
+ return
496
+ }
497
+ // Get the source IP address
498
+ this._source_address_list = this._getSourceAddressList()
499
+ // Set up a UDP tranceiver
500
+ this._udp = mDgram.createSocket({
501
+ type: 'udp4',
502
+ reuseAddr: true,
503
+ })
504
+ this._udp.once('error', (error) => {
505
+ this._is_listening = false
506
+ reject(error)
507
+ })
508
+ this._udp.once('listening', () => {
509
+ this._udp.setMulticastLoopback(false)
510
+ this._addMembership()
511
+ this._is_listening = true
512
+ resolve()
513
+ })
514
+ this._udp.on('message', (buf, rinfo) => {
515
+ this._receivePacket(buf, rinfo)
516
+ })
517
+ this._udp.bind({ port: this._UDP_PORT }, () => {
518
+ this._udp.removeAllListeners('error')
519
+ })
520
+ })
521
+ return promise
522
+ }
523
+
524
+ DnsSd.prototype._stopListening = function () {
525
+ return new Promise((resolve) => {
526
+ this._dropMembership()
527
+ if (this._is_discovering || this._is_monitoring) {
528
+ resolve()
529
+ } else {
530
+ const cleanObj = () => {
531
+ if (this._udp) {
532
+ this._udp.unref()
533
+ this._udp = null
534
+ }
535
+ this._is_listening = false
536
+ resolve()
537
+ }
538
+ if (this._udp) {
539
+ this._udp.removeAllListeners('message')
540
+ this._udp.removeAllListeners('error')
541
+ this._udp.removeAllListeners('listening')
542
+ this._udp.close(() => {
543
+ cleanObj()
544
+ })
545
+ } else {
546
+ cleanObj()
547
+ }
548
+ }
549
+ })
550
+ }
551
+
552
+ DnsSd.prototype._receivePacket = function (buf, rinfo) {
553
+ const p = mDnsSdParser.parse(buf)
554
+ if (!p) {
555
+ return
556
+ }
557
+ p.address = rinfo.address
558
+ if (this._is_discovering) {
559
+ if (this._isAnswerPacket(p, rinfo.address)) {
560
+ this._onreceive(rinfo.address, p)
561
+ }
562
+ }
563
+ if (this._is_monitoring) {
564
+ if (typeof (this.ondata) === 'function') {
565
+ this.ondata(p)
566
+ }
567
+ }
568
+ }
569
+
570
+ DnsSd.prototype._isAnswerPacket = function (p, address) {
571
+ if (this._source_address_list.includes(address)) {
572
+ return false
573
+ }
574
+ if (!(p.header.qr === 1 && p.header.op === 0)) {
575
+ return false
576
+ }
577
+ return true
578
+ }
579
+
580
+ export default new DnsSd()