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/09 18:12:44 UTC

[2/3] incubator-mynewt-core git commit: oic; serialize outgoing coap header/options directly to a mbuf.

oic; serialize outgoing coap header/options directly to a mbuf.


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/0b7a6b9e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/0b7a6b9e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/0b7a6b9e

Branch: refs/heads/develop
Commit: 0b7a6b9e78fcbd3ce642894e0152edde34379f69
Parents: 3a55f42
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Dec 9 09:46:59 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Dec 9 09:46:59 2016 -0800

----------------------------------------------------------------------
 net/oic/src/api/oc_buffer.c               |  14 ++
 net/oic/src/api/oc_buffer.h               |   3 +
 net/oic/src/api/oc_client_api.c           | 326 +++++++++++++------------
 net/oic/src/api/oc_ri.c                   |  11 +-
 net/oic/src/api/oc_server_api.c           |   4 +-
 net/oic/src/messaging/coap/coap.c         | 256 ++++++++++---------
 net/oic/src/messaging/coap/coap.h         |  92 +++----
 net/oic/src/messaging/coap/engine.c       |  38 +--
 net/oic/src/messaging/coap/observe.c      |   8 +-
 net/oic/src/messaging/coap/separate.c     |   9 +-
 net/oic/src/messaging/coap/transactions.c |  30 +--
 net/oic/src/messaging/coap/transactions.h |   2 +-
 12 files changed, 406 insertions(+), 387 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/net/oic/src/api/oc_buffer.c
----------------------------------------------------------------------
diff --git a/net/oic/src/api/oc_buffer.c b/net/oic/src/api/oc_buffer.c
index c3815ca..e9dc35a 100644
--- a/net/oic/src/api/oc_buffer.c
+++ b/net/oic/src/api/oc_buffer.c
@@ -56,6 +56,20 @@ oc_allocate_message(void)
     return message;
 }
 
+struct os_mbuf *
+oc_allocate_mbuf(struct oc_endpoint *oe)
+{
+    struct os_mbuf *m;
+
+    /* get a packet header */
+    m = os_msys_get_pkthdr(0, sizeof(struct oc_endpoint));
+    if (!m) {
+        return NULL;
+    }
+    memcpy(OC_MBUF_ENDPOINT(m), oe, sizeof(struct oc_endpoint));
+    return m;
+}
+
 void
 oc_message_add_ref(oc_message_t *message)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/net/oic/src/api/oc_buffer.h
