Added support for CBOR content format option.
authorStephane Lejeune <stlejeun@cisco.com>
Mon, 24 Aug 2015 14:15:30 +0000 (16:15 +0200)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Tue, 8 Sep 2015 17:34:54 +0000 (17:34 +0000)
Added a new option defining content format for CBOR encoded payloads.
This will allow a more robust interpretation of incomming payloads
and will also permit generic stacks that have no apriori knowledge
about OIC to interpret the payloads going accross the network.

Change-Id: I34feb4e305458fcef4e7343cda313d9a52d12046
Signed-off-by: Stephane Lejeune <stlejeun@cisco.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2262
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
Reviewed-by: Hauke Mehrtens <hauke.mehrtens@lantiq.com>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/common/src/caremotehandler.c
resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/stack/src/ocserverrequest.c
resource/csdk/stack/src/ocstack.c

index 720720f..2a952e5 100644 (file)
@@ -323,6 +323,16 @@ typedef enum
 } CAAdapterState_t;
 
 /**
+ * Format indicating which encoding has been used on the payload.
+ */
+typedef enum
+{
+    CA_FORMAT_UNDEFINED,    /**< Undefined enoding format */
+    CA_FORMAT_UNSUPPORTED,  /**< Unsupported encoding format */
+    CA_FORMAT_CBOR          /**< CBOR encoding format */
+} CAPayloadFormat_t;
+
+/**
  * Header options structure to be filled
  *
  * This structure is used to hold header information.
@@ -354,6 +364,7 @@ typedef struct
     uint8_t numOptions;         /**< Number of Header options */
     CAPayload_t payload;        /**< payload of the request  */
     size_t payloadSize;         /**< size in bytes of the payload */
+    CAPayloadFormat_t payloadFormat;         /**< format of the payload */
     CAURI_t resourceUri;        /**< Resource URI information **/
     CARemoteId_t identity;      /**< endpoint identity */
 } CAInfo_t;
index 7b6ce44..edab3cc 100644 (file)
@@ -284,6 +284,7 @@ CAResult_t CACloneInfo(const CAInfo_t *info, CAInfo_t *clone)
         clone->payload = temp;
         clone->payloadSize = info->payloadSize;
     }
+    clone->payloadFormat = info->payloadFormat;
 
     if (info->resourceUri)
     {
index 792ee92..e10be71 100644 (file)
@@ -150,6 +150,7 @@ char *coap_response_phrase(unsigned char code);
 #define COAP_MEDIATYPE_APPLICATION_RDF_XML           43 /* application/rdf+xml */
 #define COAP_MEDIATYPE_APPLICATION_EXI               47 /* application/exi  */
 #define COAP_MEDIATYPE_APPLICATION_JSON              50 /* application/json  */
+#define COAP_MEDIATYPE_APPLICATION_CBOR              60 /* application/cbor  */
 
 /* Note that identifiers for registered media types are in the range 0-65535. We
  * use an unallocated type here and hope for the best. */
@@ -169,7 +170,7 @@ typedef struct
     unsigned int code:8; /* request method (value 1--10) or response code (value 40-255) */
     unsigned short id; /* message id */
     unsigned char token[]; /* the actual token, if any */
-}coap_hdr_t;
+} coap_hdr_t;
 #else
 typedef struct
 {
index ec48e71..3551e5d 100644 (file)
@@ -503,6 +503,35 @@ CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t *info, coap_list_t **
         }
     }
 
+    // insert one extra header with the payload format if applicable.
+    if (CA_FORMAT_UNDEFINED != info->payloadFormat)
+    {
+        coap_list_t* node = NULL;
+        uint8_t buf[3] = {0};
+        switch (info->payloadFormat) {
+            case CA_FORMAT_CBOR:
+                node = CACreateNewOptionNode(
+                        COAP_OPTION_CONTENT_FORMAT,
+                        coap_encode_var_bytes(buf, (uint16_t)COAP_MEDIATYPE_APPLICATION_CBOR),
+                        (char *)buf);
+                break;
+            default:
+                OIC_LOG_V(ERROR, TAG, "format option:[%d] not supported", info->payloadFormat);
+        }
+        if (!node)
+        {
+            OIC_LOG(ERROR, TAG, "format option not created");
+            return CA_STATUS_INVALID_PARAM;
+        }
+        int ret = coap_insert(optlist, node, CAOrderOpts);
+        if (ret <= 0)
+        {
+            coap_delete(node);
+            OIC_LOG(ERROR, TAG, "format option not inserted in header");
+            return CA_STATUS_INVALID_PARAM;
+        }
+    }
+
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -592,7 +621,8 @@ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter)
     {
         if (COAP_OPTION_URI_PATH != opt_iter.type && COAP_OPTION_URI_QUERY != opt_iter.type
             && COAP_OPTION_BLOCK1 != opt_iter.type && COAP_OPTION_BLOCK2 != opt_iter.type
-            && COAP_OPTION_SIZE1 != opt_iter.type && COAP_OPTION_SIZE2 != opt_iter.type)
+            && COAP_OPTION_SIZE1 != opt_iter.type && COAP_OPTION_SIZE2 != opt_iter.type
+            && COAP_OPTION_CONTENT_FORMAT != opt_iter.type)
         {
             count++;
         }
@@ -631,6 +661,7 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
 
     // set message id
     outInfo->messageId = pdu->hdr->id;
+    outInfo->payloadFormat = CA_FORMAT_UNDEFINED;
 
     if (count > 0)
     {
@@ -738,6 +769,18 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
             {
                 OIC_LOG_V(DEBUG, TAG, "option[%d] will be filtering", opt_iter.type);
             }
+            else if (COAP_OPTION_CONTENT_FORMAT == opt_iter.type)
+            {
+                if (1 == COAP_OPT_LENGTH(option) && COAP_MEDIATYPE_APPLICATION_CBOR == buf[0])
+                {
+                    outInfo->payloadFormat = CA_FORMAT_CBOR;
+                }
+                else
+                {
+                    outInfo->payloadFormat = CA_FORMAT_UNSUPPORTED;
+                }
+                OIC_LOG_V(DEBUG, TAG, "option[%d] has format [%d]", opt_iter.type, (uint8_t)buf[0]);
+            }
             else
             {
                 if (idx < count)
index a3b4841..cbf4d0b 100644 (file)
@@ -533,12 +533,15 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
             OICFree(responseInfo.info.options);
             return result;
         }
+        /** @todo FIXME: this should really be set according to directives from OCConverPayload. */
+        responseInfo.info.payloadFormat = CA_FORMAT_CBOR;
     }
     else
     {
         responseInfo.isMulticast = false;
         responseInfo.info.payload = NULL;
         responseInfo.info.payloadSize = 0;
+        responseInfo.info.payloadFormat = CA_FORMAT_UNDEFINED;
     }
 
 #ifdef WITH_PRESENCE
index 6c46302..f0538d1 100644 (file)
@@ -2138,11 +2138,13 @@ OCStackResult OCDoResource(OCDoHandle *handle,
             OC_LOG(ERROR, TAG, PCF("Failed to create CBOR Payload"));
             goto exit;
         }
+        requestInfo.info.payloadFormat = CA_FORMAT_CBOR;
     }
     else
     {
         requestInfo.info.payload = NULL;
         requestInfo.info.payloadSize = 0;
+        requestInfo.info.payloadFormat = CA_FORMAT_UNDEFINED;
     }
 
     if (result != OC_STACK_OK)