You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/12/07 04:46:38 UTC

[04/10] incubator-mynewt-core git commit: oic; add parsing/encoding TCP like CoAP. Use this with BLE.

oic; add parsing/encoding TCP like CoAP. Use this with BLE.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/3b8b6928
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/3b8b6928
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/3b8b6928

Branch: refs/heads/develop
Commit: 3b8b69283744cdec31c6537bccd21dbaa56cf455
Parents: 524a6ea
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Dec 2 17:49:22 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Dec 6 20:45:59 2016 -0800

----------------------------------------------------------------------
 net/oic/src/api/oc_client_api.c        |  54 +++++-----
 net/oic/src/api/oc_ri.c                |  23 ++--
 net/oic/src/api/oc_server_api.c        |   2 +-
 net/oic/src/messaging/coap/coap.c      | 162 +++++++++++++++++++---------
 net/oic/src/messaging/coap/coap.h      |   4 +-
 net/oic/src/messaging/coap/constants.h |  72 ++++++++++++-
 net/oic/src/messaging/coap/engine.c    |  14 ++-
 net/oic/src/messaging/coap/observe.c   |   3 +-
 net/oic/src/messaging/coap/separate.c  |   3 +-
 net/oic/src/port/oc_connectivity.h     |  10 ++
 10 files changed, 247 insertions(+), 100 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/api/oc_client_api.c
