LCOV - code coverage report
Current view: top level - lib/src/services/impls - mdns_scanner_service_impl.dart (source / functions) Coverage Total Hit
Test: coverage.lcov Lines: 35.6 % 59 21
Test Date: 2025-08-17 13:02:53 Functions: - 0 0

            Line data    Source code
       1              : import 'package:multicast_dns/multicast_dns.dart';
       2              : import 'package:network_tools/network_tools.dart';
       3              : import 'package:network_tools/src/mdns_scanner/get_srv_list_by_os/srv_list.dart';
       4              : import 'package:network_tools/src/network_tools_utils.dart';
       5              : import 'package:universal_io/io.dart';
       6              : 
       7              : class MdnsScannerServiceImpl extends MdnsScannerService {
       8              :   /// This method searching for all the mdns devices in the network.
       9              :   /// TODO: The implementation is **Lacking!** and will not find all the
      10              :   /// TODO: results that actual exist in the network!, only some of them.
      11              :   /// TODO: This is because missing functionality in dart
      12              :   /// TODO: https://github.com/flutter/flutter/issues/97210
      13              :   /// TODO: In some cases we resolve this missing functionality using
      14              :   /// TODO: specific os tools.
      15              : 
      16            1 :   @override
      17              :   Future<List<ActiveHost>> searchMdnsDevices({
      18              :     bool forceUseOfSavedSrvRecordList = false,
      19              :   }) async {
      20              :     List<String> srvRecordListToSearchIn;
      21              : 
      22              :     if (forceUseOfSavedSrvRecordList) {
      23            0 :       srvRecordListToSearchIn = tcpSrvRecordsList;
      24            0 :       srvRecordListToSearchIn.addAll(udpSrvRecordsList);
      25              :     } else {
      26            1 :       final List<String>? srvRecordsFromOs = await SrvList.getSrvRecordList();
      27              : 
      28            1 :       if (srvRecordsFromOs == null || srvRecordsFromOs.isEmpty) {
      29            1 :         srvRecordListToSearchIn = tcpSrvRecordsList;
      30            2 :         srvRecordListToSearchIn.addAll(udpSrvRecordsList);
      31              :       } else {
      32              :         srvRecordListToSearchIn = srvRecordsFromOs;
      33              :       }
      34              :     }
      35              : 
      36            1 :     final List<Future<List<ActiveHost>>> activeHostListsFuture = [];
      37            2 :     for (final String srvRecord in srvRecordListToSearchIn) {
      38            2 :       activeHostListsFuture.add(findingMdnsWithAddress(srvRecord));
      39              :     }
      40              : 
      41            1 :     final List<ActiveHost> activeHostList = [];
      42              : 
      43              :     for (final Future<List<ActiveHost>> activeHostListFuture
      44            2 :         in activeHostListsFuture) {
      45            1 :       activeHostList.addAll(await activeHostListFuture);
      46              :     }
      47              : 
      48              :     return activeHostList;
      49              :   }
      50              : 
      51            1 :   @override
      52              :   Future<List<ActiveHost>> findingMdnsWithAddress(String serviceType) async {
      53            1 :     final MDnsClient client = MDnsClient(
      54              :       rawDatagramSocketFactory:
      55            1 :           (
      56              :             dynamic host,
      57              :             int port, {
      58              :             bool? reuseAddress,
      59              :             bool? reusePort,
      60              :             int? ttl,
      61              :           }) {
      62            1 :             return RawDatagramSocket.bind(
      63              :               host,
      64              :               port,
      65            2 :               reusePort: !Platform.isWindows && !Platform.isAndroid,
      66              :               ttl: ttl!,
      67              :             );
      68              :           },
      69              :     );
      70              : 
      71            1 :     final List<ActiveHost> listOfActiveHost = [];
      72            1 :     await client.start();
      73              : 
      74            2 :     await for (final PtrResourceRecord ptr in client.lookup<PtrResourceRecord>(
      75            1 :       ResourceRecordQuery.serverPointer(serviceType),
      76            0 :     )) {
      77            0 :       await for (final SrvResourceRecord srv
      78            0 :           in client.lookup<SrvResourceRecord>(
      79            0 :             ResourceRecordQuery.service(ptr.domainName),
      80            0 :           )) {
      81            0 :         await for (final TxtResourceRecord txtRecords
      82            0 :             in client.lookup<TxtResourceRecord>(
      83            0 :               ResourceRecordQuery.text(ptr.domainName),
      84            0 :             )) {
      85            0 :           listOfActiveHost.addAll(
      86            0 :             await findAllActiveHostForSrv(
      87            0 :               addressType: InternetAddress.anyIPv4,
      88              :               client: client,
      89              :               ptr: ptr,
      90              :               srv: srv,
      91              :               txt: txtRecords,
      92              :             ),
      93              :           );
      94            0 :           listOfActiveHost.addAll(
      95            0 :             await findAllActiveHostForSrv(
      96            0 :               addressType: InternetAddress.anyIPv6,
      97              :               client: client,
      98              :               ptr: ptr,
      99              :               srv: srv,
     100              :               txt: txtRecords,
     101              :             ),
     102              :           );
     103              :         }
     104              :       }
     105              :     }
     106            1 :     client.stop();
     107              : 
     108              :     return listOfActiveHost;
     109              :   }
     110              : 
     111            0 :   @override
     112              :   Future<List<ActiveHost>> findAllActiveHostForSrv({
     113              :     required InternetAddress addressType,
     114              :     required MDnsClient client,
     115              :     required PtrResourceRecord ptr,
     116              :     required SrvResourceRecord srv,
     117              :     required TxtResourceRecord txt,
     118              :   }) async {
     119            0 :     final List<ActiveHost> listOfActiveHost = [];
     120              :     try {
     121              :       Stream<IPAddressResourceRecord> iPAddressResourceRecordStream;
     122              : 
     123            0 :       if (addressType == InternetAddress.anyIPv4) {
     124            0 :         iPAddressResourceRecordStream = client.lookup<IPAddressResourceRecord>(
     125            0 :           ResourceRecordQuery.addressIPv4(srv.target),
     126              :         );
     127              :       } else {
     128            0 :         iPAddressResourceRecordStream = client.lookup<IPAddressResourceRecord>(
     129            0 :           ResourceRecordQuery.addressIPv6(srv.target),
     130              :         );
     131              :       }
     132            0 :       await for (final IPAddressResourceRecord ip
     133            0 :           in iPAddressResourceRecordStream) {
     134            0 :         final ActiveHost activeHost = convertSrvToHostName(
     135            0 :           internetAddress: InternetAddress.fromRawAddress(
     136            0 :             ip.address.rawAddress,
     137              :           ),
     138              :           ptr: ptr,
     139              :           srv: srv,
     140              :           txt: txt,
     141              :         );
     142              : 
     143            0 :         listOfActiveHost.add(activeHost);
     144              :       }
     145              :     } catch (e) {
     146            0 :       logger.severe(
     147            0 :         'Error finding ip of mdns record ${ptr.name} srv target ${srv.target}, will add it with ip 0.0.0.0\n$e',
     148              :       );
     149            0 :       final ActiveHost activeHost = convertSrvToHostName(
     150            0 :         internetAddress: InternetAddress('0.0.0.0'),
     151              :         srv: srv,
     152              :         ptr: ptr,
     153              :         txt: txt,
     154              :       );
     155            0 :       listOfActiveHost.add(activeHost);
     156              :     }
     157              :     return listOfActiveHost;
     158              :   }
     159              : 
     160            0 :   @override
     161              :   ActiveHost convertSrvToHostName({
     162              :     required InternetAddress internetAddress,
     163              :     required PtrResourceRecord ptr,
     164              :     required SrvResourceRecord srv,
     165              :     required TxtResourceRecord txt,
     166              :   }) {
     167            0 :     final MdnsInfo mdnsInfo = MdnsInfo(
     168              :       srvResourceRecord: srv,
     169              :       ptrResourceRecord: ptr,
     170              :       txtResourceRecord: txt,
     171              :     );
     172            0 :     return ActiveHost(internetAddress: internetAddress, mdnsInfoVar: mdnsInfo);
     173              :   }
     174              : }
        

Generated by: LCOV version 2.0-1