Skip to content

Commit b4a6213

Browse files
authoredApr 17, 2024··
[Python] Create pairingDelegate for each DeviceController (#32369)
* Create pairingDelegate for each DeviceController * restore the original pairingcomplete callback logic
1 parent 692e9e1 commit b4a6213

File tree

3 files changed

+128
-78
lines changed

3 files changed

+128
-78
lines changed
 

‎src/controller/python/ChipDeviceController-ScriptBinding.cpp

+56-41
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ chip::Controller::CommissioningParameters sCommissioningParameters;
105105

106106
} // namespace
107107

108-
chip::Controller::ScriptDevicePairingDelegate sPairingDelegate;
109108
chip::Controller::ScriptPairingDeviceDiscoveryDelegate sPairingDeviceDiscoveryDelegate;
110109
chip::Credentials::GroupDataProviderImpl sGroupDataProvider;
111110
chip::Credentials::PersistentStorageOpCertStore sPersistentStorageOpCertStore;
@@ -121,9 +120,8 @@ extern "C" {
121120
PyChipError pychip_DeviceController_StackInit(Controller::Python::StorageAdapter * storageAdapter, bool enableServerInteractions);
122121
PyChipError pychip_DeviceController_StackShutdown();
123122

124-
PyChipError pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl,
125-
chip::NodeId localDeviceId, bool useTestCommissioner);
126-
PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl);
123+
PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl,
124+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate);
127125
PyChipError pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
128126
char * outAddress, uint64_t maxAddressLen, uint16_t * outPort);
129127
PyChipError pychip_DeviceController_GetCompressedFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId);
@@ -168,35 +166,46 @@ PyChipError pychip_DeviceController_DiscoverCommissionableNodesDeviceType(chip::
168166
uint16_t device_type);
169167
PyChipError pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl);
170168

171-
PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, uint64_t nodeId,
172-
uint32_t setupPasscode, const uint8_t filterType, const char * filterParam,
173-
uint32_t discoveryTimeoutMsec);
169+
PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl,
170+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
171+
uint64_t nodeId, uint32_t setupPasscode, const uint8_t filterType,
172+
const char * filterParam, uint32_t discoveryTimeoutMsec);
174173

175174
PyChipError pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext);
176175

177-
PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid,
178-
uint16_t timeout, uint32_t iteration, uint16_t discriminator,
179-
uint8_t optionInt);
176+
PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl,
177+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
178+
chip::NodeId nodeid, uint16_t timeout, uint32_t iteration,
179+
uint16_t discriminator, uint8_t optionInt);
180180

181181
void pychip_DeviceController_PrintDiscoveredDevices(chip::Controller::DeviceCommissioner * devCtrl);
182182
bool pychip_DeviceController_GetIPForDiscoveredDevice(chip::Controller::DeviceCommissioner * devCtrl, int idx, char * addrStr,
183183
uint32_t len);
184184

185185
// Pairing Delegate
186186
PyChipError
187-
pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl,
187+
pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
188188
chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback);
189189

190190
PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback(
191-
chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback);
191+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
192+
chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback);
192193

193194
PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback(
194-
chip::Controller::DeviceCommissioner * devCtrl,
195+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
195196
chip::Controller::DevicePairingDelegate_OnCommissioningStatusUpdateFunct callback);
197+
196198
PyChipError
197-
pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback);
199+
pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
200+
chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback);
201+
198202
PyChipError pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback(
199-
chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback);
203+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
204+
chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback);
205+
206+
PyChipError
207+
pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
208+
bool value);
200209