----------------------------------------------------------------------
diff --git a/net/oic/src/api/oc_buffer.h b/net/oic/src/api/oc_buffer.h
index 9631ceb..bf72910 100644
--- a/net/oic/src/api/oc_buffer.h
+++ b/net/oic/src/api/oc_buffer.h
@@ -23,7 +23,10 @@ extern "C" {
 
 struct oc_message;
 struct os_mbuf;
+struct oc_endpoint;
 struct oc_message *oc_allocate_message(void);
+struct os_mbuf *oc_allocate_mbuf(struct oc_endpoint *oe);
+
 void oc_message_add_ref(struct oc_message *message);
 void oc_message_unref(struct oc_message *message);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/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 be6e160..bc681ec 100644
--- a/net/oic/src/api/oc_client_api.c
+++ b/net/oic/src/api/oc_client_api.c
@@ -22,7 +22,8 @@
 #ifdef OC_CLIENT
 #define OC_CLIENT_CB_TIMEOUT_SECS COAP_RESPONSE_TIMEOUT
 
-static oc_message_t *message;
+static struct os_mbuf *message;
+static oc_message_t *rsp;
 static coap_transaction_t *transaction;
 coap_packet_t request[1];
 
@@ -30,31 +31,30 @@ 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_payload(request, rsp->data, 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;
+            coap_serialize_message(request, message,
+                               oc_endpoint_use_tcp(OC_MBUF_ENDPOINT(message)));
+            oc_message_unref(rsp);
+            coap_send_message(message, 0);
+            message = NULL;
             return true;
         }
     } else {
         if (response_length) {
-            coap_set_payload(request,
-                             transaction->message->data + COAP_MAX_HEADER_SIZE,
-                             response_length);
+            coap_set_payload(request, transaction->m, 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_serialize_message(request, transaction->m,
+                         oc_endpoint_use_tcp(OC_MBUF_ENDPOINT(transaction->m)));
+        oc_message_unref(rsp);
         coap_send_transaction(transaction);
-        transaction = 0;
+        transaction = NULL;
         return true;
     }
     return false;
@@ -63,226 +63,234 @@ dispatch_coap_request(void)
 static bool
 prepare_coap_request(oc_client_cb_t *cb, oc_string_t *query)
 {
-  coap_message_type_t type = COAP_TYPE_NON;
-
-  if (cb->qos == HIGH_QOS) {
-    type = COAP_TYPE_CON;
-    transaction = coap_new_transaction(cb->mid, &cb->server.endpoint);
-    if (!transaction)
-      return false;
-    oc_rep_new(transaction->message->data + COAP_MAX_HEADER_SIZE,
-               COAP_MAX_BLOCK_SIZE);
-  } else {
-    message = oc_allocate_message();
-    if (!message)
-      return false;
-    memcpy(&message->endpoint, &cb->server.endpoint, sizeof(oc_endpoint_t));
-    oc_rep_new(message->data + COAP_MAX_HEADER_SIZE, COAP_MAX_BLOCK_SIZE);
-  }
-
-  coap_init_message(request, type, cb->method, cb->mid);
-
-  coap_set_header_accept(request, APPLICATION_CBOR);
-
-  coap_set_token(request, cb->token, cb->token_len);
+    coap_message_type_t type = COAP_TYPE_NON;
 
-  coap_set_header_uri_path(request, oc_string(cb->uri));
-
-  if (cb->observe_seq != -1)
-    coap_set_header_observe(request, cb->observe_seq);
-
-  if (query && oc_string_len(*query))
-    coap_set_header_uri_query(request, oc_string(*query));
-
-  if (cb->observe_seq == -1 && cb->qos == LOW_QOS) {
-      os_callout_reset(&cb->callout,
-        OC_CLIENT_CB_TIMEOUT_SECS * OS_TICKS_PER_SEC);
-  }
+    rsp = oc_allocate_message();
+    if (!rsp) {
+        return false;
+    }
+    if (cb->qos == HIGH_QOS) {
+        type = COAP_TYPE_CON;
+        transaction = coap_new_transaction(cb->mid, &cb->server.endpoint);
+        if (!transaction) {
+            goto free_rsp;
+        }
+    } else {
+        message = oc_allocate_mbuf(&cb->server.endpoint);
+        if (!message) {
+            goto free_rsp;
+        }
+    }
+    oc_rep_new(rsp->data, COAP_MAX_BLOCK_SIZE);
+
+    coap_init_message(request, type, cb->method, cb->mid);
+    coap_set_header_accept(request, APPLICATION_CBOR);
+    coap_set_token(request, cb->token, cb->token_len);
+    coap_set_header_uri_path(request, oc_string(cb->uri));
+    if (cb->observe_seq != -1) {
+        coap_set_header_observe(request, cb->observe_seq);
+    }
+    if (query && oc_string_len(*query)) {
+        coap_set_header_uri_query(request, oc_string(*query));
+    }
+    if (cb->observe_seq == -1 && cb->qos == LOW_QOS) {
+        os_callout_reset(&cb->callout,
+          OC_CLIENT_CB_TIMEOUT_SECS * OS_TICKS_PER_SEC);
+    }
 
-  return true;
+    return true;
+free_rsp:
+    oc_message_unref(rsp);
+    return false;
 }
 
 bool
 oc_do_delete(const char *uri, oc_server_handle_t *server,
              oc_response_handler_t handler, oc_qos_t qos)
 {
-  oc_client_cb_t *cb =
-    oc_ri_alloc_client_cb(uri, server, OC_DELETE, handler, qos);
-  if (!cb)
-    return false;
+    oc_client_cb_t *cb;
+    bool status = false;
 
-  bool status = false;
-
-  status = prepare_coap_request(cb, NULL);
+    cb = oc_ri_alloc_client_cb(uri, server, OC_DELETE, handler, qos);
+    if (!cb) {
+        return false;
+    }
 
-  if (status)
-    status = dispatch_coap_request();
+    status = prepare_coap_request(cb, NULL);
 
-  return status;
+    if (status) {
+        status = dispatch_coap_request();
+    }
+    return status;
 }
 
 bool
 oc_do_get(const char *uri, oc_server_handle_t *server, const char *query,
           oc_response_handler_t handler, oc_qos_t qos)
 {
-  oc_client_cb_t *cb = oc_ri_alloc_client_cb(uri, server, OC_GET, handler, qos);
-  if (!cb)
-    return false;
-
-  bool status = false;
-
-  if (query && strlen(query)) {
+    oc_client_cb_t *cb;
+    bool status = false;
     oc_string_t q;
-    oc_concat_strings(&q, "?", query);
-    status = prepare_coap_request(cb, &q);
-    oc_free_string(&q);
-  } else {
-    status = prepare_coap_request(cb, NULL);
-  }
 
-  if (status)
-    status = dispatch_coap_request();
+    cb = oc_ri_alloc_client_cb(uri, server, OC_GET, handler, qos);
+    if (!cb) {
+        return false;
+    }
 
-  return status;
+    if (query && strlen(query)) {
+        oc_concat_strings(&q, "?", query);
+        status = prepare_coap_request(cb, &q);
+        oc_free_string(&q);
+    } else {
+        status = prepare_coap_request(cb, NULL);
+    }
+
+    if (status) {
+        status = dispatch_coap_request();
+    }
+    return status;
 }
 
 bool
 oc_init_put(const char *uri, oc_server_handle_t *server, const char *query,
             oc_response_handler_t handler, oc_qos_t qos)
 {
-  oc_client_cb_t *cb = oc_ri_alloc_client_cb(uri, server, OC_PUT, handler, qos);
-  if (!cb)
-    return false;
+    oc_client_cb_t *cb;
+    bool status = false;
+    oc_string_t q;
 
-  bool status = false;
+    cb = oc_ri_alloc_client_cb(uri, server, OC_PUT, handler, qos);
+    if (!cb) {
+        return false;
+    }
 
-  if (query && strlen(query)) {
-    oc_string_t q;
-    oc_concat_strings(&q, "?", query);
-    status = prepare_coap_request(cb, &q);
-    oc_free_string(&q);
-  } else {
-    status = prepare_coap_request(cb, NULL);
-  }
+    if (query && strlen(query)) {
+        oc_concat_strings(&q, "?", query);
+        status = prepare_coap_request(cb, &q);
+        oc_free_string(&q);
+    } else {
+        status = prepare_coap_request(cb, NULL);
+    }
 
-  return status;
+    return status;
 }
 
 bool
 oc_init_post(const char *uri, oc_server_handle_t *server, const char *query,
              oc_response_handler_t handler, oc_qos_t qos)
 {
-  oc_client_cb_t *cb =
-    oc_ri_alloc_client_cb(uri, server, OC_POST, handler, qos);
-  if (!cb)
-    return false;
+    oc_client_cb_t *cb;
+    bool status = false;
+    oc_string_t q;
 
-  bool status = false;
+    cb = oc_ri_alloc_client_cb(uri, server, OC_POST, handler, qos);
+    if (!cb) {
+        return false;
+    }
 
-  if (query && strlen(query)) {
-    oc_string_t q;
-    oc_concat_strings(&q, "?", query);
-    status = prepare_coap_request(cb, &q);
-    oc_free_string(&q);
-  } else {
-    status = prepare_coap_request(cb, NULL);
-  }
+    if (query && strlen(query)) {
+        oc_concat_strings(&q, "?", query);
+        status = prepare_coap_request(cb, &q);
+        oc_free_string(&q);
+    } else {
+        status = prepare_coap_request(cb, NULL);
+    }
 
-  return status;
+    return status;
 }
 
 bool
 oc_do_put(void)
 {
-  return dispatch_coap_request();
+    return dispatch_coap_request();
 }
 
 bool
 oc_do_post(void)
 {
-  return dispatch_coap_request();
+    return dispatch_coap_request();
 }
 
 bool
 oc_do_observe(const char *uri, oc_server_handle_t *server, const char *query,
               oc_response_handler_t handler, oc_qos_t qos)
 {
-  oc_client_cb_t *cb = oc_ri_alloc_client_cb(uri, server, OC_GET, handler, qos);
-  if (!cb)
-    return false;
-
-  cb->observe_seq = 0;
-
-  bool status = false;
-
-  if (query && strlen(query)) {
+    oc_client_cb_t *cb;
+    bool status = false;
     oc_string_t q;
-    oc_concat_strings(&q, "?", query);
-    status = prepare_coap_request(cb, &q);
-    oc_free_string(&q);
-  } else {
-    status = prepare_coap_request(cb, NULL);
-  }
 
-  if (status)
-    status = dispatch_coap_request();
+    cb = oc_ri_alloc_client_cb(uri, server, OC_GET, handler, qos);
+    if (!cb) {
+        return false;
+    }
+    cb->observe_seq = 0;
 
-  return status;
+    if (query && strlen(query)) {
+        oc_concat_strings(&q, "?", query);
+        status = prepare_coap_request(cb, &q);
+        oc_free_string(&q);
+    } else {
+        status = prepare_coap_request(cb, NULL);
+    }
+
+    if (status) {
+        status = dispatch_coap_request();
+    }
+    return status;
 }
 
 bool
 oc_stop_observe(const char *uri, oc_server_handle_t *server)
 {
-  oc_client_cb_t *cb = oc_ri_get_client_cb(uri, server, OC_GET);
-
-  if (!cb)
-    return false;
-
-  cb->observe_seq = 1;
+    oc_client_cb_t *cb;
+    bool status = false;
 
-  bool status = false;
-
-  status = prepare_coap_request(cb, NULL);
+    cb = oc_ri_get_client_cb(uri, server, OC_GET);
+    if (!cb) {
+        return false;
+    }
+    cb->observe_seq = 1;
 
-  if (status)
-    status = dispatch_coap_request();
 
-  return status;
+    status = prepare_coap_request(cb, NULL);
+    if (status) {
+        status = dispatch_coap_request();
+    }
+    return status;
 }
 
 bool
 oc_do_ip_discovery(const char *rt, oc_discovery_cb_t handler)
 {
-  oc_make_ip_endpoint(mcast, IP | MULTICAST, 5683, 0xff, 0x02, 0, 0, 0, 0, 0, 0,
-                      0, 0, 0, 0, 0, 0, 0, 0xfd);
-  mcast.ipv6_addr.scope = 0;
+    oc_server_handle_t handle;
+    oc_client_cb_t *cb;
+    bool status = false;
+    oc_string_t query;
 
-  oc_server_handle_t handle;
-  memcpy(&handle.endpoint, &mcast, sizeof(oc_endpoint_t));
+    oc_make_ip_endpoint(mcast, IP | MULTICAST, 5683,
+                       0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfd);
+    mcast.ipv6_addr.scope = 0;
 
-  oc_client_cb_t *cb =
-    oc_ri_alloc_client_cb("/oic/res", &handle, OC_GET, handler, LOW_QOS);
+    memcpy(&handle.endpoint, &mcast, sizeof(oc_endpoint_t));
 
-  if (!cb)
-    return false;
-
-  cb->discovery = true;
-
-  bool status = false;
-
-  oc_string_t query;
+    cb = oc_ri_alloc_client_cb("/oic/res", &handle, OC_GET, handler, LOW_QOS);
 
-  if (rt && strlen(rt) > 0) {
-    oc_concat_strings(&query, "if=oic.if.ll&rt=", rt);
-  } else {
-    oc_new_string(&query, "if=oic.if.ll");
-  }
-  status = prepare_coap_request(cb, &query);
-  oc_free_string(&query);
+    if (!cb) {
+        return false;
+    }
+    cb->discovery = true;
 
-  if (status)
-    status = dispatch_coap_request();
+    if (rt && strlen(rt) > 0) {
+        oc_concat_strings(&query, "if=oic.if.ll&rt=", rt);
+    } else {
+        oc_new_string(&query, "if=oic.if.ll");
+    }
+    status = prepare_coap_request(cb, &query);
+    oc_free_string(&query);
 
-  return status;
+    if (status) {
+        status = dispatch_coap_request();
+    }
+    return status;
 }
 #endif /* OC_CLIENT */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/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 12b1849..64ce1f3 100644
--- a/net/oic/src/api/oc_ri.c
+++ b/net/oic/src/api/oc_ri.c
@@ -697,14 +697,15 @@ oc_ri_send_rst(oc_endpoint_t *endpoint, uint8_t *token, uint8_t token_len,
                uint16_t mid)
 {
     coap_packet_t rst[1];
+    struct os_mbuf *m;
+
     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);
+    m = oc_allocate_mbuf(endpoint);
+    if (m) {
+        coap_serialize_message(rst, m, oc_endpoint_use_tcp(endpoint));
+        coap_send_message(m, 0);
         return true;
     }
     return false;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/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 9cdb4e1..50b7fdc 100644
--- a/net/oic/src/api/oc_server_api.c
+++ b/net/oic/src/api/oc_server_api.c
@@ -259,8 +259,8 @@ oc_send_separate_response(oc_separate_response_t *handle,
                       response_buffer.response_length);
                 }
                 t->type = response->type;
-                t->message->length = coap_serialize_message(response,
-                  t->message->data, oc_endpoint_use_tcp(&cur->endpoint));
+                coap_serialize_message(response, t->m,
+                                       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/0b7a6b9e/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 dc3a44e..cb9cada 100644
--- a/net/oic/src/messaging/coap/coap.c
+++ b/net/oic/src/messaging/coap/coap.c
@@ -33,6 +33,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 
 #include "coap.h"
 #include "transactions.h"
@@ -47,6 +48,7 @@ STATS_NAME_START(coap_stats)
     STATS_NAME(coap_stats, iframe)
     STATS_NAME(coap_stats, ierr)
     STATS_NAME(coap_stats, oframe)
+    STATS_NAME(coap_stats, oerr)
 STATS_NAME_END(coap_stats)
 
 /*---------------------------------------------------------------------------*/
@@ -97,9 +99,11 @@ coap_option_nibble(unsigned int value)
     }
 }
 /*---------------------------------------------------------------------------*/
