Skip to content

Commit

Permalink
Implement a good chunk of the python side.
Browse files Browse the repository at this point in the history
  • Loading branch information
harimau-qirex committed Aug 22, 2024
1 parent 3680655 commit 0ead7f3
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 18 deletions.
78 changes: 63 additions & 15 deletions src/controller/python/chip/bdx/Bdx.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,41 +32,89 @@ def _OnTransferObtainedCallback(future: Future, result: PyChipError, bdxTransfer
startOffset: int, length: int, fileDesignator, fileDesignatorLength: int, metadata,
metadataLength: int):
if result is CHIP_NO_ERROR:
transfer = BdxTransfer()
# TODO: Set the parameters of the transfer.
future.set_result(transfer)
fileDesignatorData = ctypes.string_at(fileDesignator, fileDesignatorLength)
metadataData = ctypes.string_at(metadata, metadataLength)

initMessage = InitMessage()
initMessage.TransferControlFlags = transferControlFlags
initMessage.MaxBlockSize = maxBlockSize
initMessage.StartOffset = startOffset
initMessage.Length = length
initMessage.FileDesignator = fileDesignatorData[:]
initMessage.Metadata = metadataData[:]

future.handleTransfer(bdxTransfer, initMessage)
else:
future.set_exception(result.to_exception())
future.handleError(result)


@_OnDataReceivedCallbackFunct
def _OnDataReceivedCallback(context, dataBuffer, bufferLength: int):
# TODO: Call the context with the data.
pass
data = ctypes.string_at(dataBuffer, bufferLength)
context(data[:])


@_OnTransferCompletedCallbackFunct
def _OnTransferCompletedCallback(future: Future, result: PyChipError):
future.set_result(result)
if result is CHIP_NO_ERROR:
future.set_result(result)
else:
future.set_exception(result.to_exception())


class AsyncTransferObtainedTransaction:
def __init__(self, future, data=None):
self._future = future
self._data = data

def handleTransfer(self, bdxTransfer, initMessage: InitMessage):
transfer = BdxTransfer(bdx_transfer=bdxTransfer, init_message=initMessage, data=self._data)
self._future.set_result(transfer)

def handleError(self, result: PyChipError):
self._future.set_exception(result.to_exception())


async def PrepareToReceiveBdxData(future: Future):
handle = chip.native.GetLibraryHandle()
transaction = AsyncTransferObtainedTransaction(future=future)

ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction))
return await builtins.chipStack.CallAsync(
lambda: handle.pychip_Bdx_ExpectBdxTransfer(ctypes.py_object(transaction))
)


async def PrepareToSendBdxData(future: Future, data: bytes):
handle = chip.native.GetLibraryHandle()
transaction = AsyncTransferObtainedTransaction(future=future, data=data)

# TODO: Do I need to increment a reference to the future? (using ctypes.pythonapi.Py_IncRef(ctypes.py_object(future)))
ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction))
return await builtins.chipStack.CallAsync(
lambda: handle.pychip_Bdx_ExpectBdxTransfer(future)
lambda: handle.pychip_Bdx_ExpectBdxTransfer(ctypes.py_object(transaction))
)


async def PrepareToSendBdxData(future: Future, data): # TODO: Type of data?
async def AcceptSendTransfer(transfer: c_void_p, dataReceivedClosure, transferComplete: Future):
handle = chip.native.GetLibraryHandle()
ctypes.pythonapi.Py_IncRef(ctypes.py_object(dataReceivedClosure))
ctypes.pythonapi.Py_IncRef(ctypes.py_object(transferComplete))
return await builtins.chipStack.CallAsync(
lambda: handle.pychip_Bdx_AcceptSendTransfer(transfer, dataReceivedClosure, transferComplete)
)

# TODO: Store data somewhere.

# TODO: Do I need to increment a reference to the future? (using ctypes.pythonapi.Py_IncRef(ctypes.py_object(future)))
async def AcceptReceiveTransfer(transfer: c_void_p, data: bytes, transferComplete: Future):
handle = chip.native.GetLibraryHandle()
return await builtins.chipStack.CallAsync(
lambda: handle.pychip_Bdx_AcceptReceiveTransfer(transfer, ctypes.c_char_p(data), len(data), transferComplete)
)


