OLD | NEW |
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 library mdns.src.native_extension_client; | 5 library mdns.src.native_extension_client; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 import 'dart:isolate'; | 9 import 'dart:isolate'; |
10 | 10 |
11 import 'package:mdns/mdns.dart'; | 11 import 'package:mdns/mdns.dart'; |
12 import 'package:mdns/src/lookup_resolver.dart'; | 12 import 'package:mdns/src/lookup_resolver.dart'; |
13 import 'package:mdns/src/native_extension_api.dart' | 13 import 'package:mdns/src/native_extension_api.dart' |
14 deferred as native_extension_api; | 14 deferred as native_extension_api; |
15 import 'package:mdns/src/packet.dart'; | 15 import 'package:mdns/src/packet.dart'; |
| 16 import 'package:mdns/src/constants.dart'; |
16 | 17 |
17 // Requests Ids. This should be aligned with the C code. | 18 // Requests Ids. This should be aligned with the C code. |
18 enum RequestType { | 19 enum RequestType { |
19 echoRequest, // 0 | 20 echoRequest, // 0 |
20 lookupRequest, // 1 | 21 lookupRequest, // 1 |
21 } | 22 } |
22 | 23 |
23 // Implementation of mDNS client using a native extension. | 24 // Implementation of mDNS client using a native extension. |
24 class NativeExtensionMDnsClient implements MDnsClient { | 25 class NativeExtensionMDnsClient implements MDnsClient { |
25 bool _starting = false; | 26 bool _starting = false; |
(...skipping 19 matching lines...) Expand all Loading... |
45 } | 46 } |
46 | 47 |
47 void stop() { | 48 void stop() { |
48 if (!_started) return; | 49 if (!_started) return; |
49 if (_starting) { | 50 if (_starting) { |
50 throw new StateError('Cannot stop mDNS client wile it is starting'); | 51 throw new StateError('Cannot stop mDNS client wile it is starting'); |
51 } | 52 } |
52 | 53 |
53 _incoming.close(); | 54 _incoming.close(); |
54 | 55 |
| 56 _resolver.clearPendingRequests(); |
| 57 |
55 _started = false; | 58 _started = false; |
56 } | 59 } |
57 | 60 |
58 Future<InternetAddress> lookup( | 61 Stream<ResourceRecord> lookup( |
59 String hostname, {Duration timeout: const Duration(seconds: 5)}) { | 62 int type, |
| 63 String name, |
| 64 {Duration timeout: const Duration(seconds: 5)}) { |
60 if (!_started) { | 65 if (!_started) { |
61 throw new StateError('mDNS client is not started'); | 66 throw new StateError('mDNS client is not started'); |
62 } | 67 } |
63 | 68 |
| 69 if (type != RRType.A) { |
| 70 // TODO(karlklose): add support. |
| 71 throw 'RR type $type not supported.'; |
| 72 } |
| 73 |
64 // Add the pending request before sending the query. | 74 // Add the pending request before sending the query. |
65 var future = _resolver.addPendingRequest(hostname, timeout); | 75 var result = _resolver.addPendingRequest(type, name, timeout); |
66 | 76 |
67 // Send the request. | 77 // Send the request. |
68 _service.send([_incoming.sendPort, | 78 _service.send([_incoming.sendPort, |
69 RequestType.lookupRequest.index, | 79 RequestType.lookupRequest.index, |
70 hostname]); | 80 name]); |
71 | 81 |
72 return future; | 82 return result; |
73 } | 83 } |
74 | 84 |
75 // Process incoming responses. | 85 // Process incoming responses. |
76 _handleIncoming(response) { | 86 _handleIncoming(response) { |
77 // Right not the only response we can get is the response to a | 87 // Right now the only response we can get is the response to a |
78 // lookupRequest where the response looks like this: | 88 // lookupRequest where the response looks like this: |
79 // | 89 // |
80 // response[0]: hostname (String) | 90 // response[0]: hostname (String) |
81 // response[1]: IPv4 address (Uint8List) | 91 // response[1]: IPv4 address (Uint8List) |
82 if (response is List && response.length == 2) { | 92 if (response is List && response.length == 2) { |
83 if (response[0] is String && | 93 if (response[0] is String && |
84 response[1] is List && response[1].length == 4) { | 94 response[1] is List && response[1].length == 4) { |
85 response = new DecodeResult(response[0], | 95 response = new ResourceRecord( |
86 new InternetAddress(response[1].join('.'))); | 96 RRType.A, |
| 97 response[0], |
| 98 response[1].codeUnits, |
| 99 // TODO(karlklose): modify extension to return TTL too. For new |
| 100 // we set it to 2 seconds. |
| 101 new DateTime.now().millisecondsSinceEpoch + 2000); |
87 _resolver.handleResponse([response]); | 102 _resolver.handleResponse([response]); |
88 } else { | 103 } else { |
89 // TODO(sgjesse): Improve the error handling. | 104 // TODO(sgjesse): Improve the error handling. |
90 print('mDNS Response not understood'); | 105 print('mDNS Response not understood'); |
91 } | 106 } |
92 } | 107 } |
93 } | 108 } |
94 } | 109 } |
95 | 110 |
96 Future nativeExtensionEchoTest(dynamic message) async { | 111 Future nativeExtensionEchoTest(dynamic message) async { |
97 await native_extension_api.loadLibrary(); | 112 await native_extension_api.loadLibrary(); |
98 SendPort service = native_extension_api.servicePort(); | 113 SendPort service = native_extension_api.servicePort(); |
99 ReceivePort port = new ReceivePort(); | 114 ReceivePort port = new ReceivePort(); |
100 try { | 115 try { |
101 service.send([port.sendPort, RequestType.echoRequest.index, message]); | 116 service.send([port.sendPort, RequestType.echoRequest.index, message]); |
102 return await port.first; | 117 return await port.first; |
103 } finally { | 118 } finally { |
104 port.close(); | 119 port.close(); |
105 } | 120 } |
106 } | 121 } |
OLD | NEW |