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:43 UTC

[1/3] incubator-mynewt-core git commit: oic; engine.c - bring coding style closer to mynewt.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop e5bca719d -> a3775fd39


oic; engine.c - bring coding style closer to mynewt.


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

Branch: refs/heads/develop
Commit: 3a55f424c473eda273502d84411bdfce4c19e41e
Parents: e5bca71
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Thu Dec 8 15:58:31 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Thu Dec 8 15:58:51 2016 -0800

----------------------------------------------------------------------
 net/oic/src/messaging/coap/engine.c | 389 ++++++++++++++++---------------
 1 file changed, 201 insertions(+), 188 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3a55f424/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 19f9ef9..10225f9 100644
--- a/net/oic/src/messaging/coap/engine.c
+++ b/net/oic/src/messaging/coap/engine.c
@@ -56,71 +56,77 @@ extern bool oc_ri_invoke_coap_entity_handler(void *request, void *response,
 int
 coap_receive(oc_message_t *msg)
 {
-  erbium_status_code = NO_ERROR;
+    /* static declaration reduces stack peaks and program code size */
+    /* this way the packet can be treated as pointer as usual */
+    static coap_packet_t message[1];
+    static coap_packet_t response[1];
+    static coap_transaction_t *transaction = NULL;
 
-  LOG("\n\nCoAP Engine: received datalen=%u \n", (unsigned int) msg->length);
+    erbium_status_code = NO_ERROR;
 
-  /* static declaration reduces stack peaks and program code size */
-  static coap_packet_t
-    message[1]; /* this way the packet can be treated as pointer as usual */
-  static coap_packet_t response[1];
-  static coap_transaction_t *transaction = NULL;
+    LOG("\nCoAP Engine: received datalen=%u\n", (unsigned int) 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) {
+    erbium_status_code = coap_parse_message(message, msg->data, msg->length,
+                                           oc_endpoint_use_tcp(&msg->endpoint));
+    if (erbium_status_code != NO_ERROR) {
+        goto out;
+    }
 
 /*TODO duplicates suppression, if required by application */
-
     OC_LOG_DEBUG("  Parsed: CoAP version: %u, token: 0x%02X%02X, mid: %u\n",
-        message->version, message->token[0], message->token[1], message->mid);
+                 message->version, message->token[0], message->token[1],
+                 message->mid);
     switch (message->type) {
     case COAP_TYPE_CON:
-      OC_LOG_DEBUG("  type: CON\n");
-      break;
+        OC_LOG_DEBUG("  type: CON\n");
+        break;
     case COAP_TYPE_NON:
-      OC_LOG_DEBUG("  type: NON\n");
-      break;
+        OC_LOG_DEBUG("  type: NON\n");
+        break;
     case COAP_TYPE_ACK:
-      OC_LOG_DEBUG("  type: ACK\n");
-      break;
+        OC_LOG_DEBUG("  type: ACK\n");
+        break;
     case COAP_TYPE_RST:
-      OC_LOG_DEBUG("  type: RST\n");
-      break;
+        OC_LOG_DEBUG("  type: RST\n");
+        break;
     default:
-      break;
+        break;
     }
 
-    /* handle requests */
     if (message->code >= COAP_GET && message->code <= COAP_DELETE) {
-
-      switch (message->code) {
-      case COAP_GET:
-        OC_LOG_DEBUG("  method: GET\n");
-        break;
-      case COAP_PUT:
-        OC_LOG_DEBUG("  method: PUT\n");
-        break;
-      case COAP_POST:
-        OC_LOG_DEBUG("  method: POST\n");
-        break;
-      case COAP_DELETE:
-        OC_LOG_DEBUG("  method: DELETE\n");
-        break;
-      }
+        /* handle requests */
+        switch (message->code) {
+        case COAP_GET:
+            OC_LOG_DEBUG("  method: GET\n");
+            break;
+        case COAP_PUT:
+            OC_LOG_DEBUG("  method: PUT\n");
+            break;
+        case COAP_POST:
+            OC_LOG_DEBUG("  method: POST\n");
+            break;
+        case COAP_DELETE:
+            OC_LOG_DEBUG("  method: DELETE\n");
+            break;
+        }
 
 #if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG
-      uint8_t uri[64];
-      memcpy(uri, message->uri_path, message->uri_path_len);
-      uri[message->uri_path_len] = '\0';
+        uint8_t uri[64];
+        memcpy(uri, message->uri_path, message->uri_path_len);
+        uri[message->uri_path_len] = '\0';
 
-      OC_LOG_DEBUG("  URL: %s\n", uri);
-      OC_LOG_DEBUG("  Payload: %d bytes\n", message->payload_len);
+        OC_LOG_DEBUG("  URL: %s\n", uri);
+        OC_LOG_DEBUG("  Payload: %d bytes\n", message->payload_len);
 #endif
 
-      /* use transaction buffer for response to confirmable request */
-      if ((transaction = coap_new_transaction(message->mid, &msg->endpoint))) {
+        /* use transaction buffer for response to confirmable request */
+        transaction = coap_new_transaction(message->mid, &msg->endpoint);
+        if (!transaction) {
+            erbium_status_code = SERVICE_UNAVAILABLE_5_03;
+            coap_error_message = "NoFreeTraBuffer";
+            goto out;
+        }
+
         uint32_t block_num = 0;
         uint16_t block_size = COAP_MAX_BLOCK_SIZE;
         uint32_t block_offset = 0;
@@ -128,184 +134,191 @@ coap_receive(oc_message_t *msg)
 
         /* prepare response */
         if (message->type == COAP_TYPE_CON) {
-          /* reliable CON requests are answered with an ACK */
-          coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05,
-                            message->mid);
+            /* reliable CON requests are answered with an ACK */
+            coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05,
+                              message->mid);
         } else {
-          /* unreliable NON requests are answered with a NON as well */
-          coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
-                            coap_get_mid());
-          /* mirror token */
+            /* unreliable NON requests are answered with a NON */
+            coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
+                              coap_get_mid());
+            /* mirror token */
         }
         if (message->token_len) {
-          coap_set_token(response, message->token, message->token_len);
-          /* get offset for blockwise transfers */
+            coap_set_token(response, message->token, message->token_len);
+            /* get offset for blockwise transfers */
         }
