Cloud Interface Feature base on CoAP over TCP in CA Layer
[platform/upstream/iotivity.git] / resource / csdk / connectivity / lib / libcoap-4.1.1 / option.c
index 9a52fb4..67272d9 100644 (file)
 #include "pdu.h"
 
 coap_opt_t *
-options_start(coap_pdu_t *pdu)
+options_start(coap_pdu_t *pdu, coap_transport_type transport)
 {
-
-    if (pdu && pdu->hdr
-            && (pdu->hdr->token + pdu->hdr->token_length < (unsigned char *) pdu->hdr + pdu->length))
+    if (pdu && pdu->hdr)
     {
-
-        coap_opt_t *opt = pdu->hdr->token + pdu->hdr->token_length;
-        return (*opt == COAP_PAYLOAD_START) ? NULL : opt;
-
+        if (coap_udp == transport && (pdu->hdr->coap_hdr_udp_t.token +
+                pdu->hdr->coap_hdr_udp_t.token_length
+                < (unsigned char *) pdu->hdr + pdu->length))
+        {
+            coap_opt_t *opt = pdu->hdr->coap_hdr_udp_t.token +
+                    pdu->hdr->coap_hdr_udp_t.token_length;
+            return (*opt == COAP_PAYLOAD_START) ? NULL : opt;
+        }
+#ifdef WITH_TCP
+        else if(coap_tcp == transport && (pdu->hdr->coap_hdr_tcp_t.token +
+                pdu->hdr->coap_hdr_tcp_t.token_length
+                < (unsigned char *) pdu->hdr + pdu->length))
+        {
+            coap_opt_t *opt = pdu->hdr->coap_hdr_tcp_t.token +
+                    pdu->hdr->coap_hdr_tcp_t.token_length;
+            return (*opt == COAP_PAYLOAD_START) ? NULL : opt;
+        }
+#endif
+        return NULL;
     }
     else
         return NULL;
@@ -122,7 +135,8 @@ size_t coap_opt_parse(const coap_opt_t *opt, size_t length, coap_option_t *resul
 }
 
 coap_opt_iterator_t *
-coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t filter)
+coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi,
+                          const coap_opt_filter_t filter, coap_transport_type transport)
 {
     assert(pdu);
     assert(pdu->hdr);
@@ -130,16 +144,59 @@ coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_o
 
     memset(oi, 0, sizeof(coap_opt_iterator_t));
 
-    oi->next_option = (unsigned char *) pdu->hdr + sizeof(coap_hdr_t) + pdu->hdr->token_length;
-    if ((unsigned char *) pdu->hdr + pdu->length <= oi->next_option)
+    unsigned int token_length;
+    unsigned int headerSize;
+
+    switch(transport)
     {
-        oi->bad = 1;
-        return NULL;
+#ifdef WITH_TCP
+        case coap_tcp:
+            token_length = pdu->hdr->coap_hdr_tcp_t.token_length;
+            headerSize = COAP_TCP_HEADER_NO_FIELD;
+            break;
+        case coap_tcp_8bit:
+            token_length = pdu->hdr->coap_hdr_tcp_t.token_length;
+            headerSize = COAP_TCP_HEADER_8_BIT;
+            break;
+        case coap_tcp_16bit:
+            token_length = pdu->hdr->coap_hdr_tcp_t.token_length;
+            headerSize = COAP_TCP_HEADER_16_BIT;
+            break;
+        case coap_tcp_32bit:
+            token_length = pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] & 0x0f;
+            headerSize = COAP_TCP_HEADER_32_BIT;
+            break;
+#endif
+        default:
+            token_length = pdu->hdr->coap_hdr_udp_t.token_length;
+            headerSize = sizeof(pdu->hdr->coap_hdr_udp_t);
+            break;
+    }
+
+    oi->next_option = (unsigned char *) pdu->hdr + headerSize + token_length;
+
+    if (coap_udp == transport)
+    {
+        if ((unsigned char *) &(pdu->hdr->coap_hdr_udp_t) + pdu->length <= oi->next_option)
+        {
+            oi->bad = 1;
+            return NULL;
+        }
     }
+#ifdef WITH_TCP
+    else
+    {
+        if ((unsigned char *) &(pdu->hdr->coap_hdr_tcp_t) + pdu->length <= oi->next_option)
+        {
+            oi->bad = 1;
+            return NULL;
+        }
+    }
+#endif
 
-    assert((sizeof(coap_hdr_t) + pdu->hdr->token_length) <= pdu->length);
+    assert((headerSize + token_length) <= pdu->length);
 
-    oi->length = pdu->length - (sizeof(coap_hdr_t) + pdu->hdr->token_length);
+    oi->length = pdu->length - (headerSize + token_length);
 
     if (filter)
     {
@@ -224,7 +281,7 @@ coap_check_option(coap_pdu_t *pdu, unsigned char type, coap_opt_iterator_t *oi)
     coap_option_filter_clear(f);
     coap_option_setb(f, type);
 
-    coap_option_iterator_init(pdu, oi, f);
+    coap_option_iterator_init(pdu, oi, f, coap_udp);
 
     return coap_option_next(oi);
 }