diff options
author | eeumay <154113236+eeumay@users.noreply.github.com> | 2024-03-23 01:25:59 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-22 10:25:59 -0700 |
commit | f917a5320f5c0834e3dd967c532aed93a3693b60 (patch) | |
tree | 27d2bee9c1da4c51babd76ae1013fa6cefcaac58 | |
parent | 51ab865600d73c78eab0900d2790f56ef6631a20 (diff) | |
download | openthread-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.cpp | 6 | ||||
-rw-r--r-- | src/core/coap/coap_message.cpp | 31 | ||||
-rw-r--r-- | src/core/coap/coap_message.hpp | 29 |
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; |