From b4a62135a0eee4061c427512d64951b554835420 Mon Sep 17 00:00:00 2001 From: "tianfeng.yang" <130436698+tianfeng-yang@users.noreply.github.com> Date: Wed, 17 Apr 2024 21:53:13 +0800 Subject: [PATCH] [Python] Create pairingDelegate for each DeviceController (#32369) * Create pairingDelegate for each DeviceController * restore the original pairingcomplete callback logic --- .../ChipDeviceController-ScriptBinding.cpp | 97 +++++++++++-------- src/controller/python/OpCredsBinding.cpp | 40 +++++--- src/controller/python/chip/ChipDeviceCtrl.py | 69 ++++++++----- 3 files changed, 128 insertions(+), 78 deletions(-) diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index d78c9da8ed74d3..a55d3865bdccae 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -105,7 +105,6 @@ chip::Controller::CommissioningParameters sCommissioningParameters; } // namespace -chip::Controller::ScriptDevicePairingDelegate sPairingDelegate; chip::Controller::ScriptPairingDeviceDiscoveryDelegate sPairingDeviceDiscoveryDelegate; chip::Credentials::GroupDataProviderImpl sGroupDataProvider; chip::Credentials::PersistentStorageOpCertStore sPersistentStorageOpCertStore; @@ -121,9 +120,8 @@ extern "C" { PyChipError pychip_DeviceController_StackInit(Controller::Python::StorageAdapter * storageAdapter, bool enableServerInteractions); PyChipError pychip_DeviceController_StackShutdown(); -PyChipError pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl, - chip::NodeId localDeviceId, bool useTestCommissioner); -PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl); +PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate); PyChipError pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, char * outAddress, uint64_t maxAddressLen, uint16_t * outPort); PyChipError pychip_DeviceController_GetCompressedFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId); @@ -168,15 +166,17 @@ PyChipError pychip_DeviceController_DiscoverCommissionableNodesDeviceType(chip:: uint16_t device_type); PyChipError pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl); -PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, uint64_t nodeId, - uint32_t setupPasscode, const uint8_t filterType, const char * filterParam, - uint32_t discoveryTimeoutMsec); +PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + uint64_t nodeId, uint32_t setupPasscode, const uint8_t filterType, + const char * filterParam, uint32_t discoveryTimeoutMsec); PyChipError pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext); -PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid, - uint16_t timeout, uint32_t iteration, uint16_t discriminator, - uint8_t optionInt); +PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::NodeId nodeid, uint16_t timeout, uint32_t iteration, + uint16_t discriminator, uint8_t optionInt); void pychip_DeviceController_PrintDiscoveredDevices(chip::Controller::DeviceCommissioner * devCtrl); bool pychip_DeviceController_GetIPForDiscoveredDevice(chip::Controller::DeviceCommissioner * devCtrl, int idx, char * addrStr, @@ -184,19 +184,28 @@ bool pychip_DeviceController_GetIPForDiscoveredDevice(chip::Controller::DeviceCo // Pairing Delegate PyChipError -pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl, +pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback); PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback( - chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback); + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback); PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback( - chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, chip::Controller::DevicePairingDelegate_OnCommissioningStatusUpdateFunct callback); + PyChipError -pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback); +pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback); + PyChipError pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback( - chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback); + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback); + +PyChipError +pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + bool value); // BLE PyChipError pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::DeviceCommissioner * devCtrl); @@ -354,7 +363,6 @@ const char * pychip_DeviceController_StatusReportToString(uint32_t profileId, ui PyChipError pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator, uint32_t setupPINCode, chip::NodeId nodeid) { - sPairingDelegate.SetExpectingPairingComplete(true); return ToPyChipError(devCtrl->PairDevice(nodeid, chip::RendezvousParameters() .SetPeerAddress(Transport::PeerAddress(Transport::Type::kBle)) @@ -378,14 +386,12 @@ PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommission addr.SetTransportType(chip::Transport::Type::kUdp).SetIPAddress(peerAddr).SetInterface(ifaceOutput); params.SetPeerAddress(addr).SetDiscriminator(0); - sPairingDelegate.SetExpectingPairingComplete(true); return ToPyChipError(devCtrl->PairDevice(nodeid, params, sCommissioningParameters)); } PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload, chip::NodeId nodeid, uint8_t discoveryType) { - sPairingDelegate.SetExpectingPairingComplete(true); return ToPyChipError(devCtrl->PairDevice(nodeid, onboardingPayload, sCommissioningParameters, static_cast(discoveryType))); } @@ -430,9 +436,10 @@ PyChipError pychip_DeviceController_UnpairDevice(chip::Controller::DeviceCommiss return ToPyChipError(err); } -PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, uint64_t nodeId, - uint32_t setupPasscode, const uint8_t filterType, const char * filterParam, - uint32_t discoveryTimeoutMsec) +PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + uint64_t nodeId, uint32_t setupPasscode, const uint8_t filterType, + const char * filterParam, uint32_t discoveryTimeoutMsec) { Dnssd::DiscoveryFilter filter(static_cast(filterType)); switch (static_cast(filterType)) @@ -467,9 +474,8 @@ PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::Device return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT); } - sPairingDelegate.SetExpectingPairingComplete(true); - CHIP_ERROR err = sPairingDeviceDiscoveryDelegate.Init(nodeId, setupPasscode, sCommissioningParameters, &sPairingDelegate, - devCtrl, discoveryTimeoutMsec); + CHIP_ERROR err = sPairingDeviceDiscoveryDelegate.Init(nodeId, setupPasscode, sCommissioningParameters, pairingDelegate, devCtrl, + discoveryTimeoutMsec); VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter)); } @@ -587,7 +593,6 @@ PyChipError pychip_DeviceController_EstablishPASESessionIP(chip::Controller::Dev addr.SetPort(port); } params.SetPeerAddress(addr).SetDiscriminator(0); - sPairingDelegate.SetExpectingPairingComplete(true); return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, params)); } @@ -598,14 +603,12 @@ PyChipError pychip_DeviceController_EstablishPASESessionBLE(chip::Controller::De RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode); addr.SetTransportType(chip::Transport::Type::kBle); params.SetPeerAddress(addr).SetDiscriminator(discriminator); - sPairingDelegate.SetExpectingPairingComplete(true); return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, params)); } PyChipError pychip_DeviceController_EstablishPASESession(chip::Controller::DeviceCommissioner * devCtrl, const char * setUpCode, chip::NodeId nodeid) { - sPairingDelegate.SetExpectingPairingComplete(true); return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, setUpCode)); } @@ -656,15 +659,17 @@ PyChipError pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnab } PyChipError pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback( - chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback) + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback) { - sPairingDelegate.SetCommissioningWindowOpenCallback(callback); + pairingDelegate->SetCommissioningWindowOpenCallback(callback); return ToPyChipError(CHIP_NO_ERROR); } -PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid, - uint16_t timeout, uint32_t iteration, uint16_t discriminator, - uint8_t optionInt) +PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::NodeId nodeid, uint16_t timeout, uint32_t iteration, + uint16_t discriminator, uint8_t optionInt) { const auto option = static_cast(optionInt); if (option == Controller::CommissioningWindowOpener::CommissioningWindowOption::kOriginalSetupCode) @@ -680,7 +685,7 @@ PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::De Platform::New(static_cast(devCtrl)); PyChipError err = ToPyChipError(opener->OpenCommissioningWindow(nodeid, System::Clock::Seconds16(timeout), iteration, discriminator, NullOptional, NullOptional, - sPairingDelegate.GetOpenWindowCallback(opener), payload)); + pairingDelegate->GetOpenWindowCallback(opener), payload)); return err; } @@ -688,32 +693,42 @@ PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::De } PyChipError -pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl, +pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback) { - sPairingDelegate.SetKeyExchangeCallback(callback); + pairingDelegate->SetKeyExchangeCallback(callback); return ToPyChipError(CHIP_NO_ERROR); } PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback( - chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback) + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback) { - sPairingDelegate.SetCommissioningCompleteCallback(callback); + pairingDelegate->SetCommissioningCompleteCallback(callback); return ToPyChipError(CHIP_NO_ERROR); } PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback( - chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, chip::Controller::DevicePairingDelegate_OnCommissioningStatusUpdateFunct callback) { - sPairingDelegate.SetCommissioningStatusUpdateCallback(callback); + pairingDelegate->SetCommissioningStatusUpdateCallback(callback); + return ToPyChipError(CHIP_NO_ERROR); +} + +PyChipError +pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback) +{ + pairingDelegate->SetFabricCheckCallback(callback); return ToPyChipError(CHIP_NO_ERROR); } PyChipError -pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(chip::Controller::DevicePairingDelegate_OnFabricCheckFunct callback) +pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(chip::Controller::ScriptDevicePairingDelegate * pairingDelegate, + bool value) { - sPairingDelegate.SetFabricCheckCallback(callback); + pairingDelegate->SetExpectingPairingComplete(value); return ToPyChipError(CHIP_NO_ERROR); } diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp index 79995d133b45e0..66a6c841843cde 100644 --- a/src/controller/python/OpCredsBinding.cpp +++ b/src/controller/python/OpCredsBinding.cpp @@ -402,12 +402,11 @@ void pychip_OnCommissioningStatusUpdate(chip::PeerId peerId, chip::Controller::C * TODO(#25214): Need clean up API * */ -PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow(chip::Controller::DeviceCommissioner ** outDevCtrl, - chip::python::pychip_P256Keypair * operationalKey, - uint8_t * noc, uint32_t nocLen, uint8_t * icac, - uint32_t icacLen, uint8_t * rcac, uint32_t rcacLen, - const uint8_t * ipk, uint32_t ipkLen, - chip::VendorId adminVendorId, bool enableServerInteractions) +PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow( + chip::Controller::DeviceCommissioner ** outDevCtrl, chip::Controller::ScriptDevicePairingDelegate ** outPairingDelegate, + chip::python::pychip_P256Keypair * operationalKey, uint8_t * noc, uint32_t nocLen, uint8_t * icac, uint32_t icacLen, + uint8_t * rcac, uint32_t rcacLen, const uint8_t * ipk, uint32_t ipkLen, chip::VendorId adminVendorId, + bool enableServerInteractions) { ReturnErrorCodeIf(nocLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); ReturnErrorCodeIf(icacLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); @@ -415,11 +414,13 @@ PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow(chip::Co ChipLogDetail(Controller, "Creating New Device Controller"); + auto pairingDelegate = std::make_unique(); + VerifyOrReturnError(pairingDelegate != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); auto devCtrl = std::make_unique(); VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); Controller::SetupParams initParams; - initParams.pairingDelegate = &sPairingDelegate; + initParams.pairingDelegate = pairingDelegate.get(); initParams.operationalCredentialsDelegate = &sPlaceholderOperationalCredentialsIssuer; initParams.operationalKeypair = operationalKey; initParams.controllerRCAC = ByteSpan(rcac, rcacLen); @@ -450,13 +451,15 @@ PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow(chip::Co chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), fabricIpk, compressedFabricIdSpan); VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); - *outDevCtrl = devCtrl.release(); + *outDevCtrl = devCtrl.release(); + *outPairingDelegate = pairingDelegate.release(); return ToPyChipError(CHIP_NO_ERROR); } // TODO(#25214): Need clean up API PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Controller::DeviceCommissioner ** outDevCtrl, + chip::Controller::ScriptDevicePairingDelegate ** outPairingDelegate, FabricId fabricId, chip::NodeId nodeId, chip::VendorId adminVendorId, const char * paaTrustStorePath, bool useTestCommissioner, bool enableServerInteractions, CASEAuthTag * caseAuthTags, uint32_t caseAuthTagLen, @@ -468,6 +471,8 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co VerifyOrReturnError(context != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); + auto pairingDelegate = std::make_unique(); + VerifyOrReturnError(pairingDelegate != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); auto devCtrl = std::make_unique(); VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); @@ -524,7 +529,7 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); Controller::SetupParams initParams; - initParams.pairingDelegate = &sPairingDelegate; + initParams.pairingDelegate = pairingDelegate.get(); initParams.operationalCredentialsDelegate = context->mAdapter.get(); initParams.operationalKeypair = controllerKeyPair; initParams.controllerRCAC = rcacSpan; @@ -538,9 +543,9 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co if (useTestCommissioner) { initParams.defaultCommissioner = &sTestCommissioner; - sPairingDelegate.SetCommissioningSuccessCallback(pychip_OnCommissioningSuccess); - sPairingDelegate.SetCommissioningFailureCallback(pychip_OnCommissioningFailure); - sPairingDelegate.SetCommissioningStatusUpdateCallback(pychip_OnCommissioningStatusUpdate); + pairingDelegate->SetCommissioningSuccessCallback(pychip_OnCommissioningSuccess); + pairingDelegate->SetCommissioningFailureCallback(pychip_OnCommissioningFailure); + pairingDelegate->SetCommissioningStatusUpdateCallback(pychip_OnCommissioningStatusUpdate); } err = Controller::DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, *devCtrl); @@ -562,7 +567,8 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, devCtrl->GetFabricIndex(), defaultIpk, compressedFabricIdSpan); VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err)); - *outDevCtrl = devCtrl.release(); + *outDevCtrl = devCtrl.release(); + *outPairingDelegate = pairingDelegate.release(); return ToPyChipError(CHIP_NO_ERROR); } @@ -596,7 +602,8 @@ void pychip_OpCreds_FreeDelegate(OpCredsContext * context) Platform::Delete(context); } -PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl) +PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl, + chip::Controller::ScriptDevicePairingDelegate * pairingDelegate) { if (devCtrl != nullptr) { @@ -604,6 +611,11 @@ PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::Dev delete devCtrl; } + if (pairingDelegate != nullptr) + { + delete pairingDelegate; + } + return ToPyChipError(CHIP_NO_ERROR); } diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 369260787d9af8..b553b2f85b641e 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -253,8 +253,10 @@ def __init__(self, name: str = ''): self._InitLib() + pairingDelegate = c_void_p(None) devCtrl = c_void_p(None) + self.pairingDelegate = pairingDelegate self.devCtrl = devCtrl self.name = name self.fabricCheckNodeId = -1 @@ -263,7 +265,7 @@ def __init__(self, name: str = ''): self._Cluster = ChipClusters(builtins.chipStack) self._Cluster.InitLib(self._dmLib) - def _set_dev_ctrl(self, devCtrl): + def _set_dev_ctrl(self, devCtrl, pairingDelegate): def HandleCommissioningComplete(nodeid, err): if err.is_success: logging.info("Commissioning complete") @@ -321,25 +323,26 @@ def HandlePASEEstablishmentComplete(err: PyChipError): if not err.is_success: HandleCommissioningComplete(0, err) + self.pairingDelegate = pairingDelegate self.devCtrl = devCtrl self.cbHandlePASEEstablishmentCompleteFunct = _DevicePairingDelegate_OnPairingCompleteFunct( HandlePASEEstablishmentComplete) self._dmLib.pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback( - self.devCtrl, self.cbHandlePASEEstablishmentCompleteFunct) + self.pairingDelegate, self.cbHandlePASEEstablishmentCompleteFunct) self.cbHandleCommissioningCompleteFunct = _DevicePairingDelegate_OnCommissioningCompleteFunct( HandleCommissioningComplete) self._dmLib.pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback( - self.devCtrl, self.cbHandleCommissioningCompleteFunct) + self.pairingDelegate, self.cbHandleCommissioningCompleteFunct) self.cbHandleFabricCheckFunct = _DevicePairingDelegate_OnFabricCheckFunct(HandleFabricCheck) - self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(self.cbHandleFabricCheckFunct) + self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback(self.pairingDelegate, self.cbHandleFabricCheckFunct) self.cbHandleOpenWindowCompleteFunct = _DevicePairingDelegate_OnOpenWindowCompleteFunct( HandleOpenWindowComplete) self._dmLib.pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback( - self.devCtrl, self.cbHandleOpenWindowCompleteFunct) + self.pairingDelegate, self.cbHandleOpenWindowCompleteFunct) self.cbHandleDeviceUnpairCompleteFunct = _DeviceUnpairingCompleteFunct(HandleUnpairDeviceComplete) @@ -355,6 +358,11 @@ def _finish_init(self): ChipDeviceController.activeList.add(self) + def _enablePairingCompeleteCallback(self, value: bool): + self._ChipStack.Call( + lambda: self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(self.pairingDelegate, value) + ).raise_on_error() + @property def fabricAdmin(self) -> FabricAdmin.FabricAdmin: return self._fabricAdmin @@ -389,8 +397,9 @@ def Shutdown(self): if self.devCtrl is not None: self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DeleteDeviceController( - self.devCtrl) + self.devCtrl, self.pairingDelegate) ).raise_on_error() + self.pairingDelegate = None self.devCtrl = None ChipDeviceController.activeList.remove(self) @@ -437,6 +446,7 @@ def ConnectBLE(self, discriminator, setupPinCode, nodeid) -> PyChipError: self._ChipStack.commissioningCompleteEvent.clear() self.state = DCState.COMMISSIONING + self._enablePairingCompeleteCallback(True) self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectBLE( self.devCtrl, discriminator, setupPinCode, nodeid) @@ -487,6 +497,7 @@ def EstablishPASESessionBLE(self, setupPinCode: int, discriminator: int, nodeid: self.CheckIsActive() self.state = DCState.RENDEZVOUS_ONGOING + self._enablePairingCompeleteCallback(True) return self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionBLE( self.devCtrl, setupPinCode, discriminator, nodeid) @@ -496,6 +507,7 @@ def EstablishPASESessionIP(self, ipaddr: str, setupPinCode: int, nodeid: int, po self.CheckIsActive() self.state = DCState.RENDEZVOUS_ONGOING + self._enablePairingCompeleteCallback(True) return self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionIP( self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid, port) @@ -505,6 +517,7 @@ def EstablishPASESession(self, setUpCode: str, nodeid: int): self.CheckIsActive() self.state = DCState.RENDEZVOUS_ONGOING + self._enablePairingCompeleteCallback(True) return self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_EstablishPASESession( self.devCtrl, setUpCode.encode("utf-8"), nodeid) @@ -726,7 +739,7 @@ def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: int, self.CheckIsActive() self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OpenCommissioningWindow( - self.devCtrl, nodeid, timeout, iteration, discriminator, option) + self.devCtrl, self.pairingDelegate, nodeid, timeout, iteration, discriminator, option) ).raise_on_error() self._ChipStack.callbackRes.raise_on_error() return self._ChipStack.openCommissioningWindowPincode[nodeid] @@ -1515,16 +1528,13 @@ def _InitLib(self): self._dmLib = CDLL(self._ChipStack.LocateChipDLL()) self._dmLib.pychip_DeviceController_DeleteDeviceController.argtypes = [ - c_void_p] + c_void_p, c_void_p] self._dmLib.pychip_DeviceController_DeleteDeviceController.restype = PyChipError self._dmLib.pychip_DeviceController_ConnectBLE.argtypes = [ c_void_p, c_uint16, c_uint32, c_uint64] self._dmLib.pychip_DeviceController_ConnectBLE.restype = PyChipError - self._dmLib.pychip_DeviceController_ConnectIP.argtypes = [ - c_void_p, c_char_p, c_uint32, c_uint64] - self._dmLib.pychip_DeviceController_SetThreadOperationalDataset.argtypes = [ c_char_p, c_uint32] self._dmLib.pychip_DeviceController_SetThreadOperationalDataset.restype = PyChipError @@ -1560,7 +1570,7 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_Commission.restype = PyChipError self._dmLib.pychip_DeviceController_OnNetworkCommission.argtypes = [ - c_void_p, c_uint64, c_uint32, c_uint8, c_char_p, c_uint32] + c_void_p, c_void_p, c_uint64, c_uint32, c_uint8, c_char_p, c_uint32] self._dmLib.pychip_DeviceController_OnNetworkCommission.restype = PyChipError self._dmLib.pychip_DeviceController_DiscoverCommissionableNodes.argtypes = [ @@ -1598,6 +1608,7 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_EstablishPASESessionBLE.argtypes = [ c_void_p, c_uint32, c_uint16, c_uint64] self._dmLib.pychip_DeviceController_EstablishPASESessionBLE.restype = PyChipError + self._dmLib.pychip_DeviceController_EstablishPASESession.argtypes = [ c_void_p, c_char_p, c_uint64] self._dmLib.pychip_DeviceController_EstablishPASESession.restype = PyChipError @@ -1605,10 +1616,12 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes.argtypes = [ c_void_p] self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes.restype = PyChipError + self._dmLib.pychip_DeviceController_PrintDiscoveredDevices.argtypes = [ c_void_p] self._dmLib.pychip_DeviceController_PrintDiscoveredDevices.argtypes = [ c_void_p, _ChipDeviceController_IterateDiscoveredCommissionableNodesFunct] + self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode.argtypes = [c_void_p] self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode.restype = c_bool @@ -1653,9 +1666,13 @@ def _InitLib(self): self._dmLib.pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback.restype = PyChipError self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback.argtypes = [ - _DevicePairingDelegate_OnFabricCheckFunct] + c_void_p, _DevicePairingDelegate_OnFabricCheckFunct] self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback.restype = PyChipError + self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete.argtypes = [ + c_void_p, c_bool] + self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete.restype = PyChipError + self._dmLib.pychip_GetConnectedDeviceByNodeId.argtypes = [ c_void_p, c_uint64, py_object, _DeviceAvailableCallbackFunct] self._dmLib.pychip_GetConnectedDeviceByNodeId.restype = PyChipError @@ -1683,8 +1700,9 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_GetCompressedFabricId.restype = PyChipError self._dmLib.pychip_DeviceController_OpenCommissioningWindow.argtypes = [ - c_void_p, c_uint64, c_uint16, c_uint32, c_uint16, c_uint8] + c_void_p, c_void_p, c_uint64, c_uint16, c_uint32, c_uint16, c_uint8] self._dmLib.pychip_DeviceController_OpenCommissioningWindow.restype = PyChipError + self._dmLib.pychip_TestCommissionerUsed.argtypes = [] self._dmLib.pychip_TestCommissionerUsed.restype = c_bool @@ -1700,6 +1718,7 @@ def _InitLib(self): self._dmLib.pychip_SetTestCommissionerSimulateFailureOnStage.argtypes = [ c_uint8] self._dmLib.pychip_SetTestCommissionerSimulateFailureOnStage.restype = c_bool + self._dmLib.pychip_SetTestCommissionerSimulateFailureOnReport.argtypes = [ c_uint8] self._dmLib.pychip_SetTestCommissionerSimulateFailureOnReport.restype = c_bool @@ -1712,8 +1731,7 @@ def _InitLib(self): self._dmLib.pychip_GetCompletionError.restype = PyChipError self._dmLib.pychip_DeviceController_IssueNOCChain.argtypes = [ - c_void_p, py_object, c_char_p, c_size_t, c_uint64 - ] + c_void_p, py_object, c_char_p, c_size_t, c_uint64] self._dmLib.pychip_DeviceController_IssueNOCChain.restype = PyChipError self._dmLib.pychip_OpCreds_InitGroupTestingData.argtypes = [ @@ -1734,11 +1752,11 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_GetLogFilter = c_uint8 self._dmLib.pychip_OpCreds_AllocateController.argtypes = [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] + 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] self._dmLib.pychip_OpCreds_AllocateController.restype = PyChipError self._dmLib.pychip_OpCreds_AllocateControllerForPythonCommissioningFLow.argtypes = [ - 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] + 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] self._dmLib.pychip_OpCreds_AllocateControllerForPythonCommissioningFLow.restype = PyChipError 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, self._dmLib.pychip_DeviceController_SetIssueNOCChainCallbackPythonCallback(_IssueNOCChainCallbackPythonCallback) + pairingDelegate = c_void_p(None) devCtrl = c_void_p(None) c_catTags = (c_uint32 * len(catTags))() @@ -1771,7 +1790,7 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int, self._externalKeyPair = keypair self._ChipStack.Call( lambda: self._dmLib.pychip_OpCreds_AllocateController(c_void_p( - 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) + 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) ).raise_on_error() self._fabricAdmin = fabricAdmin @@ -1779,7 +1798,7 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int, self._nodeId = nodeId self._caIndex = fabricAdmin.caIndex - self._set_dev_ctrl(devCtrl=devCtrl) + self._set_dev_ctrl(devCtrl=devCtrl, pairingDelegate=pairingDelegate) self._finish_init() @@ -1925,9 +1944,10 @@ def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, self._ChipStack.commissioningCompleteEvent.clear() + self._enablePairingCompeleteCallback(True) self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OnNetworkCommission( - self.devCtrl, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") + b"\x00" if filter is not None else None, discoveryTimeoutMsec) + self.devCtrl, self.pairingDelegate, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") + b"\x00" if filter is not None else None, discoveryTimeoutMsec) ) if not self._ChipStack.commissioningCompleteEvent.isSet(): # Error 50 is a timeout @@ -1948,6 +1968,7 @@ def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType: Disc self._ChipStack.commissioningCompleteEvent.clear() + self._enablePairingCompeleteCallback(True) self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectWithCode( self.devCtrl, setupPayload, nodeid, discoveryType.value) @@ -1967,6 +1988,7 @@ def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> PyChipErr self._ChipStack.commissioningCompleteEvent.clear() + self._enablePairingCompeleteCallback(True) self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectIP( self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid) @@ -2011,6 +2033,7 @@ def __init__(self, operationalKey: p256keypair.P256Keypair, noc: bytes, ''' super().__init__(name or f"ctrl(v/{adminVendorId})") + pairingDelegate = c_void_p(None) devCtrl = c_void_p(None) # 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, self._ChipStack.Call( lambda: self._dmLib.pychip_OpCreds_AllocateControllerForPythonCommissioningFLow( - 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) + 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) ).raise_on_error() - self._set_dev_ctrl(devCtrl) + self._set_dev_ctrl(devCtrl, pairingDelegate) self._finish_init()