Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: wakaama/er-coap-13/er-coap-13.c
- Revision:
- 2:5a8853c481ad
- Parent:
- 0:f9d13e09cf11
- Child:
- 10:df97539c6ddd
--- a/wakaama/er-coap-13/er-coap-13.c Fri Apr 28 08:16:22 2017 +0000 +++ b/wakaama/er-coap-13/er-coap-13.c Fri Apr 28 09:53:26 2017 +0000 @@ -48,7 +48,7 @@ #include "liblwm2m.h" /* for lwm2m_malloc() and lwm2m_free() */ -#define DEBUG 0 +#define DEBUG 1 #if DEBUG #include <stdio.h> #define PRINTF(...) printf(__VA_ARGS__) @@ -66,7 +66,7 @@ static uint16_t current_mid = 0; coap_status_t coap_error_code = NO_ERROR; -char *coap_error_message = ""; +const char *coap_error_message = ""; /*-----------------------------------------------------------------------------------*/ /*- LOCAL HELP FUNCTIONS ------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/ @@ -88,7 +88,7 @@ coap_parse_int_option(uint8_t *bytes, size_t length) { uint32_t var = 0; - int i = 0; + size_t i = 0; while (i<length) { var <<= 8; @@ -120,11 +120,11 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer) { size_t written = 0; + unsigned int *x = δ buffer[0] = coap_option_nibble(delta)<<4 | coap_option_nibble(length); /* avoids code duplication without function overhead */ - unsigned int *x = δ do { if (*x>268) @@ -175,7 +175,7 @@ if (split_char!='\0') { - int j; + size_t j; uint8_t *part_start = array; uint8_t *part_end = NULL; size_t temp_length; @@ -231,7 +231,7 @@ /*-----------------------------------------------------------------------------------*/ static void -coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option, size_t option_len, char separator) +coap_merge_multi_option(uint8_t **dst, size_t *dst_len, uint8_t *option, size_t option_len, char separator) { /* Merge multiple options. */ if (*dst_len > 0) @@ -248,12 +248,11 @@ else { /* dst is empty: set to option */ - *dst = (char *) option; + *dst = option; *dst_len = option_len; } } -static void coap_add_multi_option(multi_option_t **dst, uint8_t *option, size_t option_len, uint8_t is_static) { @@ -262,7 +261,7 @@ if (opt) { opt->next = NULL; - opt->len = option_len; + opt->len = (uint8_t)option_len; if (is_static) { opt->data = option; @@ -271,7 +270,7 @@ else { opt->is_static = 0; - opt->data = (char *)lwm2m_malloc(option_len); + opt->data = (uint8_t *)lwm2m_malloc(option_len); if (opt->data == NULL) { lwm2m_free(opt); @@ -296,13 +295,13 @@ } } -static void free_multi_option(multi_option_t *dst) { if (dst) { multi_option_t *n = dst->next; + dst->next = NULL; if (dst->is_static == 0) { lwm2m_free(dst->data); @@ -345,11 +344,11 @@ /*-----------------------------------------------------------------------------------*/ static int -coap_get_variable(const char *buffer, size_t length, const char *name, const char **output) +coap_get_variable(const uint8_t *buffer, size_t length, const char *name, const char **output) { - const char *start = NULL; - const char *end = NULL; - const char *value_end = NULL; + const uint8_t *start = NULL; + const uint8_t *end = NULL; + const uint8_t *value_end = NULL; size_t name_len = 0; /*initialize the output buffer first*/ @@ -360,18 +359,18 @@ for (start = buffer; start + name_len < end; ++start){ if ((start == buffer || start[-1] == '&') && start[name_len] == '=' && - strncmp(name, start, name_len)==0) { + strncmp(name, (char *)start, name_len)==0) { /* Point start to variable value */ start += name_len + 1; /* Point end to the end of the value */ - value_end = (const char *) memchr(start, '&', end - start); + value_end = (const uint8_t *) memchr(start, '&', end - start); if (value_end == NULL) { value_end = end; } - *output = start; + *output = (char *)start; return (value_end - start); } @@ -410,6 +409,112 @@ free_multi_option(coap_pkt->uri_path); free_multi_option(coap_pkt->uri_query); free_multi_option(coap_pkt->location_path); + coap_pkt->uri_path = NULL; + coap_pkt->uri_query = NULL; + coap_pkt->location_path = NULL; +} + +/*-----------------------------------------------------------------------------------*/ +size_t coap_serialize_get_size(void *packet) +{ + coap_packet_t *const coap_pkt = (coap_packet_t *) packet; + size_t length = 0; + + length = COAP_HEADER_LEN + coap_pkt->payload_len + coap_pkt->token_len; + + if (IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) + { + length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->if_match_len; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) + { + length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->uri_host_len; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) + { + length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->etag_len; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_IF_NONE_MATCH)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_URI_PORT)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) + { + multi_option_t * optP; + + for (optP = coap_pkt->location_path ; optP != NULL ; optP = optP->next) + { + length += COAP_MAX_OPTION_HEADER_LEN + optP->len; + } + } + if (IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) + { + multi_option_t * optP; + + for (optP = coap_pkt->uri_path ; optP != NULL ; optP = optP->next) + { + length += COAP_MAX_OPTION_HEADER_LEN + optP->len; + } + } + if (IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) + { + multi_option_t * optP; + + for (optP = coap_pkt->uri_query ; optP != NULL ; optP = optP->next) + { + length += COAP_MAX_OPTION_HEADER_LEN + optP->len; + } + } + if (IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) + { + length += coap_pkt->accept_num * COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) + { + length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->location_query_len; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_SIZE)) + { + // can be stored in extended fields + length += COAP_MAX_OPTION_HEADER_LEN; + } + if (IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) + { + length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->proxy_uri_len; + } + + return length; } /*-----------------------------------------------------------------------------------*/ @@ -476,24 +581,14 @@ coap_free_header(packet); /* Pack payload */ - if ((option - coap_pkt->buffer)<=COAP_MAX_HEADER_SIZE) + /* Payload marker */ + if (coap_pkt->payload_len) { - /* Payload marker */ - if (coap_pkt->payload_len) - { - *option = 0xFF; - ++option; - } + *option = 0xFF; + ++option; + } - memmove(option, coap_pkt->payload, coap_pkt->payload_len); - } - else - { - /* An error occured. Caller must check for !=0. */ - coap_pkt->buffer = NULL; - coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE"; - return 0; - } + memmove(option, coap_pkt->payload, coap_pkt->payload_len); PRINTF("-Done %u B (header len %u, payload len %u)-\n", coap_pkt->payload_len + option - buffer, option - buffer, coap_pkt->payload_len); @@ -515,6 +610,11 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; + uint8_t *current_option; + unsigned int option_number = 0; + unsigned int option_delta = 0; + size_t option_length = 0; + unsigned int *x; /* Initialize packet */ memset(coap_pkt, 0, sizeof(coap_packet_t)); @@ -535,7 +635,7 @@ return BAD_REQUEST_4_00; } - uint8_t *current_option = data + COAP_HEADER_LEN; + current_option = data + COAP_HEADER_LEN; if (coap_pkt->token_len != 0) { @@ -557,10 +657,6 @@ /* parse options */ current_option += coap_pkt->token_len; - unsigned int option_number = 0; - unsigned int option_delta = 0; - size_t option_length = 0; - while (current_option < data+data_len) { /* Payload marker 0xFF, currently only checking for 0xF* because rest is reserved */ @@ -569,12 +665,6 @@ coap_pkt->payload = ++current_option; coap_pkt->payload_len = data_len - (coap_pkt->payload - data); - /* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */ - if (coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) - { - coap_pkt->payload_len = REST_MAX_CHUNK_SIZE; - } - break; } @@ -583,7 +673,7 @@ ++current_option; /* avoids code duplication without function overhead */ - unsigned int *x = &option_delta; + x = &option_delta; do { if (*x==13) @@ -604,7 +694,15 @@ option_number += option_delta; - PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, option_length); + if (current_option + option_length > data + data_len) + { + PRINTF("OPTION %u (delta %u, len %u) has invalid length.\n", option_number, option_delta, option_length); + return BAD_REQUEST_4_00; + } + else + { + PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, option_length); + } SET_OPTION(coap_pkt, option_number); @@ -619,7 +717,7 @@ PRINTF("Max-Age [%lu]\n", coap_pkt->max_age); break; case COAP_OPTION_ETAG: - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length); + coap_pkt->etag_len = (uint8_t)(MIN(COAP_ETAG_LEN, option_length)); memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len); PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len, coap_pkt->etag[0], @@ -642,7 +740,7 @@ break; case COAP_OPTION_IF_MATCH: /*FIXME support multiple ETags */ - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length); + coap_pkt->if_match_len = (uint8_t)(MIN(COAP_ETAG_LEN, option_length)); memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len); PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->if_match_len, coap_pkt->if_match[0], @@ -661,7 +759,7 @@ break; case COAP_OPTION_URI_HOST: - coap_pkt->uri_host = (char *) current_option; + coap_pkt->uri_host = current_option; coap_pkt->uri_host_len = option_length; PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host); break; @@ -673,13 +771,13 @@ /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ // coap_merge_multi_option( (char **) &(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_length, 0); coap_add_multi_option( &(coap_pkt->uri_path), current_option, option_length, 1); - PRINTF("Uri-Path [%.*s]\n", sizeof(multi_option_t), coap_pkt->uri_path); + PRINTF("Uri-Path [%.*s]\n", option_length, current_option); break; case COAP_OPTION_URI_QUERY: /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ // coap_merge_multi_option( (char **) &(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_length, '&'); coap_add_multi_option( &(coap_pkt->uri_query), current_option, option_length, 1); - PRINTF("Uri-Query [%.*s]\n", sizeof(multi_option_t), coap_pkt->uri_query); + PRINTF("Uri-Query [%.*s]\n", option_length, current_option); break; case COAP_OPTION_LOCATION_PATH: @@ -687,13 +785,13 @@ break; case COAP_OPTION_LOCATION_QUERY: /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ - coap_merge_multi_option( (char **) &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_length, '&'); - PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, coap_pkt->location_query); + coap_merge_multi_option( &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_length, '&'); + PRINTF("Location-Query [%.*s]\n", option_length, current_option); break; case COAP_OPTION_PROXY_URI: /*FIXME check for own end-point */ - coap_pkt->proxy_uri = (char *) current_option; + coap_pkt->proxy_uri = current_option; coap_pkt->proxy_uri_len = option_length; /*TODO length > 270 not implemented (actually not required) */ PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri); @@ -765,7 +863,7 @@ coap_packet_t *const coap_pkt = (coap_packet_t *) packet; if (coap_pkt->payload_len) { - return coap_get_variable((const char *)coap_pkt->payload, coap_pkt->payload_len, name, output); + return coap_get_variable(coap_pkt->payload, coap_pkt->payload_len, name, output); } return 0; } @@ -871,7 +969,7 @@ { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len); + coap_pkt->etag_len = (uint8_t)(MIN(COAP_ETAG_LEN, etag_len)); memcpy(coap_pkt->etag, etag, coap_pkt->etag_len); SET_OPTION(coap_pkt, COAP_OPTION_ETAG); @@ -895,7 +993,7 @@ { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len); + coap_pkt->if_match_len = (uint8_t)(MIN(COAP_ETAG_LEN, etag_len)); memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len); SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH); @@ -931,7 +1029,7 @@ { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len); + coap_pkt->token_len = (uint8_t)(MIN(COAP_TOKEN_LEN, token_len)); memcpy(coap_pkt->token, token, coap_pkt->token_len); SET_OPTION(coap_pkt, COAP_OPTION_TOKEN); @@ -945,7 +1043,7 @@ if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0; - *uri = coap_pkt->proxy_uri; + *uri = (const char *)coap_pkt->proxy_uri; return coap_pkt->proxy_uri_len; } @@ -954,7 +1052,7 @@ { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - coap_pkt->proxy_uri = uri; + coap_pkt->proxy_uri = (uint8_t *)uri; coap_pkt->proxy_uri_len = strlen(uri); SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI); @@ -968,7 +1066,7 @@ if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) return 0; - *host = coap_pkt->uri_host; + *host = (char *)coap_pkt->uri_host; return coap_pkt->uri_host_len; } @@ -977,7 +1075,7 @@ { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - coap_pkt->uri_host = host; + coap_pkt->uri_host = (uint8_t *)host; coap_pkt->uri_host_len = strlen(host); SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST); @@ -1126,18 +1224,18 @@ if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0; - *query = coap_pkt->location_query; + *query = (const char*)coap_pkt->location_query; return coap_pkt->location_query_len; } int -coap_set_header_location_query(void *packet, const char *query) +coap_set_header_location_query(void *packet, char *query) { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; while (query[0]=='?') ++query; - coap_pkt->location_query = query; + coap_pkt->location_query = (uint8_t *)query; coap_pkt->location_query_len = strlen(query); SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY); @@ -1273,10 +1371,8 @@ { coap_packet_t *const coap_pkt = (coap_packet_t *) packet; - //PRINTF("setting payload (%u/%u)\n", length, REST_MAX_CHUNK_SIZE); - coap_pkt->payload = (uint8_t *) payload; - coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length); + coap_pkt->payload_len = (uint16_t)(length); return coap_pkt->payload_len; }