-static size_t
-coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
+
+static int
+coap_append_opt_hdr(struct os_mbuf *m, unsigned int delta, size_t length)
 {
+    uint8_t buffer[4];
     size_t written = 0;
 
     buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
@@ -118,16 +122,17 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
         buffer[++written] = (length - 13);
     }
 
-    LOG("WRITTEN %zu B opt header\n", 1 + written);
-
-    return ++written;
+    return os_mbuf_append(m, buffer, written + 1);
 }
+
 /*---------------------------------------------------------------------------*/
-static size_t
-coap_serialize_int_option(unsigned int number, unsigned int current_number,
-                          uint8_t *buffer, uint32_t value)
+static int
+coap_append_int_opt(struct os_mbuf *m, unsigned int number,
+                    unsigned int current_number, uint32_t value)
 {
     size_t i = 0;
+    uint8_t buffer[4];
+    int rc;
 
     if (0xFF000000 & value) {
         ++i;
@@ -143,8 +148,12 @@ coap_serialize_int_option(unsigned int number, unsigned int current_number,
     }
     LOG("OPTION %u (delta %u, len %zu)\n", number, number - current_number, i);
 
-    i = coap_set_option_header(number - current_number, i, buffer);
+    rc = coap_append_opt_hdr(m, number - current_number, i);
+    if (rc) {
+        return rc;
+    }
 
+    i = 0;
     if (0xFF000000 & value) {
         buffer[i++] = (uint8_t)(value >> 24);
     }
@@ -157,38 +166,40 @@ coap_serialize_int_option(unsigned int number, unsigned int current_number,
     if (0xFFFFFFFF & value) {
         buffer[i++] = (uint8_t)(value);
     }
-    return i;
+    return os_mbuf_append(m, buffer, i);
 }
 /*---------------------------------------------------------------------------*/
-static size_t
-coap_serialize_array_option(unsigned int number, unsigned int current_number,
-                            uint8_t *buffer, uint8_t *array, size_t length,
-                            char split_char)
+static int
+coap_append_array_opt(struct os_mbuf *m,
+                      unsigned int number, unsigned int current_number,
+                      uint8_t *array, size_t length, char split_char)
 {
-    size_t i = 0;
+    int rc;
+    int j;
+    uint8_t *part_start = array;
+    uint8_t *part_end = NULL;
+    size_t blk;
 
-    LOG("ARRAY type %u, len %zu, full [%.*s]\n", number, length, (int)length,
-      array);
+    LOG("ARRAY type %u, len %zu\n", number, length);
 
     if (split_char != '\0') {
-        int j;
-        uint8_t *part_start = array;
-        uint8_t *part_end = NULL;
-        size_t temp_length;
-
         for (j = 0; j <= length + 1; ++j) {
             LOG("STEP %u/%zu (%c)\n", j, length, array[j]);
             if (array[j] == split_char || j == length) {
                 part_end = array + j;
-                temp_length = part_end - part_start;
+                blk = part_end - part_start;
 
-                i += coap_set_option_header(number - current_number,
-                                            temp_length, &buffer[i]);
-                memcpy(&buffer[i], part_start, temp_length);
-                i += temp_length;
+                rc = coap_append_opt_hdr(m, number - current_number, blk);
+                if (rc) {
+                    return rc;
+                }
+                rc = os_mbuf_append(m, part_start, blk);
+                if (rc) {
+                    return rc;
+                }
 
-                LOG("OPTION type %u, delta %u, len %zu, part [%.*s]\n", number,
-                    number - current_number, i, (int)temp_length, part_start);
+                LOG("OPTION type %u, delta %u, len %zu\n", number,
+                    number - current_number, (int)blk);
 
                 ++j; /* skip the splitter */
                 current_number = number;
@@ -196,16 +207,20 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
             }
         } /* for */
     } else {
-        i += coap_set_option_header(number - current_number, length,
-                                    &buffer[i]);
-        memcpy(&buffer[i], array, length);
-        i += length;
+        rc = coap_append_opt_hdr(m, number - current_number, length);
+        if (rc) {
+            return rc;
+        }
+        rc = os_mbuf_append(m, array, length);
+        if (rc) {
+            return rc;
+        }
 
         LOG("OPTION type %u, delta %u, len %zu\n", number,
             number - current_number, length);
     }
 
-    return i;
+    return 0;
 }
 /*---------------------------------------------------------------------------*/
 
@@ -300,177 +315,160 @@ coap_init_message(coap_packet_t *pkt, coap_message_type_t type,
 
 /*---------------------------------------------------------------------------*/
 
-size_t
-coap_serialize_message(coap_packet_t *pkt, uint8_t *buffer, int tcp_hdr)
+int
+coap_serialize_message(coap_packet_t *pkt, struct os_mbuf *m, 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 0x%x, ", pkt->mid, (unsigned)buffer);
+    LOG("-Serializing message %u to 0x%x, ", pkt->mid, (unsigned)m);
+
+    /*
+     * Move data pointer, leave enough space to insert coap header and
+     * token before options.
+     */
+    m->om_data += (sizeof(struct coap_tcp_hdr32) + pkt->token_len);
 
     /* Serialize options */
     current_number = 0;
 
-    option = buffer;
-    LOG("-Serializing options at 0x%x-\n", (unsigned)option);
 #if 0
     /* The options must be serialized in the order of their number */
-    COAP_SERIALIZE_BYTE_OPTION(pkt, COAP_OPTION_IF_MATCH, if_match, "If-Match");
-    COAP_SERIALIZE_STRING_OPTION(pkt, COAP_OPTION_URI_HOST, uri_host, '\0',
+    COAP_SERIALIZE_BYTE_OPT(pkt, m, COAP_OPTION_IF_MATCH, if_match, "If-Match");
+    COAP_SERIALIZE_STRING_OPT(pkt, m, COAP_OPTION_URI_HOST, uri_host, '\0',
                                  "Uri-Host");
-    COAP_SERIALIZE_BYTE_OPTION(pkt, COAP_OPTION_ETAG, etag, "ETag");
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_IF_NONE_MATCH,
+    COAP_SERIALIZE_BYTE_OPT(pkt, m, COAP_OPTION_ETAG, etag, "ETag");
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_IF_NONE_MATCH,
         content_format - pkt-> content_format /* hack to get a zero field */,
-                              "If-None-Match");
+                           "If-None-Match");
 #endif
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_OBSERVE, observe, "Observe");
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_OBSERVE, observe, "Observe");
 #if 0
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_URI_PORT, uri_port, "Uri-Port");
-    COAP_SERIALIZE_STRING_OPTION(pkt, COAP_OPTION_LOCATION_PATH, location_path,
-                                 '/', "Location-Path");
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_URI_PORT, uri_port,
+                              "Uri-Port");
+    COAP_SERIALIZE_STRING_OPT(pkt, m, COAP_OPTION_LOCATION_PATH,
+                              location_path, '/', "Location-Path");
 #endif
