diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 8c751f7f791dd0..938313aa230fb5 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -1343,6 +1343,40 @@ def WriteGroupAttribute( # An empty list is the expected return for sending group write attribute. return [] + async def PrepareToReceiveBdxData(self): + ''' + Sets up the system to expect a node to initiate a BDX transfer. The transfer will send data here. + + Returns: + - a BdxTransfer with the init message from the transfer. + Raises: + - ? on error + ''' + self.CheckIsActive() + + eventLoop = asyncio.get_running_loop() + future = eventLoop.create_future() + + res = await Bdx.PrepareToReceiveBdxData(future) + res.raise_on_error() + return await future + + async def PrepareToSendBdxData(self, data: bytes): # TODO: Type of `data`. + ''' + Sets up the system to expect a node to initiate a BDX transfer. The transfer will send data to the node. + + Raises: + - ? on error + ''' + self.CheckIsActive() + + eventLoop = asyncio.get_running_loop() + future = eventLoop.create_future() + + res = await Bdx.PrepareToSendBdxData(future, data) + res.raise_on_error() + return await future + def _parseAttributePathTuple(self, pathTuple: typing.Union[ None, # Empty tuple, all wildcard typing.Tuple[int], # Endpoint diff --git a/src/controller/python/chip/bdx/Bdx.py b/src/controller/python/chip/bdx/Bdx.py index 593d8f885a6082..f4e69fbb90a826 100644 --- a/src/controller/python/chip/bdx/Bdx.py +++ b/src/controller/python/chip/bdx/Bdx.py @@ -28,23 +28,46 @@ @_OnTransferObtainedCallbackFunct -def _OnTransferObtainedCallback(closure, result: PyChipError, bdxTransfer, transferControlFlags: int, maxBlockSize: int, +def _OnTransferObtainedCallback(future: Future, result: PyChipError, bdxTransfer, transferControlFlags: int, maxBlockSize: int, startOffset: int, length: int, fileDesignator, fileDesignatorLength: int, metadata, metadataLength: int): - # TODO: Call the closure with the rest of the parameters. - pass + if result is CHIP_NO_ERROR: + transfer = BdxTransfer() + # TODO: Set the parameters of the transfer. + future.set_result(transfer) + else: + future.set_exception(result.to_exception()) @_OnDataReceivedCallbackFunct -def _OnDataReceivedCallback(closure, dataBuffer, bufferLength: int): - # TODO: Call the closure with the data. +def _OnDataReceivedCallback(context, dataBuffer, bufferLength: int): + # TODO: Call the context with the data. pass @_OnTransferCompletedCallbackFunct -def _OnTransferCompletedCallback(closure, result: PyChipError): - # TODO: Call the closure. - pass +def _OnTransferCompletedCallback(future: Future, result: PyChipError): + future.set_result(result) + + +async def PrepareToReceiveBdxData(future: Future): + handle = chip.native.GetLibraryHandle() + + # TODO: Do I need to increment a reference to the future? (using ctypes.pythonapi.Py_IncRef(ctypes.py_object(future))) + return await builtins.chipStack.CallAsync( + lambda: handle.pychip_Bdx_ExpectBdxTransfer(future) + ) + + +async def PrepareToSendBdxData(future: Future, data): # TODO: Type of data? + handle = chip.native.GetLibraryHandle() + + # TODO: Store data somewhere. + + # TODO: Do I need to increment a reference to the future? (using ctypes.pythonapi.Py_IncRef(ctypes.py_object(future))) + return await builtins.chipStack.CallAsync( + lambda: handle.pychip_Bdx_ExpectBdxTransfer(future) + ) def Init(): diff --git a/src/controller/python/chip/bdx/bdx.cpp b/src/controller/python/chip/bdx/bdx.cpp index ed25f7b1c3a507..9d7e5a4b682d61 100644 --- a/src/controller/python/chip/bdx/bdx.cpp +++ b/src/controller/python/chip/bdx/bdx.cpp @@ -62,6 +62,16 @@ class TransferMap return &*result; } + TransferData * TransferDataForTransferObtainedContext(PyObject transferObtainedContext) + { + std::vector::iterator result = std::find(mTransfers.begin(), mTransfers.end(), + [transferObtainedContext](const TransferData& data) { + return data.OnTransferObtainedContext == transferObtainedContext; + }); + VerifyOrReturnValue(result != mTransfers.end(), nullptr); + return &*result; + } + // This returns the next transfer data that has no associated BdxTransfer. TransferData * NextUnassociatedTransferData() { @@ -80,10 +90,7 @@ class TransferMap void RemoveTransferData(TransferData * transferData) { - std::vector::iterator result = std::find(mTransfers.begin(), mTransfers.end(), - [transferData](const TransferData& data) { - return &data == transferData; - }); + std::vector::iterator result = std::find(mTransfers.begin(), mTransfers.end(), *transferData); VerifyOrReturn(result != mTransfers.end()); mTransfers.erase(result); } @@ -100,7 +107,7 @@ class TransferDelegate : public bdx::BdxTransfer::Delegate virtual void InitMessageReceived(bdx::BdxTransfer * transfer, bdx::TransferSession::TransferInitData init_data) { - TransferData * transferData = mTransfers->CreateUnassociatedTransferData(); + TransferData * transferData = mTransfers->NextUnassociatedTransferData(); if (gOnTransferObtainedCallback && transferData) { transferData->Transfer = transfer; @@ -165,14 +172,20 @@ void pychip_Bdx_InitCallbacks(OnTransferObtainedCallback onTransferObtainedCallb OnTransferCompletedCallback gOnTransferCompletedCallback = onTransferCompletedCallback; } -PyChipError pychip_Bdx_ExpectBdxTransfer() +PyChipError pychip_Bdx_ExpectBdxTransfer(PyObject transferObtainedContext) { + TransferData * transferData = gTransfers.CreateUnassociatedTransferData(); + VerifyOrReturnValue(transferData != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY)); + transferData->OnTransferObtainedContext = transferObtainedContext; gBdxTransferManager.ExpectATransfer(); } -PyChipError pychip_Bdx_StopExpectingBdxTransfer() +PyChipError pychip_Bdx_StopExpectingBdxTransfer(PyObject transferObtainedContext) { + TransferData * transferData = gTransfers.TransferDataForTransferObtainedContext(transferObtainedContext); + VerifyOrReturnValue(transferData != nullptr, ToPyChipError(CHIP_ERROR_NOT_FOUND)); gBdxTransferManager.StopExpectingATransfer(); + gTransfers.RemoveTransferData(transferData); } PyChipError pychip_Bdx_AcceptSendTransfer(chip::bdx::BdxTransfer * transfer, PyObject dataReceivedContext,