201210
// BLE
202211
PyChipError pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::DeviceCommissioner * devCtrl);
@@ -354,7 +363,6 @@ const char * pychip_DeviceController_StatusReportToString(uint32_t profileId, ui
354363
PyChipError pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
355364
uint32_t setupPINCode, chip::NodeId nodeid)
356365
{
357-
sPairingDelegate.SetExpectingPairingComplete(true);
358366
return ToPyChipError(devCtrl->PairDevice(nodeid,
359367
chip::RendezvousParameters()
360368
.SetPeerAddress(Transport::PeerAddress(Transport::Type::kBle))
@@ -378,14 +386,12 @@ PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommission
378386
addr.SetTransportType(chip::Transport::Type::kUdp).SetIPAddress(peerAddr).SetInterface(ifaceOutput);
379387
params.SetPeerAddress(addr).SetDiscriminator(0);
380388

381-
sPairingDelegate.SetExpectingPairingComplete(true);
382389
return ToPyChipError(devCtrl->PairDevice(nodeid, params, sCommissioningParameters));
383390
}
384391

385392
PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload,
386393
chip::NodeId nodeid, uint8_t discoveryType)
387394
{
388-
sPairingDelegate.SetExpectingPairingComplete(true);
389395
return ToPyChipError(devCtrl->PairDevice(nodeid, onboardingPayload, sCommissioningParameters,
390396
static_cast<chip::Controller::DiscoveryType>(discoveryType)));
391397
}
@@ -430,9 +436,10 @@ PyChipError pychip_DeviceController_UnpairDevice(chip::Controller::DeviceCommiss
430436
return ToPyChipError(err);
431437
}
432438

433-
PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, uint64_t nodeId,
434-
uint32_t setupPasscode, const uint8_t filterType, const char * filterParam,
435-
uint32_t discoveryTimeoutMsec)
439+
PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl,
440+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
441+
uint64_t nodeId, uint32_t setupPasscode, const uint8_t filterType,
442+
const char * filterParam, uint32_t discoveryTimeoutMsec)
436443
{
437444
Dnssd::DiscoveryFilter filter(static_cast<Dnssd::DiscoveryFilterType>(filterType));
438445
switch (static_cast<Dnssd::DiscoveryFilterType>(filterType))
@@ -467,9 +474,8 @@ PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::Device
467474
return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT);
468475
}
469476

470-
sPairingDelegate.SetExpectingPairingComplete(true);
471-
CHIP_ERROR err = sPairingDeviceDiscoveryDelegate.Init(nodeId, setupPasscode, sCommissioningParameters, &sPairingDelegate,
472-
devCtrl, discoveryTimeoutMsec);
477+
CHIP_ERROR err = sPairingDeviceDiscoveryDelegate.Init(nodeId, setupPasscode, sCommissioningParameters, pairingDelegate, devCtrl,
478+
discoveryTimeoutMsec);
473479
VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err));
474480
return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
475481
}
@@ -587,7 +593,6 @@ PyChipError pychip_DeviceController_EstablishPASESessionIP(chip::Controller::Dev
587593
addr.SetPort(port);
588594
}
589595
params.SetPeerAddress(addr).SetDiscriminator(0);
590-
sPairingDelegate.SetExpectingPairingComplete(true);
591596
return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, params));
592597
}
593598

@@ -598,14 +603,12 @@ PyChipError pychip_DeviceController_EstablishPASESessionBLE(chip::Controller::De
598603
RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode);
599604
addr.SetTransportType(chip::Transport::Type::kBle);
600605
params.SetPeerAddress(addr).SetDiscriminator(discriminator);
601-
sPairingDelegate.SetExpectingPairingComplete(true);
602606
return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, params));
603607
}
604608

605609
PyChipError pychip_DeviceController_EstablishPASESession(chip::Controller::DeviceCommissioner * devCtrl, const char * setUpCode,
606610
chip::NodeId nodeid)
607611
{
608-
sPairingDelegate.SetExpectingPairingComplete(true);
609612
return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, setUpCode));
610613
}
611614

@@ -656,15 +659,17 @@ PyChipError pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnab
656659
}
657660

658661
PyChipError pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback(
659-
chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback)
662+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
663+
chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback)
660664
{
661-
sPairingDelegate.SetCommissioningWindowOpenCallback(callback);
665+
pairingDelegate->SetCommissioningWindowOpenCallback(callback);
662666
return ToPyChipError(CHIP_NO_ERROR);
663667
}
664668

665-
PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid,
666-
uint16_t timeout, uint32_t iteration, uint16_t discriminator,
667-
uint8_t optionInt)
669+
PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl,
670+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
671+
chip::NodeId nodeid, uint16_t timeout, uint32_t iteration,
672+
uint16_t discriminator, uint8_t optionInt)
668673
{
669674
const auto option = static_cast<Controller::CommissioningWindowOpener::CommissioningWindowOption>(optionInt);
670675
if (option == Controller::CommissioningWindowOpener::CommissioningWindowOption::kOriginalSetupCode)
@@ -680,40 +685,50 @@ PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::De
680685
Platform::New<Controller::CommissioningWindowOpener>(static_cast<chip::Controller::DeviceController *>(devCtrl));
681686
PyChipError err = ToPyChipError(opener->OpenCommissioningWindow(nodeid, System::Clock::Seconds16(timeout), iteration,
682687
discriminator, NullOptional, NullOptional,
683-
sPairingDelegate.GetOpenWindowCallback(opener), payload));
688+
pairingDelegate->GetOpenWindowCallback(opener), payload));
684689
return err;
685690
}
686691