-    COAP_SERIALIZE_STRING_OPTION(pkt, COAP_OPTION_URI_PATH, uri_path, '/',
-                                 "Uri-Path");
+    COAP_SERIALIZE_STRING_OPT(pkt, m, COAP_OPTION_URI_PATH, uri_path, '/',
+                              "Uri-Path");
     LOG("Serialize content format: %d\n", pkt->content_format);
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_CONTENT_FORMAT, content_format,
-                              "Content-Format");
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_CONTENT_FORMAT, content_format,
+                           "Content-Format");
 #if 0
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_MAX_AGE, max_age, "Max-Age");
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_MAX_AGE, max_age, "Max-Age");
 #endif
-    COAP_SERIALIZE_STRING_OPTION(pkt, COAP_OPTION_URI_QUERY, uri_query, '&',
-                                 "Uri-Query");
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_ACCEPT, accept, "Accept");
+    COAP_SERIALIZE_STRING_OPT(pkt, m, COAP_OPTION_URI_QUERY, uri_query, '&',
+                              "Uri-Query");
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_ACCEPT, accept, "Accept");
 #if 0
-    COAP_SERIALIZE_STRING_OPTION(pkt, COAP_OPTION_LOCATION_QUERY,
-                                 location_query, '&', "Location-Query");
+    COAP_SERIALIZE_STRING_OPT(pkt, m, COAP_OPTION_LOCATION_QUERY,
+                              location_query, '&', "Location-Query");
 #endif
