diff --git a/include/openthread/coap.h b/include/openthread/coap.h index d5d02060b..a19fb16a6 100644 --- a/include/openthread/coap.h +++ b/include/openthread/coap.h @@ -608,6 +608,19 @@ otError otCoapMessageAppendObserveOption(otMessage *aMessage, uint32_t aObserve) */ otError otCoapMessageAppendUriPathOptions(otMessage *aMessage, const char *aUriPath); +/** + * Appends a Uri-Query option. + * + * @param[in,out] aMessage A pointer to the CoAP message. + * @param[in] aUriQuery A pointer to a NULL-terminated string. + * + * @retval OT_ERROR_NONE Successfully appended the option. + * @retval OT_ERROR_INVALID_ARGS The option type is not equal or greater than the last option type. + * @retval OT_ERROR_NO_BUFS The option length exceeds the buffer size. + * + */ +otError otCoapMessageAppendUriQueryOptions(otMessage *aMessage, const char *aUriQuery); + /** * Converts a CoAP Block option SZX field to the actual block size * diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 7f18df902..ef6e2d4f8 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (427) +#define OPENTHREAD_API_VERSION (428) /** * @addtogroup api-instance diff --git a/src/cli/cli_coap.cpp b/src/cli/cli_coap.cpp index 5edbe00c6..e91439109 100644 --- a/src/cli/cli_coap.cpp +++ b/src/cli/cli_coap.cpp @@ -583,7 +583,8 @@ otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode) otError error = OT_ERROR_NONE; otMessage *message = nullptr; otMessageInfo messageInfo; - uint16_t payloadLength = 0; + uint16_t payloadLength = 0; + char *uriQueryStartPtr = nullptr; // Default parameters char coapUri[kMaxUriLength] = "test"; @@ -682,7 +683,20 @@ otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode) } #endif - SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri)); + uriQueryStartPtr = const_cast(StringFind(coapUri, '?')); + + if (uriQueryStartPtr == nullptr) + { + // "?" doesn't present in URI --> contains only URI path parts + SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri)); + } + else + { + // "?" presents in URI --> contains URI path AND URI query parts + *uriQueryStartPtr++ = '\0'; + SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri)); + SuccessOrExit(error = otCoapMessageAppendUriQueryOptions(message, uriQueryStartPtr)); + } #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE if (coapBlock) diff --git a/src/core/api/coap_api.cpp b/src/core/api/coap_api.cpp index 25f3208e7..7539eba75 100644 --- a/src/core/api/coap_api.cpp +++ b/src/core/api/coap_api.cpp @@ -99,6 +99,11 @@ otError otCoapMessageAppendUriPathOptions(otMessage *aMessage, const char *aUriP return AsCoapMessage(aMessage).AppendUriPathOptions(aUriPath); } +otError otCoapMessageAppendUriQueryOptions(otMessage *aMessage, const char *aUriQuery) +{ + return AsCoapMessage(aMessage).AppendUriQueryOptions(aUriQuery); +} + uint16_t otCoapBlockSizeFromExponent(otCoapBlockSzx aSize) { return static_cast(1 << (static_cast(aSize) + Coap::Message::kBlockSzxBase)); diff --git a/src/core/coap/coap_message.cpp b/src/core/coap/coap_message.cpp index 6743f2055..cc82145e8 100644 --- a/src/core/coap/coap_message.cpp +++ b/src/core/coap/coap_message.cpp @@ -275,6 +275,24 @@ exit: return error; } +Error Message::AppendUriQueryOptions(const char *aUriQuery) +{ + Error error = kErrorNone; + const char *cur = aUriQuery; + const char *end; + + while ((end = StringFind(cur, '&')) != nullptr) + { + SuccessOrExit(error = AppendOption(kOptionUriQuery, static_cast(end - cur), cur)); + cur = end + 1; + } + + SuccessOrExit(error = AppendStringOption(kOptionUriQuery, cur)); + +exit: + return error; +} + Error Message::AppendBlockOption(Message::BlockType aType, uint32_t aNum, bool aMore, otCoapBlockSzx aSize) { Error error = kErrorNone; diff --git a/src/core/coap/coap_message.hpp b/src/core/coap/coap_message.hpp index 62128b6a3..6156df8ce 100644 --- a/src/core/coap/coap_message.hpp +++ b/src/core/coap/coap_message.hpp @@ -479,6 +479,18 @@ public: */ Error ReadUriPathOptions(char (&aUriPath)[kMaxReceivedUriPath + 1]) const; + /** + * Appends a Uri-Query option. + * + * @param[in] aUriQuery A pointer to a null-terminated string. + * + * @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. + * + */ + Error AppendUriQueryOptions(const char *aUriQuery); + /** * Appends a Block option *