687692
return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT);
688693
}
689694

690695
PyChipError
691-
pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl,
696+
pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
692697
chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback)
693698
{
694-
sPairingDelegate.SetKeyExchangeCallback(callback);
699+
pairingDelegate->SetKeyExchangeCallback(callback);
695700
return ToPyChipError(CHIP_NO_ERROR);
696701
}
697702

698703
PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback(
699-
chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback)
704+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
705+
chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback)
700706
{
701-
sPairingDelegate.SetCommissioningCompleteCallback(callback);
707+
pairingDelegate->SetCommissioningCompleteCallback(callback);
702708
return ToPyChipError(CHIP_NO_ERROR);
703709
}
704710

705711
PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback(
706-
chip::Controller::DeviceCommissioner * devCtrl,
712+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
707713
chip::Controller::DevicePairingDelegate_OnCommissioningStatusUpdateFunct callback)
708714
{
709-
sPairingDelegate.SetCommissioningStatusUpdateCallback(callback);
715+
pairingDelegate->SetCommissioningStatusUpdateCallback(callback);
716+
return ToPyChipError(CHIP_NO_ERROR);
717+
}
718+
719+
PyChipError
720+
pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
721+
chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback)
722+
{
723+
pairingDelegate->SetFabricCheckCallback(callback);
710724
return ToPyChipError(CHIP_NO_ERROR);
711725
}
712726

713727
PyChipError
714-
pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback)
728+
pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate,
729+
bool value)
715730
{
716-
sPairingDelegate.SetFabricCheckCallback(callback);
731+
pairingDelegate->SetExpectingPairingComplete(value);
717732
return ToPyChipError(CHIP_NO_ERROR);
718733
}
719734

‎src/controller/python/OpCredsBinding.cpp

+26-14
Original file line numberDiff line numberDiff line change
@@ -402,24 +402,25 @@ void pychip_OnCommissioningStatusUpdate(chip::PeerId peerId, chip::Controller::C
402402
* TODO(#25214): Need clean up API
403403
*
404404
*/
405-
PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow(chip::Controller::DeviceCommissioner ** outDevCtrl,
406-
chip::python::pychip_P256Keypair * operationalKey,
407-
uint8_t * noc, uint32_t nocLen, uint8_t * icac,
408-
uint32_t icacLen, uint8_t * rcac, uint32_t rcacLen,
409-
const uint8_t * ipk, uint32_t ipkLen,
410-
chip::VendorId adminVendorId, bool enableServerInteractions)
405+
PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow(
406+
chip::Controller::DeviceCommissioner ** outDevCtrl, chip::Controller::ScriptDevicePairingDelegate ** outPairingDelegate,
407+
chip::python::pychip_P256Keypair * operationalKey, uint8_t * noc, uint32_t nocLen, uint8_t * icac, uint32_t icacLen,
408+
uint8_t * rcac, uint32_t rcacLen, const uint8_t * ipk, uint32_t ipkLen, chip::VendorId adminVendorId,
409+
bool enableServerInteractions)
411410
{
412411
ReturnErrorCodeIf(nocLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY));
413412
ReturnErrorCodeIf(icacLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY));
414413
ReturnErrorCodeIf(rcacLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY));
415414

416415
ChipLogDetail(Controller, "Creating New Device Controller");
417416

417+
auto pairingDelegate = std::make_unique<chip::Controller::ScriptDevicePairingDelegate>();
418+
VerifyOrReturnError(pairingDelegate != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY));
418419
auto devCtrl = std::make_unique<chip::Controller::DeviceCommissioner>();
419420
VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY));
420421

421422
Controller::SetupParams initParams;
422-
initParams.pairingDelegate = &sPairingDelegate;
423+
initParams.pairingDelegate = pairingDelegate.get();
423424
initParams.operationalCredentialsDelegate = &sPlaceholderOperationalCredentialsIssuer;
424425
initParams.operationalKeypair = operationalKey;
425426
initParams.controllerRCAC = ByteSpan(rcac, rcacLen);
@@ -450,13 +451,15 @@ PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow(chip::Co
450451
chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), fabricIpk, compressedFabricIdSpan);
451452
VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err));
452453