-    COAP_SERIALIZE_BLOCK_OPTION(pkt, COAP_OPTION_BLOCK2, block2, "Block2");
-    COAP_SERIALIZE_BLOCK_OPTION(pkt, COAP_OPTION_BLOCK1, block1, "Block1");
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_SIZE2, size2, "Size2");
+    COAP_SERIALIZE_BLOCK_OPT(pkt, m, COAP_OPTION_BLOCK2, block2, "Block2");
+    COAP_SERIALIZE_BLOCK_OPT(pkt, m, COAP_OPTION_BLOCK1, block1, "Block1");
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_SIZE2, size2, "Size2");
 #if 0
-    COAP_SERIALIZE_STRING_OPTION(pkt, COAP_OPTION_PROXY_URI, proxy_uri, '\0',
-                                 "Proxy-Uri");
-    COAP_SERIALIZE_STRING_OPTION(pkt, COAP_OPTION_PROXY_SCHEME, proxy_scheme,
-                                 '\0', "Proxy-Scheme");
+    COAP_SERIALIZE_STRING_OPT(pkt, m, COAP_OPTION_PROXY_URI, proxy_uri, '\0',
+                              "Proxy-Uri");
+    COAP_SERIALIZE_STRING_OPT(pkt, m, COAP_OPTION_PROXY_SCHEME, proxy_scheme,
+                              '\0', "Proxy-Scheme");
 #endif
-    COAP_SERIALIZE_INT_OPTION(pkt, COAP_OPTION_SIZE1, size1, "Size1");
-
-    LOG("-Done serializing at 0x%x----\n", (unsigned)option);
+    COAP_SERIALIZE_INT_OPT(pkt, m, COAP_OPTION_SIZE1, size1, "Size1");
 
     /* Payload marker */
     if (pkt->payload_len) {
-        *option = 0xFF;
-        ++option;
+        if (os_mbuf_append(m, "\xff", 1)) {
+            goto err_mem;
+        }
     }
-    len = option - buffer;
-    data_len = len + pkt->payload_len;
+    data_len = OS_MBUF_PKTLEN(m) + 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(buffer + sizeof(*cuh) + pkt->token_len, buffer, len);
-        cuh = (struct coap_udp_hdr *)buffer;
+        len = sizeof(struct coap_udp_hdr) + pkt->token_len;
+        os_mbuf_prepend(m, len);
+        cuh = (struct coap_udp_hdr *)m->om_data;
         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);
+        memcpy(cuh + 1, pkt->token, pkt->token_len);
     } else {
         if (data_len < 13) {
-            memmove(buffer + sizeof(*cth0) + pkt->token_len, buffer, len);
-            cth0 = (struct coap_tcp_hdr0 *)buffer;
+            len = sizeof(struct coap_tcp_hdr0) + pkt->token_len;
+            os_mbuf_prepend(m, len);
+            cth0 = (struct coap_tcp_hdr0 *)m->om_data;
             cth0->data_len = data_len;
             cth0->token_len = pkt->token_len;
             cth0->code = pkt->code;
-            option = (uint8_t *)(cth0 + 1);
+            memcpy(cth0 + 1, pkt->token, pkt->token_len);
         } else if (data_len < 269) {
-            memmove(buffer + sizeof(*cth8) + pkt->token_len, buffer, len);
-            cth8 = (struct coap_tcp_hdr8 *)buffer;
+            len = sizeof(struct coap_tcp_hdr8) + pkt->token_len;
+            os_mbuf_prepend(m, len);
+            cth8 = (struct coap_tcp_hdr8 *)m->om_data;
             cth8->type = COAP_TCP_TYPE8;
             cth8->token_len = pkt->token_len;
             cth8->data_len = data_len - COAP_TCP_LENGTH8_OFF;
             cth8->code = pkt->code;
-            option = (uint8_t *)(cth8 + 1);
+            memcpy(cth8 + 1, pkt->token, pkt->token_len);
         } else if (data_len < 65805) {
-            memmove(buffer + sizeof(*cth16) + pkt->token_len, buffer, len);
-            cth16 = (struct coap_tcp_hdr16 *)buffer;
+            len = sizeof(struct coap_tcp_hdr16) + pkt->token_len;
+            os_mbuf_prepend(m, len);
+            cth16 = (struct coap_tcp_hdr16 *)m->om_data;
             cth16->type = COAP_TCP_TYPE16;
             cth16->token_len = pkt->token_len;
             cth16->data_len = htons(data_len - COAP_TCP_LENGTH16_OFF);
             cth16->code = pkt->code;
-            option = (uint8_t *)(cth16 + 1);
+            memcpy(cth16 + 1, pkt->token, pkt->token_len);
         } else {
-            memmove(buffer + sizeof(*cth32) + pkt->token_len, buffer, len);
-            cth32 = (struct coap_tcp_hdr32 *)buffer;
+            len = sizeof(struct coap_tcp_hdr32) + pkt->token_len;
+            os_mbuf_prepend(m, len);
+            cth32 = (struct coap_tcp_hdr32 *)m->om_data;
             cth32->type = COAP_TCP_TYPE32;
             cth32->token_len = pkt->token_len;
             cth32->data_len = htonl(data_len - COAP_TCP_LENGTH32_OFF);
             cth32->code = pkt->code;
-            option = (uint8_t *)(cth32 + 1);
+            memcpy(cth32 + 1, pkt->token, pkt->token_len);
         }
     }
 
