diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 1ca5a64e7cf198..cdd6c1a0bcc7f7 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -227,33 +227,36 @@ def wrapper(*args, **kwargs): class CallbackContext: - def __init__(self) -> None: + def __init__(self, lock: asyncio.Lock) -> None: + self._lock = lock self._future = None - def __enter__(self): + async def __aenter__(self): + await self._lock.acquire() self._future = concurrent.futures.Future() return self @property - def future(self) -> concurrent.futures.Future | None: + def future(self) -> typing.Optional[concurrent.futures.Future]: return self._future - def __exit__(self, exc_type, exc_value, traceback): + async def __aexit__(self, exc_type, exc_value, traceback): self._future = None + self._lock.release() class CommissioningContext(CallbackContext): - def __init__(self, devCtrl: ChipDeviceController) -> None: - super().__init__() + def __init__(self, devCtrl: ChipDeviceController, lock: asyncio.Lock) -> None: + super().__init__(lock) self._devCtrl = devCtrl - def __enter__(self): - super().__enter__() + async def __aenter__(self): + await super().__aenter__() self._devCtrl._fabricCheckNodeId = -1 return self - def __exit__(self, exc_type, exc_value, traceback): - super().__exit__(exc_type, exc_value, traceback) + async def __aexit__(self, exc_type, exc_value, traceback): + await super().__aexit__(exc_type, exc_value, traceback) class CommissionableNode(discovery.CommissionableNode): @@ -372,10 +375,11 @@ def __init__(self, name: str = ''): self._Cluster = ChipClusters(builtins.chipStack) self._Cluster.InitLib(self._dmLib) - self._commissioning_context: CommissioningContext = CommissioningContext(self) - self._open_window_context: CallbackContext = CallbackContext() - self._unpair_device_context: CallbackContext = CallbackContext() - self._pase_establishment_context: CallbackContext = CallbackContext() + self._commissioning_lock: asyncio.Lock = asyncio.Lock() + self._commissioning_context: CommissioningContext = CommissioningContext(self, self._commissioning_lock) + self._open_window_context: CallbackContext = CallbackContext(asyncio.Lock()) + self._unpair_device_context: CallbackContext = CallbackContext(asyncio.Lock()) + self._pase_establishment_context: CallbackContext = CallbackContext(self._commissioning_lock) def _set_dev_ctrl(self, devCtrl, pairingDelegate): def HandleCommissioningComplete(nodeId: int, err: PyChipError): @@ -579,7 +583,7 @@ async def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, i self.CheckIsActive() self._enablePairingCompleteCallback(True) - with self._commissioning_context as ctx: + async with self._commissioning_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectBLE( self.devCtrl, discriminator, isShortDiscriminator, setupPinCode, nodeid) @@ -591,7 +595,7 @@ async def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, i async def UnpairDevice(self, nodeid: int) -> None: self.CheckIsActive() - with self._unpair_device_context as ctx: + async with self._unpair_device_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_UnpairDevice( self.devCtrl, nodeid, self.cbHandleDeviceUnpairCompleteFunct) @@ -632,7 +636,7 @@ def CloseSession(self, nodeid): async def _establishPASESession(self, callFunct): self.CheckIsActive() - with self._pase_establishment_context as ctx: + async with self._pase_establishment_context as ctx: res = await self._ChipStack.CallAsync(callFunct) res.raise_on_error() await asyncio.futures.wrap_future(ctx.future) @@ -795,7 +799,7 @@ async def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: in ''' self.CheckIsActive() - with self._open_window_context as ctx: + async with self._open_window_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OpenCommissioningWindow( self.devCtrl, self.pairingDelegate, nodeid, timeout, iteration, discriminator, option) @@ -1814,7 +1818,7 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int, f"caIndex({fabricAdmin.caIndex:x})/fabricId(0x{fabricId:016X})/nodeId(0x{nodeId:016X})" ) - self._issue_node_chain_context: CallbackContext = CallbackContext() + self._issue_node_chain_context: CallbackContext = CallbackContext(asyncio.Lock()) self._dmLib.pychip_DeviceController_SetIssueNOCChainCallbackPythonCallback(_IssueNOCChainCallbackPythonCallback) pairingDelegate = c_void_p(None) @@ -1869,7 +1873,7 @@ async def Commission(self, nodeid) -> int: self.CheckIsActive() self._enablePairingCompleteCallback(False) - with self._commissioning_context as ctx: + async with self._commissioning_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_Commission( self.devCtrl, nodeid) @@ -2017,7 +2021,7 @@ async def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, filter = str(filter) self._enablePairingCompleteCallback(True) - with self._commissioning_context as ctx: + async with self._commissioning_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OnNetworkCommission( self.devCtrl, self.pairingDelegate, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") if filter is not None else None, discoveryTimeoutMsec) @@ -2038,7 +2042,7 @@ async def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType self.CheckIsActive() self._enablePairingCompleteCallback(True) - with self._commissioning_context as ctx: + async with self._commissioning_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectWithCode( self.devCtrl, setupPayload.encode("utf-8"), nodeid, discoveryType.value) @@ -2058,7 +2062,7 @@ async def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> int self.CheckIsActive() self._enablePairingCompleteCallback(True) - with self._commissioning_context as ctx: + async with self._commissioning_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectIP( self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid) @@ -2079,7 +2083,7 @@ async def IssueNOCChain(self, csr: Clusters.OperationalCredentials.Commands.CSRR The NOC chain will be provided in TLV cert format.""" self.CheckIsActive() - with self._issue_node_chain_context as ctx: + async with self._issue_node_chain_context as ctx: res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_IssueNOCChain( self.devCtrl, py_object(self), csr.NOCSRElements, len(csr.NOCSRElements), nodeId)