-        if (coap_get_header_block2(message, &block_num, NULL, &block_size,
-                                   &block_offset)) {
-          LOG("\tBlockwise: block request %u (%u/%u) @ %u bytes\n", (unsigned int) block_num,
-              block_size, COAP_MAX_BLOCK_SIZE, (unsigned int) block_offset);
-          block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
-          new_offset = block_offset;
+        if (coap_get_header_block2(message, &block_num, NULL,
+                                   &block_size, &block_offset)) {
+            LOG("\tBlockwise: block request %u (%u/%u) @ %u bytes\n",
+                (unsigned int) block_num, block_size,
+                COAP_MAX_BLOCK_SIZE, (unsigned int) block_offset);
+            block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
+            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)) {
-
-          if (erbium_status_code == NO_ERROR) {
-
-            /* TODO coap_handle_blockwise(request, response, start_offset,
-             * end_offset); */
-
-            /* resource is unaware of Block1 */
-            if (IS_OPTION(message, COAP_OPTION_BLOCK1) &&
-                response->code < BAD_REQUEST_4_00 &&
-                !IS_OPTION(response, COAP_OPTION_BLOCK1)) {
-              LOG("\tBlock1 option NOT IMPLEMENTED\n");
-
-              erbium_status_code = NOT_IMPLEMENTED_5_01;
-              coap_error_message = "NoBlock1Support";
-
-              /* client requested Block2 transfer */
-            } else if (IS_OPTION(message, COAP_OPTION_BLOCK2)) {
-
-              /* unchanged new_offset indicates that resource is unaware of
-               * blockwise transfer */
-              if (new_offset == block_offset) {
-                LOG("\tBlockwise: unaware resource with payload length %u/%u\n",
-                    response->payload_len, block_size);
-                if (block_offset >= response->payload_len) {
-                  LOG("\t\t: block_offset >= response->payload_len\n");
-
-                  response->code = BAD_OPTION_4_02;
-                  coap_set_payload(response, "BlockOutOfScope",
-                                   15); /* a const char str[] and sizeof(str)
-                                           produces larger code size */
-                } else {
-                  coap_set_header_block2(response, block_num,
+        if (oc_ri_invoke_coap_entity_handler(message, response,
+                              transaction->message->data + COAP_MAX_HEADER_SIZE,
+                              block_size, &new_offset, &msg->endpoint)) {
+
+            if (erbium_status_code == NO_ERROR) {
+                /*
+                 * TODO coap_handle_blockwise(request, response,
+                 * start_offset, end_offset);
+                 */
+
+                /* resource is unaware of Block1 */
+                if (IS_OPTION(message, COAP_OPTION_BLOCK1) &&
+                  response->code < BAD_REQUEST_4_00 &&
+                  !IS_OPTION(response, COAP_OPTION_BLOCK1)) {
+                    LOG("\tBlock1 option NOT IMPLEMENTED\n");
+
+                    erbium_status_code = NOT_IMPLEMENTED_5_01;
+                    coap_error_message = "NoBlock1Support";
+
+                    /* client requested Block2 transfer */
+                } else if (IS_OPTION(message, COAP_OPTION_BLOCK2)) {
+
+                    /*
+                     * Unchanged new_offset indicates that resource is
+                     * unaware of blockwise transfer
+                     */
+                    if (new_offset == block_offset) {
+                        LOG("\tBlockwise: unaware resource with payload"
+                            " length %u/%u\n", response->payload_len,
+                                               block_size);
+                        if (block_offset >= response->payload_len) {
+                            LOG("\t\t: block_offset >= "
+                                "response->payload_len\n");
+
+                            response->code = BAD_OPTION_4_02;
+                            coap_set_payload(response, "BlockOutOfScope", 15);
+                            /* a const char str[] and sizeof(str)
+                               produces larger code size */
+                        } else {
+                            coap_set_header_block2(response, block_num,
                                          response->payload_len - block_offset >
-                                           block_size,
-                                         block_size);
-                  coap_set_payload(
-                    response, response->payload + block_offset,
-                    MIN(response->payload_len - block_offset, block_size));
-                } /* if(valid offset) */
-
-                /* resource provides chunk-wise data */
-              } else {
-                LOG("\tBlockwise: blockwise resource, new offset %d\n",
-                    (int) new_offset);
-                coap_set_header_block2(response, block_num,
-                                       new_offset != -1 ||
+                                           block_size, block_size);
+                            coap_set_payload(response,
+                                             response->payload + block_offset,
+                                             MIN(response->payload_len -
+                                                 block_offset, block_size));
+                        } /* if(valid offset) */
+
+                        /* resource provides chunk-wise data */
+                    } else {
+                        LOG("\tBlockwise: blockwise resource, new "
+                            "offset %d\n", (int) new_offset);
+                        coap_set_header_block2(response, block_num,
+                                               new_offset != -1 ||
                                          response->payload_len > block_size,
-                                       block_size);
-
-                if (response->payload_len > block_size) {
-                  coap_set_payload(response, response->payload, block_size);
-                }
-              } /* if(resource aware of blockwise) */
-
-              /* Resource requested Block2 transfer */
-            } else if (new_offset != 0) {
-              LOG("\tBlockwise: no block option for blockwise resource, using "
-                  "block size %u\n",
-                  COAP_MAX_BLOCK_SIZE);
-
-              coap_set_header_block2(response, 0, new_offset != -1,
-                                     COAP_MAX_BLOCK_SIZE);
-              coap_set_payload(response, response->payload,
-                               MIN(response->payload_len, COAP_MAX_BLOCK_SIZE));
-            } /* blockwise transfer handling */
-          }   /* no errors/hooks */
-          /* successful service callback */
-          /* serialize response */
+                                               block_size);
+
+                        if (response->payload_len > block_size) {
+                            coap_set_payload(response, response->payload,
+                                             block_size);
+                        }
+                    } /* if(resource aware of blockwise) */
+
+                    /* Resource requested Block2 transfer */
+                } else if (new_offset != 0) {
+                    LOG("\tBlockwise: no block option for blockwise "
+                        "resource, using block size %u\n",
+                        COAP_MAX_BLOCK_SIZE);
+
+                    coap_set_header_block2(response, 0, new_offset != -1,
+                                           COAP_MAX_BLOCK_SIZE);
+                    coap_set_payload(response, response->payload,
+                                     MIN(response->payload_len,
+                                         COAP_MAX_BLOCK_SIZE));
+                } /* blockwise transfer handling */
+            }   /* no errors/hooks */
+            /* successful service callback */
+            /* 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) {
-            erbium_status_code = PACKET_SERIALIZATION_ERROR;
-          }
-          transaction->type = response->type;
+            if ((transaction->message->length =
+                coap_serialize_message(response, transaction->message->data,
+                                   oc_endpoint_use_tcp(&msg->endpoint))) == 0) {
+                erbium_status_code = PACKET_SERIALIZATION_ERROR;
+            }
+            transaction->type = response->type;
         }
-      } else {
-        erbium_status_code = SERVICE_UNAVAILABLE_5_03;
-        coap_error_message = "NoFreeTraBuffer";
-      } /* if(transaction buffer) */
 
-      /* handle responses */
     } else { // Fix this
-      if (message->type == COAP_TYPE_CON) {
-        erbium_status_code = EMPTY_ACK_RESPONSE;
-      } else if (message->type == COAP_TYPE_ACK) {
-        /* transactions are closed through lookup below */
-      } else if (message->type == COAP_TYPE_RST) {
+        /* handle responses */
+        if (message->type == COAP_TYPE_CON) {
+            erbium_status_code = EMPTY_ACK_RESPONSE;
+        } else if (message->type == COAP_TYPE_ACK) {
+            /* transactions are closed through lookup below */
+        } else if (message->type == COAP_TYPE_RST) {
 #ifdef OC_SERVER
-        /* cancel possible subscriptions */
-        coap_remove_observer_by_mid(&msg->endpoint, message->mid);
+            /* cancel possible subscriptions */
+            coap_remove_observer_by_mid(&msg->endpoint, message->mid);
 #endif
-      }
+        }
 
-      /* Open transaction now cleared for ACK since mid matches */
-      if ((transaction = coap_get_transaction_by_mid(message->mid))) {
-        coap_clear_transaction(transaction);
-      }
-      /* if(ACKed transaction) */
-      transaction = NULL;
+        /* Open transaction now cleared for ACK since mid matches */
+        if ((transaction = coap_get_transaction_by_mid(message->mid))) {
+            coap_clear_transaction(transaction);
+        }
+        /* if(ACKed transaction) */
+        transaction = NULL;
 
-#ifdef OC_CLIENT // ACKs and RSTs sent to oc_ri.. RSTs cleared, ACKs sent to
-                 // client
-      oc_ri_invoke_client_cb(message, &msg->endpoint);
+#ifdef OC_CLIENT
+        /*
+         * ACKs and RSTs sent to oc_ri.. RSTs cleared, ACKs sent to
+         * client.
+         */
+        oc_ri_invoke_client_cb(message, &msg->endpoint);
 #endif
 
     } /* request or response */
-  }   /* parsed correctly */
 
