Skip to content

Commit 7de5d5c

Browse files
committed
feat: implement unicast DNS-SD
1 parent 0badb0b commit 7de5d5c

File tree

2 files changed

+83
-8
lines changed

2 files changed

+83
-8
lines changed

lib/src/core/implementation/thing_discovery.dart

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import "dart:async";
88

9+
import "package:basic_utils/basic_utils.dart";
910
import "package:coap/coap.dart";
1011
import "package:collection/collection.dart";
1112
import "package:multicast_dns/multicast_dns.dart";
@@ -222,7 +223,7 @@ class ThingDiscovery extends Stream<ThingDescription>
222223
if (dnsName.endsWith("local")) {
223224
yield* _discoverUsingMdnssd(dnsName);
224225
} else {
225-
throw UnimplementedError("Only mDNS-SD is currently supported!");
226+
yield* _discoverUsingDnsSd(dnsName);
226227
}
227228
}
228229

@@ -242,24 +243,97 @@ class ThingDiscovery extends Stream<ThingDescription>
242243
);
243244
}
244245

246+
Map<String, String> _parseTxtRecords(String txtRecords) {
247+
final recordsList = txtRecords
248+
.split("\n")
249+
.map((property) => property.split("="))
250+
.where((list) => list.length > 1)
251+
.map((list) => MapEntry(list[0], list[1]));
252+
253+
return Map.fromEntries(recordsList);
254+
}
255+
245256
Future<Map<String, String>?> _lookupTxtRecords(
246257
MDnsClient client,
247258
String domainName,
248259
) async {
249260
final txtRecords = await client
250261
.lookup<TxtResourceRecord>(ResourceRecordQuery.text(domainName))
251262
.toList();
252-
final recordsList = txtRecords.firstOrNull?.text
253-
.split("\n")
254-
.map((property) => property.split("="))
255-
.where((list) => list.length > 1)
256-
.map((list) => MapEntry(list[0], list[1]));
257263

258-
if (recordsList == null) {
264+
final firstTxtRecord = txtRecords.firstOrNull?.text;
265+
266+
if (firstTxtRecord == null) {
259267
return null;
260268
}
261269

262-
return Map.fromEntries(recordsList);
270+
return _parseTxtRecords(firstTxtRecord);
271+
}
272+
273+
Stream<ThingDescription> _discoverUsingDnsSd(String name) async* {
274+
// TODO: Refactor
275+
final ptrRecords = await DnsUtils.lookupRecord(name, RRecordType.PTR);
276+
final defaultScheme = _isUdpDiscovery(name) ? "coap" : "http";
277+
final discoveredUris = <Uri>{};
278+
const defaultType = "Thing";
279+
280+
for (final ptrRecord in ptrRecords ?? <RRecord>[]) {
281+
final srvRecords =
282+
await DnsUtils.lookupRecord(ptrRecord.name, RRecordType.SRV);
283+
284+
for (final srvRecord in srvRecords ?? <RRecord>[]) {
285+
final srvRecordEntries = srvRecord.data.split(" ");
286+
287+
final validSrvRecord = srvRecordEntries.length == 7;
288+
289+
if (!validSrvRecord) {
290+
continue;
291+
}
292+
293+
final target = srvRecordEntries.last;
294+
final port =
295+
int.tryParse(srvRecordEntries[srvRecordEntries.length - 2]);
296+
297+
if (port == null) {
298+
continue;
299+
}
300+
301+
final txtRecords =
302+
await DnsUtils.lookupRecord(srvRecord.name, RRecordType.TXT) ?? [];
303+
304+
final txtRecord = txtRecords.firstOrNull;
305+
306+
if (txtRecord == null) {
307+
continue;
308+
}
309+
310+
final parsedTxtRecord = _parseTxtRecords(txtRecord.data);
311+
312+
final uri = Uri(
313+
host: target,
314+
port: port,
315+
path: parsedTxtRecord["td"],
316+
scheme: parsedTxtRecord["scheme"] ?? defaultScheme,
317+
);
318+
319+
final duplicate = discoveredUris.add(uri);
320+
321+
if (duplicate) {
322+
continue;
323+
}
324+
325+
final type = parsedTxtRecord["type"] ?? defaultType;
326+
327+
print(parsedTxtRecord);
328+
switch (type) {
329+
case "Thing":
330+
yield* _discoverDirectly(uri);
331+
case "Directory":
332+
// TODO(JKRhb): Implement directory discovery.
333+
break;
334+
}
335+
}
336+
}
263337
}
264338

265339
Stream<ThingDescription> _discoverUsingMdnssd(String name) async* {

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dev_dependencies:
1515
test: ^1.24.3
1616

1717
dependencies:
18+
basic_utils: ^5.6.1
1819
cbor: ^6.1.0
1920
coap: ^9.0.0
2021
collection: ^1.17.2

0 commit comments

Comments
 (0)