22
22
#import < dns_sd.h>
23
23
#import < os/lock.h>
24
24
25
- @interface MTRDeviceConnectivityMonitor ()
26
- - (void )handleResolvedHostname : (const char *)hostName port : (uint16_t )port error : (DNSServiceErrorType)error ;
27
- @end
25
+ #include < lib/dnssd/ServiceNaming.h>
28
26
29
27
@implementation MTRDeviceConnectivityMonitor {
30
28
NSString * _instanceName;
@@ -38,26 +36,36 @@ @implementation MTRDeviceConnectivityMonitor {
38
36
namespace {
39
37
constexpr char kLocalDot [] = " local." ;
40
38
constexpr char kOperationalType [] = " _matter._tcp" ;
39
+ constexpr int64_t kSharedConnectionLingerIntervalSeconds = (10 );
41
40
}
42
41
43
- static dispatch_once_t sConnecitivityMonitorOnceToken ;
44
- static os_unfair_lock sConnectivityMonitorLock ;
42
+ static os_unfair_lock sConnectivityMonitorLock = OS_UNFAIR_LOCK_INIT;
45
43
static NSUInteger sConnectivityMonitorCount ;
46
44
static DNSServiceRef sSharedResolverConnection ;
47
45
static dispatch_queue_t sSharedResolverQueue ;
48
46
49
47
- (instancetype )initWithInstanceName : (NSString *)instanceName
50
48
{
51
49
if (self = [super init ]) {
52
- dispatch_once (&sConnecitivityMonitorOnceToken , ^{
53
- sConnectivityMonitorLock = OS_UNFAIR_LOCK_INIT;
54
- });
55
50
_instanceName = [instanceName copy ];
56
51
_connections = [NSMutableDictionary dictionary ];
57
52
}
58
53
return self;
59
54
}
60
55
56
+ - (instancetype )initWithCompressedFabricID : (NSNumber *)compressedFabricID nodeID : (NSNumber *)nodeID
57
+ {
58
+ char instanceName[chip::Dnssd::kMaxOperationalServiceNameSize ];
59
+ chip::PeerId peerId (static_cast <chip::CompressedFabricId>(compressedFabricID.unsignedLongLongValue ), static_cast <chip::NodeId>(nodeID.unsignedLongLongValue ));
60
+ CHIP_ERROR err = chip::Dnssd::MakeInstanceName (instanceName, sizeof (instanceName), peerId);
61
+ if (err != CHIP_NO_ERROR) {
62
+ MTR_LOG_ERROR (" %@ could not make instance name" , self);
63
+ return nil ;
64
+ }
65
+
66
+ return [self initWithInstanceName: [NSString stringWithUTF8String: instanceName]];
67
+ }
68
+
61
69
- (void )dealloc
62
70
{
63
71
if (_resolver) {
@@ -76,7 +84,7 @@ + (DNSServiceRef)_sharedResolverConnection
76
84
77
85
if (!sSharedResolverConnection ) {
78
86
DNSServiceErrorType dnsError = DNSServiceCreateConnection (&sSharedResolverConnection );
79
- if (dnsError) {
87
+ if (dnsError != kDNSServiceErr_NoError ) {
80
88
MTR_LOG_ERROR (" MTRDeviceConnectivityMonitor: DNSServiceCreateConnection failed %d" , dnsError);
81
89
return NULL ;
82
90
}
@@ -99,7 +107,7 @@ - (void)_callHandler
99
107
os_unfair_lock_assert_owner (&sConnectivityMonitorLock );
100
108
MTRDeviceConnectivityMonitorHandler handlerToCall = self->_monitorHandler ;
101
109
if (handlerToCall) {
102
- dispatch_async (self->_handlerQueue , ^{ handlerToCall (); } );
110
+ dispatch_async (self->_handlerQueue , handlerToCall);
103
111
}
104
112
}
105
113
@@ -151,36 +159,37 @@ - (void)handleResolvedHostname:(const char *)hostName port:(uint16_t)port error:
151
159
}
152
160
});
153
161
nw_connection_start (connection);
162
+
163
+ _connections[hostNameString] = connection;
154
164
}
155
165
}
156
166
157
- static void _resolveReplyCallback (
167
+ static void ResolveCallback (
158
168
DNSServiceRef sdRef,
159
169
DNSServiceFlags flags,
160
170
uint32_t interfaceIndex,
161
171
DNSServiceErrorType errorCode,
162
- const char * fullname ,
163
- const char * hosttarget ,
172
+ const char * fullName ,
173
+ const char * hostName ,
164
174
uint16_t port, /* In network byte order */
165
175
uint16_t txtLen,
166
176
const unsigned char * txtRecord,
167
177
void * context)
168
178
{
169
179
auto * connectivityMonitor = (__bridge MTRDeviceConnectivityMonitor *) context;
170
- [connectivityMonitor handleResolvedHostname: hosttarget port: port error: errorCode];
180
+ [connectivityMonitor handleResolvedHostname: hostName port: port error: errorCode];
171
181
}
172
182
173
183
- (void )startMonitoringWithHandler : (MTRDeviceConnectivityMonitorHandler)handler queue : (dispatch_queue_t )queue
174
184
{
175
185
std::lock_guard lock (sConnectivityMonitorLock );
176
186
177
- MTRDeviceConnectivityMonitorHandler handlerCopy = [handler copy ];
178
- _monitorHandler = handlerCopy;
187
+ _monitorHandler = handler;
179
188
_handlerQueue = queue;
180
189
181
190
// If there's already a resolver running, just return
182
191
if (_resolver) {
183
- MTR_LOG_INFO (" %@ connectivity monitor updated handler " , self);
192
+ MTR_LOG_INFO (" %@ connectivity monitor already running " , self);
184
193
return ;
185
194
}
186
195
@@ -197,7 +206,7 @@ - (void)startMonitoringWithHandler:(MTRDeviceConnectivityMonitorHandler)handler
197
206
_instanceName.UTF8String ,
198
207
kOperationalType ,
199
208
kLocalDot ,
200
- _resolveReplyCallback ,
209
+ ResolveCallback ,
201
210
(__bridge void *) self);
202
211
if (dnsError != kDNSServiceErr_NoError ) {
203
212
MTR_LOG_ERROR (" %@ failed to create resolver" , self);
@@ -207,8 +216,6 @@ - (void)startMonitoringWithHandler:(MTRDeviceConnectivityMonitorHandler)handler
207
216
sConnectivityMonitorCount ++;
208
217
}
209
218
210
- #define MTRDEVICECONNECTIVITYMONITOR_SHARED_CONNECTION_LINGER_INTERVAL (10 )
211
-
212
219
- (void )_stopMonitoring
213
220
{
214
221
os_unfair_lock_assert_owner (&sConnectivityMonitorLock );
@@ -217,18 +224,21 @@ - (void)_stopMonitoring
217
224
}
218
225
[_connections removeAllObjects ];
219
226
227
+ _monitorHandler = nil ;
228
+ _handlerQueue = nil ;
229
+
220
230
if (_resolver) {
221
231
DNSServiceRefDeallocate (_resolver);
222
232
_resolver = NULL ;
223
233
224
234
// If no monitor objects exist, schedule to deallocate shared connection and queue
225
235
sConnectivityMonitorCount --;
226
236
if (!sConnectivityMonitorCount ) {
227
- dispatch_after (dispatch_time (DISPATCH_TIME_NOW, ( int64_t ) (MTRDEVICECONNECTIVITYMONITOR_SHARED_CONNECTION_LINGER_INTERVAL * NSEC_PER_SEC) ), sSharedResolverQueue , ^{
237
+ dispatch_after (dispatch_time (DISPATCH_TIME_NOW, kSharedConnectionLingerIntervalSeconds * NSEC_PER_SEC), sSharedResolverQueue , ^{
228
238
std::lock_guard lock (sConnectivityMonitorLock );
229
239
230
240
if (!sConnectivityMonitorCount ) {
231
- MTR_LOG_INFO (" %@ Closing shared resolver connection" , self );
241
+ MTR_LOG_INFO (" MTRDeviceConnectivityMonitor: Closing shared resolver connection" );
232
242
DNSServiceRefDeallocate (sSharedResolverConnection );
233
243
sSharedResolverConnection = NULL ;
234
244
sSharedResolverQueue = nil ;
0 commit comments