-  /* if(parsed correctly) */
-  if (erbium_status_code == NO_ERROR) {
-    if (transaction) { // Server transactions sent from here
-      coap_send_transaction(transaction);
-    }
-  } else if (erbium_status_code == CLEAR_TRANSACTION) {
-    LOG("Clearing transaction for manual response\n");
-    coap_clear_transaction(transaction); // used in server for separate response
+out:
+    /* if(parsed correctly) */
+    if (erbium_status_code == NO_ERROR) {
+        if (transaction) { // Server transactions sent from here
+            coap_send_transaction(transaction);
+        }
+    } else if (erbium_status_code == CLEAR_TRANSACTION) {
+        LOG("Clearing transaction for manual response\n");
+        /* used in server for separate response */
+        coap_clear_transaction(transaction);
   }
 #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();
-    if (response) {
-      memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
-      response->length = coap_serialize_message(message, response->data,
+    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();
+        if (response) {
+            memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
+            response->length = coap_serialize_message(message, response->data,
                                           oc_endpoint_use_tcp(&msg->endpoint));
-      coap_send_message(response);
+            coap_send_message(response);
+        }
     }
-  }
 #endif /* OC_CLIENT */
 #ifdef OC_SERVER
-  else { // framework errors handled here
-    coap_message_type_t reply_type = COAP_TYPE_RST;
+    else { // framework errors handled here
+        coap_message_type_t reply_type = COAP_TYPE_RST;
 
-    coap_clear_transaction(transaction);
+        coap_clear_transaction(transaction);
 
-    coap_init_message(message, reply_type, SERVICE_UNAVAILABLE_5_03,
-                      message->mid);
+        coap_init_message(message, reply_type, SERVICE_UNAVAILABLE_5_03,
+                          message->mid);
 
-    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,
+        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,
                                      oc_endpoint_use_tcp(&response->endpoint));
-      coap_send_message(response);
+            coap_send_message(response);
+        }
     }
