Skip to content

Commit

Permalink
Merge pull request #340 from freasy/feature/refactor_mdns_response
Browse files Browse the repository at this point in the history
refactoring mdns request parsing
  • Loading branch information
jurgelenas authored May 23, 2022
2 parents 6258532 + d6a364e commit f62c7be
Showing 1 changed file with 88 additions and 76 deletions.
164 changes: 88 additions & 76 deletions src/api/src/services/MulticastDns/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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);
}
}
}
}
}
Expand Down

0 comments on commit f62c7be

Please sign in to comment.