oic; change the RX data path to use data within mbuf, instead of
copying it to a flat buffer.


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

Branch: refs/heads/develop
Commit: 5c307f69b6effa54e4472208324c5c1f4c75f421
Parents: 6897586
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Jan 6 11:29:40 2017 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Jan 6 15:03:00 2017 -0800

----------------------------------------------------------------------
 net/oic/include/oic/oc_client_state.h  |   7 +-
 net/oic/include/oic/oc_rep.h           |   4 +-
 net/oic/include/oic/oc_ri.h            |  19 +-
 net/oic/src/api/oc_buffer.c            |  29 +--
 net/oic/src/api/oc_discovery.c         |   9 +-
 net/oic/src/api/oc_rep.c               |  12 +-
 net/oic/src/api/oc_ri.c                |  14 +-
 net/oic/src/messaging/coap/coap.c      | 276 ++++++++++++++++++----------
 net/oic/src/messaging/coap/coap.h      | 123 ++++++++++---
 net/oic/src/messaging/coap/constants.h |   2 +
 net/oic/src/messaging/coap/engine.c    |  49 ++---
 net/oic/src/messaging/coap/engine.h    |   2 +-
 net/oic/src/messaging/coap/observe.c   |  32 ++--
 net/oic/src/messaging/coap/observe.h   |   2 +-
 net/oic/src/messaging/coap/separate.c  |   2 +-
 net/oic/src/messaging/coap/separate.h  |   2 +-
 16 files changed, 371 insertions(+), 213 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/include/oic/oc_client_state.h