-  }
 #endif /* OC_SERVER */
 
-  /* if(new data) */
-  return erbium_status_code;
+    /* if(new data) */
+    return erbium_status_code;
 }
 
 void


[3/3] incubator-mynewt-core git commit: oic; move the check for use of tcp-style headers to take place inside coap_serialize_message().

Posted by ma...@apache.org.
oic; move the check for use of tcp-style headers to take place
inside coap_serialize_message().


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

Branch: refs/heads/develop
Commit: a3775fd3976f68790dff59fbcb939659d583bb12
Parents: 0b7a6b9
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Dec 9 10:11:23 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Dec 9 10:11:23 2016 -0800

----------------------------------------------------------------------
 net/oic/src/api/oc_client_api.c       | 16 ++++++++++------
 net/oic/src/api/oc_ri.c               |  7 +++++--
 net/oic/src/api/oc_server_api.c       |  8 +++++---
 net/oic/src/messaging/coap/coap.c     |  5 ++++-
 net/oic/src/messaging/coap/coap.h     |  2 +-
 net/oic/src/messaging/coap/engine.c   | 19 +++++++++++--------
 net/oic/src/messaging/coap/observe.c  | 11 ++++++-----
 net/oic/src/messaging/coap/separate.c |  3 +--
 8 files changed, 43 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a3775fd3/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 bc681ec..c15e412 100644