async def RejectTransfer(transfer: c_void_p):
handle = chip.native.GetLibraryHandle()
return await builtins.chipStack.CallAsync(
lambda: handle.pychip_Bdx_ExpectBdxTransfer(future)
lambda: handle.pychip_Bdx_RejectTransfer(transfer)
)


Expand All @@ -77,9 +125,9 @@ def Init():
setter = chip.native.NativeLibraryHandleMethodArguments(handle)

setter.Set('pychip_Bdx_ExpectBdxTransfer',
PyChipError, [])
PyChipError, [py_object])
setter.Set('pychip_Bdx_StopExpectingBdxTransfer',
PyChipError, [])
PyChipError, [py_object])
setter.Set('pychip_Bdx_AcceptSendTransfer',
PyChipError, [c_void_p, py_object, py_object])
setter.Set('pychip_Bdx_AcceptReceiveTransfer',
Expand Down
51 changes: 51 additions & 0 deletions src/controller/python/chip/bdx/BdxTransfer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# Copyright (c) 2024 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

@dataclass
class InitMessage:
TransferControlFlags: int
MaxBlockSize: int
StartOffset: int
Length: int
FileDesignator
Metadata

class BdxTransfer:
__init__(self, bdx_transfer: c_void_p, init_message: InitMessage, data = None):
self.init_message = init_message
self._bdx_transfer = bdx_transfer
self._data = data

async def accept(self):
eventLoop = asyncio.get_running_loop()
future = eventLoop.create_future()

if self._data != None:
res = await Bdx.AcceptReceiveTransfer(self._bdx_transfer, self._data, future)
res.raise_on_error()
return await future
else:
self._data = []
res = await Bdx.AcceptSendTransfer(self._bdx_transfer, lambda data: self._data.extend(data), future)
res.raise_on_error()
await future
return self._data

async def reject(self):
res = await Bdx.RejectTransfer(self._bdx_transfer)
res.raise_on_error()
return res
8 changes: 5 additions & 3 deletions src/controller/python/chip/bdx/bdx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ PyChipError pychip_Bdx_ExpectBdxTransfer(PyObject transferObtainedContext)
VerifyOrReturnValue(transferData != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY));
transferData->OnTransferObtainedContext = transferObtainedContext;
gBdxTransferManager.ExpectATransfer();
return ToPyChipError(CHIP_NO_ERROR);
}

PyChipError pychip_Bdx_StopExpectingBdxTransfer(PyObject transferObtainedContext)
Expand All @@ -186,6 +187,7 @@ PyChipError pychip_Bdx_StopExpectingBdxTransfer(PyObject transferObtainedContext
VerifyOrReturnValue(transferData != nullptr, ToPyChipError(CHIP_ERROR_NOT_FOUND));
gBdxTransferManager.StopExpectingATransfer();
gTransfers.RemoveTransferData(transferData);
return ToPyChipError(CHIP_NO_ERROR);
}

PyChipError pychip_Bdx_AcceptSendTransfer(chip::bdx::BdxTransfer * transfer, PyObject dataReceivedContext,
Expand All @@ -194,7 +196,7 @@ PyChipError pychip_Bdx_AcceptSendTransfer(chip::bdx::BdxTransfer * transfer, PyO
TransferData * transferData = gTransfers.TransferDataForTransfer(transfer);
transferData->OnDataReceivedContext = dataReceivedContext;
transferData->OnTransferCompletedContext = transferCompletedContext;
transfer->AcceptSend();
return ToPyChipError(transfer->AcceptSend());
}

PyChipError pychip_Bdx_AcceptReceiveTransfer(chip::bdx::BdxTransfer * transfer, const uint8_t * dataBuffer, size_t dataLength,
Expand All @@ -203,12 +205,12 @@ PyChipError pychip_Bdx_AcceptReceiveTransfer(chip::bdx::BdxTransfer * transfer,
TransferData * transferData = gTransfers.TransferDataForTransfer(transfer);
transferData->OnTransferCompletedContext = transferCompletedContext;
chip::ByteSpan data(dataBuffer, dataLength);
transfer->AcceptReceive(data);
return ToPyChipError(transfer->AcceptReceive(data));
}

PyChipError pychip_Bdx_RejectTransfer(chip::bdx::BdxTransfer * transfer)
{
transfer->Reject();
return ToPyChipError(transfer->Reject());
}

}

0 comments on commit 0ead7f3

Please sign in to comment.