453-
*outDevCtrl = devCtrl.release();
454+
*outDevCtrl = devCtrl.release();
455+
*outPairingDelegate = pairingDelegate.release();
454456

455457
return ToPyChipError(CHIP_NO_ERROR);
456458
}
457459

458460
// TODO(#25214): Need clean up API
459461
PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Controller::DeviceCommissioner ** outDevCtrl,
462+
chip::Controller::ScriptDevicePairingDelegate ** outPairingDelegate,
460463
FabricId fabricId, chip::NodeId nodeId, chip::VendorId adminVendorId,
461464
const char * paaTrustStorePath, bool useTestCommissioner,
462465
bool enableServerInteractions, CASEAuthTag * caseAuthTags, uint32_t caseAuthTagLen,
@@ -468,6 +471,8 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co
468471

469472
VerifyOrReturnError(context != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
470473

474+
auto pairingDelegate = std::make_unique<chip::Controller::ScriptDevicePairingDelegate>();
475+
VerifyOrReturnError(pairingDelegate != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY));
471476
auto devCtrl = std::make_unique<chip::Controller::DeviceCommissioner>();
472477
VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY));
473478

@@ -524,7 +529,7 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co
524529
VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err));
525530

526531
Controller::SetupParams initParams;
527-
initParams.pairingDelegate = &sPairingDelegate;
532+
initParams.pairingDelegate = pairingDelegate.get();
528533
initParams.operationalCredentialsDelegate = context->mAdapter.get();
529534
initParams.operationalKeypair = controllerKeyPair;
530535
initParams.controllerRCAC = rcacSpan;
@@ -538,9 +543,9 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co
538543
if (useTestCommissioner)
539544
{
540545
initParams.defaultCommissioner = &sTestCommissioner;
541-
sPairingDelegate.SetCommissioningSuccessCallback(pychip_OnCommissioningSuccess);
542-
sPairingDelegate.SetCommissioningFailureCallback(pychip_OnCommissioningFailure);
543-
sPairingDelegate.SetCommissioningStatusUpdateCallback(pychip_OnCommissioningStatusUpdate);
546+
pairingDelegate->SetCommissioningSuccessCallback(pychip_OnCommissioningSuccess);
547+
pairingDelegate->SetCommissioningFailureCallback(pychip_OnCommissioningFailure);
548+
pairingDelegate->SetCommissioningStatusUpdateCallback(pychip_OnCommissioningStatusUpdate);
544549
}
545550

546551
err = Controller::DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, *devCtrl);
@@ -562,7 +567,8 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co
562567
chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), defaultIpk, compressedFabricIdSpan);
563568
VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err));
564569

565-
*outDevCtrl = devCtrl.release();
570+
*outDevCtrl = devCtrl.release();
571+
*outPairingDelegate = pairingDelegate.release();
566572

567573
return ToPyChipError(CHIP_NO_ERROR);
568574
}
@@ -596,14 +602,20 @@ void pychip_OpCreds_FreeDelegate(OpCredsContext * context)
596602
Platform::Delete(context);
597603
}
598604

599-
PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl)
605+
PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl,
606+
chip::Controller::ScriptDevicePairingDelegate * pairingDelegate)
600607
{
601608
if (devCtrl != nullptr)
602609
{
603610
devCtrl->Shutdown();
604611
delete devCtrl;
605612
}
606613

614+
if (pairingDelegate != nullptr)
615+
{
616+
delete pairingDelegate;
617+
}
618+
607619
return ToPyChipError(CHIP_NO_ERROR);
608620
}
609621

‎src/controller/python/chip/ChipDeviceCtrl.py

+46-23
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,10 @@ def __init__(self, name: str = ''):
253253

254254
self._InitLib()
255255

256+
pairingDelegate = c_void_p(None)
256257
devCtrl = c_void_p(None)
257258

259+
self.pairingDelegate = pairingDelegate
258260
self.devCtrl = devCtrl
259261
self.name = name
260262
self.fabricCheckNodeId = -1
@@ -263,7 +265,7 @@ def __init__(self, name: str = ''):
263265
self._Cluster = ChipClusters(builtins.chipStack)
264266
self._Cluster.InitLib(self._dmLib)
265267

266-
def _set_dev_ctrl(self, devCtrl):
268+
def _set_dev_ctrl(self, devCtrl, pairingDelegate):
267269
def HandleCommissioningComplete(nodeid, err):
268270
if err.is_success:
269271
logging.info("Commissioning complete")
@@ -321,25 +323,26 @@ def HandlePASEEstablishmentComplete(err: PyChipError):
321323
if not err.is_success:
322324
HandleCommissioningComplete(0, err)
323325