--- a/net/oic/src/api/oc_client_api.c
+++ b/net/oic/src/api/oc_client_api.c
@@ -38,10 +38,12 @@ dispatch_coap_request(void)
                 coap_set_payload(request, rsp->data, response_length);
                 coap_set_header_content_format(request, APPLICATION_CBOR);
             }
-            coap_serialize_message(request, message,
-                               oc_endpoint_use_tcp(OC_MBUF_ENDPOINT(message)));
+            if (!coap_serialize_message(request, message)) {
+                coap_send_message(message, 0);
+            } else {
+                os_mbuf_free_chain(message);
+            }
             oc_message_unref(rsp);
-            coap_send_message(message, 0);
             message = NULL;
             return true;
         }
@@ -50,10 +52,12 @@ dispatch_coap_request(void)
             coap_set_payload(request, transaction->m, response_length);
             coap_set_header_content_format(request, APPLICATION_CBOR);
         }
-        coap_serialize_message(request, transaction->m,
-                         oc_endpoint_use_tcp(OC_MBUF_ENDPOINT(transaction->m)));
+        if (!coap_serialize_message(request, transaction->m)) {
+            coap_send_transaction(transaction);
+        } else {
+            coap_clear_transaction(transaction);
+        }
         oc_message_unref(rsp);
-        coap_send_transaction(transaction);
         transaction = NULL;
         return true;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a3775fd3/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 64ce1f3..9c84e01 100644
--- a/net/oic/src/api/oc_ri.c
+++ b/net/oic/src/api/oc_ri.c
@@ -704,8 +704,11 @@ oc_ri_send_rst(oc_endpoint_t *endpoint, uint8_t *token, uint8_t token_len,
     coap_set_token(rst, token, token_len);
     m = oc_allocate_mbuf(endpoint);
     if (m) {
-        coap_serialize_message(rst, m, oc_endpoint_use_tcp(endpoint));
-        coap_send_message(m, 0);
+        if (!coap_serialize_message(rst, m)) {
+            coap_send_message(m, 0);
+        } else {
+            os_mbuf_free_chain(m);
+        }
         return true;
     }
     return false;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a3775fd3/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 50b7fdc..071bf40 100644
--- a/net/oic/src/api/oc_server_api.c
+++ b/net/oic/src/api/oc_server_api.c
@@ -259,9 +259,11 @@ oc_send_separate_response(oc_separate_response_t *handle,
                       response_buffer.response_length);
                 }
                 t->type = response->type;