----------------------------------------------------------------------
diff --git a/net/oic/src/api/oc_client_api.c b/net/oic/src/api/oc_client_api.c
index 8122f17..0dce249 100644
--- a/net/oic/src/api/oc_client_api.c
+++ b/net/oic/src/api/oc_client_api.c
@@ -28,33 +28,35 @@ coap_packet_t request[1];
 static bool
 dispatch_coap_request(void)
 {
-  int response_length = oc_rep_finalize();
-  if (!transaction) {
-    if (message) {
-      if (response_length) {
-        coap_set_payload(request, message->data + COAP_MAX_HEADER_SIZE,
-                         response_length);
-        coap_set_header_content_format(request, APPLICATION_CBOR);
-      }
-      message->length = coap_serialize_message(request, message->data);
-      coap_send_message(message);
-      message = 0;
-      return true;
+    int response_length = oc_rep_finalize();
+    if (!transaction) {
+        if (message) {
+            if (response_length) {
+                coap_set_payload(request, message->data + COAP_MAX_HEADER_SIZE,
+                                 response_length);
+                coap_set_header_content_format(request, APPLICATION_CBOR);
+            }
+            message->length = coap_serialize_message(request, message->data,
+                                       oc_endpoint_use_tcp(&message->endpoint));
+            coap_send_message(message);
+            message = 0;
+            return true;
+        }
+    } else {
+        if (response_length) {
+            coap_set_payload(request,
+                             transaction->message->data + COAP_MAX_HEADER_SIZE,
+                             response_length);
+            coap_set_header_content_format(request, APPLICATION_CBOR);
+        }
+        transaction->message->length =
+          coap_serialize_message(request, transaction->message->data,
+                          oc_endpoint_use_tcp(&transaction->message->endpoint));
+        coap_send_transaction(transaction);
+        transaction = 0;
+        return true;
     }
-  } else {
-    if (response_length) {
-      coap_set_payload(request,
-                       transaction->message->data + COAP_MAX_HEADER_SIZE,
-                       response_length);
-      coap_set_header_content_format(request, APPLICATION_CBOR);
-    }
-    transaction->message->length =
-      coap_serialize_message(request, transaction->message->data);
-    coap_send_transaction(transaction);
-    transaction = 0;
-    return true;
-  }
-  return false;
+    return false;
 }
 
 static bool

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/api/oc_ri.c
----------------------------------------------------------------------
diff --git a/net/oic/src/api/oc_ri.c b/net/oic/src/api/oc_ri.c
index da89d11..fae737c 100644
--- a/net/oic/src/api/oc_ri.c
+++ b/net/oic/src/api/oc_ri.c
@@ -696,17 +696,18 @@ bool
 oc_ri_send_rst(oc_endpoint_t *endpoint, uint8_t *token, uint8_t token_len,
                uint16_t mid)
 {
-  coap_packet_t rst[1];
-  coap_init_message(rst, COAP_TYPE_RST, 0, mid);
-  coap_set_header_observe(rst, 1);
-  coap_set_token(rst, token, token_len);
-  oc_message_t *message = oc_allocate_message();
-  if (message) {
-    message->length = coap_serialize_message(rst, message->data);
-    coap_send_message(message);
-    return true;
-  }
-  return false;
+    coap_packet_t rst[1];
+    coap_init_message(rst, COAP_TYPE_RST, 0, mid);
+    coap_set_header_observe(rst, 1);
+    coap_set_token(rst, token, token_len);
+    oc_message_t *message = oc_allocate_message();
+    if (message) {
+        message->length = coap_serialize_message(rst, message->data,
+                                                 oc_endpoint_use_tcp(endpoint));
+        coap_send_message(message);
+        return true;
+    }
+    return false;
 }
 
 bool

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/api/oc_server_api.c
----------------------------------------------------------------------
diff --git a/net/oic/src/api/oc_server_api.c b/net/oic/src/api/oc_server_api.c
index a45cc6f..9cdb4e1 100644
--- a/net/oic/src/api/oc_server_api.c
+++ b/net/oic/src/api/oc_server_api.c
@@ -260,7 +260,7 @@ oc_send_separate_response(oc_separate_response_t *handle,
                 }
                 t->type = response->type;
                 t->message->length = coap_serialize_message(response,
-                  t->message->data);
+                  t->message->data, oc_endpoint_use_tcp(&cur->endpoint));
                 coap_send_transaction(t);
             }
             coap_separate_clear(handle, cur);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/messaging/coap/coap.c
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/coap.c b/net/oic/src/messaging/coap/coap.c
index 5e490bd..470af9c 100644
--- a/net/oic/src/messaging/coap/coap.c
+++ b/net/oic/src/messaging/coap/coap.c
@@ -289,46 +289,27 @@ coap_init_message(coap_packet_t *pkt, coap_message_type_t type,
 /*---------------------------------------------------------------------------*/
 
 size_t
-coap_serialize_message(coap_packet_t *pkt, uint8_t *buffer)
+coap_serialize_message(coap_packet_t *pkt, uint8_t *buffer, int tcp_hdr)
 {
     struct coap_udp_hdr *cuh;
+    struct coap_tcp_hdr0 *cth0;
+    struct coap_tcp_hdr8 *cth8;
+    struct coap_tcp_hdr16 *cth16;
+    struct coap_tcp_hdr32 *cth32;
     uint8_t *option;
     unsigned int current_number = 0;
+    int len, data_len;
 
     /* Initialize */
     pkt->buffer = buffer;
     pkt->version = 1;
 
-    LOG("-Serializing MID %u to %p, ", pkt->mid, pkt->buffer);
-
-    /* set header fields */
-    cuh = (struct coap_udp_hdr *)pkt->buffer;
-    cuh->version = pkt->version;
-    cuh->type = pkt->type;
-    cuh->token_len = pkt->token_len;
-    cuh->code = pkt->code;
-    cuh->id = htons(pkt->mid);
-
-    /* empty packet, dont need to do more stuff */
-    if (!pkt->code) {
-        LOG("-Done serializing empty message at %p-\n", pkt->buffer);
-        return 4;
-    }
-
-    /* set Token */
-    LOG("Token (len %u)", pkt->token_len);
-    option = pkt->buffer + COAP_HEADER_LEN;
-    for (current_number = 0; current_number < pkt->token_len;
-         ++current_number) {
-        LOG(" %02X", pkt->token[current_number]);
-        *option = pkt->token[current_number];
-        ++option;
-    }
-    LOG("-\n");
+    LOG("-Serializing MID %u to %p, ", pkt->mid, buffer);
 
     /* Serialize options */
     current_number = 0;
 
+    option = buffer;
     LOG("-Serializing options at %p-\n", option);
 #if 0
     /* The options must be serialized in the order of their number */
@@ -374,21 +355,68 @@ coap_serialize_message(coap_packet_t *pkt, uint8_t *buffer)
 
     LOG("-Done serializing at %p----\n", option);
 
-    /* Pack payload */
-    if ((option - pkt->buffer) <= COAP_MAX_HEADER_SIZE) {
-        /* Payload marker */
-        if (pkt->payload_len) {
-            *option = 0xFF;
-            ++option;
+    /* Payload marker */
+    if (pkt->payload_len) {
+        *option = 0xFF;
+        ++option;
+    }
+    len = option - buffer;
+    data_len = len + pkt->payload_len;
+
+    /* set header fields */
+    if (!tcp_hdr) {
+        if (len + sizeof(*cuh) + pkt->token_len > COAP_MAX_HEADER_SIZE) {
+            pkt->buffer = NULL;
+            coap_error_message = "Serialized header exceeds MAX_HEADER_SIZE";
+            return 0;
         }
-        memmove(option, pkt->payload, pkt->payload_len);
+        memmove(buffer + sizeof(*cuh) + pkt->token_len, buffer, len);
+        cuh = (struct coap_udp_hdr *)buffer;
+        cuh->version = pkt->version;
+        cuh->type = pkt->type;
+        cuh->token_len = pkt->token_len;
+        cuh->code = pkt->code;
+        cuh->id = htons(pkt->mid);
+        option = (uint8_t *)(cuh + 1);
     } else {
-        /* an error occurred: caller must check for !=0 */
-        pkt->buffer = NULL;
-        coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE";
-        return 0;
+        if (data_len < 13) {
+            memmove(buffer + sizeof(*cth0) + pkt->token_len, buffer, len);
+            cth0 = (struct coap_tcp_hdr0 *)buffer;
+            cth0->data_len = data_len;
+            cth0->token_len = pkt->token_len;
+            cth0->code = pkt->code;
+            option = (uint8_t *)(cth0 + 1);
+        } else if (data_len < 269) {
+            memmove(buffer + sizeof(*cth8) + pkt->token_len, buffer, len);
+            cth8 = (struct coap_tcp_hdr8 *)buffer;
+            cth8->type = COAP_TCP_TYPE8;
+            cth8->token_len = pkt->token_len;
+            cth8->data_len = data_len - 13;
+            cth8->code = pkt->code;
+            option = (uint8_t *)(cth8 + 1);
+        } else if (data_len < 65805) {
+            memmove(buffer + sizeof(*cth16) + pkt->token_len, buffer, len);
+            cth16 = (struct coap_tcp_hdr16 *)buffer;
+            cth16->type = COAP_TCP_TYPE16;
+            cth16->token_len = pkt->token_len;
+            cth16->data_len = htons(data_len - 269);
+            cth16->code = pkt->code;
+            option = (uint8_t *)(cth16 + 1);
+        } else {
+            memmove(buffer + sizeof(*cth32) + pkt->token_len, buffer, len);
+            cth32 = (struct coap_tcp_hdr32 *)buffer;
+            cth32->type = COAP_TCP_TYPE32;
+            cth32->token_len = pkt->token_len;
+            cth32->data_len = htonl(data_len - 65805);
+            cth32->code = pkt->code;
+            option = (uint8_t *)(cth32 + 1);
+        }
     }
 
+    memcpy(option, pkt->token, pkt->token_len);
+    option += (len + pkt->token_len);
+    memmove(option, pkt->payload, pkt->payload_len);
+
     LOG("-Done %u B (header len %u, payload len %u)-\n",
         (unsigned int)(pkt->payload_len + option - buffer),
         (unsigned int)(option - buffer), (unsigned int)pkt->payload_len);
@@ -409,9 +437,14 @@ coap_send_message(oc_message_t *message)
 
 /*---------------------------------------------------------------------------*/
 coap_status_t
-coap_parse_message(coap_packet_t *pkt, uint8_t *data, uint16_t data_len)
+coap_parse_message(coap_packet_t *pkt, uint8_t *data, uint16_t data_len,
+                   int tcp_hdr)
 {
     struct coap_udp_hdr *udp;
+    struct coap_tcp_hdr0 *cth0;
+    struct coap_tcp_hdr8 *cth8;
+    struct coap_tcp_hdr16 *cth16;
+    struct coap_tcp_hdr32 *cth32;
     uint8_t *cur_opt;
     unsigned int opt_num = 0;
     unsigned int opt_delta = 0;
@@ -423,24 +456,51 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, uint16_t data_len)
     pkt->buffer = data;
 
     /* parse header fields */
-    udp = (struct coap_udp_hdr *)data;
-    pkt->version = udp->version;
-    pkt->type = udp->type;
-    pkt->token_len = udp->token_len;
-    pkt->code = udp->code;
-    pkt->mid = ntohs(udp->id);
-
-    if (pkt->version != 1) {
-        coap_error_message = "CoAP version must be 1";
-        return BAD_REQUEST_4_00;
+    if (!tcp_hdr) {
+        udp = (struct coap_udp_hdr *)data;
+        pkt->version = udp->version;
+        pkt->type = udp->type;
+        pkt->token_len = udp->token_len;
+        pkt->code = udp->code;
+        pkt->mid = ntohs(udp->id);
+        if (pkt->version != 1) {
+            coap_error_message = "CoAP version must be 1";
+            return BAD_REQUEST_4_00;
+        }
+        cur_opt = (uint8_t *)(udp + 1);
+    } else {
+        /*
+         * We cannot just look at the data length, as token might or might
+         * not be present. Need to figure out which header is present
+         * programmatically.
+         */
+        cth0 = (struct coap_tcp_hdr0 *)data;
+        if (cth0->data_len < 13) {
+            pkt->token_len = cth0->token_len;
+            pkt->code = cth0->code;
+            cur_opt = (uint8_t *)(cth0 + 1);
+        } else if (cth0->data_len == 13) {
+            cth8 = (struct coap_tcp_hdr8 *)data;
+            pkt->token_len = cth8->token_len;
+            pkt->code = cth8->code;
+            cur_opt = (uint8_t *)(cth8 + 1);
+        } else if (cth0->data_len == 14) {
+            cth16 = (struct coap_tcp_hdr16 *)data;
+            pkt->token_len = cth16->token_len;
+            pkt->code = cth16->code;
+            cur_opt = (uint8_t *)(cth16 + 1);
+        } else {
+            cth32 = (struct coap_tcp_hdr32 *)data;
+            pkt->token_len = cth32->token_len;
+            pkt->code = cth32->code;
+            cur_opt = (uint8_t *)(cth32 + 1);
+        }
     }
     if (pkt->token_len > COAP_TOKEN_LEN) {
         coap_error_message = "Token Length must not be more than 8";
         return BAD_REQUEST_4_00;
     }
 
-    cur_opt = data + sizeof(*udp);
-
     memcpy(pkt->token, cur_opt, pkt->token_len);
 
     LOG("Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/messaging/coap/coap.h
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/coap.h b/net/oic/src/messaging/coap/coap.h
index 11377eb..987f34a 100644
--- a/net/oic/src/messaging/coap/coap.h
+++ b/net/oic/src/messaging/coap/coap.h
@@ -212,10 +212,10 @@ uint16_t coap_get_mid(void);
 
 void coap_init_message(coap_packet_t *, coap_message_type_t type,
                        uint8_t code, uint16_t mid);
-size_t coap_serialize_message(coap_packet_t *, uint8_t *buffer);
+size_t coap_serialize_message(coap_packet_t *, uint8_t *buffer, int tcp_hdr);
 void coap_send_message(oc_message_t *message);
 coap_status_t coap_parse_message(coap_packet_t *request, uint8_t *data,
-                                 uint16_t data_len);
+                                 uint16_t data_len, int tcp_hdr);
 
 int coap_get_query_variable(coap_packet_t *, const char *name,
                             const char **output);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/messaging/coap/constants.h
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/constants.h b/net/oic/src/messaging/coap/constants.h
index e0c0f66..385df69 100644
--- a/net/oic/src/messaging/coap/constants.h
+++ b/net/oic/src/messaging/coap/constants.h
@@ -50,6 +50,9 @@ extern "C" {
 #define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
 #define COAP_ETAG_LEN 8  /* The maximum number of bytes for the ETag */
 
+/*
+ * Standard COAP header
+ */
 struct coap_udp_hdr {
 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     uint8_t  version:2;         /* protocol version */
@@ -60,10 +63,75 @@ struct coap_udp_hdr {
     uint8_t  type:2;            /* type flag */
     uint8_t  version:2;         /* protocol version */
 #endif
-    uint8_t  code;          /* request (1-10) or response (value 40-255) */
-    uint16_t id;          /* transaction id */
+    uint8_t  code;              /* request (1-10) or response (value 40-255) */
+    uint16_t id;                /* transaction id */
+};
+
+/*
+ * Header used by Iotivity for TCP-like transports.
+ * 4 different kinds of headers.
+ */
+#define COAP_TCP_LENGTH_FIELD_8_BIT      13
+#define COAP_TCP_LENGTH_FIELD_16_BIT     269
+#define COAP_TCP_LENGTH_FIELD_32_BIT     65805
+
+#define COAP_TCP_TYPE0      0
+#define COAP_TCP_TYPE8      13
+#define COAP_TCP_TYPE16     14
+#define COAP_TCP_TYPE32     15
+
+struct coap_tcp_hdr0 {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    uint8_t  data_len:4;        /* packet length */
+    uint8_t  token_len:4;       /* length of token */
+#else
+    uint8_t  token_len:4;       /* length of token */
+    uint8_t  data_len:4;        /* packet length */
+#endif
+    uint8_t  code;
+};
+
+struct coap_tcp_hdr8 {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    uint8_t  type:4;            /* header type == 13 */
+    uint8_t  token_len:4;       /* length of token */
+#else
+    uint8_t  token_len:4;       /* length of token */
+    uint8_t  type:4;            /* header type == 13*/
+#endif
+    uint8_t  data_len;          /* packet size - 13 */
+    uint8_t  code;
 };
 
+struct coap_tcp_hdr16 {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    uint8_t  type:4;            /* header type == 14 */
+    uint8_t  token_len:4;       /* length of token */
+#else
+    uint8_t  token_len:4;       /* length of token */
+    uint8_t  type:4;            /* header type == 14 */
+#endif
+    uint16_t data_len;          /* packet size - 269 */
+    uint8_t  code;
+} __attribute__((packed));
+
+struct coap_tcp_hdr32 {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    uint8_t  type:4;            /* header type == 15 */
+    uint8_t  token_len:4;       /* length of token */
+#else
+    uint8_t  token_len:4;       /* length of token */
+    uint8_t  type:4;            /* header type == 15*/
+#endif
+    uint32_t data_len;       /* packet size - 65805 */
+    uint8_t  code;
+} __attribute__((packed));
+
+#define COAP_TCP_TYPE8  13
+#define COAP_TCP_TYPE16 14
+#define COAP_TCP_TYPE32 15
+
+
 #define COAP_HEADER_OPTION_DELTA_MASK 0xF0
 #define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/messaging/coap/engine.c
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/engine.c b/net/oic/src/messaging/coap/engine.c
index 511b71c..009a2e3 100644
--- a/net/oic/src/messaging/coap/engine.c
+++ b/net/oic/src/messaging/coap/engine.c
@@ -66,7 +66,8 @@ coap_receive(oc_message_t *msg)
   static coap_packet_t response[1];
   static coap_transaction_t *transaction = NULL;
 
-  erbium_status_code = coap_parse_message(message, msg->data, msg->length);
+  erbium_status_code = coap_parse_message(message, msg->data, msg->length,
+                                          oc_endpoint_use_tcp(&msg->endpoint));
 
   if (erbium_status_code == NO_ERROR) {
 
@@ -220,7 +221,8 @@ coap_receive(oc_message_t *msg)
         }
         if (erbium_status_code == NO_ERROR) {
           if ((transaction->message->length = coap_serialize_message(
-                 response, transaction->message->data)) == 0) {
+                response, transaction->message->data,
+                  oc_endpoint_use_tcp(&msg->endpoint))) == 0) {
             erbium_status_code = PACKET_SERIALIZATION_ERROR;
           }
           transaction->type = response->type;
@@ -264,7 +266,7 @@ coap_receive(oc_message_t *msg)
       coap_send_transaction(transaction);
     }
   } else if (erbium_status_code == CLEAR_TRANSACTION) {
-    LOG("Clearing transaction for manual response");
+    LOG("Clearing transaction for manual response\n");
     coap_clear_transaction(transaction); // used in server for separate response
   }
 #ifdef OC_CLIENT
@@ -273,7 +275,8 @@ coap_receive(oc_message_t *msg)
     oc_message_t *response = oc_allocate_message();
     if (response) {
       memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
-      response->length = coap_serialize_message(message, response->data);
+      response->length = coap_serialize_message(message, response->data,
+                                          oc_endpoint_use_tcp(&msg->endpoint));
       coap_send_message(response);
     }
   }
@@ -290,7 +293,8 @@ coap_receive(oc_message_t *msg)
     oc_message_t *response = oc_allocate_message();
     if (response) {
       memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
-      response->length = coap_serialize_message(message, response->data);
+      response->length = coap_serialize_message(message, response->data,
+                                     oc_endpoint_use_tcp(&response->endpoint));
       coap_send_message(response);
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/messaging/coap/observe.c
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/observe.c b/net/oic/src/messaging/coap/observe.c
index 0202bb6..d6c5cba 100644
--- a/net/oic/src/messaging/coap/observe.c
+++ b/net/oic/src/messaging/coap/observe.c
@@ -297,7 +297,8 @@ coap_notify_observers(oc_resource_t *resource,
 
                 transaction->message->length =
                   coap_serialize_message(notification,
-                    transaction->message->data);
+                    transaction->message->data,
+                    oc_endpoint_use_tcp(&obs->endpoint));
                 transaction->type = notification->type;
 
                 coap_send_transaction(transaction);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/messaging/coap/separate.c
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/separate.c b/net/oic/src/messaging/coap/separate.c
index 015aa2d..757860e 100644
--- a/net/oic/src/messaging/coap/separate.c
+++ b/net/oic/src/messaging/coap/separate.c
@@ -105,7 +105,8 @@ coap_separate_accept(coap_packet_t *coap_req,
         if (message != NULL) {
             message->endpoint.flags = IP;
             memcpy(&message->endpoint, endpoint, sizeof(oc_endpoint_t));
-            message->length = coap_serialize_message(ack, message->data);
+            message->length = coap_serialize_message(ack, message->data,
+              oc_endpoint_use_tcp(&message->endpoint));
             coap_send_message(message);
         } else {
             coap_separate_clear(separate_response, separate_store);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3b8b6928/net/oic/src/port/oc_connectivity.h
----------------------------------------------------------------------
diff --git a/net/oic/src/port/oc_connectivity.h b/net/oic/src/port/oc_connectivity.h
index 123db7c..f5a075e 100644
--- a/net/oic/src/port/oc_connectivity.h
+++ b/net/oic/src/port/oc_connectivity.h
@@ -73,6 +73,16 @@ uint16_t oc_connectivity_get_dtls_port(void);
 int oc_connectivity_init(void);
 void oc_connectivity_shutdown(void);
 
+static inline int
+oc_endpoint_use_tcp(struct oc_endpoint *oe)
+{
+    if (oe->flags & GATT) {
+        return 1;
+    }
+    return 0;
+}
+
+
 void oc_send_buffer(struct os_mbuf *);
 void oc_send_multicast_message(struct os_mbuf *);