From 50117e46299ec74bb6e378328d52de43b26af7eb Mon Sep 17 00:00:00 2001 From: Daniel Adam Date: Thu, 3 Aug 2023 19:40:28 +0200 Subject: [PATCH] fixup! api: refactor coap_receive --- api/oc_buffer.c | 2 + api/oc_ri.c | 3 + messaging/coap/coap_signal.c | 253 ++++---- messaging/coap/coap_signal.h | 40 +- messaging/coap/engine.c | 634 +++++++++++---------- messaging/coap/engine.h | 12 +- messaging/coap/observe.c | 2 +- messaging/coap/unittest/coapsignaltest.cpp | 101 +--- 8 files changed, 522 insertions(+), 525 deletions(-) diff --git a/api/oc_buffer.c b/api/oc_buffer.c index 408c88c353..cdc3d86344 100644 --- a/api/oc_buffer.c +++ b/api/oc_buffer.c @@ -22,6 +22,7 @@ #include "oc_config.h" #include "oc_events_internal.h" #include "oc_signal_event_loop.h" +#include "port/oc_log_internal.h" #include "port/oc_network_event_handler_internal.h" #include "util/oc_features.h" #include "util/oc_macros_internal.h" @@ -34,6 +35,7 @@ #include "security/oc_tls_internal.h" #endif /* OC_SECURITY */ +#include #include #include #ifdef OC_DYNAMIC_ALLOCATION diff --git a/api/oc_ri.c b/api/oc_ri.c index 0cf6da0807..32bb864d20 100644 --- a/api/oc_ri.c +++ b/api/oc_ri.c @@ -25,6 +25,7 @@ #include "messaging/coap/constants.h" #include "messaging/coap/engine.h" #include "messaging/coap/oc_coap.h" +#include "messaging/coap/transactions.h" #include "oc_api.h" #include "oc_buffer.h" #include "oc_core_res.h" @@ -51,6 +52,8 @@ #ifdef OC_SERVER #include "api/oc_ri_server_internal.h" #include "api/oc_server_api_internal.h" +#include "messaging/coap/observe.h" +#include "messaging/coap/separate.h" #ifdef OC_COLLECTIONS #include "api/oc_collection_internal.h" #include "api/oc_link_internal.h" diff --git a/messaging/coap/coap_signal.c b/messaging/coap/coap_signal.c index 2f2e4833f3..10f8f88e81 100644 --- a/messaging/coap/coap_signal.c +++ b/messaging/coap/coap_signal.c @@ -116,26 +116,26 @@ coap_send_ping_message(const oc_endpoint_t *endpoint, uint8_t custody_option, } int -coap_send_pong_message(const oc_endpoint_t *endpoint, void *packet) +coap_send_pong_message(const oc_endpoint_t *endpoint, + const coap_packet_t *packet) { if (!endpoint || !packet) return 0; - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - coap_packet_t pong_pkt[1]; - coap_tcp_init_message(pong_pkt, PONG_7_03); + coap_packet_t pong_pkt; + coap_tcp_init_message(&pong_pkt, PONG_7_03); - coap_set_token(pong_pkt, coap_pkt->token, coap_pkt->token_len); + coap_set_token(&pong_pkt, packet->token, packet->token_len); - if (coap_pkt->custody) { - if (!coap_signal_set_custody(pong_pkt, coap_pkt->custody)) { + if (packet->custody) { + if (!coap_signal_set_custody(&pong_pkt, packet->custody)) { OC_ERR("coap_signal_set_custody failed"); return 0; } } OC_DBG("send pong signal message."); - return coap_send_signal_message(endpoint, pong_pkt); + return coap_send_signal_message(endpoint, &pong_pkt); } int @@ -198,28 +198,24 @@ coap_send_abort_message(const oc_endpoint_t *endpoint, uint16_t opt, return coap_send_signal_message(endpoint, abort_pkt); } -int -coap_check_signal_message(void *packet) +bool +coap_check_signal_message(const coap_packet_t *packet) { - if (!packet) - return 0; - - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - if (coap_pkt->code == CSM_7_01 || coap_pkt->code == PING_7_02 || - coap_pkt->code == PONG_7_03 || coap_pkt->code == RELEASE_7_04 || - coap_pkt->code == ABORT_7_05) - return 1; + if (!packet) { + return false; + } - return 0; + return packet->code == CSM_7_01 || packet->code == PING_7_02 || + packet->code == PONG_7_03 || packet->code == RELEASE_7_04 || + packet->code == ABORT_7_05; } int -handle_coap_signal_message(void *packet, const oc_endpoint_t *endpoint) +handle_coap_signal_message(const coap_packet_t *packet, + const oc_endpoint_t *endpoint) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - OC_DBG("Coap signal message received.(code: %d)", coap_pkt->code); - if (coap_pkt->code == CSM_7_01) { + OC_DBG("Coap signal message received.(code: %d)", packet->code); + if (packet->code == CSM_7_01) { tcp_csm_state_t state = oc_tcp_get_csm_state(endpoint); if (state == CSM_DONE) { // TODO: max-message-size, blockwise_transfer handling @@ -228,182 +224,161 @@ handle_coap_signal_message(void *packet, const oc_endpoint_t *endpoint) coap_send_csm_message(endpoint, OC_PDU_SIZE, 0); } oc_tcp_update_csm_state(endpoint, CSM_DONE); - } else if (coap_pkt->code == PING_7_02) { + } else if (packet->code == PING_7_02) { coap_send_pong_message(endpoint, packet); - } else if (coap_pkt->code == PONG_7_03) { + } else if (packet->code == PONG_7_03) { OC_DBG("Find client cb using token :"); - OC_DBG(" [%02X%02X%02X%02X%02X%02X%02X%02X]", coap_pkt->token[0], - coap_pkt->token[1], coap_pkt->token[2], coap_pkt->token[3], - coap_pkt->token[4], coap_pkt->token[5], coap_pkt->token[6], - coap_pkt->token[7]); - } else if (coap_pkt->code == RELEASE_7_04) { + OC_DBG(" [%02X%02X%02X%02X%02X%02X%02X%02X]", packet->token[0], + packet->token[1], packet->token[2], packet->token[3], + packet->token[4], packet->token[5], packet->token[6], + packet->token[7]); + } else if (packet->code == RELEASE_7_04) { // alternative address // hold off oc_connectivity_end_session(endpoint); - } else if (coap_pkt->code == ABORT_7_05) { - OC_WRN("Peer aborted! [code: %d(diagnostic: %*.s)]", coap_pkt->bad_csm_opt, - (int)coap_pkt->payload_len, (char *)coap_pkt->payload); + } else if (packet->code == ABORT_7_05) { + OC_WRN("Peer aborted! [code: %d(diagnostic: %*.s)]", packet->bad_csm_opt, + (int)packet->payload_len, (char *)packet->payload); } return COAP_NO_ERROR; } -int -coap_signal_get_max_msg_size(void *packet, uint32_t *size) +bool +coap_signal_get_max_msg_size(const coap_packet_t *packet, uint32_t *size) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != CSM_7_01 || - !IS_OPTION(coap_pkt, COAP_SIGNAL_OPTION_MAX_MSG_SIZE)) { - return 0; + if (packet->code != CSM_7_01 || + !IS_OPTION(packet, COAP_SIGNAL_OPTION_MAX_MSG_SIZE)) { + return false; } - *size = coap_pkt->max_msg_size; - return 1; + *size = packet->max_msg_size; + return true; } -int -coap_signal_set_max_msg_size(void *packet, uint32_t size) +bool +coap_signal_set_max_msg_size(coap_packet_t *packet, uint32_t size) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != CSM_7_01) { - return 0; + if (packet->code != CSM_7_01) { + return false; } - coap_pkt->max_msg_size = size; - SET_OPTION(coap_pkt, COAP_SIGNAL_OPTION_MAX_MSG_SIZE); - return 1; + packet->max_msg_size = size; + SET_OPTION(packet, COAP_SIGNAL_OPTION_MAX_MSG_SIZE); + return true; } -int -coap_signal_get_blockwise_transfer(void *packet, uint8_t *blockwise_transfer) +bool +coap_signal_get_blockwise_transfer(const coap_packet_t *packet, + uint8_t *blockwise_transfer) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != CSM_7_01 || - !IS_OPTION(coap_pkt, COAP_SIGNAL_OPTION_BLOCKWISE_TRANSFER)) { - return 0; + if (packet->code != CSM_7_01 || + !IS_OPTION(packet, COAP_SIGNAL_OPTION_BLOCKWISE_TRANSFER)) { + return false; } - *blockwise_transfer = coap_pkt->blockwise_transfer; - return 1; + *blockwise_transfer = packet->blockwise_transfer; + return true; } -int -coap_signal_set_blockwise_transfer(void *packet, uint8_t blockwise_transfer) +bool +coap_signal_set_blockwise_transfer(coap_packet_t *packet, + uint8_t blockwise_transfer) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != CSM_7_01 || + if (packet->code != CSM_7_01 || (blockwise_transfer != 0 && blockwise_transfer != 1)) { - return 0; + return false; } - coap_pkt->blockwise_transfer = blockwise_transfer; - SET_OPTION(coap_pkt, COAP_SIGNAL_OPTION_BLOCKWISE_TRANSFER); - return 1; + packet->blockwise_transfer = blockwise_transfer; + SET_OPTION(packet, COAP_SIGNAL_OPTION_BLOCKWISE_TRANSFER); + return true; } -int -coap_signal_get_custody(void *packet, uint8_t *custody) +bool +coap_signal_get_custody(const coap_packet_t *packet, uint8_t *custody) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if ((coap_pkt->code != PING_7_02 && coap_pkt->code != PONG_7_03) || - !IS_OPTION(coap_pkt, COAP_SIGNAL_OPTION_CUSTODY)) { - return 0; + if ((packet->code != PING_7_02 && packet->code != PONG_7_03) || + !IS_OPTION(packet, COAP_SIGNAL_OPTION_CUSTODY)) { + return false; } - *custody = coap_pkt->custody; - return 1; + *custody = packet->custody; + return true; } -int -coap_signal_set_custody(void *packet, uint8_t custody) +bool +coap_signal_set_custody(coap_packet_t *packet, uint8_t custody) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if ((coap_pkt->code != PING_7_02 && coap_pkt->code != PONG_7_03) || + if ((packet->code != PING_7_02 && packet->code != PONG_7_03) || (custody != 0 && custody != 1)) { - return 0; + return false; } - coap_pkt->custody = custody; - SET_OPTION(coap_pkt, COAP_SIGNAL_OPTION_CUSTODY); - return 1; + packet->custody = custody; + SET_OPTION(packet, COAP_SIGNAL_OPTION_CUSTODY); + return true; } size_t -coap_signal_get_alt_addr(void *packet, const char **addr) +coap_signal_get_alt_addr(const coap_packet_t *packet, const char **addr) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != RELEASE_7_04 || - !IS_OPTION(coap_pkt, COAP_SIGNAL_OPTION_ALT_ADDR)) { + if (packet->code != RELEASE_7_04 || + !IS_OPTION(packet, COAP_SIGNAL_OPTION_ALT_ADDR)) { return 0; } - *addr = coap_pkt->alt_addr; - return coap_pkt->alt_addr_len; + *addr = packet->alt_addr; + return packet->alt_addr_len; } size_t -coap_signal_set_alt_addr(void *packet, const char *addr, size_t addr_len) +coap_signal_set_alt_addr(coap_packet_t *packet, const char *addr, + size_t addr_len) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != RELEASE_7_04 || !addr || addr_len <= 0) { + if (packet->code != RELEASE_7_04 || !addr || addr_len <= 0) { return 0; } - coap_pkt->alt_addr = addr; - coap_pkt->alt_addr_len = addr_len; - SET_OPTION(coap_pkt, COAP_SIGNAL_OPTION_ALT_ADDR); - return coap_pkt->alt_addr_len; + packet->alt_addr = addr; + packet->alt_addr_len = addr_len; + SET_OPTION(packet, COAP_SIGNAL_OPTION_ALT_ADDR); + return packet->alt_addr_len; } -int -coap_signal_get_hold_off(void *packet, uint32_t *time_seconds) +bool +coap_signal_get_hold_off(const coap_packet_t *packet, uint32_t *time_seconds) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != RELEASE_7_04 || - !IS_OPTION(coap_pkt, COAP_SIGNAL_OPTION_HOLD_OFF)) { - return 0; + if (packet->code != RELEASE_7_04 || + !IS_OPTION(packet, COAP_SIGNAL_OPTION_HOLD_OFF)) { + return false; } - *time_seconds = coap_pkt->hold_off; - return 1; + *time_seconds = packet->hold_off; + return true; } -int -coap_signal_set_hold_off(void *packet, uint32_t time_seconds) +bool +coap_signal_set_hold_off(coap_packet_t *packet, uint32_t time_seconds) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != RELEASE_7_04) { - return 0; + if (packet->code != RELEASE_7_04) { + return false; } - coap_pkt->hold_off = time_seconds; - SET_OPTION(coap_pkt, COAP_SIGNAL_OPTION_HOLD_OFF); - return 1; + packet->hold_off = time_seconds; + SET_OPTION(packet, COAP_SIGNAL_OPTION_HOLD_OFF); + return true; } -int -coap_signal_get_bad_csm(void *packet, uint16_t *opt) +bool +coap_signal_get_bad_csm(const coap_packet_t *packet, uint16_t *opt) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != ABORT_7_05 || - !IS_OPTION(coap_pkt, COAP_SIGNAL_OPTION_BAD_CSM)) { - return 0; + if (packet->code != ABORT_7_05 || + !IS_OPTION(packet, COAP_SIGNAL_OPTION_BAD_CSM)) { + return false; } - *opt = coap_pkt->bad_csm_opt; - return 1; + *opt = packet->bad_csm_opt; + return true; } -int -coap_signal_set_bad_csm(void *packet, uint16_t opt) +bool +coap_signal_set_bad_csm(coap_packet_t *packet, uint16_t opt) { - coap_packet_t *const coap_pkt = (coap_packet_t *)packet; - - if (coap_pkt->code != ABORT_7_05) { - return 0; + if (packet->code != ABORT_7_05) { + return false; } - coap_pkt->bad_csm_opt = opt; - SET_OPTION(coap_pkt, COAP_SIGNAL_OPTION_BAD_CSM); - return 1; + packet->bad_csm_opt = opt; + SET_OPTION(packet, COAP_SIGNAL_OPTION_BAD_CSM); + return true; } #endif /* OC_TCP */ diff --git a/messaging/coap/coap_signal.h b/messaging/coap/coap_signal.h index dee226a333..c51d72fbc7 100644 --- a/messaging/coap/coap_signal.h +++ b/messaging/coap/coap_signal.h @@ -20,6 +20,8 @@ #define COAP_SIGNAL_H #include "oc_endpoint.h" +#include "messaging/coap/coap.h" +#include #ifdef __cplusplus extern "C" { @@ -52,30 +54,34 @@ int coap_send_csm_message(const oc_endpoint_t *endpoint, int coap_send_ping_message(const oc_endpoint_t *endpoint, uint8_t custody_option, const uint8_t *token, uint8_t token_len); -int coap_send_pong_message(const oc_endpoint_t *endpoint, void *packet); +int coap_send_pong_message(const oc_endpoint_t *endpoint, + const coap_packet_t *packet); int coap_send_release_message(const oc_endpoint_t *endpoint, const char *alt_addr, size_t alt_addr_len, uint32_t hold_off); int coap_send_abort_message(const oc_endpoint_t *endpoint, uint16_t opt, const char *diagnostic, size_t diagnostic_len); -int coap_check_signal_message(void *packet); -int handle_coap_signal_message(void *packet, const oc_endpoint_t *endpoint); +bool coap_check_signal_message(const coap_packet_t *packet); +int handle_coap_signal_message(const coap_packet_t *packet, + const oc_endpoint_t *endpoint); -int coap_signal_get_max_msg_size(void *packet, uint32_t *size); -int coap_signal_set_max_msg_size(void *packet, uint32_t size); -int coap_signal_get_blockwise_transfer(void *packet, - uint8_t *blockwise_transfer); -int coap_signal_set_blockwise_transfer(void *packet, - uint8_t blockwise_transfer); -int coap_signal_get_custody(void *packet, uint8_t *custody); -int coap_signal_set_custody(void *packet, uint8_t custody); -size_t coap_signal_get_alt_addr(void *packet, const char **addr); -size_t coap_signal_set_alt_addr(void *packet, const char *addr, +bool coap_signal_get_max_msg_size(const coap_packet_t *packet, uint32_t *size); +bool coap_signal_set_max_msg_size(coap_packet_t *packet, uint32_t size); +bool coap_signal_get_blockwise_transfer(const coap_packet_t *packet, + uint8_t *blockwise_transfer); +bool coap_signal_set_blockwise_transfer(coap_packet_t *packet, + uint8_t blockwise_transfer); +bool coap_signal_get_custody(const coap_packet_t *packet, uint8_t *custody); +bool coap_signal_set_custody(coap_packet_t *packet, uint8_t custody); +size_t coap_signal_get_alt_addr(const coap_packet_t *packet, const char **addr); +size_t coap_signal_set_alt_addr(coap_packet_t *packet, const char *addr, size_t addr_len); -int coap_signal_get_hold_off(void *packet, uint32_t *time_seconds); -int coap_signal_set_hold_off(void *packet, uint32_t time_seconds); -int coap_signal_get_bad_csm(void *packet, uint16_t *opt); -int coap_signal_set_bad_csm(void *packet, uint16_t opt); +bool coap_signal_get_hold_off(const coap_packet_t *packet, + uint32_t *time_seconds); +bool coap_signal_set_hold_off(coap_packet_t *packet, uint32_t time_seconds); +bool coap_signal_get_bad_csm(const coap_packet_t *packet, uint16_t *opt); +bool coap_signal_set_bad_csm(coap_packet_t *packet, uint16_t opt); + #endif /* OC_TCP */ #ifdef __cplusplus diff --git a/messaging/coap/engine.c b/messaging/coap/engine.c index 191bdb4c97..ed79e997ae 100644 --- a/messaging/coap/engine.c +++ b/messaging/coap/engine.c @@ -56,6 +56,8 @@ #include "api/oc_ri_internal.h" #include "messaging/coap/coap_internal.h" #include "messaging/coap/coap_options.h" +#include "messaging/coap/observe.h" +#include "messaging/coap/transactions.h" #include "oc_api.h" #include "oc_buffer.h" #include "util/oc_macros_internal.h" @@ -230,7 +232,6 @@ enum { COAP_SUCCESS = 0, COAP_SKIP_DUPLICATE_MESSAGE, COAP_SEND_MESSAGE, - COAP_SEND_RESET_MESSAGE, }; static int @@ -267,6 +268,19 @@ coap_receive_init_response(coap_packet_t *response, return COAP_SUCCESS; } +typedef struct +{ + const coap_packet_t *request; + coap_packet_t *response; + coap_transaction_t *transaction; + coap_block_options_t block1; + coap_block_options_t block2; +#ifdef OC_BLOCK_WISE + oc_blockwise_state_t *request_buffer; + oc_blockwise_state_t *response_buffer; +#endif /* OC_BLOCK_WISE */ +} coap_receive_ctx_t; + #ifdef OC_BLOCK_WISE static oc_blockwise_state_t * @@ -297,19 +311,8 @@ coap_receive_create_request_buffer(const coap_packet_t *request, return request_buffer; } -typedef struct -{ - const coap_packet_t *request; - oc_blockwise_state_t *request_buffer; - coap_packet_t *response; - oc_blockwise_state_t *response_buffer; - coap_transaction_t *transaction; - coap_block_options_t block1; - coap_block_options_t block2; -} coap_receive_blockwise_ctx_t; - static int -coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, +coap_receive_blockwise(coap_receive_ctx_t *ctx, const char *href, size_t href_len, const oc_endpoint_t *endpoint) { const uint8_t *incoming_block; @@ -334,7 +337,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, if (oc_drop_command(endpoint->device) && ctx->request->code >= COAP_GET && ctx->request->code <= COAP_DELETE) { OC_WRN("cannot process new request during closing TLS sessions"); - return COAP_SEND_RESET_MESSAGE; + return -1; } uint32_t buffer_size; @@ -355,7 +358,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, if (ctx->request_buffer == NULL) { OC_ERR("could not create block-wise request buffer"); - return COAP_SEND_RESET_MESSAGE; + return -1; } OC_DBG("processing incoming block"); @@ -363,7 +366,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, ctx->request_buffer, ctx->block1.offset, incoming_block, MIN((uint16_t)incoming_block_len, ctx->block1.size))) { OC_ERR("could not process incoming block"); - return COAP_SEND_RESET_MESSAGE; + return -1; } if (ctx->block1.more) { @@ -415,7 +418,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, ctx->block2.size, &payload_size); if (payload == NULL) { OC_ERR("could not dispatch block"); - return COAP_SEND_RESET_MESSAGE; + return -1; } OC_DBG("dispatching next block"); uint8_t more = (ctx->response_buffer->next_block_offset < @@ -447,7 +450,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, "buffer"); if (ctx->block2.num != 0) { OC_ERR("initiating block-wise transfer with request for block_num > 0"); - return COAP_SEND_RESET_MESSAGE; + return -1; } if (incoming_block_len == 0) { @@ -464,7 +467,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, if (oc_drop_command(endpoint->device) && ctx->request->code >= COAP_GET && ctx->request->code <= COAP_DELETE) { OC_WRN("cannot process new request during closing TLS sessions"); - return COAP_SEND_RESET_MESSAGE; + return -1; } uint32_t buffer_size; @@ -477,7 +480,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, ctx->request, href, href_len, endpoint, buffer_size, incoming_block, incoming_block_len); if (ctx->request_buffer == NULL) { - return COAP_SEND_RESET_MESSAGE; + return -1; } return COAP_SUCCESS; } @@ -486,7 +489,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, if (oc_drop_command(endpoint->device) && ctx->request->code >= COAP_GET && ctx->request->code <= COAP_DELETE) { OC_WRN("cannot process new request during closing TLS sessions"); - return COAP_SEND_RESET_MESSAGE; + return -1; } #ifdef OC_TCP @@ -499,7 +502,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, #endif /* OC_TCP */ if (!is_valid_size) { OC_ERR("incoming payload size exceeds block size"); - return COAP_SEND_RESET_MESSAGE; + return -1; } if (incoming_block_len > 0) { @@ -521,7 +524,7 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, ctx->request, href, href_len, endpoint, buffer_size, incoming_block, incoming_block_len); if (ctx->request_buffer == NULL) { - return COAP_SEND_RESET_MESSAGE; + return -1; } ctx->request_buffer->ref_count = 0; } @@ -546,176 +549,161 @@ coap_receive_blockwise(coap_receive_blockwise_ctx_t *ctx, const char *href, #endif /* OC_BLOCK_WISE */ -int -coap_receive(oc_message_t *msg) +typedef struct { - coap_set_global_status_code(COAP_NO_ERROR); - - OC_DBG("CoAP Engine: received datalen=%u from", (unsigned int)msg->length); - OC_LOGipaddr(msg->endpoint); - OC_LOGbytes(msg->data, msg->length); - - /* static declaration reduces stack peaks and program code size */ - static coap_packet_t - message[1]; /* this way the packet can be treated as pointer as usual */ - static coap_packet_t response[1]; - static coap_transaction_t *transaction; - transaction = NULL; - -#ifdef OC_BLOCK_WISE - oc_blockwise_state_t *request_buffer = NULL; - oc_blockwise_state_t *response_buffer = NULL; -#endif /* OC_BLOCK_WISE */ + const coap_packet_t *request; + coap_packet_t *response; + coap_transaction_t *transaction; +#if defined(OC_CLIENT) && defined(OC_BLOCK_WISE) + oc_blockwise_state_t *request_buffer; + oc_blockwise_state_t *response_buffer; +#endif /* OC_CLIENT && OC_BLOCK_WISE */ +} coap_send_response_ctx_t; -#ifdef OC_CLIENT - oc_client_cb_t *client_cb = NULL; -#endif /* OC_CLIENT */ +static void +coap_send_response(coap_send_response_ctx_t *ctx) +{ + if (coap_global_status_code() == CLEAR_TRANSACTION) { + coap_clear_transaction(ctx->transaction); + return; + } - coap_status_t status; -#ifdef OC_TCP - if (msg->endpoint.flags & TCP) { - status = coap_tcp_parse_message(message, msg->data, msg->length, false); - } else -#endif /* OC_TCP */ - { - status = coap_udp_parse_message(message, msg->data, msg->length, false); + if (ctx->transaction == NULL) { + OC_ERR("cannot send response: transaction is NULL"); + return; } - coap_set_global_status_code(status); - if (status != COAP_NO_ERROR) { - OC_ERR("Unexpected CoAP command"); -#ifdef OC_SECURITY - coap_audit_log(msg); -#endif /* OC_SECURITY */ -#ifdef OC_TCP - if ((msg->endpoint.flags & TCP) != 0) { - coap_send_empty_response(COAP_TYPE_NON, 0, message->token, - message->token_len, (uint8_t)status, - &msg->endpoint); - return status; + if (ctx->response->type != COAP_TYPE_RST && ctx->request->token_len > 0) { + if (ctx->request->code >= COAP_GET && ctx->request->code <= COAP_DELETE) { + coap_set_token(ctx->response, ctx->request->token, + ctx->request->token_len); } -#endif /* OC_TCP */ - coap_send_empty_response(message->type == COAP_TYPE_CON ? COAP_TYPE_ACK - : COAP_TYPE_NON, - message->mid, message->token, message->token_len, - (uint8_t)status, &msg->endpoint); - - return status; +#if defined(OC_CLIENT) && defined(OC_BLOCK_WISE) + else { + const oc_blockwise_response_state_t *b = + (oc_blockwise_response_state_t *)ctx->response_buffer; + if (b != NULL && b->observe_seq != OC_COAP_OPTION_OBSERVE_NOT_SET) { + ctx->response->token_len = sizeof(ctx->response->token); + oc_random_buffer(ctx->response->token, ctx->response->token_len); + if (ctx->request_buffer != NULL) { + memcpy(ctx->request_buffer->token, ctx->response->token, + ctx->response->token_len); + ctx->request_buffer->token_len = ctx->response->token_len; + } + memcpy(ctx->response_buffer->token, ctx->response->token, + ctx->response->token_len); + ctx->response_buffer->token_len = ctx->response->token_len; + } else { + coap_set_token(ctx->response, ctx->request->token, + ctx->request->token_len); + } + } +#endif /* OC_CLIENT && OC_BLOCK_WISE */ } -#if OC_DBG_IS_ENABLED - coap_packet_log_message(message); -#endif /* OC_DBG_IS_ENABLED */ - -#ifdef OC_TCP - if (coap_check_signal_message(message)) { - status = handle_coap_signal_message(message, &msg->endpoint); - coap_set_global_status_code(status); + if (ctx->response->token_len > 0) { + memcpy(ctx->transaction->token, ctx->response->token, + ctx->response->token_len); + ctx->transaction->token_len = ctx->response->token_len; } -#endif /* OC_TCP */ - - /* extract block options */ - coap_block_options_t block1 = coap_packet_get_block_options(message, false); - coap_block_options_t block2 = coap_packet_get_block_options(message, true); - -#ifdef OC_TCP - if ((msg->endpoint.flags & TCP) == 0) -#endif /* OC_TCP */ - { - transaction = coap_get_transaction_by_mid(message->mid); - if (transaction != NULL) { - coap_clear_transaction(transaction); - } - transaction = NULL; + OC_DBG("data buffer from:%p to:%p", (void *)ctx->transaction->message->data, + (void *)(ctx->transaction->message->data + oc_message_buffer_size())); + ctx->transaction->message->length = coap_serialize_message( + ctx->response, ctx->transaction->message->data, oc_message_buffer_size()); + if (ctx->transaction->message->length > 0) { + coap_send_transaction(ctx->transaction); + } else { + coap_clear_transaction(ctx->transaction); } +} +static int +coap_receive(coap_receive_ctx_t *ctx, oc_endpoint_t *endpoint) +{ /* handle requests */ - if (message->code >= COAP_GET && message->code <= COAP_DELETE) { + if (ctx->request->code >= COAP_GET && ctx->request->code <= COAP_DELETE) { #if OC_DBG_IS_ENABLED - OC_DBG(" method: %s", oc_method_to_str((oc_method_t)message->code)); - OC_DBG(" URL: %.*s", (int)message->uri_path_len, message->uri_path); - OC_DBG(" QUERY: %.*s", (int)message->uri_query_len, message->uri_query); - OC_DBG(" Payload: %.*s", (int)message->payload_len, message->payload); + OC_DBG(" method: %s", oc_method_to_str((oc_method_t)ctx->request->code)); + OC_DBG(" URL: %.*s", (int)ctx->request->uri_path_len, + ctx->request->uri_path); + OC_DBG(" QUERY: %.*s", (int)ctx->request->uri_query_len, + ctx->request->uri_query); + OC_DBG(" Payload: %.*s", (int)ctx->request->payload_len, + ctx->request->payload); #endif /* OC_DBG_IS_ENABLED */ const char *href; - size_t href_len = coap_options_get_uri_path(message, &href); - if (coap_receive_init_response(response, &msg->endpoint, message->type, - message->mid, href, + size_t href_len = coap_options_get_uri_path(ctx->request, &href); + if (coap_receive_init_response(ctx->response, endpoint, ctx->request->type, + ctx->request->mid, href, href_len) == COAP_SKIP_DUPLICATE_MESSAGE) { return 0; } /* create transaction for response */ - transaction = coap_new_transaction(response->mid, NULL, 0, &msg->endpoint); - if (transaction == NULL) { + ctx->transaction = + coap_new_transaction(ctx->response->mid, NULL, 0, endpoint); + if (ctx->transaction == NULL) { goto init_reset_message; } #ifdef OC_BLOCK_WISE - coap_receive_blockwise_ctx_t bwt_ctx = { - .request = message, - .request_buffer = request_buffer, - .response = response, - .response_buffer = response_buffer, - .transaction = transaction, - .block1 = block1, - .block2 = block2, - }; - int bwt_ret = - coap_receive_blockwise(&bwt_ctx, href, href_len, &msg->endpoint); - request_buffer = bwt_ctx.request_buffer; - response_buffer = bwt_ctx.response_buffer; - if (bwt_ret == COAP_SEND_MESSAGE) { - goto send_message; - } else if (bwt_ret == COAP_SEND_RESET_MESSAGE) { + int bwt_ret = coap_receive_blockwise(ctx, href, href_len, endpoint); + if (bwt_ret < 0) { goto init_reset_message; + } else if (bwt_ret == COAP_SEND_MESSAGE) { + goto send_message; } else if (bwt_ret == COAP_SKIP_DUPLICATE_MESSAGE) { return 0; } #else /* OC_BLOCK_WISE */ - if (block1.enabled || block2.enabled) { + if (ctx->block1.enabled || ctx->block2.enabled) { goto init_reset_message; } #endif /* !OC_BLOCK_WISE */ oc_ri_invoke_coap_entity_handler_ctx_t handler_ctx; #ifdef OC_BLOCK_WISE - handler_ctx.request_state = &request_buffer; - handler_ctx.response_state = &response_buffer; - handler_ctx.block2_size = block2.size; + handler_ctx.request_state = &ctx->request_buffer; + handler_ctx.response_state = &ctx->response_buffer; + handler_ctx.block2_size = ctx->block2.size; #else /* !OC_BLOCK_WISE */ handler_ctx.buffer = transaction->message->data + COAP_MAX_HEADER_SIZE; #endif /* OC_BLOCK_WISE */ - if (oc_ri_invoke_coap_entity_handler(message, response, &msg->endpoint, + if (oc_ri_invoke_coap_entity_handler(ctx->request, ctx->response, endpoint, handler_ctx) && - (response->code != VALID_2_03)) { + (ctx->response->code != VALID_2_03)) { #ifdef OC_BLOCK_WISE uint32_t payload_size = 0; #ifdef OC_TCP - if (msg->endpoint.flags & TCP) { + if ((endpoint->flags & TCP) != 0) { void *payload = oc_blockwise_dispatch_block( - response_buffer, 0, response_buffer->payload_size + 1, &payload_size); - if (payload && response_buffer->payload_size > 0) { - coap_set_payload(response, payload, payload_size); + ctx->response_buffer, 0, ctx->response_buffer->payload_size + 1, + &payload_size); + if (payload && ctx->response_buffer->payload_size > 0) { + coap_set_payload(ctx->response, payload, payload_size); } - response_buffer->ref_count = 0; + ctx->response_buffer->ref_count = 0; } else { #endif /* OC_TCP */ - void *payload = oc_blockwise_dispatch_block(response_buffer, 0, - block2.size, &payload_size); + void *payload = oc_blockwise_dispatch_block( + ctx->response_buffer, 0, ctx->block2.size, &payload_size); if (payload) { - coap_set_payload(response, payload, payload_size); + coap_set_payload(ctx->response, payload, payload_size); } - if (block2.enabled || response_buffer->payload_size > block2.size) { + if (ctx->block2.enabled || + ctx->response_buffer->payload_size > ctx->block2.size) { coap_options_set_block2( - response, 0, (response_buffer->payload_size > block2.size) ? 1 : 0, - block2.size, 0); - coap_options_set_size2(response, response_buffer->payload_size); - oc_blockwise_response_state_t *response_state = - (oc_blockwise_response_state_t *)response_buffer; - coap_options_set_etag(response, response_state->etag, COAP_ETAG_LEN); + ctx->response, 0, + (ctx->response_buffer->payload_size > ctx->block2.size) ? 1 : 0, + ctx->block2.size, 0); + coap_options_set_size2(ctx->response, + ctx->response_buffer->payload_size); + const oc_blockwise_response_state_t *response_state = + (oc_blockwise_response_state_t *)ctx->response_buffer; + coap_options_set_etag(ctx->response, response_state->etag, + COAP_ETAG_LEN); } else { - response_buffer->ref_count = 0; + ctx->response_buffer->ref_count = 0; } #ifdef OC_TCP } @@ -724,180 +712,193 @@ coap_receive(oc_message_t *msg) } #ifdef OC_BLOCK_WISE else { - if (request_buffer) { - request_buffer->ref_count = 0; + if (ctx->request_buffer) { + ctx->request_buffer->ref_count = 0; } - if (response_buffer) { - response_buffer->ref_count = 0; + if (ctx->response_buffer) { + ctx->response_buffer->ref_count = 0; } } #endif /* OC_BLOCK_WISE */ - if (response->code != 0) { + if (ctx->response->code != 0) { goto send_message; } } else { #ifdef OC_CLIENT + oc_client_cb_t *client_cb = NULL; + #ifdef OC_BLOCK_WISE uint16_t response_mid = coap_get_mid(); bool error_response = false; #endif /* OC_BLOCK_WISE */ - if (message->type != COAP_TYPE_RST) { - client_cb = - oc_ri_find_client_cb_by_token(message->token, message->token_len); + if (ctx->request->type != COAP_TYPE_RST) { + client_cb = oc_ri_find_client_cb_by_token(ctx->request->token, + ctx->request->token_len); #ifdef OC_BLOCK_WISE - if (message->code >= BAD_REQUEST_4_00 && - message->code != REQUEST_ENTITY_TOO_LARGE_4_13) { + if (ctx->request->code >= BAD_REQUEST_4_00 && + ctx->request->code != REQUEST_ENTITY_TOO_LARGE_4_13) { error_response = true; } #endif /* OC_BLOCK_WISE */ } #endif /* OC_CLIENT */ - if (message->type == COAP_TYPE_CON) { - coap_send_empty_response(COAP_TYPE_ACK, message->mid, NULL, 0, 0, - &msg->endpoint); + if (ctx->request->type == COAP_TYPE_CON) { + coap_send_empty_response(COAP_TYPE_ACK, ctx->request->mid, NULL, 0, 0, + endpoint); } #ifdef OC_SERVER - else if (message->type == COAP_TYPE_RST) { + else if (ctx->request->type == COAP_TYPE_RST) { /* cancel possible subscriptions */ - coap_remove_observer_by_mid(&msg->endpoint, message->mid); + coap_remove_observer_by_mid(endpoint, ctx->request->mid); } #endif #ifdef OC_CLIENT #ifdef OC_BLOCK_WISE if (client_cb) { - request_buffer = oc_blockwise_find_request_buffer_by_client_cb( - &msg->endpoint, client_cb); + ctx->request_buffer = + oc_blockwise_find_request_buffer_by_client_cb(endpoint, client_cb); } else { - request_buffer = oc_blockwise_find_request_buffer_by_mid(message->mid); - if (!request_buffer) { - request_buffer = oc_blockwise_find_request_buffer_by_token( - message->token, message->token_len); + ctx->request_buffer = + oc_blockwise_find_request_buffer_by_mid(ctx->request->mid); + if (!ctx->request_buffer) { + ctx->request_buffer = oc_blockwise_find_request_buffer_by_token( + ctx->request->token, ctx->request->token_len); } } - if (!error_response && request_buffer && - (block1.enabled || message->code == REQUEST_ENTITY_TOO_LARGE_4_13)) { + if (!error_response && ctx->request_buffer && + (ctx->block1.enabled || + ctx->request->code == REQUEST_ENTITY_TOO_LARGE_4_13)) { OC_DBG("found request buffer for uri %s", - oc_string(request_buffer->href)); - client_cb = (oc_client_cb_t *)request_buffer->client_cb; + oc_string(ctx->request_buffer->href)); + client_cb = (oc_client_cb_t *)ctx->request_buffer->client_cb; uint32_t payload_size = 0; void *payload = NULL; - if (block1.enabled) { - payload = oc_blockwise_dispatch_block(request_buffer, - block1.offset + block1.size, - block1.size, &payload_size); + if (ctx->block1.enabled) { + payload = oc_blockwise_dispatch_block( + ctx->request_buffer, ctx->block1.offset + ctx->block1.size, + ctx->block1.size, &payload_size); } else { OC_DBG("initiating block-wise transfer with block1 option"); uint32_t peer_mtu = 0; - if (coap_options_get_size1(message, &peer_mtu) == 1) { - block1.size = MIN((uint16_t)peer_mtu, (uint16_t)OC_BLOCK_SIZE); + if (coap_options_get_size1(ctx->request, &peer_mtu) == 1) { + ctx->block1.size = MIN((uint16_t)peer_mtu, (uint16_t)OC_BLOCK_SIZE); } else { - block1.size = (uint16_t)OC_BLOCK_SIZE; + ctx->block1.size = (uint16_t)OC_BLOCK_SIZE; } - payload = oc_blockwise_dispatch_block(request_buffer, 0, block1.size, - &payload_size); - request_buffer->ref_count = 1; + payload = oc_blockwise_dispatch_block(ctx->request_buffer, 0, + ctx->block1.size, &payload_size); + ctx->request_buffer->ref_count = 1; } if (payload) { OC_DBG("dispatching next block"); - transaction = - coap_new_transaction(response_mid, NULL, 0, &msg->endpoint); - if (transaction) { - coap_udp_init_message(response, COAP_TYPE_CON, client_cb->method, + ctx->transaction = + coap_new_transaction(response_mid, NULL, 0, endpoint); + if (ctx->transaction) { + coap_udp_init_message(ctx->response, COAP_TYPE_CON, client_cb->method, response_mid); - uint8_t more = - (request_buffer->next_block_offset < request_buffer->payload_size) - ? 1 - : 0; - coap_options_set_uri_path(response, oc_string(client_cb->uri), + uint8_t more = (ctx->request_buffer->next_block_offset < + ctx->request_buffer->payload_size) + ? 1 + : 0; + coap_options_set_uri_path(ctx->response, oc_string(client_cb->uri), oc_string_len(client_cb->uri)); - coap_set_payload(response, payload, payload_size); - if (block1.enabled) { - coap_options_set_block1(response, block1.num + 1, more, block1.size, - 0); + coap_set_payload(ctx->response, payload, payload_size); + if (ctx->block1.enabled) { + coap_options_set_block1(ctx->response, ctx->block1.num + 1, more, + ctx->block1.size, 0); } else { - coap_options_set_block1(response, 0, more, block1.size, 0); - coap_options_set_size1(response, request_buffer->payload_size); + coap_options_set_block1(ctx->response, 0, more, ctx->block1.size, + 0); + coap_options_set_size1(ctx->response, + ctx->request_buffer->payload_size); } if (oc_string_len(client_cb->query) > 0) { - coap_options_set_uri_query(response, oc_string(client_cb->query), + coap_options_set_uri_query(ctx->response, + oc_string(client_cb->query), oc_string_len(client_cb->query)); } - coap_options_set_accept(response, APPLICATION_VND_OCF_CBOR); - coap_options_set_content_format(response, APPLICATION_VND_OCF_CBOR); - request_buffer->mid = response_mid; + coap_options_set_accept(ctx->response, APPLICATION_VND_OCF_CBOR); + coap_options_set_content_format(ctx->response, + APPLICATION_VND_OCF_CBOR); + ctx->request_buffer->mid = response_mid; goto send_message; } } else { - request_buffer->ref_count = 0; + ctx->request_buffer->ref_count = 0; } } - if (request_buffer && (request_buffer->ref_count == 0 || error_response)) { - oc_blockwise_free_request_buffer(request_buffer); - request_buffer = NULL; + if (ctx->request_buffer && + (ctx->request_buffer->ref_count == 0 || error_response)) { + oc_blockwise_free_request_buffer(ctx->request_buffer); + ctx->request_buffer = NULL; } if (client_cb) { - response_buffer = oc_blockwise_find_response_buffer_by_client_cb( - &msg->endpoint, client_cb); - if (!response_buffer) { + ctx->response_buffer = + oc_blockwise_find_response_buffer_by_client_cb(endpoint, client_cb); + if (!ctx->response_buffer) { uint32_t buffer_size = (uint32_t)OC_MAX_APP_DATA_SIZE; - response_buffer = oc_blockwise_alloc_response_buffer( + ctx->response_buffer = oc_blockwise_alloc_response_buffer( oc_string(client_cb->uri) + 1, oc_string_len(client_cb->uri) - 1, - &msg->endpoint, client_cb->method, OC_BLOCKWISE_CLIENT, buffer_size); - if (response_buffer) { + endpoint, client_cb->method, OC_BLOCKWISE_CLIENT, buffer_size); + if (ctx->response_buffer) { OC_DBG("created new response buffer for uri %s", - oc_string(response_buffer->href)); - response_buffer->client_cb = client_cb; + oc_string(ctx->response_buffer->href)); + ctx->response_buffer->client_cb = client_cb; } } } else { - response_buffer = oc_blockwise_find_response_buffer_by_mid(message->mid); - if (!response_buffer) { - response_buffer = oc_blockwise_find_response_buffer_by_token( - message->token, message->token_len); + ctx->response_buffer = + oc_blockwise_find_response_buffer_by_mid(ctx->request->mid); + if (!ctx->response_buffer) { + ctx->response_buffer = oc_blockwise_find_response_buffer_by_token( + ctx->request->token, ctx->request->token_len); } } - if (!error_response && response_buffer) { + if (!error_response && ctx->response_buffer) { OC_DBG("got response buffer for uri %s", - oc_string(response_buffer->href)); - client_cb = (oc_client_cb_t *)response_buffer->client_cb; + oc_string(ctx->response_buffer->href)); + client_cb = (oc_client_cb_t *)ctx->response_buffer->client_cb; oc_blockwise_response_state_t *response_state = - (oc_blockwise_response_state_t *)response_buffer; - coap_options_get_observe(message, &response_state->observe_seq); + (oc_blockwise_response_state_t *)ctx->response_buffer; + coap_options_get_observe(ctx->request, &response_state->observe_seq); const uint8_t *incoming_block; - uint32_t incoming_block_len = coap_get_payload(message, &incoming_block); + uint32_t incoming_block_len = + coap_get_payload(ctx->request, &incoming_block); if (incoming_block_len > 0 && - oc_blockwise_handle_block(response_buffer, block2.offset, + oc_blockwise_handle_block(ctx->response_buffer, ctx->block2.offset, incoming_block, (uint32_t)incoming_block_len)) { OC_DBG("processing incoming block"); - if (block2.enabled && block2.more) { + if (ctx->block2.enabled && ctx->block2.more) { OC_DBG("issuing request for next block"); - transaction = - coap_new_transaction(response_mid, NULL, 0, &msg->endpoint); - if (transaction) { - coap_udp_init_message(response, COAP_TYPE_CON, client_cb->method, - response_mid); - response_buffer->mid = response_mid; + ctx->transaction = + coap_new_transaction(response_mid, NULL, 0, endpoint); + if (ctx->transaction) { + coap_udp_init_message(ctx->response, COAP_TYPE_CON, + client_cb->method, response_mid); + ctx->response_buffer->mid = response_mid; client_cb->mid = response_mid; - coap_options_set_accept(response, APPLICATION_VND_OCF_CBOR); - coap_options_set_block2(response, block2.num + 1, 0, block2.size, - 0); - coap_options_set_uri_path(response, oc_string(client_cb->uri), + coap_options_set_accept(ctx->response, APPLICATION_VND_OCF_CBOR); + coap_options_set_block2(ctx->response, ctx->block2.num + 1, 0, + ctx->block2.size, 0); + coap_options_set_uri_path(ctx->response, oc_string(client_cb->uri), oc_string_len(client_cb->uri)); if (oc_string_len(client_cb->query) > 0) { - coap_options_set_uri_query(response, oc_string(client_cb->query), + coap_options_set_uri_query(ctx->response, + oc_string(client_cb->query), oc_string_len(client_cb->query)); } goto send_message; } } - response_buffer->payload_size = response_buffer->next_block_offset; + ctx->response_buffer->payload_size = + ctx->response_buffer->next_block_offset; } } @@ -906,19 +907,20 @@ coap_receive(oc_message_t *msg) if (client_cb) { OC_DBG("calling oc_client_cb_invoke"); #ifdef OC_BLOCK_WISE - if (request_buffer) { - request_buffer->ref_count = 0; + if (ctx->request_buffer) { + ctx->request_buffer->ref_count = 0; } - oc_client_cb_invoke(message, &response_buffer, client_cb, &msg->endpoint); + oc_client_cb_invoke(ctx->request, &ctx->response_buffer, client_cb, + endpoint); /* Do not free the response buffer in case of a separate response * signal from the server. In this case, the client_cb continues * to live until the response arrives (or it times out). */ if (oc_ri_is_client_cb_valid(client_cb)) { if (client_cb->separate == 0) { - if (response_buffer) { - response_buffer->ref_count = 0; + if (ctx->response_buffer) { + ctx->response_buffer->ref_count = 0; } } else { client_cb->separate = 0; @@ -926,7 +928,7 @@ coap_receive(oc_message_t *msg) } goto send_message; #else /* OC_BLOCK_WISE */ - oc_client_cb_invoke(message, client_cb, &msg->endpoint); + oc_client_cb_invoke(ctx->request, client_cb, endpoint); #endif /* OC_BLOCK_WISE */ } #endif /* OC_CLIENT */ @@ -934,80 +936,132 @@ coap_receive(oc_message_t *msg) init_reset_message: #ifdef OC_TCP - if (msg->endpoint.flags & TCP) { - coap_tcp_init_message(response, INTERNAL_SERVER_ERROR_5_00); + if ((endpoint->flags & TCP) != 0) { + coap_tcp_init_message(ctx->response, INTERNAL_SERVER_ERROR_5_00); } else #endif /* OC_TCP */ { - coap_udp_init_message(response, COAP_TYPE_RST, 0, message->mid); + coap_udp_init_message(ctx->response, COAP_TYPE_RST, 0, ctx->request->mid); } #ifdef OC_BLOCK_WISE - if (request_buffer) { - request_buffer->ref_count = 0; + if (ctx->request_buffer) { + ctx->request_buffer->ref_count = 0; } - if (response_buffer) { - response_buffer->ref_count = 0; + if (ctx->response_buffer) { + ctx->response_buffer->ref_count = 0; } #endif /* OC_BLOCK_WISE */ -send_message: - if (coap_global_status_code() == CLEAR_TRANSACTION) { - coap_clear_transaction(transaction); - } else if (transaction) { - if (response->type != COAP_TYPE_RST && message->token_len > 0) { - if (message->code >= COAP_GET && message->code <= COAP_DELETE) { - coap_set_token(response, message->token, message->token_len); - } +send_message : { + coap_send_response_ctx_t send_ctx = { + .request = ctx->request, + .response = ctx->response, + .transaction = ctx->transaction, #if defined(OC_CLIENT) && defined(OC_BLOCK_WISE) - else { - const oc_blockwise_response_state_t *b = - (oc_blockwise_response_state_t *)response_buffer; - if (b != NULL && b->observe_seq != OC_COAP_OPTION_OBSERVE_NOT_SET) { - response->token_len = sizeof(response->token); - oc_random_buffer(response->token, response->token_len); - if (request_buffer) { - memcpy(request_buffer->token, response->token, response->token_len); - request_buffer->token_len = response->token_len; - } - if (response_buffer) { - memcpy(response_buffer->token, response->token, - response->token_len); - response_buffer->token_len = response->token_len; - } - } else { - coap_set_token(response, message->token, message->token_len); - } - } + .request_buffer = ctx->request_buffer, + .response_buffer = ctx->response_buffer, #endif /* OC_CLIENT && OC_BLOCK_WISE */ + }; + coap_send_response(&send_ctx); +} + +#ifdef OC_BLOCK_WISE + oc_blockwise_scrub_buffers(false); +#endif /* OC_BLOCK_WISE */ + + return coap_global_status_code(); +} + +int +coap_process_inbound_message(oc_message_t *msg) +{ + OC_DBG("CoAP Engine: received datalen=%u from", (unsigned int)msg->length); + OC_LOGipaddr(msg->endpoint); + OC_LOGbytes(msg->data, msg->length); + + /* static declaration reduces stack peaks and program code size */ + static coap_packet_t message; + static coap_packet_t response; + static coap_transaction_t *transaction; + + coap_status_t status; +#ifdef OC_TCP + if (msg->endpoint.flags & TCP) { + status = coap_tcp_parse_message(&message, msg->data, msg->length, false); + } else +#endif /* OC_TCP */ + { + status = coap_udp_parse_message(&message, msg->data, msg->length, false); + } + + coap_set_global_status_code(status); + + if (status != COAP_NO_ERROR) { + OC_ERR("Unexpected CoAP command"); +#ifdef OC_SECURITY + coap_audit_log(msg); +#endif /* OC_SECURITY */ +#ifdef OC_TCP + if ((msg->endpoint.flags & TCP) != 0) { + coap_send_empty_response(COAP_TYPE_NON, 0, message.token, + message.token_len, (uint8_t)status, + &msg->endpoint); + return status; } - if (response->token_len > 0) { - memcpy(transaction->token, response->token, response->token_len); - transaction->token_len = response->token_len; - } - OC_DBG("data buffer from:%p to:%p", (void *)transaction->message->data, - (void *)(transaction->message->data + oc_message_buffer_size())); - transaction->message->length = coap_serialize_message( - response, transaction->message->data, oc_message_buffer_size()); - if (transaction->message->length > 0) { - coap_send_transaction(transaction); - } else { +#endif /* OC_TCP */ + coap_send_empty_response(message.type == COAP_TYPE_CON ? COAP_TYPE_ACK + : COAP_TYPE_NON, + message.mid, message.token, message.token_len, + (uint8_t)status, &msg->endpoint); + + return status; + } + + transaction = NULL; +#ifdef OC_TCP + if ((msg->endpoint.flags & TCP) == 0) +#endif /* OC_TCP */ + { + transaction = coap_get_transaction_by_mid(message.mid); + if (transaction != NULL) { coap_clear_transaction(transaction); } + transaction = NULL; } +#if OC_DBG_IS_ENABLED + coap_packet_log_message(&message); +#endif /* OC_DBG_IS_ENABLED */ + +#ifdef OC_TCP + if (coap_check_signal_message(&message)) { + coap_set_global_status_code( + handle_coap_signal_message(&message, &msg->endpoint)); + } +#endif /* OC_TCP */ + + coap_receive_ctx_t ctx = { + .request = &message, + .response = &response, + .transaction = transaction, + /* extract block options */ + .block1 = coap_packet_get_block_options(&message, false), + .block2 = coap_packet_get_block_options(&message, true), #ifdef OC_BLOCK_WISE - oc_blockwise_scrub_buffers(false); + .request_buffer = NULL, + .response_buffer = NULL, #endif /* OC_BLOCK_WISE */ + }; - return coap_global_status_code(); + return coap_receive(&ctx, &msg->endpoint); } -/*---------------------------------------------------------------------------*/ + void coap_init_engine(void) { coap_register_as_transaction_handler(); } -/*---------------------------------------------------------------------------*/ + OC_PROCESS_THREAD(g_coap_engine, ev, data) { OC_PROCESS_BEGIN(); @@ -1020,7 +1074,7 @@ OC_PROCESS_THREAD(g_coap_engine, ev, data) if (ev == oc_event_to_oc_process_event(INBOUND_RI_EVENT)) { oc_message_t *msg = (oc_message_t *)data; - coap_receive(msg); + coap_process_inbound_message(msg); oc_message_unref(msg); } else if (ev == OC_PROCESS_EVENT_TIMER) { @@ -1030,5 +1084,3 @@ OC_PROCESS_THREAD(g_coap_engine, ev, data) OC_PROCESS_END(); } - -/*---------------------------------------------------------------------------*/ diff --git a/messaging/coap/engine.h b/messaging/coap/engine.h index 78c50aaf69..a8b2c084a1 100644 --- a/messaging/coap/engine.h +++ b/messaging/coap/engine.h @@ -50,10 +50,9 @@ #ifndef ENGINE_H #define ENGINE_H -#include "coap.h" -#include "observe.h" -#include "separate.h" -#include "transactions.h" +#include "port/oc_connectivity.h" +#include "util/oc_compiler.h" +#include "util/oc_process.h" #include #ifdef __cplusplus @@ -63,8 +62,9 @@ extern "C" { OC_PROCESS_NAME(g_coap_engine); void coap_init_engine(void); -/*---------------------------------------------------------------------------*/ -int coap_receive(oc_message_t *message); + +int coap_process_inbound_message(oc_message_t *message) OC_NONNULL(); + bool oc_coap_check_if_duplicate(uint16_t mid, uint32_t device); #ifdef __cplusplus diff --git a/messaging/coap/observe.c b/messaging/coap/observe.c index 7204cdbdbb..06faf4e3a8 100644 --- a/messaging/coap/observe.c +++ b/messaging/coap/observe.c @@ -1354,7 +1354,7 @@ notify_discovery_observers(oc_resource_t *resource) } //! buffer #endif /* OC_DYNAMIC_ALLOCATION */ - OC_DBG("notify_discovery_observers: Issue GET request to resource %s\n\n", + OC_DBG("notify_discovery_observers: Issue GET request to resource %s", oc_string(resource->uri)); oc_response_t response = { 0 }; oc_response_buffer_t response_buffer = { 0 }; diff --git a/messaging/coap/unittest/coapsignaltest.cpp b/messaging/coap/unittest/coapsignaltest.cpp index edf397ff0d..76c194a3dd 100644 --- a/messaging/coap/unittest/coapsignaltest.cpp +++ b/messaging/coap/unittest/coapsignaltest.cpp @@ -99,7 +99,7 @@ TEST_F(TestCoapSignal, coap_send_pong_message_P) coap_packet_t packet = {}; coap_tcp_init_message(&packet, PING_7_02); coap_set_token(&packet, token.data(), token.size()); - coap_signal_set_custody(&packet, 1); + ASSERT_TRUE(coap_signal_set_custody(&packet, 1)); int ret = coap_send_pong_message(target_ep, &packet); EXPECT_EQ(1, ret); @@ -170,12 +170,10 @@ TEST_F(TestCoapSignal, SignalGetMaxMsgSizeTest_P) coap_packet_t packet{}; uint32_t answer = 1152; coap_tcp_init_message(&packet, CSM_7_01); - coap_signal_set_max_msg_size(&packet, answer); + ASSERT_TRUE(coap_signal_set_max_msg_size(&packet, answer)); uint32_t size = 0; - int status = coap_signal_get_max_msg_size(&packet, &size); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_get_max_msg_size(&packet, &size)); ASSERT_EQ(answer, size); } @@ -190,9 +188,7 @@ TEST_F(TestCoapSignal, SignalGetMaxMsgSizeTest_N) { coap_packet_t packet{}; uint32_t size = 0; - int isFailure = coap_signal_get_max_msg_size(&packet, &size); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_get_max_msg_size(&packet, &size)); } /* @@ -208,12 +204,10 @@ TEST_F(TestCoapSignal, SignalSetMaxMsgSizeTest_P) coap_tcp_init_message(&packet, CSM_7_01); uint32_t size = 1152; - int status = coap_signal_set_max_msg_size(&packet, size); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_set_max_msg_size(&packet, size)); uint32_t actual = 0; - coap_signal_get_max_msg_size(&packet, &actual); + ASSERT_TRUE(coap_signal_get_max_msg_size(&packet, &actual)); ASSERT_EQ(size, actual); } @@ -228,9 +222,7 @@ TEST_F(TestCoapSignal, SignalSetMaxMsgSizeTest_N) { coap_packet_t packet{}; uint32_t size = 1152; - int isFailure = coap_signal_set_max_msg_size(&packet, size); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_set_max_msg_size(&packet, size)); } /* @@ -248,9 +240,7 @@ TEST_F(TestCoapSignal, SignalGetBertTest_P) coap_signal_set_blockwise_transfer(&packet, blockwise_transfer); uint8_t flag = 0; - int status = coap_signal_get_blockwise_transfer(&packet, &flag); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_get_blockwise_transfer(&packet, &flag)); ASSERT_EQ(blockwise_transfer, flag); } @@ -265,9 +255,7 @@ TEST_F(TestCoapSignal, SignalGetBertTest_N) { coap_packet_t packet{}; uint8_t flag = 0; - int isFailure = coap_signal_get_blockwise_transfer(&packet, &flag); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_get_blockwise_transfer(&packet, &flag)); } /* @@ -283,9 +271,7 @@ TEST_F(TestCoapSignal, SignalSetBertTest_P) coap_tcp_init_message(&packet, CSM_7_01); uint8_t blockwise_transfer = 1; - int status = coap_signal_set_blockwise_transfer(&packet, blockwise_transfer); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_set_blockwise_transfer(&packet, blockwise_transfer)); uint8_t actual = 0; coap_signal_get_blockwise_transfer(&packet, &actual); @@ -303,10 +289,7 @@ TEST_F(TestCoapSignal, SignalSetBertTest_N) { coap_packet_t packet{}; uint8_t blockwise_transfer = 1; - int isFailure = - coap_signal_set_blockwise_transfer(&packet, blockwise_transfer); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_set_blockwise_transfer(&packet, blockwise_transfer)); } /* @@ -321,12 +304,10 @@ TEST_F(TestCoapSignal, SignalGetCustodyTest_P) coap_packet_t packet{}; uint8_t custody = 1; coap_tcp_init_message(&packet, PING_7_02); - coap_signal_set_custody(&packet, custody); + ASSERT_TRUE(coap_signal_set_custody(&packet, custody)); uint8_t flag = 0; - int status = coap_signal_get_custody(&packet, &flag); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_get_custody(&packet, &flag)); ASSERT_EQ(custody, flag); } @@ -341,9 +322,7 @@ TEST_F(TestCoapSignal, SignalGetCustodyTest_N) { coap_packet_t packet{}; uint8_t flag = 0; - int isFailure = coap_signal_get_custody(&packet, &flag); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_get_custody(&packet, &flag)); } /* @@ -359,12 +338,10 @@ TEST_F(TestCoapSignal, SignalSetCustodyTest_P) coap_tcp_init_message(&packet, PING_7_02); uint8_t custody = 1; - int status = coap_signal_set_custody(&packet, custody); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_set_custody(&packet, custody)); uint8_t actual = 0; - coap_signal_get_custody(&packet, &actual); + ASSERT_TRUE(coap_signal_get_custody(&packet, &actual)); ASSERT_EQ(custody, actual); } @@ -379,9 +356,7 @@ TEST_F(TestCoapSignal, SignalSetCustodyTest_N) { coap_packet_t packet{}; uint8_t custody = 1; - int isFailure = coap_signal_set_custody(&packet, custody); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_set_custody(&packet, custody)); } /* @@ -470,12 +445,10 @@ TEST_F(TestCoapSignal, SignalGetHoldOffTest_P) coap_packet_t packet{}; coap_tcp_init_message(&packet, RELEASE_7_04); uint32_t time_seconds = 10; - coap_signal_set_hold_off(&packet, time_seconds); + ASSERT_TRUE(coap_signal_set_hold_off(&packet, time_seconds)); uint32_t actual = 0; - int status = coap_signal_get_hold_off(&packet, &actual); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_get_hold_off(&packet, &actual)); ASSERT_EQ(time_seconds, actual); } @@ -490,9 +463,7 @@ TEST_F(TestCoapSignal, SignalGetHoldOffTest_N) { coap_packet_t packet{}; uint32_t time_seconds; - size_t isFailure = coap_signal_get_hold_off(&packet, &time_seconds); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_get_hold_off(&packet, &time_seconds)); } /* @@ -508,12 +479,10 @@ TEST_F(TestCoapSignal, SignalSetHoldOffTest_P) coap_tcp_init_message(&packet, RELEASE_7_04); uint32_t time_seconds = 10; - int status = coap_signal_set_hold_off(&packet, time_seconds); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_set_hold_off(&packet, time_seconds)); uint32_t actual = 0; - coap_signal_get_hold_off(&packet, &actual); + ASSERT_TRUE(coap_signal_get_hold_off(&packet, &actual)); ASSERT_EQ(time_seconds, actual); } @@ -529,9 +498,7 @@ TEST_F(TestCoapSignal, SignalSetHoldOffTest_N) coap_packet_t packet{}; uint32_t time_seconds = 10; - size_t isFailure = coap_signal_set_hold_off(&packet, time_seconds); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_set_hold_off(&packet, time_seconds)); } /* @@ -546,12 +513,10 @@ TEST_F(TestCoapSignal, SignalGetBadCsmTest_P) coap_packet_t packet{}; coap_tcp_init_message(&packet, ABORT_7_05); uint16_t opt = 10; - coap_signal_set_bad_csm(&packet, opt); + ASSERT_TRUE(coap_signal_set_bad_csm(&packet, opt)); uint16_t actual = 0; - int status = coap_signal_get_bad_csm(&packet, &actual); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_get_bad_csm(&packet, &actual)); ASSERT_EQ(opt, actual); } @@ -566,9 +531,7 @@ TEST_F(TestCoapSignal, SignalGetBadCsmTest_N) { coap_packet_t packet{}; uint16_t opt; - size_t isFailure = coap_signal_get_bad_csm(&packet, &opt); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_get_bad_csm(&packet, &opt)); } /* @@ -584,12 +547,10 @@ TEST_F(TestCoapSignal, SignalSetBadCsmTest_P) coap_tcp_init_message(&packet, ABORT_7_05); uint16_t opt = 10; - int status = coap_signal_set_bad_csm(&packet, opt); - - ASSERT_NE(0, status); + ASSERT_TRUE(coap_signal_set_bad_csm(&packet, opt)); uint16_t actual = 0; - coap_signal_get_bad_csm(&packet, &actual); + ASSERT_TRUE(coap_signal_get_bad_csm(&packet, &actual)); ASSERT_EQ(opt, actual); } @@ -604,9 +565,7 @@ TEST_F(TestCoapSignal, SignalSetBadCsmTest_N) { coap_packet_t packet{}; uint16_t opt = 10; - size_t isFailure = coap_signal_set_bad_csm(&packet, opt); - - ASSERT_EQ(isFailure, 0); + ASSERT_FALSE(coap_signal_set_bad_csm(&packet, opt)); } TEST_F(TestCoapSignal, SignalSerializeParseTest_CSM) @@ -681,7 +640,7 @@ TEST_F(TestCoapSignal, SignalSerializeParseTest_RELEASE) std::string addr = "coap+tcp://127.0.0.1:5683"; coap_signal_set_alt_addr(&packet, addr.c_str(), addr.length() + 1); uint32_t hold_off = 10; - coap_signal_set_hold_off(&packet, hold_off); + ASSERT_TRUE(coap_signal_set_hold_off(&packet, hold_off)); std::vector buffer; buffer.reserve(OC_PDU_SIZE);