Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * Implementation of SetUp Code Pairer, a class that parses a given
22 : * setup code and uses the extracted informations to discover and
23 : * filter commissionables nodes, before initiating the pairing process.
24 : *
25 : */
26 :
27 : #include <controller/SetUpCodePairer.h>
28 :
29 : #include <controller/CHIPDeviceController.h>
30 : #include <lib/dnssd/Resolver.h>
31 : #include <lib/support/CodeUtils.h>
32 : #include <memory>
33 : #include <platform/internal/NFCCommissioningManager.h>
34 : #include <system/SystemClock.h>
35 : #include <tracing/metric_event.h>
36 : #include <vector>
37 :
38 : constexpr uint32_t kDeviceDiscoveredTimeout = CHIP_CONFIG_SETUP_CODE_PAIRER_DISCOVERY_TIMEOUT_SECS * chip::kMillisecondsPerSecond;
39 :
40 : using namespace chip::Tracing;
41 :
42 : namespace chip {
43 : namespace Controller {
44 :
45 0 : CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
46 : DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
47 : {
48 0 : VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
49 0 : VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
50 :
51 0 : std::vector<SetupPayload> payloads;
52 0 : ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
53 :
54 : // If the caller has provided a specific single resolution data, and we were
55 : // only looking for one commissionee, and the caller says that the provided
56 : // data matches that one commissionee, just go ahead and use the provided data.
57 : //
58 : // If we were looking for more than one device (i.e. if either of the
59 : // payload arrays involved does not have length 1), we can't make use of the
60 : // incoming resolution data, since it does not contain the long
61 : // discriminator of the thing that was discovered, and therefore we can't
62 : // tell which setup passcode to use for it.
63 0 : if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
64 : {
65 0 : VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
66 : CHIP_ERROR_INVALID_ARGUMENT);
67 0 : if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
68 0 : mDiscoveryType == discoveryType)
69 : {
70 : // Not passing a discriminator is ok, since we have only one payload.
71 0 : NotifyCommissionableDeviceDiscovered(resolutionData.Value(), /* matchedLongDiscriminator = */ std::nullopt);
72 0 : return CHIP_NO_ERROR;
73 : }
74 : }
75 :
76 0 : ResetDiscoveryState();
77 :
78 0 : mConnectionType = commission;
79 0 : mDiscoveryType = discoveryType;
80 0 : mRemoteId = remoteId;
81 0 : mSetupPayloads = std::move(payloads);
82 :
83 0 : if (resolutionData.HasValue() && mSetupPayloads.size() == 1)
84 : {
85 : // No need to pass in a discriminator if we have only one payload, which
86 : // is good because we don't have a full discriminator here anyway.
87 0 : NotifyCommissionableDeviceDiscovered(resolutionData.Value(), /* matchedLongDiscriminator = */ std::nullopt);
88 0 : return CHIP_NO_ERROR;
89 : }
90 :
91 0 : ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect());
92 : auto errorCode =
93 0 : mSystemLayer->StartTimer(System::Clock::Milliseconds32(kDeviceDiscoveredTimeout), OnDeviceDiscoveredTimeoutCallback, this);
94 0 : if (CHIP_NO_ERROR == errorCode)
95 : {
96 : MATTER_LOG_METRIC_BEGIN(kMetricSetupCodePairerPairDevice);
97 : }
98 0 : return errorCode;
99 0 : }
100 :
101 0 : CHIP_ERROR SetUpCodePairer::Connect()
102 : {
103 0 : if (mDiscoveryType == DiscoveryType::kAll)
104 : {
105 0 : if (ShouldDiscoverUsing(RendezvousInformationFlag::kBLE))
106 : {
107 0 : CHIP_ERROR err = StartDiscoveryOverBLE();
108 0 : if ((CHIP_ERROR_NOT_IMPLEMENTED == err) || (CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err))
109 : {
110 0 : ChipLogProgress(Controller,
111 : "Skipping commissionable node discovery over BLE since not supported by the controller!");
112 : }
113 0 : else if (err != CHIP_NO_ERROR)
114 : {
115 0 : ChipLogError(Controller, "Failed to start commissionable node discovery over BLE: %" CHIP_ERROR_FORMAT,
116 : err.Format());
117 : }
118 : }
119 0 : if (ShouldDiscoverUsing(RendezvousInformationFlag::kWiFiPAF))
120 : {
121 0 : CHIP_ERROR err = StartDiscoveryOverWiFiPAF();
122 0 : if ((CHIP_ERROR_NOT_IMPLEMENTED == err) || (CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err))
123 : {
124 0 : ChipLogProgress(Controller,
125 : "Skipping commissionable node discovery over Wi-Fi PAF since not supported by the controller!");
126 : }
127 0 : else if (err != CHIP_NO_ERROR)
128 : {
129 0 : ChipLogError(Controller, "Failed to start commissionable node discovery over Wi-Fi PAF: %" CHIP_ERROR_FORMAT,
130 : err.Format());
131 : }
132 : }
133 0 : if (ShouldDiscoverUsing(RendezvousInformationFlag::kNFC))
134 : {
135 0 : CHIP_ERROR err = StartDiscoveryOverNFC();
136 0 : if ((CHIP_ERROR_NOT_IMPLEMENTED == err) || (CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err))
137 : {
138 0 : ChipLogProgress(Controller,
139 : "Skipping commissionable node discovery over NFC since not supported by the controller!");
140 : }
141 0 : else if (err == CHIP_ERROR_NOT_FOUND)
142 : {
143 0 : ChipLogProgress(Controller,
144 : "Skipping commissionable node discovery over NFC since no NFC Reader Transport is present");
145 : }
146 0 : else if (err != CHIP_NO_ERROR)
147 : {
148 0 : ChipLogError(Controller, "Failed to start commissionable node discovery over NFC: %" CHIP_ERROR_FORMAT,
149 : err.Format());
150 : }
151 : }
152 0 : if (ShouldDiscoverUsing(RendezvousInformationFlag::kThread))
153 : {
154 0 : CHIP_ERROR err = StartDiscoveryOverThreadMeshcop();
155 0 : if ((CHIP_ERROR_NOT_IMPLEMENTED == err) || (CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err))
156 : {
157 0 : ChipLogProgress(Controller,
158 : "Skipping commissionable node discovery over ThreadMeshcop since not supported by the controller!");
159 : }
160 0 : else if (err != CHIP_NO_ERROR)
161 : {
162 0 : ChipLogError(Controller, "Failed to start commissionable node discovery over ThreadMeshcop: %" CHIP_ERROR_FORMAT,
163 : err.Format());
164 : }
165 : }
166 : }
167 :
168 : // We always want to search on network because any node that has already been commissioned will use on-network regardless of the
169 : // QR code flag.
170 0 : CHIP_ERROR err = StartDiscoveryOverDNSSD();
171 0 : if (err != CHIP_NO_ERROR)
172 : {
173 0 : ChipLogError(Controller, "Failed to start commissionable node discovery over DNS-SD: %" CHIP_ERROR_FORMAT, err.Format());
174 : }
175 0 : return err;
176 : }
177 :
178 0 : CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE()
179 : {
180 : #if CONFIG_NETWORK_LAYER_BLE
181 : #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
182 : VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
183 : mCommissioner->ConnectBleTransportToSelf();
184 : #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
185 0 : VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
186 :
187 0 : ChipLogProgress(Controller, "Starting commissionable node discovery over BLE");
188 :
189 : // Handle possibly-sync callbacks.
190 0 : mWaitingForDiscovery[kBLETransport] = true;
191 : CHIP_ERROR err;
192 : // Not all BLE backends support the new NewBleConnectionByDiscriminators
193 : // API, so use the old one when we can (i.e. when we only have one setup
194 : // payload), to avoid breaking existing API consumers.
195 0 : if (mSetupPayloads.size() == 1)
196 : {
197 0 : err = mBleLayer->NewBleConnectionByDiscriminator(mSetupPayloads[0].discriminator, this, OnDiscoveredDeviceOverBleSuccess,
198 : OnDiscoveredDeviceOverBleError);
199 : }
200 : else
201 : {
202 0 : std::vector<SetupDiscriminator> discriminators;
203 0 : discriminators.reserve(mSetupPayloads.size());
204 0 : for (auto & payload : mSetupPayloads)
205 : {
206 0 : discriminators.emplace_back(payload.discriminator);
207 : }
208 0 : err = mBleLayer->NewBleConnectionByDiscriminators(Span(discriminators.data(), discriminators.size()), this,
209 : OnDiscoveredDeviceWithDiscriminatorOverBleSuccess,
210 : OnDiscoveredDeviceOverBleError);
211 0 : }
212 0 : if (err != CHIP_NO_ERROR)
213 : {
214 0 : mWaitingForDiscovery[kBLETransport] = false;
215 : }
216 0 : return err;
217 : #else
218 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
219 : #endif // CONFIG_NETWORK_LAYER_BLE
220 : }
221 :
222 1 : CHIP_ERROR SetUpCodePairer::StopDiscoveryOverBLE()
223 : {
224 : // Make sure to not call CancelBleIncompleteConnection unless we are in fact
225 : // waiting on BLE discovery. It will cancel connections that are in fact
226 : // completed. In particular, if we just established PASE over BLE calling
227 : // CancelBleIncompleteConnection here unconditionally would cancel the BLE
228 : // connection underlying the PASE session. So make sure to only call
229 : // CancelBleIncompleteConnection if we're still waiting to hear back on the
230 : // BLE discovery bits.
231 1 : if (!mWaitingForDiscovery[kBLETransport])
232 : {
233 0 : return CHIP_NO_ERROR;
234 : }
235 :
236 1 : mWaitingForDiscovery[kBLETransport] = false;
237 : #if CONFIG_NETWORK_LAYER_BLE
238 1 : VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
239 0 : ChipLogProgress(Controller, "Stopping commissionable node discovery over BLE");
240 0 : return mBleLayer->CancelBleIncompleteConnection();
241 : #else
242 : return CHIP_NO_ERROR;
243 : #endif // CONFIG_NETWORK_LAYER_BLE
244 : }
245 :
246 0 : CHIP_ERROR SetUpCodePairer::StartDiscoveryOverDNSSD()
247 : {
248 0 : ChipLogProgress(Controller, "Starting commissionable node discovery over DNS-SD");
249 :
250 0 : Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kNone);
251 0 : if (mSetupPayloads.size() == 1)
252 : {
253 0 : auto & discriminator = mSetupPayloads[0].discriminator;
254 0 : if (discriminator.IsShortDiscriminator())
255 : {
256 0 : filter.type = Dnssd::DiscoveryFilterType::kShortDiscriminator;
257 0 : filter.code = discriminator.GetShortValue();
258 : }
259 : else
260 : {
261 0 : filter.type = Dnssd::DiscoveryFilterType::kLongDiscriminator;
262 0 : filter.code = discriminator.GetLongValue();
263 : }
264 : }
265 :
266 : // In theory we could try to filter on the vendor ID if it's the same across all the setup
267 : // payloads, but DNS-SD advertisements are not required to include the Vendor ID subtype, so in
268 : // practice that's not doable.
269 :
270 : // Handle possibly-sync callbacks.
271 0 : mWaitingForDiscovery[kIPTransport] = true;
272 0 : CHIP_ERROR err = mCommissioner->DiscoverCommissionableNodes(filter);
273 0 : if (err != CHIP_NO_ERROR)
274 : {
275 0 : mWaitingForDiscovery[kIPTransport] = false;
276 : }
277 0 : return err;
278 : }
279 :
280 2 : CHIP_ERROR SetUpCodePairer::StopDiscoveryOverDNSSD()
281 : {
282 2 : ChipLogProgress(Controller, "Stopping commissionable node discovery over DNS-SD");
283 :
284 2 : mWaitingForDiscovery[kIPTransport] = false;
285 :
286 2 : return mCommissioner->StopCommissionableDiscovery();
287 : }
288 :
289 0 : CHIP_ERROR SetUpCodePairer::StartDiscoveryOverWiFiPAF()
290 : {
291 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
292 0 : if (mSetupPayloads.size() != 1)
293 : {
294 0 : ChipLogError(Controller, "Wi-Fi PAF commissioning does not support concatenated QR codes yet.");
295 0 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
296 : }
297 :
298 0 : auto & payload = mSetupPayloads[0];
299 :
300 0 : ChipLogProgress(Controller, "Starting commissionable node discovery over Wi-Fi PAF");
301 0 : VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
302 :
303 0 : const SetupDiscriminator connDiscriminator(payload.discriminator);
304 0 : VerifyOrReturnValue(!connDiscriminator.IsShortDiscriminator(), CHIP_ERROR_INVALID_ARGUMENT,
305 : ChipLogError(Controller, "Error, Long discriminator is required"));
306 0 : uint16_t discriminator = connDiscriminator.GetLongValue();
307 0 : WiFiPAF::WiFiPAFSession sessionInfo = { .role = WiFiPAF::WiFiPafRole::kWiFiPafRole_Subscriber,
308 0 : .nodeId = mRemoteId,
309 0 : .discriminator = discriminator };
310 0 : ReturnErrorOnFailure(
311 : DeviceLayer::ConnectivityMgr().GetWiFiPAF()->AddPafSession(WiFiPAF::PafInfoAccess::kAccNodeInfo, sessionInfo));
312 :
313 0 : mWaitingForDiscovery[kWiFiPAFTransport] = true;
314 0 : CHIP_ERROR err = DeviceLayer::ConnectivityMgr().WiFiPAFSubscribe(discriminator, (void *) this, OnWiFiPAFSubscribeComplete,
315 : OnWiFiPAFSubscribeError);
316 0 : if (err != CHIP_NO_ERROR)
317 : {
318 0 : ChipLogError(Controller, "Commissionable node discovery over Wi-Fi PAF failed, err = %" CHIP_ERROR_FORMAT, err.Format());
319 0 : mWaitingForDiscovery[kWiFiPAFTransport] = false;
320 : }
321 0 : return err;
322 : #else
323 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
324 : #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
325 : }
326 :
327 1 : CHIP_ERROR SetUpCodePairer::StopDiscoveryOverWiFiPAF()
328 : {
329 1 : mWaitingForDiscovery[kWiFiPAFTransport] = false;
330 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
331 1 : return DeviceLayer::ConnectivityMgr().WiFiPAFCancelIncompleteSubscribe();
332 : #else
333 : return CHIP_NO_ERROR;
334 : #endif
335 : }
336 :
337 0 : CHIP_ERROR SetUpCodePairer::StartDiscoveryOverNFC()
338 : {
339 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
340 : if (mSetupPayloads.size() != 1)
341 : {
342 : ChipLogError(Controller, "NFC commissioning does not support concatenated QR codes yet.");
343 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
344 : }
345 :
346 : auto & payload = mSetupPayloads[0];
347 :
348 : ChipLogProgress(Controller, "Starting commissionable node discovery over NFC");
349 : VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
350 :
351 : const SetupDiscriminator connDiscriminator(payload.discriminator);
352 : VerifyOrReturnValue(!connDiscriminator.IsShortDiscriminator(), CHIP_ERROR_INVALID_ARGUMENT,
353 : ChipLogError(Controller, "Error, Long discriminator is required"));
354 : chip::Nfc::NFCTag::Identifier identifier = { .discriminator = payload.discriminator.GetLongValue() };
355 : Nfc::NFCReaderTransport * readerTransport = DeviceLayer::Internal::NFCCommissioningMgr().GetNFCReaderTransport();
356 : if (!readerTransport)
357 : {
358 : // No valid NFC reader transport
359 : return CHIP_ERROR_NOT_FOUND;
360 : }
361 :
362 : readerTransport->SetDelegate(this);
363 : CHIP_ERROR err = readerTransport->StartDiscoveringTagMatchingAddress(identifier);
364 : if (err != CHIP_NO_ERROR)
365 : {
366 : ChipLogError(Controller, "Commissionable node discovery over NFC failed, err = %" CHIP_ERROR_FORMAT, err.Format());
367 : }
368 : else
369 : {
370 : mWaitingForDiscovery[kNFCTransport] = true;
371 : }
372 : return err;
373 : #else
374 0 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
375 : #endif // CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
376 : }
377 :
378 1 : CHIP_ERROR SetUpCodePairer::StopDiscoveryOverNFC()
379 : {
380 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
381 : mWaitingForDiscovery[kNFCTransport] = false;
382 :
383 : Nfc::NFCReaderTransport * readerTransport = DeviceLayer::Internal::NFCCommissioningMgr().GetNFCReaderTransport();
384 : if (!readerTransport)
385 : {
386 : // No valid NFC reader transport.
387 : return CHIP_ERROR_NOT_FOUND;
388 : }
389 :
390 : ChipLogProgress(Controller, "Stopping commissionable node discovery over NFC by removing delegate");
391 : readerTransport->SetDelegate(nullptr);
392 : #endif
393 1 : return CHIP_NO_ERROR;
394 : }
395 :
396 0 : CHIP_ERROR SetUpCodePairer::StartDiscoveryOverThreadMeshcop()
397 : {
398 : #if CHIP_SUPPORT_THREAD_MESHCOP
399 0 : if (mSetupPayloads.size() != 1)
400 : {
401 0 : ChipLogError(Controller, "Thread Meshcop commissioning does not support concatenated QR codes yet.");
402 0 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
403 : }
404 :
405 0 : if (!mThreadMeshcopCommissionProxy)
406 : {
407 0 : ChipLogError(Controller, "The meshcopCommissioningProxy is not set");
408 0 : return CHIP_ERROR_INVALID_ARGUMENT;
409 : }
410 :
411 0 : if (!mThreadMeshcopCommissionParams.HasValue() ||
412 0 : mThreadMeshcopCommissionParams.Value().mBorderAgentAddress.GetTransportType() != Transport::Type::kThreadMeshcop)
413 : {
414 0 : ChipLogError(Controller, "The meshcopCommissioningParams is not set");
415 0 : return CHIP_ERROR_INVALID_ARGUMENT;
416 : }
417 :
418 0 : auto & payload = mSetupPayloads[0];
419 :
420 0 : ChipLogProgress(Controller, "Starting commissionable node discovery over Thread Meshcop");
421 0 : VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
422 :
423 0 : const SetupDiscriminator connDiscriminator(payload.discriminator);
424 0 : Thread::DiscoveryCode code;
425 0 : if (connDiscriminator.IsShortDiscriminator())
426 : {
427 0 : code = Thread::DiscoveryCode(connDiscriminator.GetShortValue());
428 0 : ChipLogProgress(Controller, "Discovery code from short discriminator: 0x%" PRIx64, code.AsUInt64());
429 : }
430 : else
431 : {
432 0 : code = Thread::DiscoveryCode(connDiscriminator.GetLongValue());
433 0 : ChipLogProgress(Controller, "Discovery code from long discriminator: 0x%" PRIx64, code.AsUInt64());
434 : }
435 :
436 0 : ByteSpan pskc(mThreadMeshcopCommissionParams.Value().mPSKcBuffer);
437 : {
438 0 : mWaitingForDiscovery[kThreadMeshcopTransport] = true;
439 0 : Dnssd::DiscoveredNodeData discoveredNodeData;
440 :
441 0 : CHIP_ERROR err = mThreadMeshcopCommissionProxy->Discover(pskc, mThreadMeshcopCommissionParams.Value().mBorderAgentAddress,
442 : code, connDiscriminator, discoveredNodeData, 30);
443 :
444 0 : mWaitingForDiscovery[kThreadMeshcopTransport] = false;
445 0 : ReturnErrorOnFailure(err);
446 0 : mCommissioner->OnNodeDiscovered(discoveredNodeData);
447 0 : ChipLogProgress(Controller, "Joiner discovered");
448 0 : }
449 0 : return CHIP_NO_ERROR;
450 : #else
451 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
452 : #endif // CHIP_SUPPORT_THREAD_MESHCOP
453 : }
454 :
455 1 : CHIP_ERROR SetUpCodePairer::StopDiscoveryOverThreadMeshcop()
456 : {
457 : // Currently we don't have any methods to stop discovery Over Thread Meshcop.
458 : // Still return no error here to prevent error logs.
459 1 : return CHIP_NO_ERROR;
460 : }
461 :
462 2 : bool SetUpCodePairer::ConnectToDiscoveredDevice()
463 : {
464 2 : if (mWaitingForPASE)
465 : {
466 : // Nothing to do. Just wait until we either succeed or fail at that
467 : // PASE session establishment.
468 0 : return false;
469 : }
470 :
471 2 : while (!mDiscoveredParameters.empty())
472 : {
473 0 : mCurrentPASEPayload.reset();
474 :
475 : // Grab the first element from the queue and try connecting to it.
476 : // Remove it from the queue before we try to connect, in case the
477 : // connection attempt fails and calls right back into us to try the next
478 : // thing.
479 0 : SetUpCodePairerParameters params(mDiscoveredParameters.front());
480 0 : mDiscoveredParameters.pop_front();
481 :
482 0 : if (params.mLongDiscriminator)
483 : {
484 0 : auto longDiscriminator = *params.mLongDiscriminator;
485 : // Look for a matching setup passcode.
486 0 : for (auto & payload : mSetupPayloads)
487 : {
488 0 : if (payload.discriminator.MatchesLongDiscriminator(longDiscriminator))
489 : {
490 0 : params.SetSetupPINCode(payload.setUpPINCode);
491 0 : params.SetSetupDiscriminator(payload.discriminator);
492 0 : mCurrentPASEPayload = payload;
493 0 : break;
494 : }
495 : }
496 0 : if (!mCurrentPASEPayload)
497 : {
498 0 : ChipLogError(Controller, "SetUpCodePairer: Discovered discriminator %u does not match any of our setup payloads",
499 : longDiscriminator);
500 : // Move on to the the next discovered params; nothing we can do here.
501 0 : continue;
502 : }
503 : }
504 : else
505 : {
506 : // No discriminator known for this discovered device. This can work if we have only one
507 : // setup payload, but otherwise we have no idea what setup passcode to use for it.
508 0 : if (mSetupPayloads.size() == 1)
509 : {
510 0 : params.SetSetupPINCode(mSetupPayloads[0].setUpPINCode);
511 0 : params.SetSetupDiscriminator(mSetupPayloads[0].discriminator);
512 0 : mCurrentPASEPayload = mSetupPayloads[0];
513 : }
514 : else
515 : {
516 0 : ChipLogError(Controller,
517 : "SetUpCodePairer: Unable to handle discovered parameters with no discriminator, because it has %u "
518 : "possible payloads",
519 : static_cast<unsigned>(mSetupPayloads.size()));
520 0 : continue;
521 : }
522 : }
523 :
524 : #if CHIP_PROGRESS_LOGGING
525 : char buf[Transport::PeerAddress::kMaxToStringSize];
526 0 : params.GetPeerAddress().ToString(buf);
527 0 : ChipLogProgress(Controller, "Attempting PASE connection to %s", buf);
528 : #endif // CHIP_PROGRESS_LOGGING
529 :
530 : // Handle possibly-sync call backs from attempts to establish PASE.
531 0 : ExpectPASEEstablishment();
532 :
533 0 : if (params.GetPeerAddress().GetTransportType() == Transport::Type::kUdp)
534 : {
535 0 : mCurrentPASEParameters.SetValue(params);
536 : }
537 :
538 : CHIP_ERROR err;
539 0 : if (mConnectionType == SetupCodePairerBehaviour::kCommission)
540 : {
541 0 : err = mCommissioner->PairDevice(mRemoteId, params);
542 : }
543 : else
544 : {
545 0 : err = mCommissioner->EstablishPASEConnection(mRemoteId, params);
546 : }
547 :
548 0 : LogErrorOnFailure(err);
549 0 : if (err == CHIP_NO_ERROR)
550 : {
551 0 : return true;
552 : }
553 :
554 : // Failed to start establishing PASE. Move on to the next item.
555 0 : mCurrentPASEParameters.ClearValue();
556 0 : mCurrentPASEPayload.reset();
557 0 : PASEEstablishmentComplete();
558 : }
559 :
560 2 : return false;
561 : }
562 :
563 : #if CONFIG_NETWORK_LAYER_BLE
564 0 : void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> matchedLongDiscriminator)
565 : {
566 0 : ChipLogProgress(Controller, "Discovered device to be commissioned over BLE");
567 :
568 0 : mWaitingForDiscovery[kBLETransport] = false;
569 :
570 : // In order to not wait for all the possible addresses discovered over mdns to
571 : // be tried before trying to connect over BLE, the discovered connection object is
572 : // inserted at the beginning of the list.
573 : //
574 : // It makes it the 'next' thing to try to connect to if there are already some
575 : // discovered parameters in the list.
576 : //
577 : // TODO: Consider implementing the SHOULD the spec has about commissioning things
578 : // in QR code order by waiting for a second or something before actually starting
579 : // the first PASE session when we have multiple setup payloads, and sorting the
580 : // results in setup payload order. If we do this, we might want to restrict it to
581 : // cases when the different payloads have different vendor/product IDs, since if
582 : // they are all the same product presumably ordering really does not matter.
583 0 : mDiscoveredParameters.emplace_front(connObj, matchedLongDiscriminator);
584 0 : ConnectToDiscoveredDevice();
585 0 : }
586 :
587 0 : void SetUpCodePairer::OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj)
588 : {
589 0 : (static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj, std::nullopt);
590 0 : }
591 :
592 0 : void SetUpCodePairer::OnDiscoveredDeviceWithDiscriminatorOverBleSuccess(void * appState, uint16_t matchedLongDiscriminator,
593 : BLE_CONNECTION_OBJECT connObj)
594 : {
595 0 : (static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj, std::make_optional(matchedLongDiscriminator));
596 0 : }
597 :
598 0 : void SetUpCodePairer::OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err)
599 : {
600 0 : static_cast<SetUpCodePairer *>(appState)->OnBLEDiscoveryError(err);
601 0 : }
602 :
603 0 : void SetUpCodePairer::OnBLEDiscoveryError(CHIP_ERROR err)
604 : {
605 0 : ChipLogError(Controller, "Commissionable node discovery over BLE failed: %" CHIP_ERROR_FORMAT, err.Format());
606 0 : mWaitingForDiscovery[kBLETransport] = false;
607 0 : LogErrorOnFailure(err);
608 0 : StopPairingIfTransportsExhausted(err);
609 0 : }
610 : #endif // CONFIG_NETWORK_LAYER_BLE
611 :
612 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
613 0 : void SetUpCodePairer::OnDiscoveredDeviceOverWifiPAF()
614 : {
615 0 : ChipLogProgress(Controller, "Discovered device to be commissioned over Wi-Fi PAF, RemoteId: %" PRIu64, mRemoteId);
616 :
617 0 : mWaitingForDiscovery[kWiFiPAFTransport] = false;
618 0 : auto param = SetUpCodePairerParameters();
619 0 : param.SetPeerAddress(Transport::PeerAddress(Transport::Type::kWiFiPAF, mRemoteId));
620 : // TODO: This needs to support concatenated QR codes and set the relevant
621 : // long discriminator on param.
622 : //
623 : // See https://github.com/project-chip/connectedhomeip/issues/39134
624 0 : mDiscoveredParameters.emplace_back(param);
625 0 : ConnectToDiscoveredDevice();
626 0 : }
627 :
628 0 : void SetUpCodePairer::OnWifiPAFDiscoveryError(CHIP_ERROR err)
629 : {
630 0 : ChipLogError(Controller, "Commissionable node discovery over Wi-Fi PAF failed: %" CHIP_ERROR_FORMAT, err.Format());
631 0 : mWaitingForDiscovery[kWiFiPAFTransport] = false;
632 0 : StopPairingIfTransportsExhausted(err);
633 0 : }
634 :
635 0 : void SetUpCodePairer::OnWiFiPAFSubscribeComplete(void * appState)
636 : {
637 0 : auto self = reinterpret_cast<SetUpCodePairer *>(appState);
638 0 : self->OnDiscoveredDeviceOverWifiPAF();
639 0 : }
640 :
641 0 : void SetUpCodePairer::OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err)
642 : {
643 0 : auto self = reinterpret_cast<SetUpCodePairer *>(appState);
644 0 : self->OnWifiPAFDiscoveryError(err);
645 0 : }
646 : #endif
647 :
648 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
649 : void SetUpCodePairer::OnTagDiscovered(const chip::Nfc::NFCTag::Identifier & identifier)
650 : {
651 : ChipLogProgress(Controller, "Discovered device to be commissioned over NFC, Identifier: %u", identifier.discriminator);
652 :
653 : mWaitingForDiscovery[kNFCTransport] = false;
654 : auto param = SetUpCodePairerParameters();
655 : param.SetPeerAddress(Transport::PeerAddress(Transport::PeerAddress::NFC(identifier.discriminator)));
656 : // TODO: This needs to support concatenated QR codes and set the relevant
657 : // long discriminator on param.
658 : //
659 : // See https://github.com/project-chip/connectedhomeip/issues/39134
660 : mDiscoveredParameters.emplace_back(param);
661 : ConnectToDiscoveredDevice();
662 : }
663 :
664 : void SetUpCodePairer::OnTagDiscoveryFailed(CHIP_ERROR error)
665 : {
666 : ChipLogError(Controller, "Commissionable node discovery over NFC failed: %" CHIP_ERROR_FORMAT, error.Format());
667 : mWaitingForDiscovery[kNFCTransport] = false;
668 : StopPairingIfTransportsExhausted(error);
669 : }
670 : #endif
671 :
672 0 : bool SetUpCodePairer::IdIsPresent(uint16_t vendorOrProductID)
673 : {
674 0 : return vendorOrProductID != kNotAvailable;
675 : }
676 :
677 0 : bool SetUpCodePairer::NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & discNodeData) const
678 : {
679 0 : if (!discNodeData.Is<Dnssd::CommissionNodeData>())
680 : {
681 0 : return false;
682 : }
683 :
684 0 : const Dnssd::CommissionNodeData & nodeData = discNodeData.Get<Dnssd::CommissionNodeData>();
685 :
686 0 : VerifyOrReturnError(mCommissioner != nullptr, false);
687 0 : VerifyOrReturnError(mCommissioner->HasValidCommissioningMode(nodeData), false);
688 :
689 : // Check whether this matches one of our setup payloads.
690 0 : for (auto & payload : mSetupPayloads)
691 : {
692 : // The advertisement may not include a vendor id, and the payload may not have one either.
693 0 : if (IdIsPresent(payload.vendorID) && IdIsPresent(nodeData.vendorId) && payload.vendorID != nodeData.vendorId)
694 : {
695 0 : ChipLogProgress(Controller, "Discovered device vendor ID (%u) does not match our vendor ID (%u).", nodeData.vendorId,
696 : payload.vendorID);
697 0 : continue;
698 : }
699 :
700 : // The advertisement may not include a product id, and the payload may not have one either.
701 0 : if (IdIsPresent(payload.productID) && IdIsPresent(nodeData.productId) && payload.productID != nodeData.productId)
702 : {
703 0 : ChipLogProgress(Controller, "Discovered device product ID (%u) does not match our product ID (%u).", nodeData.productId,
704 : payload.productID);
705 0 : continue;
706 : }
707 :
708 0 : if (!payload.discriminator.MatchesLongDiscriminator(nodeData.longDiscriminator))
709 : {
710 0 : ChipLogProgress(Controller, "Discovered device discriminator (%u) does not match our discriminator.",
711 : nodeData.longDiscriminator);
712 0 : continue;
713 : }
714 :
715 0 : ChipLogProgress(Controller, "Discovered device with discriminator %u matches one of our setup payloads",
716 : nodeData.longDiscriminator);
717 0 : return true;
718 : }
719 :
720 0 : return false;
721 : }
722 :
723 0 : void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::DiscoveredNodeData & nodeData)
724 : {
725 0 : if (!NodeMatchesCurrentFilter(nodeData))
726 : {
727 0 : return;
728 : }
729 :
730 0 : ChipLogProgress(Controller, "Discovered device to be commissioned over DNS-SD");
731 :
732 0 : auto & commissionableNodeData = nodeData.Get<Dnssd::CommissionNodeData>();
733 :
734 0 : NotifyCommissionableDeviceDiscovered(commissionableNodeData, std::make_optional(commissionableNodeData.longDiscriminator));
735 : }
736 :
737 0 : void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::CommonResolutionData & resolutionData,
738 : std::optional<uint16_t> matchedLongDiscriminator)
739 : {
740 0 : if (mDiscoveryType == DiscoveryType::kDiscoveryNetworkOnlyWithoutPASEAutoRetry)
741 : {
742 : // If the discovery type does not want the PASE auto retry mechanism, we will just store
743 : // a single IP. So the discovery process is stopped as it won't be of any help anymore.
744 0 : TEMPORARY_RETURN_IGNORED StopDiscoveryOverDNSSD();
745 0 : mDiscoveredParameters.emplace_back(resolutionData, matchedLongDiscriminator, 0);
746 : }
747 : else
748 : {
749 0 : for (size_t i = 0; i < resolutionData.numIPs; i++)
750 : {
751 0 : mDiscoveredParameters.emplace_back(resolutionData, matchedLongDiscriminator, i);
752 : }
753 : }
754 :
755 0 : ConnectToDiscoveredDevice();
756 0 : }
757 :
758 0 : bool SetUpCodePairer::StopPairing(NodeId remoteId)
759 : {
760 0 : VerifyOrReturnValue(mRemoteId != kUndefinedNodeId, false);
761 0 : VerifyOrReturnValue(remoteId == kUndefinedNodeId || remoteId == mRemoteId, false);
762 :
763 0 : if (mWaitingForPASE)
764 : {
765 0 : PASEEstablishmentComplete();
766 : }
767 :
768 0 : ResetDiscoveryState();
769 0 : mRemoteId = kUndefinedNodeId;
770 0 : return true;
771 : }
772 :
773 2 : bool SetUpCodePairer::TryNextRendezvousParameters()
774 : {
775 2 : if (ConnectToDiscoveredDevice())
776 : {
777 0 : ChipLogProgress(Controller, "Trying connection to commissionee over different transport");
778 0 : return true;
779 : }
780 :
781 2 : if (DiscoveryInProgress())
782 : {
783 2 : ChipLogProgress(Controller, "Waiting to discover commissionees that match our filters");
784 2 : return true;
785 : }
786 :
787 0 : return false;
788 : }
789 :
790 3 : bool SetUpCodePairer::DiscoveryInProgress() const
791 : {
792 8 : for (const auto & waiting : mWaitingForDiscovery)
793 : {
794 7 : if (waiting)
795 : {
796 2 : return true;
797 : }
798 : }
799 :
800 1 : return false;
801 : }
802 :
803 1 : void SetUpCodePairer::StopPairingIfTransportsExhausted(CHIP_ERROR err)
804 : {
805 1 : if (mWaitingForPASE || !mDiscoveredParameters.empty() || DiscoveryInProgress() || mRemoteId == kUndefinedNodeId)
806 : {
807 0 : return;
808 : }
809 : // Clear mRemoteId first to guard against re-entrant calls (e.g. from an async
810 : // cancel callback fired after StopAllDiscoveryAttempts already cleared the flags).
811 1 : mRemoteId = kUndefinedNodeId;
812 2 : CHIP_ERROR failErr = mLastPASEError != CHIP_NO_ERROR ? mLastPASEError : err;
813 : MATTER_LOG_METRIC_END(kMetricSetupCodePairerPairDevice, failErr);
814 1 : mCommissioner->OnSessionEstablishmentError(failErr);
815 : }
816 :
817 1 : void SetUpCodePairer::StopAllDiscoveryAttempts()
818 : {
819 2 : LogErrorOnFailure(StopDiscoveryOverBLE());
820 2 : LogErrorOnFailure(StopDiscoveryOverDNSSD());
821 2 : LogErrorOnFailure(StopDiscoveryOverWiFiPAF());
822 3 : LogErrorOnFailure(StopDiscoveryOverNFC().NoErrorIf(CHIP_ERROR_NOT_FOUND));
823 2 : LogErrorOnFailure(StopDiscoveryOverThreadMeshcop());
824 :
825 : // Just in case any of those failed to reset the waiting state properly.
826 5 : for (auto & waiting : mWaitingForDiscovery)
827 : {
828 4 : waiting = false;
829 : }
830 1 : }
831 :
832 0 : void SetUpCodePairer::ResetDiscoveryState()
833 : {
834 0 : StopAllDiscoveryAttempts();
835 :
836 0 : mDiscoveredParameters.clear();
837 0 : mCurrentPASEParameters.ClearValue();
838 0 : mLastPASEError = CHIP_NO_ERROR;
839 :
840 0 : mSetupPayloads.clear();
841 :
842 0 : mSystemLayer->CancelTimer(OnDeviceDiscoveredTimeoutCallback, this);
843 0 : }
844 :
845 2 : void SetUpCodePairer::ExpectPASEEstablishment()
846 : {
847 2 : VerifyOrDie(!mWaitingForPASE);
848 2 : mWaitingForPASE = true;
849 2 : auto * delegate = mCommissioner->GetPairingDelegate();
850 2 : VerifyOrDie(delegate != this);
851 2 : mPairingDelegate = delegate;
852 2 : mCommissioner->RegisterPairingDelegate(this);
853 2 : }
854 :
855 2 : void SetUpCodePairer::PASEEstablishmentComplete()
856 : {
857 2 : VerifyOrDie(mWaitingForPASE);
858 2 : mWaitingForPASE = false;
859 2 : mCommissioner->RegisterPairingDelegate(mPairingDelegate);
860 2 : mPairingDelegate = nullptr;
861 2 : }
862 :
863 0 : void SetUpCodePairer::OnStatusUpdate(DevicePairingDelegate::Status status)
864 : {
865 0 : if (status == DevicePairingDelegate::Status::SecurePairingFailed)
866 : {
867 : // If we're still waiting on discovery, don't propagate this failure
868 : // (which is due to PASE failure with something we discovered, but the
869 : // "something" may not have been the right thing) for now. Wait until
870 : // discovery completes. Then we will either succeed and notify
871 : // accordingly or time out and land in OnStatusUpdate again, but at that
872 : // point we will not be waiting on discovery anymore.
873 0 : if (!mDiscoveredParameters.empty())
874 : {
875 0 : ChipLogProgress(Controller, "Ignoring SecurePairingFailed status for now; we have more discovered devices to try");
876 0 : return;
877 : }
878 :
879 0 : if (DiscoveryInProgress())
880 : {
881 0 : ChipLogProgress(Controller,
882 : "Ignoring SecurePairingFailed status for now; we are waiting to see if we discover more devices");
883 0 : return;
884 : }
885 : }
886 :
887 0 : if (mPairingDelegate)
888 : {
889 0 : mPairingDelegate->OnStatusUpdate(status);
890 : }
891 : }
892 :
893 2 : void SetUpCodePairer::OnPairingComplete(CHIP_ERROR error, const std::optional<RendezvousParameters> & rendezvousParameters,
894 : const std::optional<SetupPayload> & setupPayload)
895 : {
896 : // Save the pairing delegate so we can notify it. We want to notify it
897 : // _after_ we restore the state on the commissioner, in case the delegate
898 : // ends up immediately calling back into the commissioner again when
899 : // notified.
900 2 : auto * pairingDelegate = mPairingDelegate;
901 2 : PASEEstablishmentComplete();
902 :
903 : // Make sure to clear out mCurrentPASEPayload whether we succeeded or failed.
904 2 : std::optional<SetupPayload> pasePayload;
905 2 : pasePayload.swap(mCurrentPASEPayload);
906 :
907 4 : if (CHIP_NO_ERROR == error)
908 : {
909 0 : ChipLogProgress(Controller, "PASE session established with commissionee. Stopping discovery.");
910 0 : ResetDiscoveryState();
911 0 : mRemoteId = kUndefinedNodeId;
912 : MATTER_LOG_METRIC_END(kMetricSetupCodePairerPairDevice, error);
913 0 : if (pairingDelegate != nullptr)
914 : {
915 : // We don't expect to have a setupPayload passed in here.
916 0 : if (setupPayload)
917 : {
918 0 : ChipLogError(Controller,
919 : "Unexpected setupPayload passed to SetUpCodePairer::OnPairingComplete. Where did it come from?");
920 : }
921 0 : pairingDelegate->OnPairingComplete(error, rendezvousParameters, pasePayload);
922 : }
923 0 : return;
924 : }
925 :
926 : // It may happen that there is a stale DNS entry. If so, ReconfirmRecord will flush
927 : // the record from the daemon cache once it determines that it is invalid.
928 : // It may not help for this particular resolve, but may help subsequent resolves.
929 4 : if (CHIP_ERROR_TIMEOUT == error && mCurrentPASEParameters.HasValue())
930 : {
931 1 : const auto & params = mCurrentPASEParameters.Value();
932 1 : const auto & peer = params.GetPeerAddress();
933 1 : const auto & ip = peer.GetIPAddress();
934 1 : auto err = Dnssd::Resolver::Instance().ReconfirmRecord(params.mHostName, ip, params.mInterfaceId);
935 3 : if (CHIP_NO_ERROR != err && CHIP_ERROR_NOT_IMPLEMENTED != err)
936 : {
937 0 : ChipLogError(Controller, "Error when verifying the validity of an address: %" CHIP_ERROR_FORMAT, err.Format());
938 : }
939 : }
940 2 : mCurrentPASEParameters.ClearValue();
941 :
942 : // We failed to establish PASE. Try the next thing we have discovered, if
943 : // any.
944 2 : if (TryNextRendezvousParameters())
945 : {
946 : // Keep waiting until that finishes. Don't call OnPairingComplete yet.
947 2 : mLastPASEError = error;
948 2 : return;
949 : }
950 :
951 : MATTER_LOG_METRIC_END(kMetricSetupCodePairerPairDevice, error);
952 0 : if (pairingDelegate != nullptr)
953 : {
954 0 : pairingDelegate->OnPairingComplete(error, rendezvousParameters, pasePayload);
955 : }
956 2 : }
957 :
958 0 : void SetUpCodePairer::OnPairingDeleted(CHIP_ERROR error)
959 : {
960 0 : if (mPairingDelegate)
961 : {
962 0 : mPairingDelegate->OnPairingDeleted(error);
963 : }
964 0 : }
965 :
966 0 : void SetUpCodePairer::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error)
967 : {
968 : // Not really expecting this, but handle it anyway.
969 0 : if (mPairingDelegate)
970 : {
971 0 : mPairingDelegate->OnCommissioningComplete(deviceId, error);
972 : }
973 0 : }
974 :
975 2 : void SetUpCodePairer::OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context)
976 : {
977 2 : ChipLogError(Controller, "Discovery timed out");
978 2 : auto * pairer = static_cast<SetUpCodePairer *>(context);
979 :
980 : // If a PASE attempt is in progress, do not stop physical-proximity
981 : // transports (BLE, Wi-Fi PAF, NFC) — they have their own completion/timeout
982 : // mechanisms. DNS-SD, however, runs indefinitely, so stop it now to
983 : // prevent DiscoveryInProgress() from being true forever.
984 2 : if (pairer->mWaitingForPASE)
985 : {
986 2 : LogErrorOnFailure(pairer->StopDiscoveryOverDNSSD());
987 1 : return;
988 : }
989 :
990 : // No PASE in progress — stop all remaining discovery and fail if nothing is left to try.
991 1 : pairer->StopAllDiscoveryAttempts();
992 1 : pairer->StopPairingIfTransportsExhausted(CHIP_ERROR_TIMEOUT);
993 : }
994 :
995 0 : bool SetUpCodePairer::ShouldDiscoverUsing(RendezvousInformationFlag commissioningChannel) const
996 : {
997 0 : for (auto & payload : mSetupPayloads)
998 : {
999 0 : auto & rendezvousInformation = payload.rendezvousInformation;
1000 0 : if (!rendezvousInformation.HasValue())
1001 : {
1002 : // No idea which commissioning channels this device supports, so we
1003 : // should be trying using all of them.
1004 0 : return true;
1005 : }
1006 :
1007 0 : if (rendezvousInformation.Value().Has(commissioningChannel))
1008 : {
1009 0 : return true;
1010 : }
1011 : }
1012 :
1013 : // None of the payloads claimed support for this commissioning channel.
1014 0 : return false;
1015 : }
1016 :
1017 0 : SetUpCodePairerParameters::SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data,
1018 0 : std::optional<uint16_t> longDiscriminator, size_t index) :
1019 0 : mLongDiscriminator(longDiscriminator)
1020 : {
1021 0 : mInterfaceId = data.interfaceId;
1022 0 : Platform::CopyString(mHostName, data.hostName);
1023 :
1024 0 : auto & ip = data.ipAddress[index];
1025 0 : SetPeerAddress(Transport::PeerAddress::UDP(ip, data.port, ip.IsIPv6LinkLocal() ? data.interfaceId : Inet::InterfaceId::Null()));
1026 :
1027 0 : if (data.mrpRetryIntervalIdle.has_value())
1028 : {
1029 0 : SetIdleInterval(*data.mrpRetryIntervalIdle);
1030 : }
1031 :
1032 0 : if (data.mrpRetryIntervalActive.has_value())
1033 : {
1034 0 : SetActiveInterval(*data.mrpRetryIntervalActive);
1035 : }
1036 0 : }
1037 :
1038 : #if CONFIG_NETWORK_LAYER_BLE
1039 0 : SetUpCodePairerParameters::SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator,
1040 0 : bool connected) :
1041 0 : mLongDiscriminator(longDiscriminator)
1042 : {
1043 0 : Transport::PeerAddress peerAddress = Transport::PeerAddress::BLE();
1044 0 : SetPeerAddress(peerAddress);
1045 0 : if (connected)
1046 : {
1047 0 : SetConnectionObject(connObj);
1048 : }
1049 : else
1050 : {
1051 0 : SetDiscoveredObject(connObj);
1052 : }
1053 0 : }
1054 : #endif // CONFIG_NETWORK_LAYER_BLE
1055 :
1056 : } // namespace Controller
1057 : } // namespace chip
|