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 <system/SystemClock.h>
33 :
34 : constexpr uint32_t kDeviceDiscoveredTimeout = CHIP_CONFIG_SETUP_CODE_PAIRER_DISCOVERY_TIMEOUT_SECS * chip::kMillisecondsPerSecond;
35 :
36 : namespace chip {
37 : namespace Controller {
38 :
39 : namespace {
40 :
41 0 : CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
42 : {
43 0 : bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
44 0 : if (isQRCode)
45 : {
46 0 : ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
47 0 : VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
48 : }
49 : else
50 : {
51 0 : ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
52 0 : VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
53 : }
54 :
55 0 : return CHIP_NO_ERROR;
56 : }
57 : } // namespace
58 :
59 0 : CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
60 : DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
61 : {
62 0 : VerifyOrReturnError(mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
63 0 : VerifyOrReturnError(remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
64 :
65 0 : SetupPayload payload;
66 0 : ReturnErrorOnFailure(GetPayload(setUpCode, payload));
67 :
68 0 : if (resolutionData.HasValue())
69 : {
70 0 : VerifyOrReturnError(discoveryType != DiscoveryType::kAll, CHIP_ERROR_INVALID_ARGUMENT);
71 0 : if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
72 0 : mDiscoveryType == discoveryType)
73 : {
74 0 : NotifyCommissionableDeviceDiscovered(resolutionData.Value());
75 0 : return CHIP_NO_ERROR;
76 : }
77 : }
78 :
79 0 : mConnectionType = commission;
80 0 : mDiscoveryType = discoveryType;
81 0 : mRemoteId = remoteId;
82 0 : mSetUpPINCode = payload.setUpPINCode;
83 :
84 0 : ResetDiscoveryState();
85 :
86 0 : if (resolutionData.HasValue())
87 : {
88 0 : NotifyCommissionableDeviceDiscovered(resolutionData.Value());
89 0 : return CHIP_NO_ERROR;
90 : }
91 :
92 0 : ReturnErrorOnFailure(Connect(payload));
93 0 : return mSystemLayer->StartTimer(System::Clock::Milliseconds32(kDeviceDiscoveredTimeout), OnDeviceDiscoveredTimeoutCallback,
94 0 : this);
95 0 : }
96 0 : CHIP_ERROR SetUpCodePairer::Connect(SetupPayload & payload)
97 : {
98 0 : CHIP_ERROR err = CHIP_NO_ERROR;
99 0 : bool isRunning = false;
100 :
101 0 : bool searchOverAll = !payload.rendezvousInformation.HasValue();
102 :
103 0 : if (mDiscoveryType == DiscoveryType::kAll)
104 : {
105 0 : if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kBLE))
106 : {
107 0 : if (CHIP_NO_ERROR == (err = StartDiscoverOverBle(payload)))
108 : {
109 0 : isRunning = true;
110 : }
111 0 : VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
112 : }
113 :
114 0 : if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kSoftAP))
115 : {
116 0 : if (CHIP_NO_ERROR == (err = StartDiscoverOverSoftAP(payload)))
117 : {
118 0 : isRunning = true;
119 : }
120 0 : VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
121 : }
122 : }
123 :
124 : // We always want to search on network because any node that has already been commissioned will use on-network regardless of the
125 : // QR code flag.
126 0 : if (CHIP_NO_ERROR == (err = StartDiscoverOverIP(payload)))
127 : {
128 0 : isRunning = true;
129 : }
130 0 : VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err, err);
131 :
132 0 : return isRunning ? CHIP_NO_ERROR : CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
133 : }
134 :
135 0 : CHIP_ERROR SetUpCodePairer::StartDiscoverOverBle(SetupPayload & payload)
136 : {
137 : #if CONFIG_NETWORK_LAYER_BLE
138 : #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
139 : VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
140 : mCommissioner->ConnectBleTransportToSelf();
141 : #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
142 0 : VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
143 :
144 0 : ChipLogProgress(Controller, "Starting commissioning discovery over BLE");
145 :
146 : // Handle possibly-sync callbacks.
147 0 : mWaitingForDiscovery[kBLETransport] = true;
148 0 : CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
149 : OnDiscoveredDeviceOverBleError);
150 0 : if (err != CHIP_NO_ERROR)
151 : {
152 0 : mWaitingForDiscovery[kBLETransport] = false;
153 : }
154 0 : return err;
155 : #else
156 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
157 : #endif // CONFIG_NETWORK_LAYER_BLE
158 : }
159 :
160 0 : CHIP_ERROR SetUpCodePairer::StopConnectOverBle()
161 : {
162 : // Make sure to not call CancelBleIncompleteConnection unless we are in fact
163 : // waiting on BLE discovery. It will cancel connections that are in fact
164 : // completed. In particular, if we just established PASE over BLE calling
165 : // CancelBleIncompleteConnection here unconditionally would cancel the BLE
166 : // connection underlying the PASE session. So make sure to only call
167 : // CancelBleIncompleteConnection if we're still waiting to hear back on the
168 : // BLE discovery bits.
169 0 : if (!mWaitingForDiscovery[kBLETransport])
170 : {
171 0 : return CHIP_NO_ERROR;
172 : }
173 :
174 0 : mWaitingForDiscovery[kBLETransport] = false;
175 : #if CONFIG_NETWORK_LAYER_BLE
176 0 : VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
177 0 : ChipLogDetail(Controller, "Stopping commissioning discovery over BLE");
178 0 : return mBleLayer->CancelBleIncompleteConnection();
179 : #else
180 : return CHIP_NO_ERROR;
181 : #endif // CONFIG_NETWORK_LAYER_BLE
182 : }
183 :
184 0 : CHIP_ERROR SetUpCodePairer::StartDiscoverOverIP(SetupPayload & payload)
185 : {
186 0 : ChipLogProgress(Controller, "Starting commissioning discovery over DNS-SD");
187 :
188 0 : auto & discriminator = payload.discriminator;
189 0 : if (discriminator.IsShortDiscriminator())
190 : {
191 0 : mCurrentFilter.type = Dnssd::DiscoveryFilterType::kShortDiscriminator;
192 0 : mCurrentFilter.code = discriminator.GetShortValue();
193 : }
194 : else
195 : {
196 0 : mCurrentFilter.type = Dnssd::DiscoveryFilterType::kLongDiscriminator;
197 0 : mCurrentFilter.code = discriminator.GetLongValue();
198 : }
199 0 : mPayloadVendorID = payload.vendorID;
200 0 : mPayloadProductID = payload.productID;
201 :
202 : // Handle possibly-sync callbacks.
203 0 : mWaitingForDiscovery[kIPTransport] = true;
204 0 : CHIP_ERROR err = mCommissioner->DiscoverCommissionableNodes(mCurrentFilter);
205 0 : if (err != CHIP_NO_ERROR)
206 : {
207 0 : mWaitingForDiscovery[kIPTransport] = false;
208 : }
209 0 : return err;
210 : }
211 :
212 0 : CHIP_ERROR SetUpCodePairer::StopConnectOverIP()
213 : {
214 0 : ChipLogDetail(Controller, "Stopping commissioning discovery over DNS-SD");
215 :
216 0 : mWaitingForDiscovery[kIPTransport] = false;
217 0 : mCurrentFilter.type = Dnssd::DiscoveryFilterType::kNone;
218 0 : mPayloadVendorID = kNotAvailable;
219 0 : mPayloadProductID = kNotAvailable;
220 :
221 0 : mCommissioner->StopCommissionableDiscovery();
222 0 : return CHIP_NO_ERROR;
223 : }
224 :
225 0 : CHIP_ERROR SetUpCodePairer::StartDiscoverOverSoftAP(SetupPayload & payload)
226 : {
227 0 : return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
228 : }
229 :
230 0 : CHIP_ERROR SetUpCodePairer::StopConnectOverSoftAP()
231 : {
232 0 : mWaitingForDiscovery[kSoftAPTransport] = false;
233 0 : return CHIP_NO_ERROR;
234 : }
235 :
236 0 : bool SetUpCodePairer::ConnectToDiscoveredDevice()
237 : {
238 0 : if (mWaitingForPASE)
239 : {
240 : // Nothing to do. Just wait until we either succeed or fail at that
241 : // PASE session establishment.
242 0 : return false;
243 : }
244 :
245 0 : while (!mDiscoveredParameters.empty())
246 : {
247 : // Grab the first element from the queue and try connecting to it.
248 : // Remove it from the queue before we try to connect, in case the
249 : // connection attempt fails and calls right back into us to try the next
250 : // thing.
251 0 : SetUpCodePairerParameters params(mDiscoveredParameters.front());
252 0 : mDiscoveredParameters.pop_front();
253 :
254 0 : params.SetSetupPINCode(mSetUpPINCode);
255 :
256 : #if CHIP_PROGRESS_LOGGING
257 : char buf[Transport::PeerAddress::kMaxToStringSize];
258 0 : params.GetPeerAddress().ToString(buf);
259 0 : ChipLogProgress(Controller, "Attempting PASE connection to %s", buf);
260 : #endif // CHIP_PROGRESS_LOGGING
261 :
262 : // Handle possibly-sync call backs from attempts to establish PASE.
263 0 : ExpectPASEEstablishment();
264 :
265 0 : if (params.GetPeerAddress().GetTransportType() == Transport::Type::kUdp)
266 : {
267 0 : mCurrentPASEParameters.SetValue(params);
268 : }
269 :
270 : CHIP_ERROR err;
271 0 : if (mConnectionType == SetupCodePairerBehaviour::kCommission)
272 : {
273 0 : err = mCommissioner->PairDevice(mRemoteId, params);
274 : }
275 : else
276 : {
277 0 : err = mCommissioner->EstablishPASEConnection(mRemoteId, params);
278 : }
279 :
280 0 : LogErrorOnFailure(err);
281 0 : if (err == CHIP_NO_ERROR)
282 : {
283 0 : return true;
284 : }
285 :
286 : // Failed to start establishing PASE. Move on to the next item.
287 0 : PASEEstablishmentComplete();
288 0 : }
289 :
290 0 : return false;
291 : }
292 :
293 : #if CONFIG_NETWORK_LAYER_BLE
294 0 : void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj)
295 : {
296 0 : ChipLogProgress(Controller, "Discovered device to be commissioned over BLE");
297 :
298 0 : mWaitingForDiscovery[kBLETransport] = false;
299 :
300 : // In order to not wait for all the possible addresses discovered over mdns to
301 : // be tried before trying to connect over BLE, the discovered connection object is
302 : // inserted at the beginning of the list.
303 : //
304 : // It makes it the 'next' thing to try to connect to if there are already some
305 : // discovered parameters in the list.
306 0 : mDiscoveredParameters.emplace_front(connObj);
307 0 : ConnectToDiscoveredDevice();
308 0 : }
309 :
310 0 : void SetUpCodePairer::OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj)
311 : {
312 0 : (static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj);
313 0 : }
314 :
315 0 : void SetUpCodePairer::OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err)
316 : {
317 0 : static_cast<SetUpCodePairer *>(appState)->OnBLEDiscoveryError(err);
318 0 : }
319 :
320 0 : void SetUpCodePairer::OnBLEDiscoveryError(CHIP_ERROR err)
321 : {
322 0 : ChipLogError(Controller, "Commissioning discovery over BLE failed: %" CHIP_ERROR_FORMAT, err.Format());
323 0 : mWaitingForDiscovery[kBLETransport] = false;
324 0 : LogErrorOnFailure(err);
325 0 : }
326 : #endif // CONFIG_NETWORK_LAYER_BLE
327 :
328 0 : bool SetUpCodePairer::IdIsPresent(uint16_t vendorOrProductID)
329 : {
330 0 : return vendorOrProductID != kNotAvailable;
331 : }
332 :
333 0 : bool SetUpCodePairer::NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const
334 : {
335 0 : if (nodeData.commissionData.commissioningMode == 0)
336 : {
337 0 : ChipLogProgress(Controller, "Discovered device does not have an open commissioning window.");
338 0 : return false;
339 : }
340 :
341 : // The advertisement may not include a vendor id.
342 0 : if (IdIsPresent(mPayloadVendorID) && IdIsPresent(nodeData.commissionData.vendorId) &&
343 0 : mPayloadVendorID != nodeData.commissionData.vendorId)
344 : {
345 0 : ChipLogProgress(Controller, "Discovered device does not match our vendor id.");
346 0 : return false;
347 : }
348 :
349 : // The advertisement may not include a product id.
350 0 : if (IdIsPresent(mPayloadProductID) && IdIsPresent(nodeData.commissionData.productId) &&
351 0 : mPayloadProductID != nodeData.commissionData.productId)
352 : {
353 0 : ChipLogProgress(Controller, "Discovered device does not match our product id.");
354 0 : return false;
355 : }
356 :
357 0 : bool discriminatorMatches = false;
358 0 : switch (mCurrentFilter.type)
359 : {
360 0 : case Dnssd::DiscoveryFilterType::kShortDiscriminator:
361 0 : discriminatorMatches = (((nodeData.commissionData.longDiscriminator >> 8) & 0x0F) == mCurrentFilter.code);
362 0 : break;
363 0 : case Dnssd::DiscoveryFilterType::kLongDiscriminator:
364 0 : discriminatorMatches = (nodeData.commissionData.longDiscriminator == mCurrentFilter.code);
365 0 : break;
366 0 : default:
367 0 : ChipLogError(Controller, "Unknown filter type; all matches will fail");
368 0 : return false;
369 : }
370 0 : if (!discriminatorMatches)
371 : {
372 0 : ChipLogProgress(Controller, "Discovered device does not match our discriminator.");
373 : }
374 0 : return discriminatorMatches;
375 : }
376 :
377 0 : void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::DiscoveredNodeData & nodeData)
378 : {
379 0 : if (!NodeMatchesCurrentFilter(nodeData))
380 : {
381 0 : return;
382 : }
383 :
384 0 : ChipLogProgress(Controller, "Discovered device to be commissioned over DNS-SD");
385 :
386 0 : NotifyCommissionableDeviceDiscovered(nodeData.resolutionData);
387 : }
388 :
389 0 : void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::CommonResolutionData & resolutionData)
390 : {
391 0 : if (mDiscoveryType == DiscoveryType::kDiscoveryNetworkOnlyWithoutPASEAutoRetry)
392 : {
393 : // If the discovery type does not want the PASE auto retry mechanism, we will just store
394 : // a single IP. So the discovery process is stopped as it won't be of any help anymore.
395 0 : StopConnectOverIP();
396 0 : mDiscoveredParameters.emplace_back(resolutionData, 0);
397 : }
398 : else
399 : {
400 0 : for (size_t i = 0; i < resolutionData.numIPs; i++)
401 : {
402 0 : mDiscoveredParameters.emplace_back(resolutionData, i);
403 : }
404 : }
405 :
406 0 : ConnectToDiscoveredDevice();
407 0 : }
408 :
409 0 : bool SetUpCodePairer::StopPairing(NodeId remoteId)
410 : {
411 0 : VerifyOrReturnValue(mRemoteId != kUndefinedNodeId, false);
412 0 : VerifyOrReturnValue(remoteId == kUndefinedNodeId || remoteId == mRemoteId, false);
413 :
414 0 : if (mWaitingForPASE)
415 : {
416 0 : PASEEstablishmentComplete();
417 : }
418 :
419 0 : ResetDiscoveryState();
420 0 : mRemoteId = kUndefinedNodeId;
421 0 : return true;
422 : }
423 :
424 0 : bool SetUpCodePairer::TryNextRendezvousParameters()
425 : {
426 0 : if (ConnectToDiscoveredDevice())
427 : {
428 0 : ChipLogProgress(Controller, "Trying connection to commissionee over different transport");
429 0 : return true;
430 : }
431 :
432 0 : if (DiscoveryInProgress())
433 : {
434 0 : ChipLogProgress(Controller, "Waiting to discover commissionees that match our filters");
435 0 : return true;
436 : }
437 :
438 0 : return false;
439 : }
440 :
441 0 : bool SetUpCodePairer::DiscoveryInProgress() const
442 : {
443 0 : for (const auto & waiting : mWaitingForDiscovery)
444 : {
445 0 : if (waiting)
446 : {
447 0 : return true;
448 : }
449 : }
450 :
451 0 : return false;
452 : }
453 :
454 0 : void SetUpCodePairer::ResetDiscoveryState()
455 : {
456 0 : StopConnectOverBle();
457 0 : StopConnectOverIP();
458 0 : StopConnectOverSoftAP();
459 :
460 : // Just in case any of those failed to reset the waiting state properly.
461 0 : for (auto & waiting : mWaitingForDiscovery)
462 : {
463 0 : waiting = false;
464 : }
465 :
466 0 : mDiscoveredParameters.clear();
467 0 : mCurrentPASEParameters.ClearValue();
468 0 : mLastPASEError = CHIP_NO_ERROR;
469 :
470 0 : mSystemLayer->CancelTimer(OnDeviceDiscoveredTimeoutCallback, this);
471 0 : }
472 :
473 0 : void SetUpCodePairer::ExpectPASEEstablishment()
474 : {
475 0 : VerifyOrDie(!mWaitingForPASE);
476 0 : mWaitingForPASE = true;
477 0 : auto * delegate = mCommissioner->GetPairingDelegate();
478 0 : VerifyOrDie(delegate != this);
479 0 : mPairingDelegate = delegate;
480 0 : mCommissioner->RegisterPairingDelegate(this);
481 0 : }
482 :
483 0 : void SetUpCodePairer::PASEEstablishmentComplete()
484 : {
485 0 : VerifyOrDie(mWaitingForPASE);
486 0 : mWaitingForPASE = false;
487 0 : mCommissioner->RegisterPairingDelegate(mPairingDelegate);
488 0 : mPairingDelegate = nullptr;
489 0 : }
490 :
491 0 : void SetUpCodePairer::OnStatusUpdate(DevicePairingDelegate::Status status)
492 : {
493 0 : if (status == DevicePairingDelegate::Status::SecurePairingFailed)
494 : {
495 : // If we're still waiting on discovery, don't propagate this failure
496 : // (which is due to PASE failure with something we discovered, but the
497 : // "something" may not have been the right thing) for now. Wait until
498 : // discovery completes. Then we will either succeed and notify
499 : // accordingly or time out and land in OnStatusUpdate again, but at that
500 : // point we will not be waiting on discovery anymore.
501 0 : if (!mDiscoveredParameters.empty())
502 : {
503 0 : ChipLogProgress(Controller, "Ignoring SecurePairingFailed status for now; we have more discovered devices to try");
504 0 : return;
505 : }
506 :
507 0 : if (DiscoveryInProgress())
508 : {
509 0 : ChipLogProgress(Controller,
510 : "Ignoring SecurePairingFailed status for now; we are waiting to see if we discover more devices");
511 0 : return;
512 : }
513 : }
514 :
515 0 : if (mPairingDelegate)
516 : {
517 0 : mPairingDelegate->OnStatusUpdate(status);
518 : }
519 : }
520 :
521 0 : void SetUpCodePairer::OnPairingComplete(CHIP_ERROR error)
522 : {
523 : // Save the pairing delegate so we can notify it. We want to notify it
524 : // _after_ we restore the state on the commissioner, in case the delegate
525 : // ends up immediately calling back into the commissioner again when
526 : // notified.
527 0 : auto * pairingDelegate = mPairingDelegate;
528 0 : PASEEstablishmentComplete();
529 :
530 0 : if (CHIP_NO_ERROR == error)
531 : {
532 0 : ChipLogProgress(Controller, "Pairing with commissionee successful, stopping discovery");
533 0 : ResetDiscoveryState();
534 0 : mRemoteId = kUndefinedNodeId;
535 0 : if (pairingDelegate != nullptr)
536 : {
537 0 : pairingDelegate->OnPairingComplete(error);
538 : }
539 0 : return;
540 : }
541 :
542 : // It may happen that there is a stale DNS entry. If so, ReconfirmRecord will flush
543 : // the record from the daemon cache once it determines that it is invalid.
544 : // It may not help for this particular resolve, but may help subsequent resolves.
545 0 : if (CHIP_ERROR_TIMEOUT == error && mCurrentPASEParameters.HasValue())
546 : {
547 0 : const auto & params = mCurrentPASEParameters.Value();
548 0 : const auto & peer = params.GetPeerAddress();
549 0 : const auto & ip = peer.GetIPAddress();
550 0 : auto err = Dnssd::Resolver::Instance().ReconfirmRecord(params.mHostName, ip, params.mInterfaceId);
551 0 : if (CHIP_NO_ERROR != err && CHIP_ERROR_NOT_IMPLEMENTED != err)
552 : {
553 0 : ChipLogError(Controller, "Error when verifying the validity of an address: %" CHIP_ERROR_FORMAT, err.Format());
554 : }
555 : }
556 0 : mCurrentPASEParameters.ClearValue();
557 :
558 : // We failed to establish PASE. Try the next thing we have discovered, if
559 : // any.
560 0 : if (TryNextRendezvousParameters())
561 : {
562 : // Keep waiting until that finishes. Don't call OnPairingComplete yet.
563 0 : mLastPASEError = error;
564 0 : return;
565 : }
566 :
567 0 : if (pairingDelegate != nullptr)
568 : {
569 0 : pairingDelegate->OnPairingComplete(error);
570 : }
571 : }
572 :
573 0 : void SetUpCodePairer::OnPairingDeleted(CHIP_ERROR error)
574 : {
575 0 : if (mPairingDelegate)
576 : {
577 0 : mPairingDelegate->OnPairingDeleted(error);
578 : }
579 0 : }
580 :
581 0 : void SetUpCodePairer::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error)
582 : {
583 : // Not really expecting this, but handle it anyway.
584 0 : if (mPairingDelegate)
585 : {
586 0 : mPairingDelegate->OnCommissioningComplete(deviceId, error);
587 : }
588 0 : }
589 :
590 0 : void SetUpCodePairer::OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context)
591 : {
592 0 : ChipLogError(Controller, "Discovery timed out");
593 0 : auto * pairer = static_cast<SetUpCodePairer *>(context);
594 0 : LogErrorOnFailure(pairer->StopConnectOverBle());
595 0 : LogErrorOnFailure(pairer->StopConnectOverIP());
596 0 : LogErrorOnFailure(pairer->StopConnectOverSoftAP());
597 0 : if (!pairer->mWaitingForPASE && pairer->mDiscoveredParameters.empty())
598 : {
599 : // We're not waiting on any more PASE attempts, and we're not going to
600 : // discover anything at this point, so we should just notify our
601 : // listener.
602 0 : CHIP_ERROR err = pairer->mLastPASEError;
603 0 : if (err == CHIP_NO_ERROR)
604 : {
605 0 : err = CHIP_ERROR_TIMEOUT;
606 : }
607 0 : pairer->mCommissioner->OnSessionEstablishmentError(err);
608 : }
609 0 : }
610 :
611 0 : SetUpCodePairerParameters::SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index)
612 : {
613 0 : mInterfaceId = data.interfaceId;
614 0 : Platform::CopyString(mHostName, data.hostName);
615 :
616 0 : auto & ip = data.ipAddress[index];
617 0 : SetPeerAddress(Transport::PeerAddress::UDP(ip, data.port, ip.IsIPv6LinkLocal() ? data.interfaceId : Inet::InterfaceId::Null()));
618 :
619 0 : if (data.mrpRetryIntervalIdle.HasValue())
620 : {
621 0 : SetIdleInterval(data.mrpRetryIntervalIdle.Value());
622 : }
623 :
624 0 : if (data.mrpRetryIntervalActive.HasValue())
625 : {
626 0 : SetActiveInterval(data.mrpRetryIntervalActive.Value());
627 : }
628 0 : }
629 :
630 : #if CONFIG_NETWORK_LAYER_BLE
631 0 : SetUpCodePairerParameters::SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected)
632 : {
633 0 : Transport::PeerAddress peerAddress = Transport::PeerAddress::BLE();
634 0 : SetPeerAddress(peerAddress);
635 0 : if (connected)
636 : {
637 0 : SetConnectionObject(connObj);
638 : }
639 : else
640 : {
641 0 : SetDiscoveredObject(connObj);
642 : }
643 0 : }
644 : #endif // CONFIG_NETWORK_LAYER_BLE
645 :
646 : } // namespace Controller
647 : } // namespace chip
|