-                coap_serialize_message(response, t->m,
-                                       oc_endpoint_use_tcp(&cur->endpoint));
-                coap_send_transaction(t);
+                if (!coap_serialize_message(response, t->m)) {
+                    coap_send_transaction(t);
+                } else {
+                    coap_clear_transaction(t);
+                }
             }
             coap_separate_clear(handle, cur);
         } else {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a3775fd3/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 cb9cada..2cea8c4 100644
--- a/net/oic/src/messaging/coap/coap.c
+++ b/net/oic/src/messaging/coap/coap.c
@@ -316,7 +316,7 @@ coap_init_message(coap_packet_t *pkt, coap_message_type_t type,
 /*---------------------------------------------------------------------------*/
 
 int
-coap_serialize_message(coap_packet_t *pkt, struct os_mbuf *m, int tcp_hdr)
+coap_serialize_message(coap_packet_t *pkt, struct os_mbuf *m)
 {
     struct coap_udp_hdr *cuh;
     struct coap_tcp_hdr0 *cth0;
@@ -324,6 +324,7 @@ coap_serialize_message(coap_packet_t *pkt, struct os_mbuf *m, int tcp_hdr)
     struct coap_tcp_hdr16 *cth16;
     struct coap_tcp_hdr32 *cth32;
     unsigned int current_number = 0;
+    int tcp_hdr;
     int len, data_len;
 
     /* Initialize */
@@ -331,6 +332,8 @@ coap_serialize_message(coap_packet_t *pkt, struct os_mbuf *m, int tcp_hdr)
 
     LOG("-Serializing message %u to 0x%x, ", pkt->mid, (unsigned)m);
 
+    tcp_hdr = oc_endpoint_use_tcp(OC_MBUF_ENDPOINT(m));
+
     /*
      * Move data pointer, leave enough space to insert coap header and
      * token before options.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a3775fd3/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 5c0d9de..586310c 100644
--- a/net/oic/src/messaging/coap/coap.h
+++ b/net/oic/src/messaging/coap/coap.h
@@ -230,7 +230,7 @@ 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);
-int coap_serialize_message(coap_packet_t *, struct os_mbuf *m, int tcp_hdr);
+int coap_serialize_message(coap_packet_t *, struct os_mbuf *m);
 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/a3775fd3/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 e4b700c..0e95dae 100644
--- a/net/oic/src/messaging/coap/engine.c
+++ b/net/oic/src/messaging/coap/engine.c
@@ -240,8 +240,7 @@ coap_receive(oc_message_t *msg)
             /* serialize response */
         }
         if (erbium_status_code == NO_ERROR) {
-            if (coap_serialize_message(response, transaction->m,
-                oc_endpoint_use_tcp(&msg->endpoint))) {
+            if (coap_serialize_message(response, transaction->m)) {
                 erbium_status_code = PACKET_SERIALIZATION_ERROR;
             }
             transaction->type = response->type;
@@ -295,9 +294,11 @@ out:
         coap_init_message(message, COAP_TYPE_ACK, 0, message->mid);
         struct os_mbuf *response = oc_allocate_mbuf(&msg->endpoint);
         if (response) {
-            coap_serialize_message(message, response,
-                                          oc_endpoint_use_tcp(&msg->endpoint));
-            coap_send_message(response, 0);
+            if (!coap_serialize_message(message, response)) {
+                coap_send_message(response, 0);
+            } else {
+                os_mbuf_free_chain(response);
+            }
         }
     }
 #endif /* OC_CLIENT */
@@ -312,9 +313,11 @@ out:
 
         struct os_mbuf *response = oc_allocate_mbuf(&msg->endpoint);
         if (response) {
-            coap_serialize_message(message, response,
-                                   oc_endpoint_use_tcp(&msg->endpoint));
-            coap_send_message(response, 0);
+            if (!coap_serialize_message(message, response)) {
+                coap_send_message(response, 0);
+            } else {
+                os_mbuf_free_chain(response);
+            }
         }
     }
 #endif /* OC_SERVER */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a3775fd3/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 01907b8..65bf85a 100644
--- a/net/oic/src/messaging/coap/observe.c
+++ b/net/oic/src/messaging/coap/observe.c
@@ -293,11 +293,12 @@ coap_notify_observers(oc_resource_t *resource,
                 }
                 coap_set_token(notification, obs->token, obs->token_len);
 
-                coap_serialize_message(notification, transaction->m,
-                                       oc_endpoint_use_tcp(&obs->endpoint));
-                transaction->type = notification->type;
-
-                coap_send_transaction(transaction);
+                if (!coap_serialize_message(notification, transaction->m)) {
+                    transaction->type = notification->type;
+                    coap_send_transaction(transaction);
+                } else {
+                    coap_clear_transaction(transaction);
+                }
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a3775fd3/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 be6c7f4..7588866 100644
--- a/net/oic/src/messaging/coap/separate.c
+++ b/net/oic/src/messaging/coap/separate.c
@@ -102,8 +102,7 @@ coap_separate_accept(coap_packet_t *coap_req,
         }
         coap_set_token(ack, coap_req->token, coap_req->token_len);
         struct os_mbuf *message = oc_allocate_mbuf(endpoint); /* XXXX? */
-        if (message != NULL) {
-            coap_serialize_message(ack, message, oc_endpoint_use_tcp(endpoint));
+        if (message != NULL && coap_serialize_message(ack, message) == 0) {
             coap_send_message(message, 0);
         } else {
             coap_separate_clear(separate_response, separate_store);


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

Posted by ma...@apache.org.
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);