----------------------------------------------------------------------
diff --git a/net/oic/include/oic/oc_client_state.h 
b/net/oic/include/oic/oc_client_state.h
index f281b8b..01acbb4 100644
--- a/net/oic/include/oic/oc_client_state.h
+++ b/net/oic/include/oic/oc_client_state.h
@@ -29,7 +29,7 @@ extern "C" {
 typedef enum { HIGH_QOS = 0, LOW_QOS } oc_qos_t;
 
 typedef struct {
-    void *packet;
+    struct coap_packet_rx *packet;
     oc_status_t code;
     uint32_t observe_option;
 } oc_client_response_t;
@@ -69,7 +69,8 @@ typedef struct oc_client_cb {
     oc_method_t method;
 } oc_client_cb_t;
 
-bool oc_ri_invoke_client_cb(coap_packet_t *response, oc_endpoint_t *endpoint);
+bool oc_ri_invoke_client_cb(struct coap_packet_rx *response,
+                            oc_endpoint_t *endpoint);
 
 oc_client_cb_t *oc_ri_alloc_client_cb(const char *uri,
                                       oc_server_handle_t *server,
@@ -81,7 +82,7 @@ oc_client_cb_t *oc_ri_get_client_cb(const char *uri, 
oc_server_handle_t *server,
 
 void oc_ri_remove_client_cb_by_mid(uint16_t mid);
 
-oc_discovery_flags_t oc_ri_process_discovery_payload(coap_packet_t *rsp,
+oc_discovery_flags_t oc_ri_process_discovery_payload(struct coap_packet_rx 
*rsp,
                                                      oc_discovery_cb_t 
*handler,
                                                      oc_endpoint_t *endpoint);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/include/oic/oc_rep.h
----------------------------------------------------------------------
diff --git a/net/oic/include/oic/oc_rep.h b/net/oic/include/oic/oc_rep.h
index 17983a4..8b9b550 100644
--- a/net/oic/include/oic/oc_rep.h
+++ b/net/oic/include/oic/oc_rep.h
@@ -227,8 +227,8 @@ typedef struct oc_rep_s
   };
 } oc_rep_t;
 
-uint16_t oc_parse_rep(const uint8_t *payload, uint16_t payload_size,
-                      oc_rep_t **value_list);
+uint16_t oc_parse_rep(struct os_mbuf *m, uint16_t payload_off,
+                      uint16_t payload_size, oc_rep_t **out_rep);
 
 void oc_free_rep(oc_rep_t *rep);
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/include/oic/oc_ri.h
----------------------------------------------------------------------
diff --git a/net/oic/include/oic/oc_ri.h b/net/oic/include/oic/oc_ri.h
index e58af0b..6f0c1fa 100644
--- a/net/oic/include/oic/oc_ri.h
+++ b/net/oic/include/oic/oc_ri.h
@@ -98,12 +98,12 @@ typedef enum {
 typedef struct oc_resource oc_resource_t;
 
 typedef struct {
-  oc_endpoint_t *origin;
-  oc_resource_t *resource;
-  const char *query;
-  int query_len;
-  oc_response_t *response;
-  void *packet;
+    oc_endpoint_t *origin;
+    oc_resource_t *resource;
+    const char *query;
+    int query_len;
+    oc_response_t *response;
+    struct coap_packet_rx *packet;
 } oc_request_t;
 
 typedef void (*oc_request_handler_t)(oc_request_t *, oc_interface_mask_t);
@@ -150,9 +150,10 @@ int oc_ri_get_query_value(const char *query, int 
query_len, const char *key,
 oc_interface_mask_t oc_ri_get_interface_mask(char *iface, int if_len);
 
 typedef struct coap_packet coap_packet_t;
-bool oc_ri_invoke_coap_entity_handler(coap_packet_t *request,
-                                      coap_packet_t *response,
-                                      int32_t *offset, oc_endpoint_t 
*endpoint);
+struct coap_packet_rx;
+bool oc_ri_invoke_coap_entity_handler(struct coap_packet_rx *request,
+                                      coap_packet_t *response, int32_t *offset,
+                                      oc_endpoint_t *endpoint);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/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 1df8b8d..15e1587 100644
--- a/net/oic/src/api/oc_buffer.c
+++ b/net/oic/src/api/oc_buffer.c
@@ -148,48 +148,29 @@ oc_buffer_tx(struct os_event *ev)
 static void
 oc_buffer_rx(struct os_event *ev)
 {
-    struct oc_message *msg;
     struct os_mbuf *m;
 #if defined(OC_SECURITY)
     uint8_t b;
 #endif
 
     while ((m = os_mqueue_get(&oc_inq)) != NULL) {
-        msg = oc_allocate_message();
-        if (!msg) {
-            goto free_msg;
-        }
         OC_LOG_DEBUG("oc_buffer_rx: ");
         OC_LOG_ENDPOINT(LOG_LEVEL_DEBUG, OC_MBUF_ENDPOINT(m));
 
-        if (OS_MBUF_PKTHDR(m)->omp_len > MAX_PAYLOAD_SIZE) {
-            STATS_INC(coap_stats, itoobig);
-            goto free_msg;
-        }
-        if (os_mbuf_copydata(m, 0, OS_MBUF_PKTHDR(m)->omp_len, msg->data)) {
-            STATS_INC(coap_stats, imem);
-            goto free_msg;
-        }
-        memcpy(&msg->endpoint, OC_MBUF_ENDPOINT(m), sizeof(msg->endpoint));
-        msg->length = OS_MBUF_PKTHDR(m)->omp_len;
-        os_mbuf_free_chain(m);
-        m = NULL;
-
 #ifdef OC_SECURITY
+        /*
+         * XXX make sure first byte is within first mbuf
+         */
         b = m->om_data[0];
         if (b > 19 && b < 64) {
             OC_LOG_DEBUG("oc_buffer_rx: encrypted request\n");
             oc_process_post(&oc_dtls_handler, oc_events[UDP_TO_DTLS_EVENT], m);
         } else {
-            coap_receive(msg);
+            coap_receive(m);
         }
 #else
-        coap_receive(msg);
+        coap_receive(&m);
 #endif
-free_msg:
-        if (msg) {
-            oc_message_unref(msg);
-        }
         if (m) {
             os_mbuf_free_chain(m);
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/src/api/oc_discovery.c
----------------------------------------------------------------------
diff --git a/net/oic/src/api/oc_discovery.c b/net/oic/src/api/oc_discovery.c
index 18992f3..066764c 100644
--- a/net/oic/src/api/oc_discovery.c
+++ b/net/oic/src/api/oc_discovery.c
@@ -176,7 +176,7 @@ oc_create_discovery_resource(void)
 
 #ifdef OC_CLIENT
 oc_discovery_flags_t
-oc_ri_process_discovery_payload(coap_packet_t *rsp,
+oc_ri_process_discovery_payload(struct coap_packet_rx *rsp,
                                 oc_discovery_cb_t *handler,
                                 oc_endpoint_t *endpoint)
 {
@@ -194,15 +194,16 @@ oc_ri_process_discovery_payload(coap_packet_t *rsp,
   oc_string_array_t types = {};
   oc_interface_mask_t interfaces = 0;
   oc_server_handle_t handle;
-  const uint8_t *payload;
+  uint16_t data_off;
+  struct os_mbuf *m;
   int len;
 
   memcpy(&handle.endpoint, endpoint, sizeof(oc_endpoint_t));
 
   oc_rep_t *array = 0, *rep;
 
-  len = coap_get_payload(rsp, &payload);
-  int s = oc_parse_rep(payload, len, &rep);
+  len = coap_get_payload(rsp, &m, &data_off);
+  int s = oc_parse_rep(m, data_off, len, &rep);
   if (s == 0)
     array = rep;
   while (array != NULL) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/src/api/oc_rep.c
----------------------------------------------------------------------
diff --git a/net/oic/src/api/oc_rep.c b/net/oic/src/api/oc_rep.c
index 2e70582..67fd1f3 100644
--- a/net/oic/src/api/oc_rep.c
+++ b/net/oic/src/api/oc_rep.c
@@ -23,7 +23,7 @@
 #include "port/oc_assert.h"
 #include "api/oc_priv.h"
 #include <tinycbor/cbor_mbuf_writer.h>
-#include <tinycbor/cbor_buf_reader.h>
+#include <tinycbor/cbor_mbuf_reader.h>
 
 #ifdef OC_CLIENT
 static struct os_mempool oc_rep_objects;
@@ -35,7 +35,7 @@ static const CborEncoder g_empty;
 static struct os_mbuf *g_outm;
 CborEncoder g_encoder, root_map, links_array;
 CborError g_err;
-struct CborMbufWriter g_buf_writer;
+struct cbor_mbuf_writer g_buf_writer;
 
 void
 oc_rep_new(struct os_mbuf *m)
@@ -282,15 +282,15 @@ oc_parse_rep_value(CborValue *value, oc_rep_t **rep, 
CborError *err)
 }
 
 uint16_t
-oc_parse_rep(const uint8_t *in_payload, uint16_t payload_size,
-             oc_rep_t **out_rep)
+oc_parse_rep(struct os_mbuf *m, uint16_t payload_off,
+             uint16_t payload_size, oc_rep_t **out_rep)
 {
   CborParser parser;
   CborValue root_value, cur_value, map;
   CborError err = CborNoError;
-  struct cbor_buf_reader br;
+  struct cbor_mbuf_reader br;
 
-  cbor_buf_reader_init(&br, in_payload, payload_size);
+  cbor_mbuf_reader_init(&br, m, payload_off);
   err |= cbor_parser_init(&br.r, 0, &parser, &root_value);
   if (cbor_value_is_map(&root_value)) {
     err |= cbor_value_enter_container(&root_value, &cur_value);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/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 d3b358a..342338d 100644
--- a/net/oic/src/api/oc_ri.c
+++ b/net/oic/src/api/oc_ri.c
@@ -357,7 +357,7 @@ does_interface_support_method(oc_resource_t *resource,
 }
 
 bool
-oc_ri_invoke_coap_entity_handler(coap_packet_t *request,
+oc_ri_invoke_coap_entity_handler(struct coap_packet_rx *request,
                                  coap_packet_t *response, int32_t *offset,
                                  oc_endpoint_t *endpoint)
 {
@@ -399,12 +399,14 @@ oc_ri_invoke_coap_entity_handler(coap_packet_t *request,
   oc_interface_mask_t interface = 0;
 
   /* Obtain request uri from the CoAP packet. */
-  const char *uri_path;
-  int uri_path_len = coap_get_header_uri_path(request, &uri_path);
+  char uri_path[COAP_MAX_URI];
+  int uri_path_len = coap_get_header_uri_path(request, uri_path,
+                                              sizeof(uri_path));
 
   /* Obtain query string from CoAP packet. */
-  const char *uri_query;
-  int uri_query_len = coap_get_header_uri_query(request, &uri_query);
+  char uri_query[COAP_MAX_URI_QUERY];
+  int uri_query_len = coap_get_header_uri_query(request, uri_query,
+                                                sizeof(uri_query));
 
   if (uri_query_len) {
     request_obj.query = uri_query;
@@ -704,7 +706,7 @@ oc_ri_send_rst(oc_endpoint_t *endpoint, uint8_t *token, 
uint8_t token_len,
 }
 
 bool
-oc_ri_invoke_client_cb(coap_packet_t *rsp, oc_endpoint_t *endpoint)
+oc_ri_invoke_client_cb(struct coap_packet_rx *rsp, oc_endpoint_t *endpoint)
 {
     oc_client_cb_t *cb, *tmp;
     oc_client_response_t client_response;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/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 909e95f..49421de 100644
--- a/net/oic/src/messaging/coap/coap.c
+++ b/net/oic/src/messaging/coap/coap.c
@@ -48,6 +48,7 @@ STATS_NAME_START(coap_stats)
     STATS_NAME(coap_stats, iframe)
     STATS_NAME(coap_stats, ierr)
     STATS_NAME(coap_stats, itoobig)
+    STATS_NAME(coap_stats, ilen)
     STATS_NAME(coap_stats, imem)
     STATS_NAME(coap_stats, oframe)
     STATS_NAME(coap_stats, oerr)
@@ -77,11 +78,18 @@ coap_log_2(uint16_t value)
 }
 /*---------------------------------------------------------------------------*/
 static uint32_t
-coap_parse_int_option(uint8_t *bytes, size_t length)
+coap_parse_int_option(struct os_mbuf *m, uint16_t off, size_t length)
 {
+    uint8_t bytes[4];
     uint32_t var = 0;
     int i = 0;
 
+    if (length >= 4) {
+        return -1;
+    }
+    if (os_mbuf_copydata(m, off, length, bytes)) {
+        return -1;
+    }
     while (i < length) {
         var <<= 8;
         var |= bytes[i++];
@@ -227,22 +235,30 @@ coap_append_array_opt(struct os_mbuf *m,
 /*---------------------------------------------------------------------------*/
 
 static void
-coap_merge_multi_option(char **dst, uint16_t *dst_len, uint8_t *option,
-                        size_t option_len, char separator)
+coap_merge_multi_option(struct os_mbuf *m, uint16_t *off1, uint16_t *len1,
+                        uint16_t off2, uint16_t len2, char separator)
 {
+    uint8_t tmp[4];
+    int i;
+    int blk;
+
     /* merge multiple options */
-    if (*dst_len > 0) {
+    if (*len1 > 0) {
         /* dst already contains an option: concatenate */
-        (*dst)[*dst_len] = separator;
-        *dst_len += 1;
+        os_mbuf_copyinto(m, *off1 + *len1, &separator, 1);
+        *len1 += 1;
+
+        for (i = 0; i < len2; i += blk) {
+            blk = min(sizeof(tmp), len2 - i);
+            os_mbuf_copydata(m, off2 + i, blk, tmp);
+            os_mbuf_copyinto(m, *off1 + *len1 + i, tmp, blk);
+        }
 
-        /* memmove handles 2-byte option headers */
-        memmove((*dst) + (*dst_len), option, option_len);
-        *dst_len += option_len;
+        *len1 += len2;
     } else {
-        /* dst is empty: set to option */
-        *dst = (char *)option;
-        *dst_len = option_len;
+        /* off1 is empty: set to off2 */
+        *off1 = off2;
+        *len1 = len2;
     }
 }
 
@@ -522,29 +538,55 @@ coap_tcp_msg_size(uint8_t *hdr, int datalen)
 
 /*---------------------------------------------------------------------------*/
 coap_status_t
-coap_parse_message(coap_packet_t *pkt, uint8_t *data, uint16_t data_len,
-                   int tcp_hdr)
+coap_parse_message(struct coap_packet_rx *pkt, struct os_mbuf **mp)
 {
+    struct os_mbuf *m;
+    int is_tcp;
     struct coap_udp_hdr *udp;
     struct coap_tcp_hdr0 *cth0;
     struct coap_tcp_hdr8 *cth8;
     struct coap_tcp_hdr16 *cth16;
     struct coap_tcp_hdr32 *cth32;
-    uint8_t *cur_opt;
+    uint8_t tmp[4];
+    uint16_t cur_opt;
     unsigned int opt_num = 0;
     unsigned int opt_delta = 0;
     size_t opt_len = 0;
 
+    m = *mp;
     /* initialize packet */
     memset(pkt, 0, sizeof(coap_packet_t));
-    /* pointer to packet bytes */
-    pkt->buffer = data;
 
     STATS_INC(coap_stats, iframe);
 
+    is_tcp = oc_endpoint_use_tcp(OC_MBUF_ENDPOINT(m));
+
+    /*
+     * Make sure that the header is in contiguous area of memory.
+     */
+    opt_len = sizeof(struct coap_tcp_hdr32);
+    if (opt_len > OS_MBUF_PKTLEN(m)) {
+        opt_len = OS_MBUF_PKTLEN(m);
+    }
+    if (m->om_len < opt_len) {
+        m = os_mbuf_pullup(m, opt_len);
+        if (!m) {
+            STATS_INC(coap_stats, imem);
+            return INTERNAL_SERVER_ERROR_5_00;
+        }
+        *mp = m;
+    }
+    pkt->m = m;
+
     /* parse header fields */
-    if (!tcp_hdr) {
-        udp = (struct coap_udp_hdr *)data;
+    if (!is_tcp) {
+        cur_opt = sizeof(*udp);
+        if (m->om_len < cur_opt) {
+err_short:
+            STATS_INC(coap_stats, ilen);
+            return BAD_REQUEST_4_00;
+        }
+        udp = (struct coap_udp_hdr *)m->om_data;
         pkt->version = udp->version;
         pkt->type = udp->type;
         pkt->token_len = udp->token_len;
@@ -555,33 +597,44 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
             STATS_INC(coap_stats, ierr);
             return BAD_REQUEST_4_00;
         }
-        cur_opt = (uint8_t *)(udp + 1);
     } else {
         /*
          * We cannot just look at the data length, as token might or might
          * not be present. Need to figure out which header is present
          * programmatically.
          */
-        cth0 = (struct coap_tcp_hdr0 *)data;
+        cth0 = (struct coap_tcp_hdr0 *)m->om_data;
         if (cth0->data_len < 13) {
+            cur_opt = sizeof(*cth0);
+            if (m->om_len < cur_opt) {
+                goto err_short;
+            }
             pkt->token_len = cth0->token_len;
             pkt->code = cth0->code;
-            cur_opt = (uint8_t *)(cth0 + 1);
         } else if (cth0->data_len == 13) {
-            cth8 = (struct coap_tcp_hdr8 *)data;
+            cur_opt = sizeof(*cth8);
+            if (m->om_len < cur_opt) {
+                goto err_short;
+            }
+            cth8 = (struct coap_tcp_hdr8 *)m->om_data;
             pkt->token_len = cth8->token_len;
             pkt->code = cth8->code;
-            cur_opt = (uint8_t *)(cth8 + 1);
         } else if (cth0->data_len == 14) {
-            cth16 = (struct coap_tcp_hdr16 *)data;
+            cur_opt = sizeof(*cth16);
+            if (m->om_len < cur_opt) {
+                goto err_short;
+            }
+            cth16 = (struct coap_tcp_hdr16 *)m->om_data;
             pkt->token_len = cth16->token_len;
             pkt->code = cth16->code;
-            cur_opt = (uint8_t *)(cth16 + 1);
         } else {
-            cth32 = (struct coap_tcp_hdr32 *)data;
+            cur_opt = sizeof(*cth32);
+            if (m->om_len < cur_opt) {
+                goto err_short;
+            }
+            cth32 = (struct coap_tcp_hdr32 *)m->om_data;
             pkt->token_len = cth32->token_len;
             pkt->code = cth32->code;
-            cur_opt = (uint8_t *)(cth32 + 1);
         }
     }
     if (pkt->token_len > COAP_TOKEN_LEN) {
@@ -590,49 +643,63 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
         return BAD_REQUEST_4_00;
     }
 
-    memcpy(pkt->token, cur_opt, pkt->token_len);
+    if (os_mbuf_copydata(m, cur_opt, pkt->token_len, pkt->token)) {
+        goto err_short;
+    }
+    cur_opt += pkt->token_len;
 
     OC_LOG_DEBUG("Token (len %u) ");
     OC_LOG_HEX(LOG_LEVEL_DEBUG, pkt->token, pkt->token_len);
 
     /* parse options */
     memset(pkt->options, 0, sizeof(pkt->options));
-    cur_opt += pkt->token_len;
 
-    while (cur_opt < data + data_len) {
+    while (cur_opt < OS_MBUF_PKTLEN(m)) {
         /* payload marker 0xFF, currently only checking for 0xF* because rest 
is
          * reserved */
-        if ((cur_opt[0] & 0xF0) == 0xF0) {
-            pkt->payload = ++cur_opt;
-            pkt->payload_len = data_len - (pkt->payload - data);
+        if (os_mbuf_copydata(m, cur_opt, 1, tmp)) {
+            goto err_short;
+        }
+        if ((tmp[0] & 0xF0) == 0xF0) {
+            pkt->payload_off = ++cur_opt;
+            pkt->payload_len = OS_MBUF_PKTLEN(m) - cur_opt;
 
             /* also for receiving, the Erbium upper bound is MAX_PAYLOAD_SIZE 
*/
             if (pkt->payload_len > MAX_PAYLOAD_SIZE) {
                 pkt->payload_len = MAX_PAYLOAD_SIZE;
-                /* null-terminate payload */
             }
-            pkt->payload[pkt->payload_len] = '\0';
-
             break;
         }
 
-        opt_delta = cur_opt[0] >> 4;
-        opt_len = cur_opt[0] & 0x0F;
+        opt_delta = tmp[0] >> 4;
+        opt_len = tmp[0] & 0x0F;
         ++cur_opt;
 
         if (opt_delta == 13) {
-            opt_delta += cur_opt[0];
+            if (os_mbuf_copydata(m, cur_opt, 1, tmp)) {
+                goto err_short;
+            }
+            opt_delta += tmp[0];
             ++cur_opt;
         } else if (opt_delta == 14) {
-            opt_delta += (255 + (cur_opt[0] << 8) + cur_opt[1]);
+            if (os_mbuf_copydata(m, cur_opt, 2, tmp)) {
+                goto err_short;
+            }
+            opt_delta += (255 + (tmp[0] << 8) + tmp[1]);
             cur_opt += 2;
         }
 
         if (opt_len == 13) {
-            opt_len += cur_opt[0];
+            if (os_mbuf_copydata(m, cur_opt, 1, tmp)) {
+                goto err_short;
+            }
+            opt_len += tmp[0];
             ++cur_opt;
         } else if (opt_len == 14) {
-            opt_len += (255 + (cur_opt[0] << 8) + cur_opt[1]);
+            if (os_mbuf_copydata(m, cur_opt, 2, tmp)) {
+                goto err_short;
+            }
+            opt_len += (255 + (tmp[0] << 8) + tmp[1]);
             cur_opt += 2;
         }
 
@@ -646,30 +713,35 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
 
         switch (opt_num) {
         case COAP_OPTION_CONTENT_FORMAT:
-            pkt->content_format = coap_parse_int_option(cur_opt, opt_len);
+            pkt->content_format = coap_parse_int_option(m, cur_opt, opt_len);
             OC_LOG_DEBUG("Content-Format [%u]\n", pkt->content_format);
             break;
         case COAP_OPTION_MAX_AGE:
-            pkt->max_age = coap_parse_int_option(cur_opt, opt_len);
+            pkt->max_age = coap_parse_int_option(m, cur_opt, opt_len);
             OC_LOG_DEBUG("Max-Age [%lu]\n", (unsigned long)pkt->max_age);
             break;
 #if 0
         case COAP_OPTION_ETAG:
             pkt->etag_len = MIN(COAP_ETAG_LEN, opt_len);
-            memcpy(pkt->etag, cur_opt, pkt->etag_len);
+            if (os_mbuf_copydata(m, cur_opt, pkt->etag_len, pkt->etag)) {
+                goto err_short;
+            }
             OC_LOG_DEBUG("ETag %u ");
             OC_LOG_HEX(LOG_LEVEL_DEBUG, pkt->etag, pkt->etag_len);
             break;
 #endif
         case COAP_OPTION_ACCEPT:
-            pkt->accept = coap_parse_int_option(cur_opt, opt_len);
+            pkt->accept = coap_parse_int_option(m, cur_opt, opt_len);
             OC_LOG_DEBUG("Accept [%u]\n", pkt->accept);
             break;
 #if 0
         case COAP_OPTION_IF_MATCH:
             /* TODO support multiple ETags */
             pkt->if_match_len = MIN(COAP_ETAG_LEN, opt_len);
-            memcpy(pkt->if_match, cur_opt, pkt->if_match_len);
+            if (os_mbuf_copydata(m, cur_opt, pkt->if_match_len,
+                                 pkt->if_match)) {
+                goto err_short;
+            }
             OC_LOG_DEBUG("If-Match %u ");
             OC_LOG_HEX(LOG_LEVEL_DEBUG, pkt->if_match, pkt->if_match_len);
             break;
@@ -680,7 +752,7 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
 
         case COAP_OPTION_PROXY_URI:
 #if COAP_PROXY_OPTION_PROCESSING
-            pkt->proxy_uri = cur_opt;
+            pkt->proxy_uri_off = cur_opt;
             pkt->proxy_uri_len = opt_len;
 #endif
             OC_LOG_DEBUG("Proxy-Uri NOT IMPLEMENTED [%s]\n",
@@ -692,7 +764,7 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
             break;
         case COAP_OPTION_PROXY_SCHEME:
 #if COAP_PROXY_OPTION_PROCESSING
-            pkt->proxy_scheme = cur_opt;
+            pkt->proxy_scheme_off = cur_opt;
             pkt->proxy_scheme_len = opt_len;
 #endif
             OC_LOG_DEBUG("Proxy-Scheme NOT IMPLEMENTED [%s]\n",
@@ -704,52 +776,57 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
             break;
 
         case COAP_OPTION_URI_HOST:
-            pkt->uri_host = cur_opt;
+            pkt->uri_host_off = cur_opt;
             pkt->uri_host_len = opt_len;
             OC_LOG_DEBUG("Uri-Host ");
-            OC_LOG_STR(LOG_LEVEL_DEBUG, pkt->uri_host, pkt->uri_host_len);
+            OC_LOG_STR_MBUF(LOG_LEVEL_DEBUG, m, pkt->uri_host_off,
+                            pkt->uri_host_len);
             break;
         case COAP_OPTION_URI_PORT:
-            pkt->uri_port = coap_parse_int_option(cur_opt, opt_len);
+            pkt->uri_port = coap_parse_int_option(m, cur_opt, opt_len);
             OC_LOG_DEBUG("Uri-Port [%u]\n", pkt->uri_port);
             break;
 #endif
         case COAP_OPTION_URI_PATH:
             /* coap_merge_multi_option() operates in-place on the buf */
-            coap_merge_multi_option(&pkt->uri_path, &pkt->uri_path_len,
+            coap_merge_multi_option(m, &pkt->uri_path_off, &pkt->uri_path_len,
                                     cur_opt, opt_len, '/');
             OC_LOG_DEBUG("Uri-Path ");
-            OC_LOG_STR(LOG_LEVEL_DEBUG, pkt->uri_path, pkt->uri_path_len);
+            OC_LOG_STR_MBUF(LOG_LEVEL_DEBUG, m, pkt->uri_path_off,
+                            pkt->uri_path_len);
             break;
         case COAP_OPTION_URI_QUERY:
             /* coap_merge_multi_option() operates in-place on the mbuf */
-            coap_merge_multi_option(&pkt->uri_query, &pkt->uri_query_len,
+            coap_merge_multi_option(m, &pkt->uri_query_off, 
&pkt->uri_query_len,
                                     cur_opt, opt_len, '&');
             OC_LOG_DEBUG("Uri-Query ");
-            OC_LOG_STR(LOG_LEVEL_DEBUG, pkt->uri_query, pkt->uri_query_len);
+            OC_LOG_STR_MBUF(LOG_LEVEL_DEBUG, m, pkt->uri_query_off,
+                            pkt->uri_query_len);
             break;
 #if 0
         case COAP_OPTION_LOCATION_PATH:
             /* coap_merge_multi_option() operates in-place on the mbuf */
-            coap_merge_multi_option(&pkt->loc_path, &pkt->loc_path_len,
+            coap_merge_multi_option(m, &pkt->loc_path_off, &pkt->loc_path_len,
                                     cur_opt, opt_len, '/');
             OC_LOG_DEBUG("Location-Path ");
-            OC_LOG_STR(LOG_LEVEL_DEBUG, pkt->loc_path, pkt->loc_path_len);
+            OC_LOG_STR_MBUF(LOG_LEVEL_DEBUG, m, pkt->loc_path,
+                            pkt->loc_path_len);
             break;
         case COAP_OPTION_LOCATION_QUERY:
             /* coap_merge_multi_option() operates in-place on the mbuf */
-            coap_merge_multi_option(&pkt->loc_query, &pkt->loc_query_len,
+            coap_merge_multi_option(m, &pkt->loc_query_off, 
&pkt->loc_query_len,
                                     cur_opt, opt_len, '&');
             OC_LOG_DEBUG("Location-Query ");
-            OC_LOG_STR(LOG_LEVEL_DEBUG, pkt->loc_query, pkt->loc_query_len);
+            OC_LOG_STR_MBUF(LOG_LEVEL_DEBUG, m, pkt->loc_query_off,
+                            pkt->loc_query_len);
             break;
 #endif
         case COAP_OPTION_OBSERVE:
-            pkt->observe = coap_parse_int_option(cur_opt, opt_len);
+            pkt->observe = coap_parse_int_option(m, cur_opt, opt_len);
             OC_LOG_DEBUG("Observe [%lu]\n", (unsigned long)pkt->observe);
             break;
         case COAP_OPTION_BLOCK2:
-            pkt->block2_num = coap_parse_int_option(cur_opt, opt_len);
+            pkt->block2_num = coap_parse_int_option(m, cur_opt, opt_len);
             pkt->block2_more = (pkt->block2_num & 0x08) >> 3;
             pkt->block2_size = 16 << (pkt->block2_num & 0x07);
             pkt->block2_offset =
@@ -760,7 +837,7 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
                          pkt->block2_more ? "+" : "", pkt->block2_size);
             break;
         case COAP_OPTION_BLOCK1:
-            pkt->block1_num = coap_parse_int_option(cur_opt, opt_len);
+            pkt->block1_num = coap_parse_int_option(m, cur_opt, opt_len);
             pkt->block1_more = (pkt->block1_num & 0x08) >> 3;
             pkt->block1_size = 16 << (pkt->block1_num & 0x07);
             pkt->block1_offset =
@@ -771,11 +848,11 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
                          pkt->block1_more ? "+" : "", pkt->block1_size);
             break;
         case COAP_OPTION_SIZE2:
-            pkt->size2 = coap_parse_int_option(cur_opt, opt_len);
+            pkt->size2 = coap_parse_int_option(m, cur_opt, opt_len);
             OC_LOG_DEBUG("Size2 [%lu]\n", (unsigned long)pkt->size2);
             break;
         case COAP_OPTION_SIZE1:
-            pkt->size1 = coap_parse_int_option(cur_opt, opt_len);
+            pkt->size1 = coap_parse_int_option(m, cur_opt, opt_len);
             OC_LOG_DEBUG("Size1 [%lu]\n", (unsigned long)pkt->size1);
             break;
         default:
@@ -792,6 +869,7 @@ coap_parse_message(coap_packet_t *pkt, uint8_t *data, 
uint16_t data_len,
 
     return NO_ERROR;
 }
+
 #if 0
 int
 coap_get_query_variable(coap_packet_t *const pkt, const char *name,
@@ -836,7 +914,7 @@ coap_set_token(coap_packet_t *pkt, const uint8_t *token, 
size_t token_len)
 }
 #ifdef OC_CLIENT
 int
-coap_get_header_content_format(coap_packet_t *pkt, unsigned int *format)
+coap_get_header_content_format(struct coap_packet_rx *pkt, unsigned int 
*format)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_CONTENT_FORMAT)) {
         return 0;
@@ -855,7 +933,7 @@ coap_set_header_content_format(coap_packet_t *pkt, unsigned 
int format)
 /*---------------------------------------------------------------------------*/
 #if 0
 int
-coap_get_header_accept(coap_packet_t *pkt, unsigned int *accept)
+coap_get_header_accept(struct coap_packet_rx *pkt, unsigned int *accept)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_ACCEPT)) {
         return 0;
@@ -877,7 +955,7 @@ coap_set_header_accept(coap_packet_t *pkt, unsigned int 
accept)
 /*---------------------------------------------------------------------------*/
 #if 0
 int
-coap_get_header_max_age(coap_packet_t *pkt, uint32_t *age)
+coap_get_header_max_age(struct coap_packet_rx *pkt, uint32_t *age)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_MAX_AGE)) {
         *age = COAP_DEFAULT_MAX_AGE;
@@ -897,7 +975,7 @@ coap_set_header_max_age(coap_packet_t *pkt, uint32_t age)
 /*---------------------------------------------------------------------------*/
 #if 0
 int
-coap_get_header_etag(coap_packet_t *pkt, const uint8_t **etag)
+coap_get_header_etag(struct coap_packet_rx *pkt, const uint8_t **etag)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_ETAG)) {
         return 0;
@@ -920,7 +998,7 @@ coap_set_header_etag(coap_packet_t *pkt, const uint8_t 
*etag,
 /*FIXME support multiple ETags */
 
 int
-coap_get_header_if_match(coap_packet_t *pkt, const uint8_t **etag)
+coap_get_header_if_match(struct coap_packet_rx *pkt, const uint8_t **etag)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_IF_MATCH)) {
         return 0;
@@ -942,7 +1020,7 @@ coap_set_header_if_match(coap_packet_t *pkt, const uint8_t 
*etag,
 
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_if_none_match(coap_packet_t *pkt)
+coap_get_header_if_none_match(struct coap_packet_rx *pkt)
 {
     return IS_OPTION(pkt, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
 }
@@ -955,7 +1033,7 @@ coap_set_header_if_none_match(coap_packet_t *pkt)
 }
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_proxy_uri(coap_packet_t *pkt, const char **uri)
+coap_get_header_proxy_uri(struct coap_packet_rx *pkt, const char **uri)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_PROXY_URI)) {
         return 0;
@@ -977,7 +1055,7 @@ coap_set_header_proxy_uri(coap_packet_t *pkt, const char 
*uri)
 }
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_uri_host(coap_packet_t *pkt, const char **host)
+coap_get_header_uri_host(struct coap_packet_rx *pkt, const char **host)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_URI_HOST)) {
         return 0;
@@ -998,13 +1076,14 @@ coap_set_header_uri_host(coap_packet_t *pkt, const char 
*host)
 #endif
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_uri_path(coap_packet_t *pkt, const char **path)
+coap_get_header_uri_path(struct coap_packet_rx *pkt, char *path, int maxlen)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_URI_PATH)) {
         return 0;
     }
-    *path = pkt->uri_path;
-    return pkt->uri_path_len;
+    maxlen = min(maxlen, pkt->uri_path_len);
+    os_mbuf_copydata(pkt->m, pkt->uri_path_off, maxlen, path);
+    return maxlen;
 }
 #ifdef OC_CLIENT
 int
@@ -1022,13 +1101,14 @@ coap_set_header_uri_path(coap_packet_t *pkt, const char 
*path)
 #endif
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_uri_query(coap_packet_t *pkt, const char **query)
+coap_get_header_uri_query(struct coap_packet_rx *pkt, char *query, int maxlen)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_URI_QUERY)) {
         return 0;
     }
-    *query = pkt->uri_query;
-    return pkt->uri_query_len;
+    maxlen = min(maxlen, pkt->uri_query_len);
+    os_mbuf_copydata(pkt->m, pkt->uri_query_off, maxlen, query);
+    return maxlen;
 }
 #ifdef OC_CLIENT
 int
@@ -1047,7 +1127,7 @@ coap_set_header_uri_query(coap_packet_t *pkt, const char 
*query)
 /*---------------------------------------------------------------------------*/
 #if 0
 int
-coap_get_header_location_path(coap_packet_t *pkt, const char **path)
+coap_get_header_location_path(struct coap_packet_rx *pkt, const char **path)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_LOCATION_PATH)) {
         return 0;
@@ -1081,7 +1161,7 @@ coap_set_header_location_path(coap_packet_t *pkt, const 
char *path)
 #if 0
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_location_query(coap_packet_t *pkt, const char **query)
+coap_get_header_location_query(struct coap_packet_rx *pkt, const char **query)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_LOCATION_QUERY)) {
         return 0;
@@ -1105,7 +1185,7 @@ coap_set_header_location_query(coap_packet_t *pkt, const 
char *query)
 #endif
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_observe(coap_packet_t *pkt, uint32_t *observe)
+coap_get_header_observe(struct coap_packet_rx *pkt, uint32_t *observe)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_OBSERVE)) {
         return 0;
@@ -1124,7 +1204,7 @@ coap_set_header_observe(coap_packet_t *pkt, uint32_t 
observe)
 
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_block2(coap_packet_t *pkt, uint32_t *num,
+coap_get_header_block2(struct coap_packet_rx *pkt, uint32_t *num,
                        uint8_t *more, uint16_t *size, uint32_t *offset)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_BLOCK2)) {
@@ -1168,7 +1248,7 @@ coap_set_header_block2(coap_packet_t *pkt, uint32_t num,
 }
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_block1(coap_packet_t *pkt, uint32_t *num, uint8_t *more,
+coap_get_header_block1(struct coap_packet_rx *pkt, uint32_t *num, uint8_t 
*more,
                        uint16_t *size, uint32_t *offset)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_BLOCK1)) {
@@ -1212,7 +1292,7 @@ coap_set_header_block1(coap_packet_t *pkt, uint32_t num, 
uint8_t more,
 }
 /*---------------------------------------------------------------------------*/
 #if 0
-int coap_get_header_size2(coap_packet_t * const pkt, uint32_t *size)
+int coap_get_header_size2(struct coap_packet_rx * const pkt, uint32_t *size)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_SIZE2)) {
         return 0;
@@ -1230,7 +1310,7 @@ coap_set_header_size2(coap_packet_t *pkt, uint32_t size)
 }
 /*---------------------------------------------------------------------------*/
 int
-coap_get_header_size1(coap_packet_t *pkt, uint32_t *size)
+coap_get_header_size1(struct coap_packet_rx *pkt, uint32_t *size)
 {
     if (!IS_OPTION(pkt, COAP_OPTION_SIZE1)) {
         return 0;
@@ -1248,18 +1328,30 @@ coap_set_header_size1(coap_packet_t *pkt, uint32_t size)
 #endif
 /*---------------------------------------------------------------------------*/
 int
-coap_get_payload(coap_packet_t *pkt, const uint8_t **payload)
+coap_get_payload_copy(struct coap_packet_rx *pkt, uint8_t *payload, int maxlen)
 {
-    if (pkt->payload) {
-        *payload = pkt->payload;
-        return pkt->payload_len;
+    if (pkt->payload_len) {
+        maxlen = min(maxlen, pkt->payload_len);
+        os_mbuf_copydata(pkt->m, pkt->payload_off, maxlen, payload);
+        return maxlen;
     } else {
-        *payload = NULL;
         return 0;
     }
 }
 
 int
+coap_get_payload(struct coap_packet_rx *pkt, struct os_mbuf **mp, uint16_t 
*off)
+{
+    if (pkt->payload_len) {
+        *off = pkt->payload_off;
+    } else {
+        *off = OS_MBUF_PKTLEN(pkt->m);
+    }
+    *mp = pkt->m;
+    return pkt->payload_len;
+}
+
+int
 coap_set_payload(coap_packet_t *pkt, struct os_mbuf *m, size_t length)
 {
     pkt->payload_m = os_mbuf_dup(m);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/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 c422a2f..11e7d8c 100644
--- a/net/oic/src/messaging/coap/coap.h
+++ b/net/oic/src/messaging/coap/coap.h
@@ -95,6 +95,72 @@ enum
 #define IS_OPTION(packet, opt)                                                 
\
   ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE)))
 
+/*
+ * For COAP RX, structure stores the offsets and lengths of option fields
+ * within the mbuf chain.
+ */
+struct coap_packet_rx {
+    struct os_mbuf *m;
+
+    uint8_t version;
+    coap_message_type_t type;
+    uint8_t code;
+    uint16_t mid;   /* message ID */
+
+    uint8_t token_len;
+    uint8_t token[COAP_TOKEN_LEN];
+
+    /* bitmap to check if option is set */
+    uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1];
+
+    /* parse options once and store */
+    uint16_t content_format;
+    uint32_t max_age;
+#if 0
+    uint8_t etag_len;
+    uint8_t etag[COAP_ETAG_LEN];
+#endif
+#if COAP_PROXY_OPTION_PROCESSING
+    uint16_t proxy_uri_len;
+    uint16_t proxy_uri_off;
+    uint16_t proxy_scheme_len;
+    uint16_t proxy_scheme_off;
+#endif
+    uint16_t uri_host_len;
+    uint16_t uri_host_off;
+#if 0
+    uint16_t loc_path_len;
+    uint16_t loc_path_off;
+    uint16_t loc_query_len;
+    uint16_t loc_query_off;
+#endif
+    uint16_t uri_port;
+    uint16_t uri_path_len;
+    uint16_t uri_path_off;
+    int32_t observe;
+    uint16_t accept;
+#if 0
+    uint8_t if_match_len;
+    uint8_t if_match[COAP_ETAG_LEN];
+#endif
+    uint32_t block2_num;
+    uint8_t block2_more;
+    uint16_t block2_size;
+    uint32_t block2_offset;
+    uint32_t block1_num;
+    uint8_t block1_more;
+    uint16_t block1_size;
+    uint32_t block1_offset;
+    uint32_t size2;
+    uint32_t size1;
+    uint16_t uri_query_len;
+    uint16_t uri_query_off;
+    uint8_t if_none_match;
+
+    uint16_t payload_off;
+    uint16_t payload_len;
+};
+
 /* parsed message struct */
 typedef struct coap_packet {
     /* pointer to CoAP header / incoming packet buffer / memory
@@ -168,6 +234,7 @@ STATS_SECT_START(coap_stats)
     STATS_SECT_ENTRY(iframe)
     STATS_SECT_ENTRY(ierr)
     STATS_SECT_ENTRY(itoobig)
+    STATS_SECT_ENTRY(ilen)
     STATS_SECT_ENTRY(imem)
     STATS_SECT_ENTRY(oframe)
     STATS_SECT_ENTRY(oerr)
@@ -175,7 +242,7 @@ STATS_SECT_END
 
 extern STATS_SECT_DECL(coap_stats) coap_stats;
 
-/* option format serialization */
+/* option format serialization (TX) */
 #define COAP_SERIALIZE_INT_OPT(pkt, m, number, field, text)             \
     if (IS_OPTION(pkt, number)) {                                       \
         OC_LOG_DEBUG(" %s [%u]\n", text, (unsigned int)pkt->field);     \
@@ -236,8 +303,8 @@ 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);
 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);
+coap_status_t coap_parse_message(struct coap_packet_rx *request,
+                                 struct os_mbuf **mp);
 
 int coap_get_query_variable(coap_packet_t *, const char *name,
                             const char **output);
@@ -250,46 +317,47 @@ int coap_set_status_code(coap_packet_t *, unsigned int 
code);
 
 int coap_set_token(coap_packet_t *, const uint8_t *token, size_t token_len);
 
-int coap_get_header_content_format(coap_packet_t *, unsigned int *format);
+int coap_get_header_content_format(struct coap_packet_rx *,
+                                   unsigned int *format);
 int coap_set_header_content_format(coap_packet_t *, unsigned int format);
 
-int coap_get_header_accept(coap_packet_t *, unsigned int *accept);
+int coap_get_header_accept(struct coap_packet_rx *, unsigned int *accept);
 int coap_set_header_accept(coap_packet_t *, unsigned int accept);
 
-int coap_get_header_max_age(coap_packet_t *, uint32_t *age);
+int coap_get_header_max_age(struct coap_packet_rx *, uint32_t *age);
 int coap_set_header_max_age(coap_packet_t *, uint32_t age);
 
-int coap_get_header_etag(coap_packet_t *, const uint8_t **etag);
+int coap_get_header_etag(struct coap_packet_rx *, const uint8_t **etag);
 int coap_set_header_etag(coap_packet_t *, const uint8_t *etag, size_t 
etag_len);
 
-int coap_get_header_if_match(coap_packet_t *, const uint8_t **etag);
+int coap_get_header_if_match(struct coap_packet_rx *, const uint8_t **etag);
 int coap_set_header_if_match(coap_packet_t *, const uint8_t *etag,
                              size_t etag_len);
 
-int coap_get_header_if_none_match(coap_packet_t *);
+int coap_get_header_if_none_match(struct coap_packet_rx *);
 int coap_set_header_if_none_match(coap_packet_t *);
 
-int coap_get_header_proxy_uri(coap_packet_t *,
+int coap_get_header_proxy_uri(struct coap_packet_rx *,
   const char **uri); /* in-place string might not be 0-terminated. */
 int coap_set_header_proxy_uri(coap_packet_t *, const char *uri);
 
-int coap_get_header_proxy_scheme(coap_packet_t *,
+int coap_get_header_proxy_scheme(struct coap_packet_rx *,
   const char **scheme); /* in-place string might not be 0-terminated. */
 int coap_set_header_proxy_scheme(coap_packet_t *, const char *scheme);
 
-int coap_get_header_uri_host(coap_packet_t *,
+int coap_get_header_uri_host(struct coap_packet_rx *,
   const char **host); /* in-place string might not be 0-terminated. */
 int coap_set_header_uri_host(coap_packet_t *, const char *host);
 
-int coap_get_header_uri_path(coap_packet_t *,
-  const char **path); /* in-place string might not be 0-terminated. */
+int coap_get_header_uri_path(struct coap_packet_rx *, char *path, int maxlen);
+                              /* in-place string might not be 0-terminated. */
 int coap_set_header_uri_path(coap_packet_t *, const char *path);
 
-int coap_get_header_uri_query(coap_packet_t *,
-  const char **query); /* in-place string might not be 0-terminated. */
+int coap_get_header_uri_query(struct coap_packet_rx *, char *qry, int maxlen);
+                              /* in-place string might not be 0-terminated. */
 int coap_set_header_uri_query(coap_packet_t *, const char *query);
 
-int coap_get_header_location_path(coap_packet_t *,
+int coap_get_header_location_path(struct coap_packet_rx *,
   const char **path); /* in-place string might not be 0-terminated. */
 int coap_set_header_location_path(coap_packet_t *,
                                   const char *path); /* also splits optional
@@ -297,30 +365,33 @@ int coap_set_header_location_path(coap_packet_t *,
                                                         Location-Query option.
                                                         */
 
-int coap_get_header_location_query(coap_packet_t *,
+int coap_get_header_location_query(struct coap_packet_rx *,
   const char **query); /* in-place string might not be 0-terminated. */
 int coap_set_header_location_query(coap_packet_t *, const char *query);
 
-int coap_get_header_observe(coap_packet_t *, uint32_t *observe);
+int coap_get_header_observe(struct coap_packet_rx *, uint32_t *observe);
 int coap_set_header_observe(coap_packet_t *, uint32_t observe);
 
-int coap_get_header_block2(coap_packet_t *, uint32_t *num, uint8_t *more,
-                           uint16_t *size, uint32_t *offset);
+int coap_get_header_block2(struct coap_packet_rx *, uint32_t *num,
+                           uint8_t *more, uint16_t *size, uint32_t *offset);
 int coap_set_header_block2(coap_packet_t *, uint32_t num, uint8_t more,
                            uint16_t size);
 
-int coap_get_header_block1(coap_packet_t *, uint32_t *num, uint8_t *more,
-                           uint16_t *size, uint32_t *offset);
+int coap_get_header_block1(struct coap_packet_rx *, uint32_t *num,
+                           uint8_t *more, uint16_t *size, uint32_t *offset);
 int coap_set_header_block1(coap_packet_t *, uint32_t num, uint8_t more,
                            uint16_t size);
 
-int coap_get_header_size2(coap_packet_t *, uint32_t *size);
+int coap_get_header_size2(struct coap_packet_rx *, uint32_t *size);
 int coap_set_header_size2(coap_packet_t *, uint32_t size);
 
-int coap_get_header_size1(coap_packet_t *, uint32_t *size);
+int coap_get_header_size1(struct coap_packet_rx *, uint32_t *size);
 int coap_set_header_size1(coap_packet_t *, uint32_t size);
 
-int coap_get_payload(coap_packet_t *, const uint8_t **payload);
+int coap_get_payload_copy(struct coap_packet_rx *, uint8_t *payload,
+                          int maxlen);
+int coap_get_payload(struct coap_packet_rx *pkt, struct os_mbuf **mp,
+                     uint16_t *off);
 int coap_set_payload(coap_packet_t *, struct os_mbuf *m, size_t length);
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/src/messaging/coap/constants.h
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/constants.h 
b/net/oic/src/messaging/coap/constants.h
index 8620a6d..6279a17 100644
--- a/net/oic/src/messaging/coap/constants.h
+++ b/net/oic/src/messaging/coap/constants.h
@@ -49,6 +49,8 @@ extern "C" {
   4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
 #define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
 #define COAP_ETAG_LEN 8  /* The maximum number of bytes for the ETag */
+#define COAP_MAX_URI         32 /* The max number of bytes for URI */
+#define COAP_MAX_URI_QUERY   32 /* The max number of bytes for URI-query */
 
 /*
  * Standard COAP header

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/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 13abeb1..456e292 100644
--- a/net/oic/src/messaging/coap/engine.c
+++ b/net/oic/src/messaging/coap/engine.c
@@ -48,25 +48,28 @@
 /*- Internal API ------------------------------------------------------------*/
 /*---------------------------------------------------------------------------*/
 int
-coap_receive(oc_message_t *msg)
+coap_receive(struct os_mbuf **mp)
 {
     /* 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];
+    struct os_mbuf *m;
+    static struct coap_packet_rx message[1];
+    static struct coap_packet response[1];
     static coap_transaction_t *transaction = NULL;
     struct os_mbuf *rsp;
+    oc_endpoint_t endpoint; /* XXX */
 
     erbium_status_code = NO_ERROR;
 
-    OC_LOG_INFO("CoAP: received datalen=%u\n", (unsigned int) msg->length);
+    OC_LOG_INFO("CoAP: received datalen=%u\n", OS_MBUF_PKTLEN(*mp));
 
-    erbium_status_code = coap_parse_message(message, msg->data, msg->length,
-                                           
oc_endpoint_use_tcp(&msg->endpoint));
+    memcpy(&endpoint, OC_MBUF_ENDPOINT(*mp), sizeof(endpoint)); /* XXXXX */
+    erbium_status_code = coap_parse_message(message, mp);
     if (erbium_status_code != NO_ERROR) {
         goto out;
     }
 
+    m = *mp;
 /*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],
@@ -108,7 +111,7 @@ coap_receive(oc_message_t *msg)
         OC_LOG_DEBUG("  Payload: %d bytes\n", message->payload_len);
 
         /* use transaction buffer for response to confirmable request */
-        transaction = coap_new_transaction(message->mid, &msg->endpoint);
+        transaction = coap_new_transaction(message->mid, OC_MBUF_ENDPOINT(m));
         if (!transaction) {
             erbium_status_code = SERVICE_UNAVAILABLE_5_03;
             coap_error_message = "NoFreeTraBuffer";
@@ -144,8 +147,8 @@ coap_receive(oc_message_t *msg)
             new_offset = block_offset;
         }
 
-        if (oc_ri_invoke_coap_entity_handler(message, response,
-                                             &new_offset, &msg->endpoint)) {
+        if (oc_ri_invoke_coap_entity_handler(message, response, &new_offset,
+                                             OC_MBUF_ENDPOINT(m))) {
             if (erbium_status_code == NO_ERROR) {
                 /*
                  * TODO coap_handle_blockwise(request, response,
@@ -233,7 +236,7 @@ coap_receive(oc_message_t *msg)
         } else if (message->type == COAP_TYPE_RST) {
 #ifdef OC_SERVER
             /* cancel possible subscriptions */
-            coap_remove_observer_by_mid(&msg->endpoint, message->mid);
+            coap_remove_observer_by_mid(OC_MBUF_ENDPOINT(m), message->mid);
 #endif
         }
 
@@ -249,7 +252,7 @@ coap_receive(oc_message_t *msg)
          * ACKs and RSTs sent to oc_ri.. RSTs cleared, ACKs sent to
          * client.
          */
-        oc_ri_invoke_client_cb(message, &msg->endpoint);
+        oc_ri_invoke_client_cb(message, OC_MBUF_ENDPOINT(m));
 #endif
 
     } /* request or response */
@@ -267,13 +270,13 @@ out:
   }
 #ifdef OC_CLIENT
     else if (erbium_status_code == EMPTY_ACK_RESPONSE) {
-        coap_init_message(message, COAP_TYPE_ACK, 0, message->mid);
-        struct os_mbuf *response = oc_allocate_mbuf(&msg->endpoint);
-        if (response) {
-            if (!coap_serialize_message(message, response)) {
-                coap_send_message(response, 0);
+        coap_init_message(response, COAP_TYPE_ACK, 0, message->mid);
+        struct os_mbuf *m_rsp = oc_allocate_mbuf(&endpoint);
+        if (m_rsp) {
+            if (!coap_serialize_message(response, m_rsp)) {
+                coap_send_message(m_rsp, 0);
             } else {
-                os_mbuf_free_chain(response);
+                os_mbuf_free_chain(m_rsp);
             }
         }
     }
@@ -284,15 +287,15 @@ out:
 
         coap_clear_transaction(transaction);
 
-        coap_init_message(message, reply_type, SERVICE_UNAVAILABLE_5_03,
+        coap_init_message(response, reply_type, SERVICE_UNAVAILABLE_5_03,
                           message->mid);
 
-        struct os_mbuf *response = oc_allocate_mbuf(&msg->endpoint);
-        if (response) {
-            if (!coap_serialize_message(message, response)) {
-                coap_send_message(response, 0);
+        struct os_mbuf *m_rsp = oc_allocate_mbuf(&endpoint);
+        if (m_rsp) {
+            if (!coap_serialize_message(response, m_rsp)) {
+                coap_send_message(m_rsp, 0);
             } else {
-                os_mbuf_free_chain(response);
+                os_mbuf_free_chain(m_rsp);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/src/messaging/coap/engine.h
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/engine.h 
b/net/oic/src/messaging/coap/engine.h
index a30793f..5e4888e 100644
--- a/net/oic/src/messaging/coap/engine.h
+++ b/net/oic/src/messaging/coap/engine.h
@@ -44,7 +44,7 @@ extern "C" {
 #endif
 
 void coap_engine_init(void);
-int coap_receive(oc_message_t *message);
+int coap_receive(struct os_mbuf **mp);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/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 7bc8537..df79262 100644
--- a/net/oic/src/messaging/coap/observe.c
+++ b/net/oic/src/messaging/coap/observe.c
@@ -238,14 +238,16 @@ coap_notify_observers(oc_resource_t *resource,
         num_observers = obs->resource->num_observers;
         if (response.separate_response != NULL &&
           response_buf->code == oc_status_code(OC_STATUS_OK)) {
-            coap_packet_t req[1];
-            /*
-              req->block1_num = 0;
-              req->block1_size = 0;
-              req->block2_num = 0;
-              req->block2_size = 0;
-            */
-            coap_init_message(req, COAP_TYPE_NON, CONTENT_2_05, 0);
+            struct coap_packet_rx req[1];
+
+            req->block1_num = 0;
+            req->block1_size = 0;
+            req->block2_num = 0;
+            req->block2_size = 0;
+
+            req->type = COAP_TYPE_NON;
+            req->code = CONTENT_2_05;
+            req->mid = 0;
             memcpy(req->token, obs->token, obs->token_len);
             req->token_len = obs->token_len;
             OC_LOG_DEBUG("Resource is SLOW; creating separate response\n");
@@ -302,7 +304,7 @@ coap_notify_observers(oc_resource_t *resource,
 }
 /*---------------------------------------------------------------------------*/
 int
-coap_observe_handler(coap_packet_t *coap_req, coap_packet_t *coap_res,
+coap_observe_handler(struct coap_packet_rx *coap_req, coap_packet_t *coap_res,
                      oc_resource_t *resource, oc_endpoint_t *endpoint)
 {
     int dup = -1;
@@ -311,14 +313,16 @@ coap_observe_handler(coap_packet_t *coap_req, 
coap_packet_t *coap_res,
       coap_res->code < 128) { /* GET request and response without error code */
         if (IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) {
             if (coap_req->observe == 0) {
-                dup =
-                  add_observer(resource, endpoint, coap_req->token,
-                    coap_req->token_len, coap_req->uri_path,
-                    coap_req->uri_path_len);
+                char uri[COAP_MAX_URI];
+                int uri_len;
+
+                uri_len = coap_get_header_uri_path(coap_req, uri, sizeof(uri));
+                dup = add_observer(resource, endpoint, coap_req->token,
+                                   coap_req->token_len, uri, uri_len);
             } else if (coap_req->observe == 1) {
                 /* remove client if it is currently observe */
                 dup = coap_remove_observer_by_token(endpoint, coap_req->token,
-                  coap_req->token_len);
+                                                    coap_req->token_len);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/src/messaging/coap/observe.h
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/observe.h 
b/net/oic/src/messaging/coap/observe.h
index df58cc2..d342cac 100644
--- a/net/oic/src/messaging/coap/observe.h
+++ b/net/oic/src/messaging/coap/observe.h
@@ -74,7 +74,7 @@ int coap_notify_observers(oc_resource_t *resource,
                           oc_endpoint_t *endpoint);
 // int coap_notify_observers_sub(oc_resource_t *resource, const char *subpath);
 
-int coap_observe_handler(coap_packet_t *request, coap_packet_t *response,
+int coap_observe_handler(struct coap_packet_rx *req, coap_packet_t *response,
                          oc_resource_t *resource, oc_endpoint_t *endpoint);
 
 void coap_observe_init(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/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 650ed5b..fe77106 100644
--- a/net/oic/src/messaging/coap/separate.c
+++ b/net/oic/src/messaging/coap/separate.c
@@ -64,7 +64,7 @@ static uint8_t 
coap_separate_area[OS_MEMPOOL_BYTES(MAX_NUM_CONCURRENT_REQUESTS,
  * then retry later.
  */
 int
-coap_separate_accept(coap_packet_t *coap_req,
+coap_separate_accept(struct coap_packet_rx *coap_req,
                      oc_separate_response_t *separate_response,
                      oc_endpoint_t *endpoint, int observe)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5c307f69/net/oic/src/messaging/coap/separate.h
----------------------------------------------------------------------
diff --git a/net/oic/src/messaging/coap/separate.h 
b/net/oic/src/messaging/coap/separate.h
index 71ee3be..190e4ec 100644
--- a/net/oic/src/messaging/coap/separate.h
+++ b/net/oic/src/messaging/coap/separate.h
@@ -64,7 +64,7 @@ typedef struct coap_separate {
 } coap_separate_t;
 
 typedef struct coap_packet coap_packet_t;
-int coap_separate_accept(coap_packet_t *request,
+int coap_separate_accept(struct coap_packet_rx *request,
                          oc_separate_response_t *separate_response,
                          oc_endpoint_t *endpoint, int observe);
 void coap_separate_resume(coap_packet_t *response,

Reply via email to