326+
self.pairingDelegate = pairingDelegate
324327
self.devCtrl = devCtrl
325328

326329
self.cbHandlePASEEstablishmentCompleteFunct = _DevicePairingDelegate_OnPairingCompleteFunct(
327330
HandlePASEEstablishmentComplete)
328331
self._dmLib.pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(
329-
self.devCtrl, self.cbHandlePASEEstablishmentCompleteFunct)
332+
self.pairingDelegate, self.cbHandlePASEEstablishmentCompleteFunct)
330333

331334
self.cbHandleCommissioningCompleteFunct = _DevicePairingDelegate_OnCommissioningCompleteFunct(
332335
HandleCommissioningComplete)
333336
self._dmLib.pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback(
334-
self.devCtrl, self.cbHandleCommissioningCompleteFunct)
337+
self.pairingDelegate, self.cbHandleCommissioningCompleteFunct)
335338

336339
self.cbHandleFabricCheckFunct = _DevicePairingDelegate_OnFabricCheckFunct(HandleFabricCheck)
337-
self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(self.cbHandleFabricCheckFunct)
340+
self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(self.pairingDelegate, self.cbHandleFabricCheckFunct)
338341

339342
self.cbHandleOpenWindowCompleteFunct = _DevicePairingDelegate_OnOpenWindowCompleteFunct(
340343
HandleOpenWindowComplete)
341344
self._dmLib.pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback(
342-
self.devCtrl, self.cbHandleOpenWindowCompleteFunct)
345+
self.pairingDelegate, self.cbHandleOpenWindowCompleteFunct)
343346

344347
self.cbHandleDeviceUnpairCompleteFunct = _DeviceUnpairingCompleteFunct(HandleUnpairDeviceComplete)
345348

@@ -355,6 +358,11 @@ def _finish_init(self):
355358

356359
ChipDeviceController.activeList.add(self)
357360

361+
def _enablePairingCompeleteCallback(self, value: bool):
362+
self._ChipStack.Call(
363+
lambda: self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(self.pairingDelegate, value)
364+
).raise_on_error()
365+
358366
@property
359367
def fabricAdmin(self) -> FabricAdmin.FabricAdmin:
360368
return self._fabricAdmin
@@ -389,8 +397,9 @@ def Shutdown(self):
389397
if self.devCtrl is not None:
390398
self._ChipStack.Call(
391399
lambda: self._dmLib.pychip_DeviceController_DeleteDeviceController(
392-
self.devCtrl)
400+
self.devCtrl, self.pairingDelegate)
393401
).raise_on_error()
402+
self.pairingDelegate = None
394403
self.devCtrl = None
395404

396405
ChipDeviceController.activeList.remove(self)
@@ -437,6 +446,7 @@ def ConnectBLE(self, discriminator, setupPinCode, nodeid) -> PyChipError:
437446
self._ChipStack.commissioningCompleteEvent.clear()
438447

