OCStop
OCStopPresence
OCUnBindResource
+OCSetHeaderOption
+OCGetHeaderOption
#endif
//#endif // DIRECT_PAIRING
+/**
+ * Add a header option to the given header option array.
+ *
+ * @param ocHdrOpt Pointer to existing options.
+ * @param numOptions Number of existing options.
+ * @param optionID COAP option ID.
+ * @param optionData Option data value.
+ * @param optionDataLength Size of Option data value.
+ *
+ * @return ::OC_STACK_OK on success and other value otherwise.
+ */
+OCStackResult
+OCSetHeaderOption(OCHeaderOption* ocHdrOpt,
+ size_t* numOptions,
+ uint16_t optionID,
+ void* optionData,
+ size_t optionDataLength);
+
+/**
+ * Get data value of the option with specified option ID from given header option array.
+ *
+ * @param ocHdrOpt Pointer to existing options.
+ * @param numOptions Number of existing options.
+ * @param optionID COAP option ID.
+ * @param optionData Pointer to option data.
+ * @param optionDataLength Size of option data value.
+ * @param receivedDatalLength Pointer to the actual length of received data.
+ *
+ * @return ::OC_STACK_OK on success and other value otherwise.
+ */
+OCStackResult
+OCGetHeaderOption(OCHeaderOption* ocHdrOpt,
+ size_t numOptions,
+ uint16_t optionID,
+ void* optionData,
+ size_t optionDataLength,
+ uint16_t* receivedDatalLength);
+
#ifdef __cplusplus
}
#endif // __cplusplus
#endif
} OCHeaderOption;
-
/**
* This structure describes the platform properties. All non-Null properties will be
* included in a platform discovery request.
if (withVendorSpecificHeaderOptions)
{
+ memset(options, 0, sizeof(OCHeaderOption)* MAX_HEADER_OPTIONS);
+ size_t numOptions = 0;
uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ uint16_t optionID = 2048;
+ size_t optionDataSize = sizeof(option0);
+ OCSetHeaderOption(options,
+ &numOptions,
+ optionID,
+ option0,
+ optionDataSize);
+
uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
- memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
- options[0].protocolID = OC_COAP_ID;
- options[0].optionID = 2048;
- memcpy(options[0].optionData, option0, sizeof(option0));
- options[0].optionLength = 10;
- options[1].protocolID = OC_COAP_ID;
- options[1].optionID = 3000;
- memcpy(options[1].optionData, option1, sizeof(option1));
- options[1].optionLength = 10;
+ optionID = 3000;
+ optionDataSize = sizeof(option1);
+ OCSetHeaderOption(options,
+ &numOptions,
+ optionID,
+ option1,
+ optionDataSize);
}
if (withVendorSpecificHeaderOptions)
{
MAX_HEADER_OPTION_DATA_LENGTH);
}
}
- OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
- uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
- uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
- sendOptions[0].protocolID = OC_COAP_ID;
- sendOptions[0].optionID = 2248;
- memcpy(sendOptions[0].optionData, option2, sizeof(option2));
- sendOptions[0].optionLength = 10;
- sendOptions[1].protocolID = OC_COAP_ID;
- sendOptions[1].optionID = 2600;
- memcpy(sendOptions[1].optionData, option3, sizeof(option3));
- sendOptions[1].optionLength = 10;
+
+ OCHeaderOption* sendOptions = response.sendVendorSpecificHeaderOptions;
+ size_t numOptions = response.numSendVendorSpecificHeaderOptions;
+ // Check if the option header has already existed before adding it in.
+ uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
+ size_t optionDataSize = sizeof(optionData);
+ uint16_t actualDataSize = 0;
+ OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
+ response.numSendVendorSpecificHeaderOptions,
+ 2248,
+ optionData,
+ optionDataSize,
+ &actualDataSize);
+ if (actualDataSize == 0)
+ {
+ uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
+ uint16_t optionID2 = 2248;
+ size_t optionDataSize2 = sizeof(option2);
+ OCSetHeaderOption(sendOptions,
+ &numOptions,
+ optionID2,
+ option2,
+ optionDataSize2);
+ }
+
+ OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
+ response.numSendVendorSpecificHeaderOptions,
+ 2600,
+ optionData,
+ optionDataSize,
+ &actualDataSize);
+ if (actualDataSize == 0)
+ {
+ uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
+ uint16_t optionID3 = 2600;
+ size_t optionDataSize3 = sizeof(option3);
+ OCSetHeaderOption(sendOptions,
+ &numOptions,
+ optionID3,
+ option3,
+ optionDataSize3);
+ }
response.numSendVendorSpecificHeaderOptions = 2;
}
}
return OC_STACK_ERROR;
}
+
+OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID,
+ void* optionData, size_t optionDataLength)
+{
+ if (!ocHdrOpt)
+ {
+ OIC_LOG (INFO, TAG, "Header options are NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (!optionData)
+ {
+ OIC_LOG (INFO, TAG, "optionData are NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (!numOptions)
+ {
+ OIC_LOG (INFO, TAG, "numOptions is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (*numOptions >= MAX_HEADER_OPTIONS)
+ {
+ OIC_LOG (INFO, TAG, "Exceeding MAX_HEADER_OPTIONS");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ ocHdrOpt += *numOptions;
+ ocHdrOpt->protocolID = OC_COAP_ID;
+ ocHdrOpt->optionID = optionID;
+ ocHdrOpt->optionLength =
+ optionDataLength < MAX_HEADER_OPTION_DATA_LENGTH ?
+ optionDataLength : MAX_HEADER_OPTION_DATA_LENGTH;
+ memcpy(ocHdrOpt->optionData, (const void*) optionData, ocHdrOpt->optionLength);
+ *numOptions += 1;
+
+ return OC_STACK_OK;
+}
+OCStackResult OCGetHeaderOption(OCHeaderOption* ocHdrOpt, size_t numOptions, uint16_t optionID,
+ void* optionData, size_t optionDataLength, uint16_t* receivedDataLength)
+{
+ if (!ocHdrOpt || !numOptions)
+ {
+ OIC_LOG (INFO, TAG, "No options present");
+ return OC_STACK_OK;
+ }
+
+ if (!optionData)
+ {
+ OIC_LOG (INFO, TAG, "optionData are NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (!receivedDataLength)
+ {
+ OIC_LOG (INFO, TAG, "receivedDataLength is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ for (uint8_t i = 0; i < numOptions; i++)
+ {
+ if (ocHdrOpt[i].optionID == optionID)
+ {
+ if (optionDataLength >= ocHdrOpt->optionLength)
+ {
+ memcpy(optionData, ocHdrOpt->optionData, ocHdrOpt->optionLength);
+ *receivedDataLength = ocHdrOpt->optionLength;
+ return OC_STACK_OK;
+ }
+ else
+ {
+ OIC_LOG (ERROR, TAG, "optionDataLength is less than the length of received data");
+ return OC_STACK_ERROR;
+ }
+ }
+ }
+ return OC_STACK_OK;
+}
#endif
void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
EXPECT_EQ(OC_STACK_ERROR, result);
}
+TEST(StackHeaderOption, setHeaderOption)
+{
+ uint8_t optionValue1[MAX_HEADER_OPTION_DATA_LENGTH] =
+ { 1 };
+ OCHeaderOption options[MAX_HEADER_OPTIONS] =
+ {
+ { OC_COAP_ID, 6, 8, optionValue1 }, };
+ uint8_t optionData = 255;
+ size_t optionDataSize = sizeof(optionData);
+ size_t numOptions = 1;
+ uint16_t optionID = 2048;
+ EXPECT_EQ(OC_STACK_OK, OCSetHeaderOption(options,
+ &numOptions,
+ optionID,
+ &optionData,
+ optionDataSize));
+ EXPECT_EQ(options[1].optionID, optionID);
+ EXPECT_EQ(options[1].optionData[0], 255);
+}
+
+TEST(StackHeaderOption, getHeaderOption)
+{
+ uint8_t optionValue1[MAX_HEADER_OPTION_DATA_LENGTH] =
+ { 1 };
+ uint8_t optionValue2[MAX_HEADER_OPTION_DATA_LENGTH] =
+ { 255 };
+ OCHeaderOption options[MAX_HEADER_OPTIONS] =
+ {
+ { OC_COAP_ID, 6, 8, optionValue1 },
+ { OC_COAP_ID, 2048, 16, optionValue2 }, };
+ uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
+ size_t optionDataSize = sizeof(optionData);
+ size_t numOptions = 2;
+ uint16_t optionID = 6;
+ uint16_t actualDataSize = 0;
+ EXPECT_EQ(OC_STACK_OK, OCGetHeaderOption(options,
+ numOptions,
+ optionID,
+ optionData,
+ optionDataSize,
+ &actualDataSize));
+ EXPECT_EQ(optionData[0], 1);
+ EXPECT_EQ(actualDataSize, 8);
+}