-    memcpy(option, pkt->token, pkt->token_len);
-    option += (len + pkt->token_len);
-    memmove(option, pkt->payload, pkt->payload_len);
+    if (os_mbuf_append(m, pkt->payload, pkt->payload_len)) {
+        goto err_mem;
+    }
 
     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);
+        OS_MBUF_PKTLEN(m), OS_MBUF_PKTLEN(m) - pkt->payload_len,
+        pkt->payload_len);
 
-    LOG("Dump [0x%02X %02X %02X %02X  %02X %02X %02X %02X]\n",
-        pkt->buffer[0], pkt->buffer[1], pkt->buffer[2], pkt->buffer[3],
-        pkt->buffer[4], pkt->buffer[5], pkt->buffer[6], pkt->buffer[7]);
-    return (option - buffer) + pkt->payload_len; /* packet length */
+    return 0;
+err_mem:
+    STATS_INC(coap_stats, oerr);
+    return -1;
 }
 /*---------------------------------------------------------------------------*/
 void
-coap_send_message(struct oc_message *msg)
+coap_send_message(struct os_mbuf *m, int dup)
 {
-    struct os_mbuf *m;
-    struct oc_endpoint *oe;
-    int rc;
-
-    LOG("-sending OCF message (%u)-\n", msg->length);
+    LOG("-sending OCF message (%u)-\n", OS_MBUF_PKTLEN(m));
 
     STATS_INC(coap_stats, oframe);
 
-    /* get a packet header */
-    m = os_msys_get_pkthdr(0, sizeof(struct oc_endpoint));
-    if (!m) {
-        ERROR("coap_send_msg: failed to alloc mbuf\n");
-        oc_message_unref(msg);
-        return;
-    }
-
-    /* add this data to the mbuf */
-    rc = os_mbuf_append(m, msg->data, msg->length);
-    if (rc != 0) {
-        ERROR("coap_send_msg: could not append data\n");
-        oc_message_unref(msg);
-        return;
+    if (dup) {
+        m = os_mbuf_dup(m);
+        if (!m) {
+            STATS_INC(coap_stats, oerr);
+            return;
+        }
     }
-
-    oe = OC_MBUF_ENDPOINT(m);
-    memcpy(oe, &msg->endpoint, sizeof(msg->endpoint));
-
-    oc_message_unref(msg);
-
     oc_send_message(m);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/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 c460fff..5c0d9de 100644
--- a/net/oic/src/messaging/coap/coap.h
+++ b/net/oic/src/messaging/coap/coap.h
@@ -167,52 +167,57 @@ STATS_SECT_START(coap_stats)
     STATS_SECT_ENTRY(iframe)
     STATS_SECT_ENTRY(ierr)
     STATS_SECT_ENTRY(oframe)
+    STATS_SECT_ENTRY(oerr)
 STATS_SECT_END
 
 extern STATS_SECT_DECL(coap_stats) coap_stats;
 
 /* option format serialization */
-#define COAP_SERIALIZE_INT_OPTION(coap_pkt, number, field, text)               \
-  if (IS_OPTION(coap_pkt, number)) {                                           \
-    LOG(text " [%u]\n", (unsigned int)coap_pkt->field);                        \
-    option += coap_serialize_int_option(number, current_number, option,        \
-                                        coap_pkt->field);                      \
-    current_number = number;                                                   \
-  }
-#define COAP_SERIALIZE_BYTE_OPTION(coap_pkt, number, field, text)              \
-  if (IS_OPTION(coap_pkt, number)) {                                           \
-    LOG(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",                     \
-        (unsigned int)coap_pkt->field##_len, coap_pkt->field[0],               \
-        coap_pkt->field[1], coap_pkt->field[2], coap_pkt->field[3],            \
-        coap_pkt->field[4], coap_pkt->field[5], coap_pkt->field[6],            \
-        coap_pkt->field[7]); /* FIXME always prints 8 bytes */                 \
-    option += coap_serialize_array_option(number, current_number, option,      \
-                                          coap_pkt->field,                     \
-                                          coap_pkt->field##_len, '\0');        \
-    current_number = number;                                                   \
-  }
-#define COAP_SERIALIZE_STRING_OPTION(coap_pkt, number, field, splitter, text)  \
-  if (IS_OPTION(coap_pkt, number)) {                                           \
-    LOG(text " [%.*s]\n", (int)coap_pkt->field##_len, coap_pkt->field);        \
-    option += coap_serialize_array_option(number, current_number, option,      \
-                                          (uint8_t *)coap_pkt->field,          \
-                                          coap_pkt->field##_len, splitter);    \
-    current_number = number;                                                   \
-  }
-#define COAP_SERIALIZE_BLOCK_OPTION(coap_pkt, number, field, text)             \
-  if (IS_OPTION(coap_pkt, number)) {                                           \
-    LOG(text " [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->field##_num,    \
-        coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size);            \
-    uint32_t block = coap_pkt->field##_num << 4;                               \
-    if (coap_pkt->field##_more) {                                              \
-      block |= 0x8;                                                            \
-    }                                                                          \
-    block |= 0xF & coap_log_2(coap_pkt->field##_size / 16);                    \
-    LOG(text " encoded: 0x%lX\n", (unsigned long)block);                       \
-    option +=                                                                  \
-      coap_serialize_int_option(number, current_number, option, block);        \
-    current_number = number;                                                   \
-  }
+#define COAP_SERIALIZE_INT_OPT(pkt, m, number, field, text)             \
+    if (IS_OPTION(pkt, number)) {                                       \
+        LOG(text " [%u]\n", (unsigned int)pkt->field);                  \
+        if (coap_append_int_opt(m, number, current_number, pkt->field)) { \
+            goto err_mem;                                               \
+        }                                                               \
+        current_number = number;                                        \
+    }
+#define COAP_SERIALIZE_BYTE_OPT(pkt, m, number, field, text)            \
+    if (IS_OPTION(pkt, number)) {                                       \
+        LOG(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",          \
+          (unsigned int)pkt->field##_len, pkt->field[0], pkt->field[1], \
+          pkt->field[2], pkt->field[3], pkt->field[4], pkt->field[5],   \
+          pkt->field[6], pkt->field[7]); /* FIXME always prints 8 bytes */ \
+        if (coap_append_array_opt(m, number, current_number, pkt->field, \
+                                  pkt->field##_len, '\0')) {            \
+            goto err_mem;                                               \
+        }                                                               \
+        current_number = number;                                        \
+    }
+#define COAP_SERIALIZE_STRING_OPT(pkt, m, number, field, splitter, text) \
+    if (IS_OPTION(pkt, number)) {                                       \
+        LOG(text " [%s]\n", pkt->field);                                \
+        if (coap_append_array_opt(m, number, current_number,            \
+                                  (uint8_t *)pkt->field,                \
+                                  pkt->field##_len, splitter)) {        \
+            goto err_mem;                                               \
+        }                                                               \
+        current_number = number;                                        \
+    }
+#define COAP_SERIALIZE_BLOCK_OPT(pkt, m, number, field, text)           \
+    if (IS_OPTION(pkt, number)) {                                       \
+        LOG(text " [%lu%s (%u B/blk)]\n", (unsigned long)pkt->field##_num, \
+          pkt->field##_more ? "+" : "", pkt->field##_size);             \
+        uint32_t block = pkt->field##_num << 4;                         \
+        if (pkt->field##_more) {                                        \
+            block |= 0x8;                                               \
+        }                                                               \
+        block |= 0xF & coap_log_2(pkt->field##_size / 16);              \
+        LOG(text " encoded: 0x%lX\n", (unsigned long)block);            \
+        if (coap_append_int_opt(m, number, current_number, block)) {    \
+            goto err_mem;                                               \
+        }                                                               \
+        current_number = number;                                        \
+    }
 
 /* to store error code and human-readable payload */
 extern coap_status_t erbium_status_code;
@@ -225,9 +230,8 @@ uint16_t coap_tcp_msg_size(uint8_t *hdr, int datalen);
 
 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, int tcp_hdr);
-typedef struct oc_message oc_message_t;
-void coap_send_message(oc_message_t *message);
+int coap_serialize_message(coap_packet_t *, struct os_mbuf *m, int tcp_hdr);
+void coap_send_message(struct os_mbuf *m, int dup);
 coap_status_t coap_parse_message(coap_packet_t *request, uint8_t *data,
                                  uint16_t data_len, int tcp_hdr);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/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 10225f9..e4b700c 100644
--- a/net/oic/src/messaging/coap/engine.c
+++ b/net/oic/src/messaging/coap/engine.c
@@ -61,6 +61,7 @@ coap_receive(oc_message_t *msg)
     static coap_packet_t message[1];
     static coap_packet_t response[1];
     static coap_transaction_t *transaction = NULL;
+    static oc_message_t *rsp;
 
     erbium_status_code = NO_ERROR;
 
@@ -156,11 +157,13 @@ coap_receive(oc_message_t *msg)
             new_offset = block_offset;
         }
 
-        /* invoke resource handler in RI layer */
-        if (oc_ri_invoke_coap_entity_handler(message, response,
-                              transaction->message->data + COAP_MAX_HEADER_SIZE,
-                              block_size, &new_offset, &msg->endpoint)) {
-
+        rsp = oc_allocate_message();
+        if (!rsp) {
+            erbium_status_code = SERVICE_UNAVAILABLE_5_03;
+            coap_error_message = "NoFreeTraBuffer";
+        } else if (oc_ri_invoke_coap_entity_handler(message, response,
+                              rsp->data, block_size, &new_offset,
+                              &msg->endpoint)) {
             if (erbium_status_code == NO_ERROR) {
                 /*
                  * TODO coap_handle_blockwise(request, response,
@@ -237,14 +240,15 @@ coap_receive(oc_message_t *msg)
             /* serialize response */
         }
         if (erbium_status_code == NO_ERROR) {
-            if ((transaction->message->length =
-                coap_serialize_message(response, transaction->message->data,
-                                   oc_endpoint_use_tcp(&msg->endpoint))) == 0) {
+            if (coap_serialize_message(response, transaction->m,
+                oc_endpoint_use_tcp(&msg->endpoint))) {
                 erbium_status_code = PACKET_SERIALIZATION_ERROR;
             }
             transaction->type = response->type;
         }
-
+        if (rsp) {
+            oc_message_unref(rsp);
+        }
     } else { // Fix this
         /* handle responses */
         if (message->type == COAP_TYPE_CON) {
@@ -289,12 +293,11 @@ out:
 #ifdef OC_CLIENT
     else if (erbium_status_code == EMPTY_ACK_RESPONSE) {
         coap_init_message(message, COAP_TYPE_ACK, 0, message->mid);
-        oc_message_t *response = oc_allocate_message();
+        struct os_mbuf *response = oc_allocate_mbuf(&msg->endpoint);
         if (response) {
-            memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
-            response->length = coap_serialize_message(message, response->data,
+            coap_serialize_message(message, response,
                                           oc_endpoint_use_tcp(&msg->endpoint));
-            coap_send_message(response);
+            coap_send_message(response, 0);
         }
     }
 #endif /* OC_CLIENT */
@@ -307,12 +310,11 @@ out:
         coap_init_message(message, reply_type, SERVICE_UNAVAILABLE_5_03,
                           message->mid);
 
-        oc_message_t *response = oc_allocate_message();
+        struct os_mbuf *response = oc_allocate_mbuf(&msg->endpoint);
         if (response) {
-            memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
-            response->length = coap_serialize_message(message, response->data,
-                                     oc_endpoint_use_tcp(&response->endpoint));
-            coap_send_message(response);
+            coap_serialize_message(message, response,
+                                   oc_endpoint_use_tcp(&msg->endpoint));
+            coap_send_message(response, 0);
         }
     }
 #endif /* OC_SERVER */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/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 d6c5cba..01907b8 100644
--- a/net/oic/src/messaging/coap/observe.c
+++ b/net/oic/src/messaging/coap/observe.c
@@ -265,8 +265,6 @@ coap_notify_observers(oc_resource_t *resource,
             coap_transaction_t *transaction = NULL;
             if (response_buf && (transaction = coap_new_transaction(
                   coap_get_mid(), &obs->endpoint))) {
-                memcpy(transaction->message->data + COAP_MAX_HEADER_SIZE,
-                  response_buf->buffer, response_buf->response_length);
 
                 /* update last MID for RST matching */
                 obs->last_mid = transaction->mid;
@@ -295,10 +293,8 @@ coap_notify_observers(oc_resource_t *resource,
                 }
                 coap_set_token(notification, obs->token, obs->token_len);
 
-                transaction->message->length =
-                  coap_serialize_message(notification,
-                    transaction->message->data,
-                    oc_endpoint_use_tcp(&obs->endpoint));
+                coap_serialize_message(notification, transaction->m,
+                                       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/0b7a6b9e/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 a6df6dc..be6c7f4 100644
--- a/net/oic/src/messaging/coap/separate.c
+++ b/net/oic/src/messaging/coap/separate.c
@@ -101,13 +101,10 @@ coap_separate_accept(coap_packet_t *coap_req,
             coap_set_header_observe(ack, observe);
         }
         coap_set_token(ack, coap_req->token, coap_req->token_len);
-        oc_message_t *message = oc_allocate_message();
+        struct os_mbuf *message = oc_allocate_mbuf(endpoint); /* XXXX? */
         if (message != NULL) {
-            message->endpoint.flags = IP;
-            memcpy(&message->endpoint, endpoint, sizeof(oc_endpoint_t));
-            message->length = coap_serialize_message(ack, message->data,
-              oc_endpoint_use_tcp(&message->endpoint));
-            coap_send_message(message);
+            coap_serialize_message(ack, message, oc_endpoint_use_tcp(endpoint));
+            coap_send_message(message, 0);
         } else {
             coap_separate_clear(separate_response, separate_store);
             erbium_status_code = SERVICE_UNAVAILABLE_5_03;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/net/oic/src/messaging/coap/transactions.c
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/transactions.c b/net/oic/src/messaging/coap/transactions.c
index 1159292..a1ffe6c 100644
--- a/net/oic/src/messaging/coap/transactions.c
+++ b/net/oic/src/messaging/coap/transactions.c
@@ -68,18 +68,16 @@ coap_transaction_t *
 coap_new_transaction(uint16_t mid, oc_endpoint_t *endpoint)
 {
     coap_transaction_t *t;
+    struct os_mbuf *m;
 
     t = os_memblock_get(&oc_transaction_memb);
     if (t) {
-        oc_message_t *message = oc_allocate_message();
-        if (message) {
-            LOG("Created new transaction %d %d\n", mid, (int) message->length);
+        m = oc_allocate_mbuf(endpoint);
+        if (m) {
+            LOG("Created new transaction %d\n", mid);
             t->mid = mid;
             t->retrans_counter = 0;
-            t->message = message;
-
-            /* save client address */
-            memcpy(&t->message->endpoint, endpoint, sizeof(oc_endpoint_t));
+            t->m = m;
 
             os_callout_init(&t->retrans_timer, oc_evq_get(),
               coap_transaction_retrans, t);
@@ -121,9 +119,7 @@ coap_send_transaction(coap_transaction_t *t)
 
             os_callout_reset(&t->retrans_timer, t->retrans_tmo);
 
-            oc_message_add_ref(t->message);
-
-            coap_send_message(t->message);
+            coap_send_message(t->m, 1);
 
             t = NULL;
         } else {
@@ -133,12 +129,12 @@ coap_send_transaction(coap_transaction_t *t)
 #ifdef OC_SERVER
             LOG("timeout.. so removing observers\n");
             /* handle observers */
-            coap_remove_observer_by_client(&t->message->endpoint);
+            coap_remove_observer_by_client(OC_MBUF_ENDPOINT(t->m));
 #endif /* OC_SERVER */
 
 #ifdef OC_SECURITY
-            if (t->message->endpoint.flags & SECURED) {
-                oc_sec_dtls_close_init(&t->message->endpoint);
+            if (OC_MBUF_ENDPOINT(t->m)->flags & SECURED) {
+                oc_sec_dtls_close_init(OC_MBUF_ENDPOINT(t->m));
             }
 #endif /* OC_SECURITY */
 
@@ -149,9 +145,8 @@ coap_send_transaction(coap_transaction_t *t)
             coap_clear_transaction(t);
         }
     } else {
-        oc_message_add_ref(t->message);
-
-        coap_send_message(t->message);
+        coap_send_message(t->m, 0);
+        t->m = NULL;
 
         coap_clear_transaction(t);
     }
@@ -166,7 +161,8 @@ coap_clear_transaction(coap_transaction_t *t)
         LOG("Freeing transaction %u: 0x%x\n", t->mid, (unsigned)t);
 
         os_callout_stop(&t->retrans_timer);
-        oc_message_unref(t->message);
+        os_mbuf_free_chain(t->m);
+
         /*
          * Transaction might not be in the list yet.
          */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b7a6b9e/net/oic/src/messaging/coap/transactions.h
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/transactions.h b/net/oic/src/messaging/coap/transactions.h
index 8768619..ba3119c 100644
--- a/net/oic/src/messaging/coap/transactions.h
+++ b/net/oic/src/messaging/coap/transactions.h
@@ -62,7 +62,7 @@ typedef struct coap_transaction {
     coap_message_type_t type;
     uint32_t retrans_tmo;
     struct os_callout retrans_timer;
-    oc_message_t *message;
+    struct os_mbuf *m;
 } coap_transaction_t;
 
 void coap_register_as_transaction_handler(void);