diff --git a/src/api/src/services/MulticastDns/index.ts b/src/api/src/services/MulticastDns/index.ts index a35c55d4e..14db82569 100644 --- a/src/api/src/services/MulticastDns/index.ts +++ b/src/api/src/services/MulticastDns/index.ts @@ -1,6 +1,7 @@ import { Service } from 'typedi'; import * as http from 'http'; import makeMdns, { ResponsePacket } from 'multicast-dns'; +import { SrvAnswer, StringAnswer, TxtAnswer } from 'dns-packet'; import MulticastDnsInformation from '../../models/MulticastDnsInformation'; import { LoggerService } from '../../logger'; import MulticastDnsEventType from '../../models/enum/MulticastDnsEventType'; @@ -118,87 +119,98 @@ export default class MulticastDnsService { private handleMulticastDnsResponse(response: ResponsePacket) { const items = [...response.answers, ...response.additionals]; - // check if any of the answers on the response have a name that starts with - // 'elrs_', which indicates that it is an elers device - const isElrs = !!items.find((item: any) => item.name.startsWith('elrs_')); - - if (isElrs) { - const txtResponse: any = items.find((answer) => answer.type === 'TXT'); - - const aResponse: any = items.find((answer) => answer.type === 'A'); - - const srvResponse: any = items.find((answer) => answer.type === 'SRV'); + const txtResponse: TxtAnswer = items.find( + (answer) => answer.type === 'TXT' + ) as TxtAnswer; + + if (txtResponse) { + let options: UserDefine[] = []; + let version = ''; + let target = ''; + let type = ''; + let vendor = ''; + let deviceName = ''; + + if (Array.isArray(txtResponse.data)) { + txtResponse.data.forEach((i) => { + if (i instanceof Buffer) { + const dataItem = i.toString('utf-8'); + const delimPos = dataItem.indexOf('='); + const key = dataItem.substring(0, delimPos); + const value = dataItem.substring(delimPos + 1); + + switch (key) { + case 'options': + options = this.parseOptions(value); + break; + case 'version': + version = value; + break; + case 'target': + target = value; + break; + case 'type': + type = value; + break; + case 'vendor': + vendor = value; + break; + case 'device': + deviceName = value; + break; + default: + break; + } + } + }); + } - if (txtResponse && aResponse && srvResponse) { - const dns: string = srvResponse.data?.target; - const port: number = srvResponse.data?.port; - const ip: string = aResponse.data; - const name: string = txtResponse.name?.substring( + if (vendor === 'elrs') { + const name = txtResponse.name?.substring( 0, txtResponse.name.indexOf('.') ); - let options: UserDefine[] = []; - let version = ''; - let target = ''; - let type = ''; - let vendor = ''; - let deviceName = ''; - - if (Array.isArray(txtResponse.data)) { - txtResponse.data.forEach((item: any) => { - if (item instanceof Buffer) { - const dataItem = item.toString('utf-8'); - const delimPos = dataItem.indexOf('='); - const key = dataItem.substring(0, delimPos); - const value = dataItem.substring(delimPos + 1); - - switch (key) { - case 'options': - options = this.parseOptions(value); - break; - case 'version': - version = value; - break; - case 'target': - target = value; - break; - case 'type': - type = value; - break; - case 'vendor': - vendor = value; - break; - case 'device': - deviceName = value; - break; - default: - break; - } - } - }); - } - - const mdnsInformation: MulticastDnsInformation = { - name, - dns, - ip, - options, - version, - target, - type, - vendor, - port, - deviceName, - }; - if (!this.devices[name]) { - this.devices[name] = mdnsInformation; - this.notifications.sendDeviceAdded(mdnsInformation); - } else if ( - JSON.stringify(this.devices[name]) !== JSON.stringify(mdnsInformation) - ) { - this.devices[name] = mdnsInformation; - this.notifications.sendDeviceUpdated(mdnsInformation); + const srvResponse: SrvAnswer = items.find( + (answer) => answer.type === 'SRV' + ) as SrvAnswer; + + if (srvResponse) { + const dns: string = srvResponse.data?.target; + const port: number = srvResponse.data?.port; + + const aResponse: StringAnswer = items.find( + (answer) => + answer.type === 'A' && answer.name === srvResponse.data.target + ) as StringAnswer; + + if (aResponse) { + const ip: string = aResponse.data; + + const mdnsInformation: MulticastDnsInformation = { + name, + dns, + ip, + options, + version, + target, + type, + vendor, + port, + deviceName, + }; + + if (!this.devices[name]) { + this.devices[name] = mdnsInformation; + this.notifications.sendDeviceAdded(mdnsInformation); + } else if ( + JSON.stringify(this.devices[name]) !== + JSON.stringify(mdnsInformation) + ) { + this.devices[name] = mdnsInformation; + this.notifications.sendDeviceUpdated(mdnsInformation); + } + } } } }