Add generic APIs for set/get header option.
authorZiran Sun <ziran.sun@samsung.com>
Tue, 30 Aug 2016 14:26:22 +0000 (15:26 +0100)
committerAshok Babu Channa <ashok.channa@samsung.com>
Tue, 27 Sep 2016 05:10:25 +0000 (05:10 +0000)
These APIs should be applicable for setting/getting
header option operations for version number and proxy-uri.

Bug: https://jira.iotivity.org/browse/IOT-1223
Change-Id: Ifd2d1b6ad30dff3a247c84b63d139c9552bfb32f
Signed-off-by: Ziran Sun <ziran.sun@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/11161
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
(cherry picked from commit b3bde9b3efd85ae9ec0ef00b2dfef232ed36ad20)
Reviewed-on: https://gerrit.iotivity.org/gerrit/12219

resource/csdk/octbstack_product.def
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/test/stacktests.cpp

index 659a020..b3c92c1 100644 (file)
@@ -100,3 +100,5 @@ OCStartPresence
 OCStop
 OCStopPresence
 OCUnBindResource
+OCSetHeaderOption
+OCGetHeaderOption
index ad06006..b517bee 100644 (file)
@@ -599,6 +599,44 @@ OCResourceHandle OCGetResourceHandleAtUri(const char *uri);
 #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
index 7fd01d8..3b8806e 100644 (file)
@@ -1135,7 +1135,6 @@ typedef struct OCHeaderOption
 #endif
 } OCHeaderOption;
 
-
 /**
  * This structure describes the platform properties. All non-Null properties will be
  * included in a platform discovery request.
index c99f939..3c5470f 100644 (file)
@@ -707,17 +707,25 @@ int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptio
 
     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)
     {
index 68c592f..2acfc24 100644 (file)
@@ -618,17 +618,48 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
                             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;
             }
 
index 7042ad9..7efe158 100644 (file)
@@ -4882,4 +4882,83 @@ OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins)
     }
     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
index 8cae176..222802f 100644 (file)
@@ -1907,3 +1907,47 @@ TEST(StackUri, Rfc6874_NoOverflow_2)
     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);
+}