439448
self.state = DCState.COMMISSIONING
449+
self._enablePairingCompeleteCallback(True)
440450
self._ChipStack.CallAsync(
441451
lambda: self._dmLib.pychip_DeviceController_ConnectBLE(
442452
self.devCtrl, discriminator, setupPinCode, nodeid)
@@ -487,6 +497,7 @@ def EstablishPASESessionBLE(self, setupPinCode: int, discriminator: int, nodeid:
487497
self.CheckIsActive()
488498

489499
self.state = DCState.RENDEZVOUS_ONGOING
500+
self._enablePairingCompeleteCallback(True)
490501
return self._ChipStack.CallAsync(
491502
lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionBLE(
492503
self.devCtrl, setupPinCode, discriminator, nodeid)
@@ -496,6 +507,7 @@ def EstablishPASESessionIP(self, ipaddr: str, setupPinCode: int, nodeid: int, po
496507
self.CheckIsActive()
497508

498509
self.state = DCState.RENDEZVOUS_ONGOING
510+
self._enablePairingCompeleteCallback(True)
499511
return self._ChipStack.CallAsync(
500512
lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionIP(
501513
self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid, port)
@@ -505,6 +517,7 @@ def EstablishPASESession(self, setUpCode: str, nodeid: int):
505517
self.CheckIsActive()
506518

507519
self.state = DCState.RENDEZVOUS_ONGOING
520+
self._enablePairingCompeleteCallback(True)
508521
return self._ChipStack.CallAsync(
509522
lambda: self._dmLib.pychip_DeviceController_EstablishPASESession(
510523
self.devCtrl, setUpCode.encode("utf-8"), nodeid)
@@ -726,7 +739,7 @@ def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: int,
726739
self.CheckIsActive()
727740
self._ChipStack.CallAsync(
728741
lambda: self._dmLib.pychip_DeviceController_OpenCommissioningWindow(
729-
self.devCtrl, nodeid, timeout, iteration, discriminator, option)
742+
self.devCtrl, self.pairingDelegate, nodeid, timeout, iteration, discriminator, option)
730743
).raise_on_error()
731744
self._ChipStack.callbackRes.raise_on_error()
732745
return self._ChipStack.openCommissioningWindowPincode[nodeid]
@@ -1515,16 +1528,13 @@ def _InitLib(self):
15151528
self._dmLib = CDLL(self._ChipStack.LocateChipDLL())
15161529

15171530
self._dmLib.pychip_DeviceController_DeleteDeviceController.argtypes = [
1518-
c_void_p]
1531+
c_void_p, c_void_p]
15191532
self._dmLib.pychip_DeviceController_DeleteDeviceController.restype = PyChipError
15201533

15211534
self._dmLib.pychip_DeviceController_ConnectBLE.argtypes = [
15221535
c_void_p, c_uint16, c_uint32, c_uint64]
15231536
self._dmLib.pychip_DeviceController_ConnectBLE.restype = PyChipError
15241537

1525-
self._dmLib.pychip_DeviceController_ConnectIP.argtypes = [
1526-
c_void_p, c_char_p, c_uint32, c_uint64]
1527-
15281538
self._dmLib.pychip_DeviceController_SetThreadOperationalDataset.argtypes = [
15291539
c_char_p, c_uint32]
15301540
self._dmLib.pychip_DeviceController_SetThreadOperationalDataset.restype = PyChipError
@@ -1560,7 +1570,7 @@ def _InitLib(self):
15601570
self._dmLib.pychip_DeviceController_Commission.restype = PyChipError
15611571

15621572
self._dmLib.pychip_DeviceController_OnNetworkCommission.argtypes = [
1563-
c_void_p, c_uint64, c_uint32, c_uint8, c_char_p, c_uint32]
1573+
c_void_p, c_void_p, c_uint64, c_uint32, c_uint8, c_char_p, c_uint32]
15641574
self._dmLib.pychip_DeviceController_OnNetworkCommission.restype = PyChipError
15651575

15661576
self._dmLib.pychip_DeviceController_DiscoverCommissionableNodes.argtypes = [
@@ -1598,17 +1608,20 @@ def _InitLib(self):
15981608
self._dmLib.pychip_DeviceController_EstablishPASESessionBLE.argtypes = [
15991609
c_void_p, c_uint32, c_uint16, c_uint64]
16001610
self._dmLib.pychip_DeviceController_EstablishPASESessionBLE.restype = PyChipError
1611+
16011612
self._dmLib.pychip_DeviceController_EstablishPASESession.argtypes = [
16021613
c_void_p, c_char_p, c_uint64]
16031614
self._dmLib.pychip_DeviceController_EstablishPASESession.restype = PyChipError
16041615

16051616
self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes.argtypes = [
16061617
c_void_p]
16071618
self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes.restype = PyChipError
1619+
16081620
self._dmLib.pychip_DeviceController_PrintDiscoveredDevices.argtypes = [
16091621
c_void_p]
16101622
self._dmLib.pychip_DeviceController_PrintDiscoveredDevices.argtypes = [
16111623
c_void_p, _ChipDeviceController_IterateDiscoveredCommissionableNodesFunct]
1624+
16121625
self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode.argtypes = [c_void_p]
16131626
self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode.restype = c_bool
16141627

@@ -1653,9 +1666,13 @@ def _InitLib(self):
16531666
self._dmLib.pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback.restype = PyChipError
16541667

16551668
self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback.argtypes = [
1656-
_DevicePairingDelegate_OnFabricCheckFunct]
1669+
c_void_p, _DevicePairingDelegate_OnFabricCheckFunct]
16571670
self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback.restype = PyChipError
16581671

1672+
self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete.argtypes = [
1673+
c_void_p, c_bool]
1674+
self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete.restype = PyChipError
1675+
16591676
self._dmLib.pychip_GetConnectedDeviceByNodeId.argtypes = [
16601677
c_void_p, c_uint64, py_object, _DeviceAvailableCallbackFunct]
16611678
self._dmLib.pychip_GetConnectedDeviceByNodeId.restype = PyChipError
@@ -1683,8 +1700,9 @@ def _InitLib(self):
16831700
self._dmLib.pychip_DeviceController_GetCompressedFabricId.restype = PyChipError
16841701

16851702
self._dmLib.pychip_DeviceController_OpenCommissioningWindow.argtypes = [
1686-
c_void_p, c_uint64, c_uint16, c_uint32, c_uint16, c_uint8]
1703+
c_void_p, c_void_p, c_uint64, c_uint16, c_uint32, c_uint16, c_uint8]
16871704
self._dmLib.pychip_DeviceController_OpenCommissioningWindow.restype = PyChipError
1705+
16881706
self._dmLib.pychip_TestCommissionerUsed.argtypes = []
16891707
self._dmLib.pychip_TestCommissionerUsed.restype = c_bool
16901708

@@ -1700,6 +1718,7 @@ def _InitLib(self):
17001718
self._dmLib.pychip_SetTestCommissionerSimulateFailureOnStage.argtypes = [
17011719
c_uint8]
17021720
self._dmLib.pychip_SetTestCommissionerSimulateFailureOnStage.restype = c_bool
1721+
17031722
self._dmLib.pychip_SetTestCommissionerSimulateFailureOnReport.argtypes = [
17041723
c_uint8]
17051724
self._dmLib.pychip_SetTestCommissionerSimulateFailureOnReport.restype = c_bool
@@ -1712,8 +1731,7 @@ def _InitLib(self):
17121731
self._dmLib.pychip_GetCompletionError.restype = PyChipError
17131732

17141733
self._dmLib.pychip_DeviceController_IssueNOCChain.argtypes = [
1715-
c_void_p, py_object, c_char_p, c_size_t, c_uint64
1716-
]
1734+
c_void_p, py_object, c_char_p, c_size_t, c_uint64]
17171735
self._dmLib.pychip_DeviceController_IssueNOCChain.restype = PyChipError
17181736

17191737
self._dmLib.pychip_OpCreds_InitGroupTestingData.argtypes = [
@@ -1734,11 +1752,11 @@ def _InitLib(self):
17341752
self._dmLib.pychip_DeviceController_GetLogFilter = c_uint8
17351753

17361754
self._dmLib.pychip_OpCreds_AllocateController.argtypes = [c_void_p, POINTER(
1737-
c_void_p), c_uint64, c_uint64, c_uint16, c_char_p, c_bool, c_bool, POINTER(c_uint32), c_uint32, c_void_p]
1755+
c_void_p), POINTER(c_void_p), c_uint64, c_uint64, c_uint16, c_char_p, c_bool, c_bool, POINTER(c_uint32), c_uint32, c_void_p]
17381756
self._dmLib.pychip_OpCreds_AllocateController.restype = PyChipError
17391757

