Skip to content

Commit 25f23ae

Browse files
authored
Make max block size for BDX transfers from DiagnosticLogs cluster configurable in the controller and device (project-chip#41447)
* Implemented override of BDX block size on cluster and controller, and added max payload size override for UDP * Revert payload limit override * Fixed data type for block size and added "= None" to explicitly give None value if parameter is missing. * Simplified the logic for setting gMaxBdxBlockSize. Restyled fixes. * Restyled nitpick * Docstring updates, renamed setter function, and replaced hardcoded 1024 with macro
1 parent 39b5015 commit 25f23ae

File tree

8 files changed

+57
-12
lines changed

8 files changed

+57
-12
lines changed

src/app/clusters/diagnostic-logs-server/BDXDiagnosticLogsProvider.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ constexpr System::Clock::Timeout kBdxPollIntervalMs = System::Clock::Millisecond
3636
// Timeout for the BDX transfer session
3737
constexpr System::Clock::Timeout kBdxTimeout = System::Clock::Seconds16(5 * 60);
3838

39-
constexpr uint16_t kBdxMaxBlockSize = 1024;
39+
constexpr uint16_t kBdxMaxBlockSize = CHIP_CONFIG_BDX_LOG_TRANSFER_MAX_BLOCK_SIZE;
4040

4141
CHIP_ERROR BDXDiagnosticLogsProvider::InitializeTransfer(CommandHandler * commandObj, const ConcreteCommandPath & path,
4242
DiagnosticLogsProviderDelegate * delegate, IntentEnum intent,

src/controller/python/matter/ChipDeviceCtrl.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,14 +1827,16 @@ def WriteGroupAttribute(
18271827
# An empty list is the expected return for sending group write attribute.
18281828
return []
18291829

1830-
def TestOnlyPrepareToReceiveBdxData(self) -> asyncio.Future:
1830+
def TestOnlyPrepareToReceiveBdxData(self, max_block_size: int | None = None) -> asyncio.Future:
18311831
'''
18321832
Sets up the system to expect a node to initiate a BDX transfer. The transfer will send data here.
18331833
18341834
If no BDX transfer is initiated, the caller must cancel the returned future to avoid interfering with other BDX transfers.
18351835
For example, the Diagnostic Logs clusters won't start a BDX transfer when the log is small so the future must be cancelled to allow later
18361836
attempts to retrieve logs to succeed.
18371837
1838+
If max_block_size is provided (1..65535), it overrides the controller's default cap.
1839+
18381840
Returns:
18391841
a future that will yield a BdxTransfer with the init message from the transfer.
18401842
@@ -1846,7 +1848,7 @@ def TestOnlyPrepareToReceiveBdxData(self) -> asyncio.Future:
18461848
eventLoop = asyncio.get_running_loop()
18471849
future = eventLoop.create_future()
18481850

1849-
Bdx.PrepareToReceiveBdxData(future).raise_on_error()
1851+
Bdx.PrepareToReceiveBdxData(future, max_block_size).raise_on_error()
18501852
return future
18511853

18521854
def TestOnlyPrepareToSendBdxData(self, data: bytes) -> asyncio.Future:

src/controller/python/matter/bdx/Bdx.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,12 @@ def _OnTransferCompletedCallback(transaction: AsyncTransferCompletedTransaction,
113113
transaction.handleResult(result)
114114

115115

116-
def _PrepareForBdxTransfer(future: Future, data: Optional[bytes]) -> PyChipError:
116+
def _PrepareForBdxTransfer(future: Future, data: Optional[bytes], max_block_size: Optional[int] = None) -> PyChipError:
117117
''' Prepares the BDX system for a BDX transfer. The BDX transfer is set as the future's result. This must be called
118118
before the BDX transfer is initiated.
119119
120+
If max_block_size is provided (1..65535), it overrides the controller's default cap.
121+
120122
Returns the CHIP_ERROR result from the C++ side.
121123
'''
122124
handle = GetLibraryHandle()
@@ -137,22 +139,32 @@ def _on_done(fut: Future):
137139

138140
ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction))
139141
res = builtins.chipStack.Call(
140-
lambda: handle.pychip_Bdx_ExpectBdxTransfer(ctypes.py_object(transaction))
142+
lambda: handle.pychip_Bdx_ExpectBdxTransfer(
143+
ctypes.py_object(transaction),
144+
# 0 means “use default”.
145+
ctypes.c_uint16(0 if max_block_size is None else max_block_size),
146+
)
141147
)
142148
if not res.is_success:
143149
ctypes.pythonapi.Py_DecRef(ctypes.py_object(transaction))
144150
return res
145151

146152

147-
def PrepareToReceiveBdxData(future: Future) -> PyChipError:
153+
def PrepareToReceiveBdxData(future: Future, max_block_size: Optional[int] = None) -> PyChipError:
148154
''' Prepares the BDX system for a BDX transfer where this device receives data. This must be called before the BDX
149155
transfer is initiated.
150156
151157
When a BDX transfer is found it's set as the future's result. If an error occurs while waiting it is set as the future's exception.
152158
159+
If max_block_size is provided (1..65535), it overrides the controller's default cap.
160+
153161
Returns an error if there was an issue preparing to wait a BDX transfer.
154162
'''
155-
return _PrepareForBdxTransfer(future, None)
163+
# Validate max_block_size to fit in uint16.
164+
if max_block_size is not None and not (1 <= max_block_size <= 0xFFFF):
165+
raise ValueError("max_block_size must be in [1, 65535]")
166+
167+
return _PrepareForBdxTransfer(future, None, max_block_size)
156168

157169

158170
def PrepareToSendBdxData(future: Future, data: bytes) -> PyChipError:
@@ -224,7 +236,7 @@ def Init():
224236
setter = NativeLibraryHandleMethodArguments(handle)
225237

226238
setter.Set('pychip_Bdx_ExpectBdxTransfer',
227-
PyChipError, [py_object])
239+
PyChipError, [py_object, c_uint16])
228240
setter.Set('pychip_Bdx_StopExpectingBdxTransfer',
229241
PyChipError, [py_object])
230242
setter.Set('pychip_Bdx_AcceptTransferAndReceiveData',

src/controller/python/matter/bdx/bdx-transfer.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,21 @@ namespace chip {
2323
namespace bdx {
2424
namespace {
2525

26-
constexpr uint32_t kMaxBdxBlockSize = 1024;
26+
constexpr uint16_t kMaxBdxBlockSize = CHIP_CONFIG_BDX_LOG_TRANSFER_MAX_BLOCK_SIZE;
2727
constexpr System::Clock::Timeout kBdxPollInterval = System::Clock::Milliseconds32(50);
2828
constexpr System::Clock::Timeout kBdxTimeout = System::Clock::Seconds16(5 * 60);
2929

30+
// Max block size for the next transfer; set from bdx.cpp when Python passes a value.
31+
// Resets to default kMaxBdxBlockSize after PrepareForTransfer is called.
32+
static uint16_t gMaxBdxBlockSize = kMaxBdxBlockSize;
33+
3034
} // namespace
3135

36+
void SetControllerBdxMaxBlockSizeForNextTransfer(uint16_t maxBlockSize)
37+
{
38+
gMaxBdxBlockSize = maxBlockSize;
39+
}
40+
3241
void BdxTransfer::SetDelegate(BdxTransfer::Delegate * delegate)
3342
{
3443
mDelegate = delegate;
@@ -204,7 +213,8 @@ CHIP_ERROR BdxTransfer::OnMessageReceived(chip::Messaging::ExchangeContext * exc
204213
role = TransferRole::kSender;
205214
}
206215
ReturnLogErrorOnFailure(
207-
Responder::PrepareForTransfer(mSystemLayer, role, flags, kMaxBdxBlockSize, kBdxTimeout, kBdxPollInterval));
216+
Responder::PrepareForTransfer(mSystemLayer, role, flags, gMaxBdxBlockSize, kBdxTimeout, kBdxPollInterval));
217+
gMaxBdxBlockSize = kMaxBdxBlockSize; // consume the one-shot override
208218
}
209219

210220
return Responder::OnMessageReceived(exchangeContext, payloadHeader, std::move(payload));

src/controller/python/matter/bdx/bdx-transfer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,8 @@ class BdxTransfer : public Responder
8686
size_t mDataTransferredCount = 0;
8787
};
8888

89+
// Overrides the cap for the next PrepareForTransfer() only. Reset after PrepareForTransfer.
90+
void SetControllerBdxMaxBlockSizeForNextTransfer(uint16_t maxBlockSize);
91+
8992
} // namespace bdx
9093
} // namespace chip

src/controller/python/matter/bdx/bdx.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,14 @@ void pychip_Bdx_InitCallbacks(OnTransferObtainedCallback onTransferObtainedCallb
216216
}
217217

218218
// Prepares the BDX system to expect a new transfer.
219-
PyChipError pychip_Bdx_ExpectBdxTransfer(PyObject transferObtainedContext)
219+
// If max_block_size != 0, it overrides the default cap for the next transfer only.
220+
PyChipError pychip_Bdx_ExpectBdxTransfer(PyObject transferObtainedContext, uint16_t max_block_size)
220221
{
221222
TransferInfo * transferInfo = gTransfers.CreateUnassociatedTransferInfo();
222223
VerifyOrReturnValue(transferInfo != nullptr, ToPyChipError(CHIP_ERROR_NO_MEMORY));
223224
transferInfo->OnTransferObtainedContext = transferObtainedContext;
225+
if (max_block_size != 0)
226+
chip::bdx::SetControllerBdxMaxBlockSizeForNextTransfer(max_block_size);
224227
gBdxTransferServer.ExpectATransfer();
225228
return ToPyChipError(CHIP_NO_ERROR);
226229
}

src/lib/core/CHIPConfig.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,6 +1922,21 @@ extern const char CHIP_NON_PRODUCTION_MARKER[];
19221922
#define CHIP_CONFIG_MAX_BDX_LOG_TRANSFERS 5
19231923
#endif // CHIP_CONFIG_MAX_BDX_LOG_TRANSFERS
19241924

1925+
/**
1926+
* @def CHIP_CONFIG_BDX_LOG_TRANSFER_MAX_BLOCK_SIZE
1927+
*
1928+
* @brief
1929+
* Maximum block size recommended by device for BDX transfers of diagnostic logs.
1930+
* If increased, also increase CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX.
1931+
* Note that SecureSession::AllowsLargePayload limits the payload size for all transport
1932+
* types besides TCP, so, if using UDP, BDX blocks larger than a certain size (e.g. 1174)
1933+
* will be unable to send.
1934+
*
1935+
*/
1936+
#ifndef CHIP_CONFIG_BDX_LOG_TRANSFER_MAX_BLOCK_SIZE
1937+
#define CHIP_CONFIG_BDX_LOG_TRANSFER_MAX_BLOCK_SIZE 1024
1938+
#endif // CHIP_CONFIG_BDX_LOG_TRANSFER_MAX_BLOCK_SIZE
1939+
19251940
/**
19261941
* @def CHIP_CONFIG_TEST_GOOGLETEST
19271942
*

src/protocols/bdx/BdxTransferDiagnosticLog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace bdx {
2525

2626
namespace {
2727
// Max block size for the BDX transfer.
28-
constexpr uint32_t kMaxBdxBlockSize = 1024;
28+
constexpr uint16_t kMaxBdxBlockSize = CHIP_CONFIG_BDX_LOG_TRANSFER_MAX_BLOCK_SIZE;
2929

3030
// How often we poll our transfer session. Sadly, we get allocated on
3131
// unsolicited message, which makes it hard for our clients to configure this.

0 commit comments

Comments
 (0)