diff --git a/.github/workflows/cmake-linux.yml b/.github/workflows/cmake-linux.yml index 21247335f4..f238eff1ac 100644 --- a/.github/workflows/cmake-linux.yml +++ b/.github/workflows/cmake-linux.yml @@ -54,8 +54,8 @@ jobs: - args: "-DOC_IPV4_ENABLED=ON -DOC_TCP_ENABLED=ON -DOC_PKI_ENABLED=OFF" # cloud on (ipv4+tcp on), collections create on - args: "-DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON" - # cloud on (ipv4+tcp on), collections create on, custom message buffer size - - args: "-DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_INOUT_BUFFER_SIZE=1024" + # cloud on (ipv4+tcp on), collections create on, custom message buffer size, custom message buffer pool size, custom app data buffer size, custom app data buffer pool size + - args: "-DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_INOUT_BUFFER_SIZE=2048 -DOC_INOUT_BUFFER_POOL=4 -DOC_APP_DATA_BUFFER_SIZE=2048 -DOC_APP_DATA_BUFFER_POOL=4" # debug on - args: "-DOC_DEBUG_ENABLED=ON" # debug on, cloud on (ipv4+tcp on) diff --git a/api/oc_blockwise.c b/api/oc_blockwise.c index f9a0fad39c..fb3068d382 100644 --- a/api/oc_blockwise.c +++ b/api/oc_blockwise.c @@ -391,7 +391,7 @@ oc_blockwise_find_response_buffer(const char *href, size_t href_len, endpoint, method, query, query_len, role); } -const void * +void * oc_blockwise_dispatch_block(oc_blockwise_state_t *buffer, uint32_t block_offset, uint32_t requested_block_size, uint32_t *payload_size) @@ -404,7 +404,7 @@ oc_blockwise_dispatch_block(oc_blockwise_state_t *buffer, uint32_t block_offset, (uint32_t)(buffer->payload_size - block_offset)); } buffer->next_block_offset = block_offset + *payload_size; - return (const void *)&buffer->buffer[block_offset]; + return (void *)&buffer->buffer[block_offset]; } return NULL; } diff --git a/api/oc_client_api.c b/api/oc_client_api.c index 311a759feb..5e31d1a867 100644 --- a/api/oc_client_api.c +++ b/api/oc_client_api.c @@ -75,7 +75,7 @@ dispatch_coap_request(void) #else /* OC_TCP */ if ((long)payload_size > OC_BLOCK_SIZE) { #endif /* !OC_TCP */ - const void *payload = oc_blockwise_dispatch_block( + void *payload = oc_blockwise_dispatch_block( g_request_buffer, 0, (uint32_t)OC_BLOCK_SIZE, &block_size); if (payload) { coap_set_payload(g_request, payload, block_size); @@ -219,7 +219,8 @@ prepare_coap_request(oc_client_cb_t *cb) } if (oc_string_len(cb->query) > 0) { - coap_set_header_uri_query(g_request, oc_string(cb->query)); + coap_set_header_uri_query(g_request, oc_string(cb->query), + oc_string_len(cb->query)); } g_dispatch.client_cb = cb; @@ -314,7 +315,7 @@ oc_init_multicast_update(const char *uri, const char *query) coap_set_header_uri_path(g_request, uri, strlen(uri)); if (query) { - coap_set_header_uri_query(g_request, query); + coap_set_header_uri_query(g_request, query, strlen(query)); } return true; diff --git a/api/oc_server_api.c b/api/oc_server_api.c index f00e29bc49..876913e6bf 100644 --- a/api/oc_server_api.c +++ b/api/oc_server_api.c @@ -754,7 +754,7 @@ handle_separate_response_request(coap_separate_t *request, response_state->payload_size = (uint32_t)response_buffer->response_length; uint32_t payload_size = 0; - const void *payload = oc_blockwise_dispatch_block( + void *payload = oc_blockwise_dispatch_block( response_state, 0, request->block2_size, &payload_size); if (payload != NULL) { coap_set_payload(&response, payload, payload_size); diff --git a/apps/client_block_linux.c b/apps/client_block_linux.c index 151f9e594e..ae0482b8b6 100644 --- a/apps/client_block_linux.c +++ b/apps/client_block_linux.c @@ -63,7 +63,7 @@ stop_observe(void *data) if (oc_init_post(array_1, array_server, NULL, &post_array, LOW_QOS, NULL)) { for (int i = 0; i < 100; i++) { - large_array[i] = oc_random_value(); + large_array[i] = (int)oc_random_value(); OC_PRINTF("(%d %d) ", i, large_array[i]); } OC_PRINTF("\n"); diff --git a/apps/cloud_server.c b/apps/cloud_server.c index 64f0af0d53..d39b9e0bf7 100644 --- a/apps/cloud_server.c +++ b/apps/cloud_server.c @@ -891,7 +891,8 @@ simulate_tpm_mbedtls_pk_parse_key(size_t device, mbedtls_pk_context *pk, return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; } uint8_t identity_private_key[4096]; - int ret = fread(identity_private_key, 1, sizeof(identity_private_key), f); + size_t ret = + fread(identity_private_key, 1, sizeof(identity_private_key), f); fclose(f); return mbedtls_pk_parse_key(pk, identity_private_key, ret, NULL, 0, f_rng, p_rng); diff --git a/include/oc_blockwise.h b/include/oc_blockwise.h index ac7c66a2b9..a7d034d182 100644 --- a/include/oc_blockwise.h +++ b/include/oc_blockwise.h @@ -228,12 +228,12 @@ void oc_blockwise_free_response_buffer(oc_blockwise_state_t *buffer); * @param block_offset the block offset * @param requested_block_size blocksize to be send * @param payload_size the send payload size - * @return const void* + * @return void* */ -const void *oc_blockwise_dispatch_block(oc_blockwise_state_t *buffer, - uint32_t block_offset, - uint32_t requested_block_size, - uint32_t *payload_size); +void *oc_blockwise_dispatch_block(oc_blockwise_state_t *buffer, + uint32_t block_offset, + uint32_t requested_block_size, + uint32_t *payload_size); /** * @brief handle the incomming block (partial message) diff --git a/messaging/coap/coap.c b/messaging/coap/coap.c index 91552e50b1..8d0c302071 100644 --- a/messaging/coap/coap.c +++ b/messaging/coap/coap.c @@ -68,64 +68,77 @@ #include "security/oc_tls_internal.h" #endif /* OC_SECURITY */ +#include #include #include #include /* option format serialization */ #define COAP_SERIALIZE_INT_OPTION(packet, number, field, text) \ - if (IS_OPTION(packet, number)) { \ - option_length += coap_serialize_int_option(number, current_number, option, \ - (packet)->field); \ - if (option) { \ - OC_DBG(text " [%u]", (unsigned int)(packet)->field); \ - option = option_array + option_length; \ + do { \ + if (IS_OPTION(packet, number)) { \ + option_length += coap_serialize_int_option(number, current_number, \ + option, (packet)->field); \ + if (option) { \ + OC_DBG(text " [%u]", (unsigned int)(packet)->field); \ + option = option_array + option_length; \ + } \ + current_number = number; \ } \ - current_number = number; \ - } + } while (0) + #define COAP_SERIALIZE_BYTE_OPTION(packet, number, field, text) \ - if (IS_OPTION(packet, number)) { \ - option_length += coap_serialize_array_option(number, current_number, \ - option, (packet)->field, \ - (packet)->field##_len, '\0'); \ - if (option) { \ - OC_DBG(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]", \ - (unsigned int)(packet)->field##_len, (packet)->field[0], \ - (packet)->field[1], (packet)->field[2], (packet)->field[3], \ - (packet)->field[4], (packet)->field[5], (packet)->field[6], \ - (packet)->field[7]); /* FIXME always prints 8 bytes */ \ - option = option_array + option_length; \ + do { \ + if (IS_OPTION(packet, number)) { \ + option_length += coap_serialize_array_option( \ + number, current_number, option, (packet)->field, \ + (packet)->field##_len, '\0'); \ + if (option) { \ + OC_DBG(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]", \ + (unsigned int)(packet)->field##_len, (packet)->field[0], \ + (packet)->field[1], (packet)->field[2], (packet)->field[3], \ + (packet)->field[4], (packet)->field[5], (packet)->field[6], \ + (packet)->field[7]); /* FIXME always prints 8 bytes */ \ + option = option_array + option_length; \ + } \ + current_number = number; \ } \ - current_number = number; \ - } + } while (0) + #define COAP_SERIALIZE_STRING_OPTION(packet, number, field, splitter, text) \ - if (IS_OPTION(packet, number)) { \ - option_length += coap_serialize_array_option( \ - number, current_number, option, (uint8_t *)(packet)->field, \ - (packet)->field##_len, splitter); \ - if (option) { \ - OC_DBG(text " [%.*s]", (int)(packet)->field##_len, (packet)->field); \ - option = option_array + option_length; \ + do { \ + if (IS_OPTION(packet, number)) { \ + option_length += coap_serialize_array_option( \ + number, current_number, option, (uint8_t *)(packet)->field, \ + (packet)->field##_len, splitter); \ + if (option) { \ + OC_DBG(text " [%.*s]", (int)(packet)->field##_len, (packet)->field); \ + option = option_array + option_length; \ + } \ + current_number = number; \ } \ - current_number = number; \ - } + } while (0) + #define COAP_SERIALIZE_BLOCK_OPTION(packet, number, field, text) \ - if (IS_OPTION(packet, number)) { \ - uint32_t block = (packet)->field##_num << 4; \ - if ((packet)->field##_more) { \ - block |= 0x8; \ + do { \ + if (IS_OPTION(packet, number)) { \ + uint32_t block = (packet)->field##_num << 4; \ + if ((packet)->field##_more) { \ + block |= 0x8; \ + } \ + block |= 0xF & coap_log_2((packet)->field##_size / 16); \ + option_length += \ + coap_serialize_int_option(number, current_number, option, block); \ + if (option) { \ + OC_DBG(text " [%lu%s (%u B/blk)]", \ + (unsigned long)(packet)->field##_num, \ + (packet)->field##_more ? "+" : "", (packet)->field##_size); \ + OC_DBG(text " encoded: 0x%lX", (unsigned long)block); \ + option = option_array + option_length; \ + } \ + current_number = number; \ } \ - block |= 0xF & coap_log_2((packet)->field##_size / 16); \ - option_length += \ - coap_serialize_int_option(number, current_number, option, block); \ - if (option) { \ - OC_DBG(text " [%lu%s (%u B/blk)]", (unsigned long)(packet)->field##_num, \ - (packet)->field##_more ? "+" : "", (packet)->field##_size); \ - OC_DBG(text " encoded: 0x%lX", (unsigned long)block); \ - option = option_array + option_length; \ - } \ - current_number = number; \ - } + } while (0) /*---------------------------------------------------------------------------*/ /*- Variables ---------------------------------------------------------------*/ @@ -402,7 +415,8 @@ coap_get_variable(const char *buffer, size_t length, const char *name, #ifdef OC_TCP static size_t -coap_serialize_signal_options(coap_packet_t *packet, uint8_t *option_array) +coap_serialize_signal_options(const coap_packet_t *packet, + uint8_t *option_array) { uint8_t *option = option_array; unsigned int current_number = 0; @@ -448,6 +462,42 @@ coap_serialize_signal_options(coap_packet_t *packet, uint8_t *option_array) } #endif /* OC_TCP */ +static size_t +coap_serialize_accept_option(uint16_t accept, unsigned int current_number, + uint8_t *buffer) +{ + if (accept == APPLICATION_VND_OCF_CBOR) { + return coap_serialize_int_option(OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER, + current_number, buffer, OCF_VER_1_0_0); + } +#ifdef OC_SPEC_VER_OIC + if (accept == APPLICATION_CBOR) { + return coap_serialize_int_option(OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER, + current_number, buffer, OIC_VER_1_1_0); + } +#endif /* OC_SPEC_VER_OIC */ + return 0; +} + +static size_t +coap_serialize_content_format_option(uint16_t content_format, + unsigned int current_number, + uint8_t *buffer) + +{ + if (content_format == APPLICATION_VND_OCF_CBOR) { + return coap_serialize_int_option(OCF_OPTION_CONTENT_FORMAT_VER, + current_number, buffer, OCF_VER_1_0_0); + } +#ifdef OC_SPEC_VER_OIC + if (content_format == APPLICATION_CBOR) { + return coap_serialize_int_option(OCF_OPTION_CONTENT_FORMAT_VER, + current_number, buffer, OIC_VER_1_1_0); + } +#endif /* OC_SPEC_VER_OIC */ + return 0; +} + /* It just caculates size of option when option_array is NULL */ static size_t coap_serialize_options(coap_packet_t *packet, uint8_t *option_array, bool inner, @@ -459,7 +509,7 @@ coap_serialize_options(coap_packet_t *packet, uint8_t *option_array, bool inner, size_t option_length = 0; #if OC_DBG_IS_ENABLED - if (option) { + if (option != NULL) { OC_DBG("Serializing options at %p", (void *)option); } else { OC_DBG("Calculating size of options"); @@ -542,51 +592,23 @@ coap_serialize_options(coap_packet_t *packet, uint8_t *option_array, bool inner, #endif if (inner) { COAP_SERIALIZE_INT_OPTION(packet, COAP_OPTION_SIZE1, size1, "Size1"); - } - - if (inner && IS_OPTION(packet, COAP_OPTION_ACCEPT)) { - if (packet->accept == APPLICATION_VND_OCF_CBOR) { - - option_length += - coap_serialize_int_option(OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER, - current_number, option, OCF_VER_1_0_0); - if (option) { - option = option_array + option_length; - } - } -#ifdef OC_SPEC_VER_OIC - else if (packet->accept == APPLICATION_CBOR) { + if (IS_OPTION(packet, COAP_OPTION_ACCEPT)) { option_length += - coap_serialize_int_option(OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER, - current_number, option, OIC_VER_1_1_0); - if (option) { - option = option_array + option_length; - } - } -#endif /* OC_SPEC_VER_OIC */ - - current_number = OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER; - } - if (inner && IS_OPTION(packet, COAP_OPTION_CONTENT_FORMAT)) { - if (packet->content_format == APPLICATION_VND_OCF_CBOR) { - - option_length += coap_serialize_int_option( - OCF_OPTION_CONTENT_FORMAT_VER, current_number, option, OCF_VER_1_0_0); + coap_serialize_accept_option(packet->accept, current_number, option); if (option) { option = option_array + option_length; } + current_number = OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER; } -#ifdef OC_SPEC_VER_OIC - else if (packet->content_format == APPLICATION_CBOR) { - option_length += coap_serialize_int_option( - OCF_OPTION_CONTENT_FORMAT_VER, current_number, option, OIC_VER_1_1_0); + if (IS_OPTION(packet, COAP_OPTION_CONTENT_FORMAT)) { + option_length += coap_serialize_content_format_option( + packet->content_format, current_number, option); if (option) { option = option_array + option_length; } } -#endif /* OC_SPEC_VER_OIC */ } if (option) { @@ -650,6 +672,159 @@ coap_parse_signal_options(coap_packet_t *packet, unsigned int option_number, } #endif /* OC_TCP */ +static coap_status_t +coap_oscore_parse_inner_option(coap_packet_t *packet, + unsigned int option_number, uint8_t *option, + size_t option_length, bool validate) +{ + switch (option_number) { + case COAP_OPTION_CONTENT_FORMAT: { + uint16_t content_format = + (uint16_t)coap_parse_int_option(option, option_length); + OC_DBG(" Content-Format [%u]", content_format); + if (content_format != APPLICATION_VND_OCF_CBOR +#ifdef OC_SPEC_VER_OIC + && content_format != APPLICATION_CBOR +#endif /* OC_SPEC_VER_OIC */ + ) { + return UNSUPPORTED_MEDIA_TYPE_4_15; + } + packet->content_format = content_format; + return COAP_NO_ERROR; + } + case COAP_OPTION_ETAG: + packet->etag_len = (uint8_t)MIN(COAP_ETAG_LEN, option_length); + memcpy(packet->etag, option, packet->etag_len); + OC_DBG(" ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]", packet->etag_len, + packet->etag[0], packet->etag[1], packet->etag[2], packet->etag[3], + packet->etag[4], packet->etag[5], packet->etag[6], + packet->etag[7]); /*FIXME always prints 8 bytes */ + return COAP_NO_ERROR; + case COAP_OPTION_ACCEPT: { + uint16_t accept = (uint16_t)coap_parse_int_option(option, option_length); + OC_DBG(" Accept [%u]", accept); + if (accept != APPLICATION_VND_OCF_CBOR +#ifdef OC_SPEC_VER_OIC + && accept != APPLICATION_CBOR +#endif /* OC_SPEC_VER_OIC */ +#ifdef OC_WKCORE + && accept != APPLICATION_LINK_FORMAT +#endif /* OC_SPEC_VER_OIC */ +#ifdef OC_CBOR + && accept != APPLICATION_CBOR +#endif /* OC_SPEC_VER_OIC */ + ) { + return NOT_ACCEPTABLE_4_06; + } + packet->accept = accept; + return COAP_NO_ERROR; + } + case COAP_OPTION_URI_PATH: + if (validate) { + return COAP_NO_ERROR; + } + /* 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 **)&(packet->uri_path), + &(packet->uri_path_len), option, option_length, + '/'); + OC_DBG(" Uri-Path [%.*s]", (int)packet->uri_path_len, packet->uri_path); + return COAP_NO_ERROR; + case COAP_OPTION_URI_QUERY: + if (validate) { + return COAP_NO_ERROR; + } + /* 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 **)&(packet->uri_query), + &(packet->uri_query_len), option, option_length, + '&'); + OC_DBG(" Uri-Query [%.*s]", (int)packet->uri_query_len, packet->uri_query); + return COAP_NO_ERROR; + case COAP_OPTION_BLOCK2: + packet->block2_num = coap_parse_int_option(option, option_length); + packet->block2_more = (packet->block2_num & 0x08) >> 3; + packet->block2_size = (uint16_t)(16 << (packet->block2_num & 0x07)); + packet->block2_offset = (packet->block2_num & ~0x0000000F) + << (packet->block2_num & 0x07); + packet->block2_num >>= 4; + OC_DBG(" Block2 [%lu%s (%u B/blk)]", (unsigned long)packet->block2_num, + packet->block2_more ? "+" : "", packet->block2_size); + return COAP_NO_ERROR; + case COAP_OPTION_BLOCK1: + packet->block1_num = coap_parse_int_option(option, option_length); + packet->block1_more = (packet->block1_num & 0x08) >> 3; + packet->block1_size = (uint16_t)(16 << (packet->block1_num & 0x07)); + packet->block1_offset = (packet->block1_num & ~0x0000000F) + << (packet->block1_num & 0x07); + packet->block1_num >>= 4; + OC_DBG(" Block1 [%lu%s (%u B/blk)]", (unsigned long)packet->block1_num, + packet->block1_more ? "+" : "", packet->block1_size); + return COAP_NO_ERROR; + case COAP_OPTION_SIZE2: + packet->size2 = coap_parse_int_option(option, option_length); + OC_DBG(" Size2 [%lu]", (unsigned long)packet->size2); + return COAP_NO_ERROR; + case COAP_OPTION_SIZE1: + packet->size1 = coap_parse_int_option(option, option_length); + OC_DBG(" Size1 [%lu]", (unsigned long)packet->size1); + return COAP_NO_ERROR; + case OCF_OPTION_CONTENT_FORMAT_VER: + case OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER: { + uint16_t version = (uint16_t)coap_parse_int_option(option, option_length); + OC_DBG(" Content-format/accept-Version: [%u]", version); + if (version < OCF_VER_1_0_0 +#ifdef OC_SPEC_VER_OIC + && version != OIC_VER_1_1_0 +#endif /* OC_SPEC_VER_OIC */ + ) { + OC_WRN("Unsupported version %d %u", option_number, version); + return UNSUPPORTED_MEDIA_TYPE_4_15; + } + return COAP_NO_ERROR; + } +#if 0 + case COAP_OPTION_IF_MATCH: + /* TODO support multiple ETags */ + packet->if_match_len = MIN(COAP_ETAG_LEN, option_length); + memcpy(packet->if_match, option, packet->if_match_len); + OC_DBG("If-Match %u", packet->if_match_len); + OC_LOGbytes(packet->if_match, packet->if_match_len); + return COAP_NO_ERROR; + case COAP_OPTION_IF_NONE_MATCH: + packet->if_none_match = 1; + OC_DBG("If-None-Match"); + return COAP_NO_ERROR; + case COAP_OPTION_LOCATION_PATH: + if (validate) { + return COAP_NO_ERROR; + } + /* 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 **)&(packet->location_path), + &(packet->location_path_len), option, option_length, + '/'); + OC_DBG("Location-Path [%.*s]", (int)packet->location_path_len, + packet->location_path); + return COAP_NO_ERROR; + case COAP_OPTION_LOCATION_QUERY: + if (validate) { + return COAP_NO_ERROR; + } + /* 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 **)&(packet->location_query), + &(packet->location_query_len), option, + option_length, '&'); + OC_DBG("Location-Query [%.*s]", (int)packet->location_query_len, + packet->location_query); + return COAP_NO_ERROR; +#endif + } + + return BAD_OPTION_4_02; +} + static coap_status_t coap_oscore_parse_option(coap_packet_t *packet, uint8_t *current_option, bool inner, bool outer, bool oscore, bool validate, @@ -661,103 +836,67 @@ coap_oscore_parse_option(coap_packet_t *packet, uint8_t *current_option, if (coap_check_signal_message(packet)) { return coap_parse_signal_options(packet, option_number, current_option, option_length, inner); - } else + } #endif /* OC_TCP */ - { - switch (option_number) { + + switch (option_number) { #if defined(OC_OSCORE) && defined(OC_SECURITY) - case COAP_OPTION_OSCORE: - if (!outer || !oscore) { - return BAD_OPTION_4_02; - } - if (coap_parse_oscore_option(packet, current_option, option_length) != - 0) { - return BAD_OPTION_4_02; - } - break; + case COAP_OPTION_OSCORE: + if (!outer || !oscore) { + return BAD_OPTION_4_02; + } + if (coap_parse_oscore_option(packet, current_option, option_length) != 0) { + return BAD_OPTION_4_02; + } + break; #endif /* OC_OSCORE && OC_SECURITY */ - case COAP_OPTION_CONTENT_FORMAT: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->content_format = - (uint16_t)coap_parse_int_option(current_option, option_length); - OC_DBG(" Content-Format [%u]", packet->content_format); - if (packet->content_format != APPLICATION_VND_OCF_CBOR -#ifdef OC_SPEC_VER_OIC - && packet->content_format != APPLICATION_CBOR -#endif /* OC_SPEC_VER_OIC */ - ) - return UNSUPPORTED_MEDIA_TYPE_4_15; - break; - case COAP_OPTION_MAX_AGE: - packet->max_age = coap_parse_int_option(current_option, option_length); - OC_DBG(" Max-Age [%lu]", (unsigned long)packet->max_age); - break; - case COAP_OPTION_ETAG: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->etag_len = (uint8_t)MIN(COAP_ETAG_LEN, option_length); - memcpy(packet->etag, current_option, packet->etag_len); - OC_DBG(" ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]", packet->etag_len, - packet->etag[0], packet->etag[1], packet->etag[2], packet->etag[3], - packet->etag[4], packet->etag[5], packet->etag[6], - packet->etag[7]); /*FIXME always prints 8 bytes */ - break; - case COAP_OPTION_ACCEPT: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->accept = - (uint16_t)coap_parse_int_option(current_option, option_length); - OC_DBG(" Accept [%u]", packet->accept); - if (packet->accept != APPLICATION_VND_OCF_CBOR -#ifdef OC_SPEC_VER_OIC - && packet->accept != APPLICATION_CBOR -#endif /* OC_SPEC_VER_OIC */ -#ifdef OC_WKCORE - && packet->accept != APPLICATION_LINK_FORMAT -#endif /* OC_SPEC_VER_OIC */ -#ifdef OC_CBOR - && packet->accept != APPLICATION_CBOR -#endif /* OC_SPEC_VER_OIC */ - ) - return NOT_ACCEPTABLE_4_06; - break; - case COAP_OPTION_PROXY_URI: - if (!outer) { - return BAD_OPTION_4_02; - } - if (validate) { - break; - } - /* 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 **)&(packet->proxy_uri), - &(packet->proxy_uri_len), current_option, - option_length, '\0'); - OC_DBG("Proxy-Uri [%.*s]", (int)packet->proxy_uri_len, packet->proxy_uri); - break; + case COAP_OPTION_CONTENT_FORMAT: + case COAP_OPTION_ETAG: + case COAP_OPTION_ACCEPT: + case COAP_OPTION_URI_PATH: + case COAP_OPTION_URI_QUERY: + case COAP_OPTION_BLOCK2: + case COAP_OPTION_BLOCK1: + case COAP_OPTION_SIZE2: + case COAP_OPTION_SIZE1: + case OCF_OPTION_CONTENT_FORMAT_VER: + case OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER: #if 0 - case COAP_OPTION_IF_MATCH: - if (!inner) { - return BAD_OPTION_4_02; - } - /* TODO support multiple ETags */ - packet->if_match_len = MIN(COAP_ETAG_LEN, option_length); - memcpy(packet->if_match, current_option, - packet->if_match_len); - OC_DBG("If-Match %u", packet->if_match_len); - OC_LOGbytes(packet->if_match, packet->if_match_len); - break; - case COAP_OPTION_IF_NONE_MATCH: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->if_none_match = 1; - OC_DBG("If-None-Match"); + case COAP_OPTION_IF_MATCH: + case COAP_OPTION_IF_NONE_MATCH: + case COAP_OPTION_LOCATION_PATH: + case COAP_OPTION_LOCATION_QUERY: +#endif + { + if (!inner) { + return BAD_OPTION_4_02; + } + coap_status_t ret = coap_oscore_parse_inner_option( + packet, option_number, current_option, option_length, validate); + if (ret != COAP_NO_ERROR) { + return ret; + } + break; + } + case COAP_OPTION_MAX_AGE: + packet->max_age = coap_parse_int_option(current_option, option_length); + OC_DBG(" Max-Age [%lu]", (unsigned long)packet->max_age); + break; + case COAP_OPTION_PROXY_URI: + if (!outer) { + return BAD_OPTION_4_02; + } + if (validate) { break; + } + /* 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 **)&(packet->proxy_uri), + &(packet->proxy_uri_len), current_option, + option_length, '\0'); + OC_DBG("Proxy-Uri [%.*s]", (int)packet->proxy_uri_len, packet->proxy_uri); + break; +#if 0 case COAP_OPTION_PROXY_SCHEME: if (!outer) { return BAD_OPTION_4_02; @@ -771,148 +910,33 @@ coap_oscore_parse_option(coap_packet_t *packet, uint8_t *current_option, return PROXYING_NOT_SUPPORTED_5_05; break; #endif - case COAP_OPTION_URI_HOST: - if (!outer) { - return BAD_OPTION_4_02; - } - packet->uri_host = (char *)current_option; - packet->uri_host_len = option_length; - OC_DBG("Uri-Host [%.*s]", (int)packet->uri_host_len, packet->uri_host); - break; - case COAP_OPTION_URI_PORT: - if (!outer) { - return BAD_OPTION_4_02; - } - packet->uri_port = - (uint16_t)coap_parse_int_option(current_option, option_length); - OC_DBG(" Uri-Port [%u]", packet->uri_port); - break; - case COAP_OPTION_URI_PATH: - if (!inner) { - return BAD_OPTION_4_02; - } - if (validate) { - break; - } - /* 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 **)&(packet->uri_path), - &(packet->uri_path_len), current_option, - option_length, '/'); - OC_DBG(" Uri-Path [%.*s]", (int)packet->uri_path_len, packet->uri_path); - break; - case COAP_OPTION_URI_QUERY: - if (!inner) { - return BAD_OPTION_4_02; - } - if (validate) { - break; - } - /* 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 **)&(packet->uri_query), - &(packet->uri_query_len), current_option, - option_length, '&'); - OC_DBG(" Uri-Query [%.*s]", (int)packet->uri_query_len, - packet->uri_query); - break; -#if 0 - case COAP_OPTION_LOCATION_PATH: - if (!inner) { - return BAD_OPTION_4_02; - } - /* 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 **)&(packet->location_path), - &(packet->location_path_len), - current_option, option_length, - '/'); - OC_DBG("Location-Path [%.*s]", (int)packet->location_path_len, - packet->location_path); - break; - case COAP_OPTION_LOCATION_QUERY: - if (!inner) { - return BAD_OPTION_4_02; - } - /* 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 **)&(packet->location_query), - &(packet->location_query_len), - current_option, option_length, - '&'); - OC_DBG("Location-Query [%.*s]", (int)packet->location_query_len, - packet->location_query); - break; -#endif - case COAP_OPTION_OBSERVE: - packet->observe = - (int32_t)coap_parse_int_option(current_option, option_length); - OC_DBG(" Observe [%lu]", (unsigned long)packet->observe); - break; - case COAP_OPTION_BLOCK2: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->block2_num = coap_parse_int_option(current_option, option_length); - packet->block2_more = (packet->block2_num & 0x08) >> 3; - packet->block2_size = 16 << (packet->block2_num & 0x07); - packet->block2_offset = (packet->block2_num & ~0x0000000F) - << (packet->block2_num & 0x07); - packet->block2_num >>= 4; - OC_DBG(" Block2 [%lu%s (%u B/blk)]", (unsigned long)packet->block2_num, - packet->block2_more ? "+" : "", packet->block2_size); - break; - case COAP_OPTION_BLOCK1: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->block1_num = coap_parse_int_option(current_option, option_length); - packet->block1_more = (packet->block1_num & 0x08) >> 3; - packet->block1_size = 16 << (packet->block1_num & 0x07); - packet->block1_offset = (packet->block1_num & ~0x0000000F) - << (packet->block1_num & 0x07); - packet->block1_num >>= 4; - OC_DBG(" Block1 [%lu%s (%u B/blk)]", (unsigned long)packet->block1_num, - packet->block1_more ? "+" : "", packet->block1_size); - break; - case COAP_OPTION_SIZE2: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->size2 = coap_parse_int_option(current_option, option_length); - OC_DBG(" Size2 [%lu]", (unsigned long)packet->size2); - break; - case COAP_OPTION_SIZE1: - if (!inner) { - return BAD_OPTION_4_02; - } - packet->size1 = coap_parse_int_option(current_option, option_length); - OC_DBG(" Size1 [%lu]", (unsigned long)packet->size1); - break; - case OCF_OPTION_CONTENT_FORMAT_VER: - case OCF_OPTION_ACCEPT_CONTENT_FORMAT_VER: { - if (!inner) { - return BAD_OPTION_4_02; - } - uint16_t version = - (uint16_t)coap_parse_int_option(current_option, option_length); - OC_DBG(" Content-format/accept-Version: [%u]", version); - if (version < OCF_VER_1_0_0 -#ifdef OC_SPEC_VER_OIC - && version != OIC_VER_1_1_0 -#endif /* OC_SPEC_VER_OIC */ - ) { - OC_WRN("Unsupported version %d %u", option_number, version); - return UNSUPPORTED_MEDIA_TYPE_4_15; - } - } break; - default: - OC_DBG(" unknown (%u)", option_number); - /* check if critical (odd) */ - if (option_number & 1) { - OC_WRN("Unsupported critical option"); - return BAD_OPTION_4_02; - } + case COAP_OPTION_URI_HOST: + if (!outer) { + return BAD_OPTION_4_02; + } + packet->uri_host = (char *)current_option; + packet->uri_host_len = option_length; + OC_DBG("Uri-Host [%.*s]", (int)packet->uri_host_len, packet->uri_host); + break; + case COAP_OPTION_URI_PORT: + if (!outer) { + return BAD_OPTION_4_02; + } + packet->uri_port = + (uint16_t)coap_parse_int_option(current_option, option_length); + OC_DBG(" Uri-Port [%u]", packet->uri_port); + break; + case COAP_OPTION_OBSERVE: + packet->observe = + (int32_t)coap_parse_int_option(current_option, option_length); + OC_DBG(" Observe [%lu]", (unsigned long)packet->observe); + break; + default: + OC_DBG(" unknown (%u)", option_number); + /* check if critical (odd) */ + if ((option_number & 1) != 0) { + OC_WRN("Unsupported critical option"); + return BAD_OPTION_4_02; } } return COAP_NO_ERROR; @@ -941,7 +965,8 @@ coap_oscore_parse_options(coap_packet_t *packet, const uint8_t *data, /* payload marker 0xFF, currently only checking for 0xF* because rest is * reserved */ if ((current_option[0] & 0xF0) == 0xF0) { - packet->payload = ++current_option; + ++current_option; + packet->payload = current_option; packet->payload_len = (uint32_t)(data_len - (packet->payload - data)); if (packet->transport_type == COAP_TRANSPORT_UDP && @@ -1026,19 +1051,20 @@ coap_tcp_set_header_fields(coap_packet_t *packet, { packet->buffer[0] = 0x00; packet->buffer[0] |= - COAP_TCP_HEADER_LEN_MASK & (len) << COAP_TCP_HEADER_LEN_POSITION; + COAP_TCP_HEADER_LEN_MASK & len << COAP_TCP_HEADER_LEN_POSITION; packet->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK & (packet->token_len) << COAP_HEADER_TOKEN_LEN_POSITION; for (int i = 1; i <= num_extended_length_bytes; i++) { packet->buffer[i] = - (uint8_t)((extended_len) >> (8 * (num_extended_length_bytes - i))); + (uint8_t)(extended_len >> (8 * (num_extended_length_bytes - i))); } packet->buffer[1 + num_extended_length_bytes] = packet->code; } static void -coap_tcp_compute_message_length(coap_packet_t *packet, size_t option_length, +coap_tcp_compute_message_length(const coap_packet_t *packet, + size_t option_length, uint8_t *num_extended_length_bytes, uint8_t *len, size_t *extended_len) { @@ -1268,13 +1294,8 @@ coap_oscore_serialize_message(coap_packet_t *packet, uint8_t *buffer, OC_DBG("Token (len %u)", packet->token_len); OC_LOGbytes(packet->token, packet->token_len); option = packet->buffer + token_location; - for (uint8_t current_number = 0; current_number < packet->token_len; - ++current_number) { - *option = packet->token[current_number]; - ++option; - } - // memcpy(option, packet->token, packet->token_len); - // option += packet->token_len; + memcpy(option, packet->token, packet->token_len); + option += packet->token_len; } else { OC_DBG("Inner CoAP code: %d", packet->code); ++header_length_calculation; @@ -1371,7 +1392,7 @@ coap_udp_parse_message(coap_packet_t *packet, uint8_t *data, size_t data_len, packet->token_len = (COAP_HEADER_TOKEN_LEN_MASK & packet->buffer[0]) >> COAP_HEADER_TOKEN_LEN_POSITION; packet->code = packet->buffer[1]; - packet->mid = packet->buffer[2] << 8 | packet->buffer[3]; + packet->mid = (uint16_t)(packet->buffer[2] << 8 | packet->buffer[3]); if (packet->version != 1) { OC_WRN("CoAP version must be 1"); @@ -1527,7 +1548,8 @@ int coap_set_header_content_format(coap_packet_t *packet, oc_content_format_t format) { - packet->content_format = format; + assert(format > 0 && format <= UINT16_MAX); + packet->content_format = (uint16_t)format; SET_OPTION(packet, COAP_OPTION_CONTENT_FORMAT); return 1; } @@ -1600,10 +1622,11 @@ coap_get_header_proxy_uri(const coap_packet_t *packet, const char **uri) } size_t -coap_set_header_proxy_uri(coap_packet_t *packet, const char *uri) +coap_set_header_proxy_uri(coap_packet_t *packet, const char *uri, + size_t uri_len) { packet->proxy_uri = uri; - packet->proxy_uri_len = strlen(uri); + packet->proxy_uri_len = uri_len; SET_OPTION(packet, COAP_OPTION_PROXY_URI); return packet->proxy_uri_len; @@ -1705,14 +1728,15 @@ coap_get_header_uri_query(const coap_packet_t *packet, const char **query) #ifdef OC_CLIENT size_t -coap_set_header_uri_query(coap_packet_t *packet, const char *query) +coap_set_header_uri_query(coap_packet_t *packet, const char *query, + size_t query_len) { while (query[0] == '?') { ++query; } packet->uri_query = query; - packet->uri_query_len = strlen(query); + packet->uri_query_len = query_len; SET_OPTION(packet, COAP_OPTION_URI_QUERY); return packet->uri_query_len; @@ -1941,9 +1965,9 @@ coap_get_payload(const coap_packet_t *packet, const uint8_t **payload) } uint32_t -coap_set_payload(coap_packet_t *packet, const void *payload, uint32_t length) +coap_set_payload(coap_packet_t *packet, uint8_t *payload, uint32_t length) { - packet->payload = (uint8_t *)payload; + packet->payload = payload; #ifdef OC_TCP if (packet->transport_type == COAP_TRANSPORT_TCP) { packet->payload_len = length; diff --git a/messaging/coap/coap.h b/messaging/coap/coap.h index c2b79ff5ce..14818c8252 100644 --- a/messaging/coap/coap.h +++ b/messaging/coap/coap.h @@ -89,8 +89,8 @@ typedef enum { /* parsed message struct */ typedef struct { - uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory - to serialize packet */ + uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / + memory to serialize packet */ coap_transport_type_t transport_type; uint8_t version; coap_message_type_t type; @@ -260,8 +260,8 @@ int coap_set_header_etag(coap_packet_t *packet, const uint8_t *etag, size_t coap_get_header_proxy_uri(const coap_packet_t *packet, const char **uri) OC_NONNULL(); /* in-place string might not be 0-terminated. */ -size_t coap_set_header_proxy_uri(coap_packet_t *packet, const char *uri) - OC_NONNULL(); +size_t coap_set_header_proxy_uri(coap_packet_t *packet, const char *uri, + size_t uri_len) OC_NONNULL(); size_t coap_get_header_uri_path(const coap_packet_t *packet, const char **path) OC_NONNULL(); /* in-place string might not be 0-terminated. */ @@ -271,8 +271,8 @@ size_t coap_set_header_uri_path(coap_packet_t *packet, const char *path, size_t coap_get_header_uri_query(const coap_packet_t *packet, const char **query) OC_NONNULL(); /* in-place string might not be 0-terminated. */ -size_t coap_set_header_uri_query(coap_packet_t *packet, const char *query) - OC_NONNULL(); +size_t coap_set_header_uri_query(coap_packet_t *packet, const char *query, + size_t query_len) OC_NONNULL(); int coap_get_header_observe(const coap_packet_t *packet, int32_t *observe) OC_NONNULL(); @@ -301,7 +301,7 @@ int coap_set_header_size1(coap_packet_t *packet, uint32_t size) OC_NONNULL(); uint32_t coap_get_payload(const coap_packet_t *packet, const uint8_t **payload) OC_NONNULL(); -uint32_t coap_set_payload(coap_packet_t *packet, const void *payload, +uint32_t coap_set_payload(coap_packet_t *packet, uint8_t *payload, uint32_t length) OC_NONNULL(); size_t coap_set_option_header(unsigned int delta, size_t length, diff --git a/messaging/coap/engine.c b/messaging/coap/engine.c index ae2708c044..57e79c484f 100644 --- a/messaging/coap/engine.c +++ b/messaging/coap/engine.c @@ -407,7 +407,7 @@ coap_receive(oc_message_t *msg) if (response_buffer) { OC_DBG("continuing ongoing block-wise transfer"); uint32_t payload_size = 0; - const void *payload = oc_blockwise_dispatch_block( + void *payload = oc_blockwise_dispatch_block( response_buffer, block2_offset, block2_size, &payload_size); if (payload) { OC_DBG("dispatching next block"); @@ -574,7 +574,7 @@ coap_receive(oc_message_t *msg) uint32_t payload_size = 0; #ifdef OC_TCP if (msg->endpoint.flags & TCP) { - const void *payload = oc_blockwise_dispatch_block( + void *payload = oc_blockwise_dispatch_block( response_buffer, 0, response_buffer->payload_size + 1, &payload_size); if (payload && response_buffer->payload_size > 0) { @@ -583,7 +583,7 @@ coap_receive(oc_message_t *msg) response_buffer->ref_count = 0; } else { #endif /* OC_TCP */ - const void *payload = oc_blockwise_dispatch_block( + void *payload = oc_blockwise_dispatch_block( response_buffer, 0, block2_size, &payload_size); if (payload) { coap_set_payload(response, payload, payload_size); @@ -666,7 +666,7 @@ coap_receive(oc_message_t *msg) oc_string(request_buffer->href)); client_cb = (oc_client_cb_t *)request_buffer->client_cb; uint32_t payload_size = 0; - const void *payload = 0; + void *payload = NULL; if (block1) { payload = oc_blockwise_dispatch_block(request_buffer, @@ -706,7 +706,8 @@ coap_receive(oc_message_t *msg) coap_set_header_size1(response, request_buffer->payload_size); } if (oc_string_len(client_cb->query) > 0) { - coap_set_header_uri_query(response, oc_string(client_cb->query)); + coap_set_header_uri_query(response, oc_string(client_cb->query), + oc_string_len(client_cb->query)); } coap_set_header_accept(response, APPLICATION_VND_OCF_CBOR); coap_set_header_content_format(response, APPLICATION_VND_OCF_CBOR); @@ -777,8 +778,8 @@ coap_receive(oc_message_t *msg) coap_set_header_uri_path(response, oc_string(client_cb->uri), oc_string_len(client_cb->uri)); if (oc_string_len(client_cb->query) > 0) { - coap_set_header_uri_query(response, - oc_string(client_cb->query)); + coap_set_header_uri_query(response, oc_string(client_cb->query), + oc_string_len(client_cb->query)); } goto send_message; } diff --git a/messaging/coap/observe.c b/messaging/coap/observe.c index 759753dd2d..900e602856 100644 --- a/messaging/coap/observe.c +++ b/messaging/coap/observe.c @@ -537,7 +537,7 @@ send_notification(coap_observer_t *obs, oc_response_t *response, response_state->payload_size = response->response_buffer->response_length; uint32_t payload_size = 0; - const void *payload = oc_blockwise_dispatch_block( + void *payload = oc_blockwise_dispatch_block( response_state, 0, obs->block2_size, &payload_size); if (payload) { coap_set_payload(notification, payload, payload_size); diff --git a/security/oc_obt.c b/security/oc_obt.c index 45559cdbde..acb945ceac 100644 --- a/security/oc_obt.c +++ b/security/oc_obt.c @@ -465,9 +465,8 @@ get_endpoints(oc_client_response_t *data) if (data->code >= OC_STATUS_BAD_REQUEST) { return; } - oc_rep_t *links = data->payload; - oc_uuid_t di; + oc_rep_t *links = data->payload; oc_rep_t *link = links != NULL ? links->value.object : NULL; while (link != NULL) { switch (link->type) { @@ -485,7 +484,7 @@ get_endpoints(oc_client_response_t *data) } const oc_uuid_t *my_uuid = oc_core_get_device_id(0); - if (memcmp(my_uuid->id, di.id, 16) == 0) { + if (memcmp(my_uuid->id, di.id, sizeof(di.id)) == 0) { return; } @@ -509,9 +508,11 @@ get_endpoints(oc_client_response_t *data) oc_free_server_endpoints(device->endpoint); device->endpoint = NULL; - oc_endpoint_t *eps_cur = NULL; + if (links == NULL) { + return; + } link = links->value.object; - oc_endpoint_t temp_ep; + oc_endpoint_t *eps_cur = NULL; while (link != NULL) { switch (link->type) { case OC_REP_OBJECT_ARRAY: { @@ -523,6 +524,7 @@ get_endpoints(oc_client_response_t *data) case OC_REP_STRING: { if (oc_string_len(ep->name) == 2 && memcmp(oc_string(ep->name), "ep", 2) == 0) { + oc_endpoint_t temp_ep; if (oc_string_to_endpoint(&ep->value.string, &temp_ep, NULL) == 0) { if (((data->endpoint->flags & IPV4) && diff --git a/security/oc_oscore_engine.c b/security/oc_oscore_engine.c index d0b84dec43..534a98acbf 100644 --- a/security/oc_oscore_engine.c +++ b/security/oc_oscore_engine.c @@ -791,7 +791,8 @@ oc_oscore_send_message(oc_message_t *msg) oc_uuid_to_str(&message->endpoint.di, uuid, OC_UUID_LEN); oc_string_t proxy_uri; oc_concat_strings(&proxy_uri, "ocf://", uuid); - coap_set_header_proxy_uri(coap_pkt, oc_string(proxy_uri)); + coap_set_header_proxy_uri(coap_pkt, oc_string(proxy_uri), + oc_string_len(proxy_uri)); /* Serialize OSCORE message to oc_message_t */ OC_DBG("### serializing OSCORE message ###");