aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreeumay <154113236+eeumay@users.noreply.github.com>2024-03-23 01:25:59 +0800
committerGitHub <noreply@github.com>2024-03-22 10:25:59 -0700
commitf917a5320f5c0834e3dd967c532aed93a3693b60 (patch)
tree27d2bee9c1da4c51babd76ae1013fa6cefcaac58
parent51ab865600d73c78eab0900d2790f56ef6631a20 (diff)
downloadopenthread-f917a5320f5c0834e3dd967c532aed93a3693b60.tar.gz
[coap] fix copying option (#9894)
- remove typo that passed a uint64_t pointer to a function which need a sufficiently large buffer - fix bug that coap copying uri path option or any other long option failed
-rw-r--r--src/core/coap/coap.cpp6
-rw-r--r--src/core/coap/coap_message.cpp31
-rw-r--r--src/core/coap/coap_message.hpp29
3 files changed, 61 insertions, 5 deletions
diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp
index 696d0fc83..6afd693a7 100644
--- a/src/core/coap/coap.cpp
+++ b/src/core/coap/coap.cpp
@@ -619,7 +619,6 @@ Error CoapBase::PrepareNextBlockRequest(Message::BlockType aType,
{
Error error = kErrorNone;
bool isOptionSet = false;
- uint64_t optionBuf = 0;
uint16_t blockOption = 0;
Option::Iterator iterator;
@@ -655,8 +654,9 @@ Error CoapBase::PrepareNextBlockRequest(Message::BlockType aType,
}
// Copy option
- SuccessOrExit(error = iterator.ReadOptionValue(&optionBuf));
- SuccessOrExit(error = aRequest.AppendOption(optionNumber, iterator.GetOption()->GetLength(), &optionBuf));
+ SuccessOrExit(error = aRequest.AppendOptionFromMessage(optionNumber, iterator.GetOption()->GetLength(),
+ iterator.GetMessage(),
+ iterator.GetOptionValueMessageOffset()));
}
if (!isOptionSet)
diff --git a/src/core/coap/coap_message.cpp b/src/core/coap/coap_message.cpp
index cbf544813..4998de7a6 100644
--- a/src/core/coap/coap_message.cpp
+++ b/src/core/coap/coap_message.cpp
@@ -146,8 +146,12 @@ uint8_t Message::WriteExtendedOptionField(uint16_t aValue, uint8_t *&aBuffer)
return rval;
}
-Error Message::AppendOption(uint16_t aNumber, uint16_t aLength, const void *aValue)
+Error Message::AppendOptionHeader(uint16_t aNumber, uint16_t aLength)
{
+ /*
+ * Appends a CoAP Option header field (Option Delta/Length) per RFC 7252.
+ */
+
Error error = kErrorNone;
uint16_t delta;
uint8_t header[kMaxOptionHeaderSize];
@@ -167,10 +171,33 @@ Error Message::AppendOption(uint16_t aNumber, uint16_t aLength, const void *aVal
VerifyOrExit(static_cast<uint32_t>(GetLength()) + headerLength + aLength < kMaxHeaderLength, error = kErrorNoBufs);
SuccessOrExit(error = AppendBytes(header, headerLength));
- SuccessOrExit(error = AppendBytes(aValue, aLength));
GetHelpData().mOptionLast = aNumber;
+exit:
+ return error;
+}
+
+Error Message::AppendOption(uint16_t aNumber, uint16_t aLength, const void *aValue)
+{
+ Error error = kErrorNone;
+
+ SuccessOrExit(error = AppendOptionHeader(aNumber, aLength));
+ SuccessOrExit(error = AppendBytes(aValue, aLength));
+
+ GetHelpData().mHeaderLength = GetLength();
+
+exit:
+ return error;
+}
+
+Error Message::AppendOptionFromMessage(uint16_t aNumber, uint16_t aLength, const Message &aMessage, uint16_t aOffset)
+{
+ Error error = kErrorNone;
+
+ SuccessOrExit(error = AppendOptionHeader(aNumber, aLength));
+ SuccessOrExit(error = AppendBytesFromMessage(aMessage, aOffset, aLength));
+
GetHelpData().mHeaderLength = GetLength();
exit:
diff --git a/src/core/coap/coap_message.hpp b/src/core/coap/coap_message.hpp
index 789c91939..62128b6a3 100644
--- a/src/core/coap/coap_message.hpp
+++ b/src/core/coap/coap_message.hpp
@@ -402,6 +402,23 @@ public:
Error AppendOption(uint16_t aNumber, uint16_t aLength, const void *aValue);
/**
+ * Appends a CoAP option reading Option value from another or potentially the same message.
+ *
+ * @param[in] aNumber The CoAP Option number.
+ * @param[in] aLength The CoAP Option length.
+ * @param[in] aMessage The message to read the CoAP Option value from (it can be the same as the current message).
+ * @param[in] aOffset The offset in @p aMessage to start reading the CoAP Option value from (@p aLength bytes are
+ * used as Option value).
+ *
+ * @retval kErrorNone Successfully appended the option.
+ * @retval kErrorInvalidArgs The option type is not equal or greater than the last option type.
+ * @retval kErrorNoBufs The option length exceeds the buffer size.
+ * @retval kErrorParse Not enough bytes in @p aMessage to read @p aLength bytes from @p aOffset.
+ *
+ */
+ Error AppendOptionFromMessage(uint16_t aNumber, uint16_t aLength, const Message &aMessage, uint16_t aOffset);
+
+ /**
* Appends an unsigned integer CoAP option as specified in RFC-7252 section-3.2
*
* @param[in] aNumber The CoAP Option number.
@@ -966,6 +983,8 @@ private:
}
uint8_t WriteExtendedOptionField(uint16_t aValue, uint8_t *&aBuffer);
+
+ Error AppendOptionHeader(uint16_t aNumber, uint16_t aLength);
};
/**
@@ -1187,6 +1206,16 @@ public:
*/
uint16_t GetPayloadMessageOffset(void) const { return mNextOptionOffset; }
+ /**
+ * Gets the offset of beginning of the CoAP Option Value.
+ *
+ * MUST be used during the iterator is in progress.
+ *
+ * @returns The offset of beginning of the CoAP Option Value
+ *
+ */
+ uint16_t GetOptionValueMessageOffset(void) const { return mNextOptionOffset - mOption.mLength; }
+
private:
// `mOption.mLength` value to indicate iterator is done.
static constexpr uint16_t kIteratorDoneLength = 0xffff;