17401758
self._dmLib.pychip_OpCreds_AllocateControllerForPythonCommissioningFLow.argtypes = [
1741-
POINTER(c_void_p), c_void_p, POINTER(c_char), c_uint32, POINTER(c_char), c_uint32, POINTER(c_char), c_uint32, POINTER(c_char), c_uint32, c_uint16, c_bool]
1759+
POINTER(c_void_p), POINTER(c_void_p), c_void_p, POINTER(c_char), c_uint32, POINTER(c_char), c_uint32, POINTER(c_char), c_uint32, POINTER(c_char), c_uint32, c_uint16, c_bool]
17421760
self._dmLib.pychip_OpCreds_AllocateControllerForPythonCommissioningFLow.restype = PyChipError
17431761

17441762
self._dmLib.pychip_DeviceController_SetIpk.argtypes = [c_void_p, POINTER(c_char), c_size_t]
@@ -1760,6 +1778,7 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int,
17601778

17611779
self._dmLib.pychip_DeviceController_SetIssueNOCChainCallbackPythonCallback(_IssueNOCChainCallbackPythonCallback)
17621780

1781+
pairingDelegate = c_void_p(None)
17631782
devCtrl = c_void_p(None)
17641783

17651784
c_catTags = (c_uint32 * len(catTags))()
@@ -1771,15 +1790,15 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int,
17711790
self._externalKeyPair = keypair
17721791
self._ChipStack.Call(
17731792
lambda: self._dmLib.pychip_OpCreds_AllocateController(c_void_p(
1774-
opCredsContext), pointer(devCtrl), fabricId, nodeId, adminVendorId, c_char_p(None if len(paaTrustStorePath) == 0 else str.encode(paaTrustStorePath)), useTestCommissioner, self._ChipStack.enableServerInteractions, c_catTags, len(catTags), None if keypair is None else keypair.native_object)
1793+
opCredsContext), pointer(devCtrl), pointer(pairingDelegate), fabricId, nodeId, adminVendorId, c_char_p(None if len(paaTrustStorePath) == 0 else str.encode(paaTrustStorePath)), useTestCommissioner, self._ChipStack.enableServerInteractions, c_catTags, len(catTags), None if keypair is None else keypair.native_object)
17751794
).raise_on_error()
17761795

