mirror of
https://github.com/espressif/openthread.git
synced 2026-08-30 22:09:54 +00:00
[coap] simplify SendMessage() for block-wise transfers (#12239)
This commit simplifies the block-wise transfer implementation within `CoapBase::SendMessage()`. It extract the logic for handling the initial block of an outgoing block-wise transfer from `CoapBase::SendMessage()` into a new private method, `ProcessBlockwiseSend()`. This improves readability and maintainability while removing code duplication when processing block-wise sends for different message types. It also cleans up `coap.hpp` by consolidating several declarations related to block-wise transfers under a single `OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE` block.
This commit is contained in:
+57
-47
@@ -196,11 +196,7 @@ Error CoapBase::SendMessage(Message &aMessage,
|
||||
Error error;
|
||||
Message *storedCopy = nullptr;
|
||||
uint16_t copyLength = 0;
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
uint8_t buf[kMaxBlockLength] = {0};
|
||||
uint16_t bufLen = kMaxBlockLength;
|
||||
bool moreBlocks = false;
|
||||
#endif
|
||||
Metadata metadata;
|
||||
|
||||
if (aTxParameters == nullptr)
|
||||
{
|
||||
@@ -211,51 +207,22 @@ Error CoapBase::SendMessage(Message &aMessage,
|
||||
SuccessOrExit(error = aTxParameters->ValidateFor(aMessage));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
metadata.mBlockwiseReceiveHook = aReceiveHook;
|
||||
metadata.mBlockwiseTransmitHook = aTransmitHook;
|
||||
|
||||
SuccessOrExit(error = ProcessBlockwiseSend(aMessage, aTransmitHook, aContext));
|
||||
#endif
|
||||
|
||||
switch (aMessage.GetType())
|
||||
{
|
||||
case kTypeAck:
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
// Check for block-wise transfer
|
||||
if ((aTransmitHook != nullptr) && (aMessage.ReadBlockOptionValues(kOptionBlock2) == kErrorNone) &&
|
||||
(aMessage.GetBlockWiseBlockNumber() == 0))
|
||||
{
|
||||
// Set payload for first block of the transfer
|
||||
VerifyOrExit((bufLen = BlockSizeFromExponent(aMessage.GetBlockWiseBlockSize())) <= kMaxBlockLength,
|
||||
error = kErrorNoBufs);
|
||||
SuccessOrExit(error = aTransmitHook(aContext, buf, aMessage.GetBlockWiseBlockNumber() * bufLen, &bufLen,
|
||||
&moreBlocks));
|
||||
SuccessOrExit(error = aMessage.AppendBytes(buf, bufLen));
|
||||
|
||||
SuccessOrExit(error = CacheLastBlockResponse(&aMessage));
|
||||
}
|
||||
#endif
|
||||
|
||||
mResponseCache.Add(aMessage, aMessageInfo, aTxParameters->CalculateExchangeLifetime());
|
||||
break;
|
||||
case kTypeReset:
|
||||
OT_ASSERT(aMessage.GetCode() == kCodeEmpty);
|
||||
break;
|
||||
default:
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
// Check for block-wise transfer
|
||||
if ((aTransmitHook != nullptr) && (aMessage.ReadBlockOptionValues(kOptionBlock1) == kErrorNone) &&
|
||||
(aMessage.GetBlockWiseBlockNumber() == 0))
|
||||
{
|
||||
// Set payload for first block of the transfer
|
||||
VerifyOrExit((bufLen = BlockSizeFromExponent(aMessage.GetBlockWiseBlockSize())) <= kMaxBlockLength,
|
||||
error = kErrorNoBufs);
|
||||
SuccessOrExit(error = aTransmitHook(aContext, buf, aMessage.GetBlockWiseBlockNumber() * bufLen, &bufLen,
|
||||
&moreBlocks));
|
||||
SuccessOrExit(error = aMessage.AppendBytes(buf, bufLen));
|
||||
|
||||
// Block-Wise messages always have to be confirmable
|
||||
if (aMessage.IsNonConfirmable())
|
||||
{
|
||||
aMessage.SetType(kTypeConfirmable);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
aMessage.SetMessageId(mMessageId++);
|
||||
break;
|
||||
}
|
||||
@@ -275,8 +242,6 @@ Error CoapBase::SendMessage(Message &aMessage,
|
||||
|
||||
if (copyLength > 0)
|
||||
{
|
||||
Metadata metadata;
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
|
||||
// Whether or not to turn on special "Observe" handling.
|
||||
Option::Iterator iterator;
|
||||
@@ -324,10 +289,6 @@ Error CoapBase::SendMessage(Message &aMessage,
|
||||
metadata.mHopLimit = aMessageInfo.GetHopLimit();
|
||||
metadata.mIsHostInterface = aMessageInfo.IsHostInterface();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
metadata.mBlockwiseReceiveHook = aReceiveHook;
|
||||
metadata.mBlockwiseTransmitHook = aTransmitHook;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
|
||||
metadata.mObserve = observe;
|
||||
#endif
|
||||
@@ -1135,6 +1096,55 @@ void CoapBase::RemoveBlockWiseResource(ResourceBlockWise &aResource)
|
||||
aResource.SetNext(nullptr);
|
||||
}
|
||||
|
||||
Error CoapBase::SendMessage(Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
const TxParameters *aTxParameters,
|
||||
ResponseHandler aHandler,
|
||||
void *aContext)
|
||||
{
|
||||
return SendMessage(aMessage, aMessageInfo, aTxParameters, aHandler, aContext, nullptr, nullptr);
|
||||
}
|
||||
|
||||
Error CoapBase::ProcessBlockwiseSend(Message &aMessage, BlockwiseTransmitHook aTransmitHook, void *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
uint8_t type = aMessage.GetType();
|
||||
bool moreBlocks = false;
|
||||
uint16_t bufLen;
|
||||
uint8_t buf[kMaxBlockLength];
|
||||
|
||||
VerifyOrExit(type != kTypeReset);
|
||||
|
||||
VerifyOrExit(aTransmitHook != nullptr);
|
||||
VerifyOrExit(aMessage.GetBlockWiseBlockNumber() == 0);
|
||||
|
||||
SuccessOrExit(aMessage.ReadBlockOptionValues(type == kTypeAck ? kOptionBlock2 : kOptionBlock1));
|
||||
|
||||
bufLen = BlockSizeFromExponent(aMessage.GetBlockWiseBlockSize());
|
||||
VerifyOrExit(bufLen <= kMaxBlockLength, error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = aTransmitHook(aContext, buf, 0, &bufLen, &moreBlocks));
|
||||
SuccessOrExit(error = aMessage.AppendBytes(buf, bufLen));
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case kTypeAck:
|
||||
SuccessOrExit(error = CacheLastBlockResponse(&aMessage));
|
||||
break;
|
||||
|
||||
case kTypeNonConfirmable:
|
||||
// Block-Wise messages always have to be confirmable
|
||||
aMessage.SetType(kTypeConfirmable);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapBase::FreeLastBlockResponse(void)
|
||||
{
|
||||
if (mLastResponse != nullptr)
|
||||
|
||||
+58
-63
@@ -269,23 +269,6 @@ public:
|
||||
*/
|
||||
void ClearRequests(const Ip6::Address &aAddress);
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
|
||||
/**
|
||||
* Adds a block-wise resource to the CoAP server.
|
||||
*
|
||||
* @param[in] aResource A reference to the resource.
|
||||
*/
|
||||
void AddBlockWiseResource(ResourceBlockWise &aResource);
|
||||
|
||||
/**
|
||||
* Removes a block-wise resource from the CoAP server.
|
||||
*
|
||||
* @param[in] aResource A reference to the resource.
|
||||
*/
|
||||
void RemoveBlockWiseResource(ResourceBlockWise &aResource);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adds a resource to the CoAP server.
|
||||
*
|
||||
@@ -423,34 +406,6 @@ public:
|
||||
*/
|
||||
Message *NewResponseMessage(const Message &aRequest);
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
/**
|
||||
* Sends a CoAP message block-wise with custom transmission parameters.
|
||||
*
|
||||
* If a response for a request is expected, respective function and context information should be provided.
|
||||
* If no response is expected, these arguments should be NULL pointers.
|
||||
* If Message ID was not set in the header (equal to 0), this method will assign unique Message ID to the message.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
* @param[in] aTxParameters A pointer to `TxParameters`. If `nullptr`, default `TxParameters` will be used.
|
||||
* @param[in] aHandler A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aTransmitHook A pointer to a hook function for outgoing block-wise transfer.
|
||||
* @param[in] aReceiveHook A pointer to a hook function for incoming block-wise transfer.
|
||||
*
|
||||
* @retval kErrorNone Successfully sent CoAP message.
|
||||
* @retval kErrorNoBufs Failed to allocate retransmission data.
|
||||
*/
|
||||
Error SendMessage(Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
const TxParameters *aTxParameters,
|
||||
otCoapResponseHandler aHandler,
|
||||
void *aContext,
|
||||
otCoapBlockwiseTransmitHook aTransmitHook = nullptr,
|
||||
otCoapBlockwiseReceiveHook aReceiveHook = nullptr);
|
||||
#else // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
|
||||
/**
|
||||
* Sends a CoAP message with custom transmission parameters.
|
||||
*
|
||||
@@ -472,7 +427,6 @@ public:
|
||||
const TxParameters *aTxParameters,
|
||||
ResponseHandler aHandler,
|
||||
void *aContext);
|
||||
#endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
|
||||
/**
|
||||
* Sends a CoAP message with custom transmission parameters.
|
||||
@@ -629,23 +583,6 @@ public:
|
||||
*/
|
||||
Error SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
/**
|
||||
* Sends a header-only CoAP message to indicate not all blocks have been sent or
|
||||
* were sent out of order.
|
||||
*
|
||||
* @param[in] aRequest A reference to the CoAP Message that was used in CoAP request.
|
||||
* @param[in] aMessageInfo The message info corresponding to the CoAP request.
|
||||
*
|
||||
* @retval kErrorNone Successfully enqueued the CoAP response message.
|
||||
* @retval kErrorNoBufs Insufficient buffers available to send the CoAP response.
|
||||
*/
|
||||
Error SendRequestEntityIncomplete(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return SendHeaderResponse(kCodeRequestIncomplete, aRequest, aMessageInfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Aborts CoAP transactions associated with given handler and context.
|
||||
*
|
||||
@@ -677,6 +614,63 @@ public:
|
||||
*/
|
||||
void GetRequestAndCachedResponsesQueueInfo(MessageQueue::Info &aQueueInfo) const;
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
/**
|
||||
* Adds a block-wise resource to the CoAP server.
|
||||
*
|
||||
* @param[in] aResource A reference to the resource.
|
||||
*/
|
||||
void AddBlockWiseResource(ResourceBlockWise &aResource);
|
||||
|
||||
/**
|
||||
* Removes a block-wise resource from the CoAP server.
|
||||
*
|
||||
* @param[in] aResource A reference to the resource.
|
||||
*/
|
||||
void RemoveBlockWiseResource(ResourceBlockWise &aResource);
|
||||
|
||||
/**
|
||||
* Sends a CoAP message block-wise with custom transmission parameters.
|
||||
*
|
||||
* If a response for a request is expected, respective function and context information should be provided.
|
||||
* If no response is expected, these arguments should be NULL pointers.
|
||||
* If Message ID was not set in the header (equal to 0), this method will assign unique Message ID to the message.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
* @param[in] aTxParameters A pointer to `TxParameters`. If `nullptr`, default `TxParameters will be used.
|
||||
* @param[in] aHandler A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aTransmitHook A pointer to a hook function for outgoing block-wise transfer.
|
||||
* @param[in] aReceiveHook A pointer to a hook function for incoming block-wise transfer.
|
||||
*
|
||||
* @retval kErrorNone Successfully sent CoAP message.
|
||||
* @retval kErrorNoBufs Failed to allocate retransmission data.
|
||||
*/
|
||||
Error SendMessage(Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
const TxParameters *aTxParameters,
|
||||
otCoapResponseHandler aHandler,
|
||||
void *aContext,
|
||||
BlockwiseTransmitHook aTransmitHook,
|
||||
BlockwiseReceiveHook aReceiveHook);
|
||||
|
||||
/**
|
||||
* Sends a header-only CoAP message to indicate not all blocks have been sent or
|
||||
* were sent out of order.
|
||||
*
|
||||
* @param[in] aRequest A reference to the CoAP Message that was used in CoAP request.
|
||||
* @param[in] aMessageInfo The message info corresponding to the CoAP request.
|
||||
*
|
||||
* @retval kErrorNone Successfully enqueued the CoAP response message.
|
||||
* @retval kErrorNoBufs Insufficient buffers available to send the CoAP response.
|
||||
*/
|
||||
Error SendRequestEntityIncomplete(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return SendHeaderResponse(kCodeRequestIncomplete, aRequest, aMessageInfo);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Defines function pointer to handle a CoAP resource.
|
||||
@@ -817,6 +811,7 @@ private:
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
|
||||
|
||||
Error ProcessBlockwiseSend(Message &aMessage, BlockwiseTransmitHook aTransmitHook, void *aContext);
|
||||
void FreeLastBlockResponse(void);
|
||||
Error CacheLastBlockResponse(Message *aResponse);
|
||||
Error PrepareNextBlockRequest(Message::BlockType aType,
|
||||
|
||||
Reference in New Issue
Block a user