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,