17771796
self._fabricAdmin = fabricAdmin
17781797
self._fabricId = fabricId
17791798
self._nodeId = nodeId
17801799
self._caIndex = fabricAdmin.caIndex
17811800

1782-
self._set_dev_ctrl(devCtrl=devCtrl)
1801+
self._set_dev_ctrl(devCtrl=devCtrl, pairingDelegate=pairingDelegate)
17831802

17841803
self._finish_init()
17851804

@@ -1925,9 +1944,10 @@ def CommissionOnNetwork(self, nodeId: int, setupPinCode: int,
19251944

19261945
self._ChipStack.commissioningCompleteEvent.clear()
19271946

1947+
self._enablePairingCompeleteCallback(True)
19281948
self._ChipStack.CallAsync(
19291949
lambda: self._dmLib.pychip_DeviceController_OnNetworkCommission(
1930-
self.devCtrl, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") + b"\x00" if filter is not None else None, discoveryTimeoutMsec)
1950+
self.devCtrl, self.pairingDelegate, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") + b"\x00" if filter is not None else None, discoveryTimeoutMsec)
19311951
)
19321952
if not self._ChipStack.commissioningCompleteEvent.isSet():
19331953
# Error 50 is a timeout
@@ -1948,6 +1968,7 @@ def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType: Disc
19481968

19491969
self._ChipStack.commissioningCompleteEvent.clear()
19501970

1971+
self._enablePairingCompeleteCallback(True)
19511972
self._ChipStack.CallAsync(
19521973
lambda: self._dmLib.pychip_DeviceController_ConnectWithCode(
19531974
self.devCtrl, setupPayload, nodeid, discoveryType.value)
@@ -1967,6 +1988,7 @@ def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> PyChipErr
19671988

19681989
self._ChipStack.commissioningCompleteEvent.clear()
19691990

1991+
self._enablePairingCompeleteCallback(True)
19701992
self._ChipStack.CallAsync(
19711993
lambda: self._dmLib.pychip_DeviceController_ConnectIP(
19721994
self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid)
@@ -2011,6 +2033,7 @@ def __init__(self, operationalKey: p256keypair.P256Keypair, noc: bytes,
20112033
'''
20122034
super().__init__(name or f"ctrl(v/{adminVendorId})")
20132035

2036+
pairingDelegate = c_void_p(None)
20142037
devCtrl = c_void_p(None)
20152038

20162039
# Device should hold a reference to the key to avoid it being GC-ed.
@@ -2019,9 +2042,9 @@ def __init__(self, operationalKey: p256keypair.P256Keypair, noc: bytes,
20192042

20202043
self._ChipStack.Call(
20212044
lambda: self._dmLib.pychip_OpCreds_AllocateControllerForPythonCommissioningFLow(
2022-
c_void_p(devCtrl), nativeKey, noc, len(noc), icac, len(icac) if icac else 0, rcac, len(rcac), ipk, len(ipk) if ipk else 0, adminVendorId, self._ChipStack.enableServerInteractions)
2045+
c_void_p(devCtrl), c_void_p(pairingDelegate), nativeKey, noc, len(noc), icac, len(icac) if icac else 0, rcac, len(rcac), ipk, len(ipk) if ipk else 0, adminVendorId, self._ChipStack.enableServerInteractions)
20232046
).raise_on_error()
20242047

2025-
self._set_dev_ctrl(devCtrl)
2048+
self._set_dev_ctrl(devCtrl, pairingDelegate)
20262049

20272050
self._finish_init()

0 commit comments

Comments
 (0)
Please sign in to comment.