uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size) { tr_debug("sn_coap_builder_calc_needed_packet_data_size_2"); uint16_t returned_byte_count = 0; if (!src_coap_msg_ptr) { return 0; } /* * * * * HEADER * * * * */ /* Header size is fixed */ returned_byte_count = COAP_HEADER_LENGTH; /* * * * * OPTIONS * * * * */ /* If else than Reset message because Reset message must be empty */ if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET) { uint16_t repeatable_option_size = 0; #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE bool is_blockwise_needed = false; if ((src_coap_msg_ptr->payload_len > blockwise_payload_size) && (blockwise_payload_size > 0)) { is_blockwise_needed = true; } #endif /* TOKEN - Length is 1-8 bytes */ if (src_coap_msg_ptr->token_ptr != NULL) { if (src_coap_msg_ptr->token_len > 8 || src_coap_msg_ptr->token_len < 1) { /* Check that option is not longer than defined */ return 0; } returned_byte_count += src_coap_msg_ptr->token_len; } /* URI PATH - Repeatable option. Length of one option is 0-255 */ /* Do not add uri-path for notification message. * Uri-path is needed for cancelling observation with RESET message */ if (!src_coap_msg_ptr->options_list_ptr || (src_coap_msg_ptr->options_list_ptr && !src_coap_msg_ptr->options_list_ptr->observe_len && !src_coap_msg_ptr->options_list_ptr->observe_ptr)) { if (src_coap_msg_ptr->uri_path_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->uri_path_len, src_coap_msg_ptr->uri_path_ptr, COAP_OPTION_URI_PATH); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { return 0; } } } /* CONTENT TYPE - Length of this option is 0-2 bytes */ if (src_coap_msg_ptr->content_type_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->content_type_len > 2) { return 0; } returned_byte_count += src_coap_msg_ptr->content_type_len; } /* If options list pointer exists */ if (src_coap_msg_ptr->options_list_ptr != NULL) { /* ACCEPT - Repeatable option. Length of this option is 0-2 bytes */ if (src_coap_msg_ptr->options_list_ptr->accept_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->accept_len, src_coap_msg_ptr->options_list_ptr->accept_ptr, COAP_OPTION_ACCEPT); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { return 0; } } /* MAX AGE - Length of this option is 0-4 bytes */ if (src_coap_msg_ptr->options_list_ptr->max_age_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->options_list_ptr->max_age_len > 4) { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->max_age_len; } /* PROXY URI - Length of this option is 1-1034 bytes */ if (src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) { if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 1 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 12) { /* Add option header byte(s) - depending of option length */ returned_byte_count++; } else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 13 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 269) { returned_byte_count += 2; } else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 270 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 1034) { returned_byte_count += 3; } else { return 0; } /* Add needed memory for Option value */ returned_byte_count += src_coap_msg_ptr->options_list_ptr->proxy_uri_len; } /* ETAG - Repeatable option. Length of this option is 1-8 bytes*/ if (src_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->etag_len, src_coap_msg_ptr->options_list_ptr->etag_ptr, COAP_OPTION_ETAG); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { return 0; } } /* URI HOST - Length of this option is 1-255 bytes */ if (src_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) { if (src_coap_msg_ptr->options_list_ptr->uri_host_len > 0 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 12) { returned_byte_count++; } else if (src_coap_msg_ptr->options_list_ptr->uri_host_len >= 13 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 255) { returned_byte_count += 2; } else { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->uri_host_len; } /* LOCATION PATH - Repeatable option. Length of this option is 0-255 bytes*/ if (src_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_path_len, src_coap_msg_ptr->options_list_ptr->location_path_ptr, COAP_OPTION_LOCATION_PATH); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { return 0; } } /* URI PORT - Length of this option is 0-2 bytes */ if (src_coap_msg_ptr->options_list_ptr->uri_port_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->options_list_ptr->uri_port_len > 2) { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->uri_port_len; } /* lOCATION QUERY - Repeatable option. Length of this option is 0-255 bytes */ if (src_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_query_len, src_coap_msg_ptr->options_list_ptr->location_query_ptr, COAP_OPTION_LOCATION_QUERY); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { return 0; } } /* OBSERVE - Length of this option is 0-3 bytes */ if (src_coap_msg_ptr->options_list_ptr->observe_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->options_list_ptr->observe_len > 3) { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->observe_len; } else if (src_coap_msg_ptr->options_list_ptr->observe) { returned_byte_count++; } /* URI QUERY - Repeatable option. Length of this option is 1-255 */ if (src_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->uri_query_len, src_coap_msg_ptr->options_list_ptr->uri_query_ptr, COAP_OPTION_URI_QUERY); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { return 0; } } /* BLOCK 1 - Length of this option is 1-3 bytes*/ if (src_coap_msg_ptr->options_list_ptr->block1_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->options_list_ptr->block1_len > 3 || src_coap_msg_ptr->options_list_ptr->block1_len < 1) { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->block1_len; } #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE else if (is_blockwise_needed && src_coap_msg_ptr->msg_code < COAP_MSG_CODE_RESPONSE_CREATED) { returned_byte_count += 2; } #endif /* SIZE1 - Length of this option is 0-4 bytes */ if (src_coap_msg_ptr->options_list_ptr->size1_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->options_list_ptr->size1_len > 4) { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->size1_len; } #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE else if (is_blockwise_needed && src_coap_msg_ptr->msg_code < COAP_MSG_CODE_RESPONSE_CREATED){ returned_byte_count++; if(src_coap_msg_ptr->payload_len < 0xFF) { returned_byte_count++; } else { returned_byte_count += 2; } } #endif /* BLOCK 2 - Length of this option is 1-3 bytes*/ if (src_coap_msg_ptr->options_list_ptr->block2_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->options_list_ptr->block2_len > 3 || src_coap_msg_ptr->options_list_ptr->block2_len < 1) { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->block2_len; } #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE else if (is_blockwise_needed && src_coap_msg_ptr->msg_code >= COAP_MSG_CODE_RESPONSE_CREATED) { returned_byte_count += 2; } #endif /* SIZE2 - Length of this option is 0-4 bytes */ if (src_coap_msg_ptr->options_list_ptr->size2_ptr != NULL) { returned_byte_count++; if (src_coap_msg_ptr->options_list_ptr->size2_len > 4) { return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->size2_len; } #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE else if (is_blockwise_needed && src_coap_msg_ptr->msg_code >= COAP_MSG_CODE_RESPONSE_CREATED){ returned_byte_count++; if(src_coap_msg_ptr->payload_len < 0xFF) { returned_byte_count++; } else { returned_byte_count += 2; } } #endif } #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* * * * * PAYLOAD * * * * */ if (is_blockwise_needed) { /* Two bytes for Block option */ if (src_coap_msg_ptr->msg_code < COAP_MSG_CODE_RESPONSE_CREATED) { returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 1); } else { /* Response message */ returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 2); } /* Add maximum payload at one Blockwise message */ returned_byte_count += blockwise_payload_size; returned_byte_count ++; /* For payload marker */ } else { returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 0); /* Add wanted payload */ returned_byte_count += src_coap_msg_ptr->payload_len; if (src_coap_msg_ptr->payload_len) { returned_byte_count ++; /* For payload marker */ } } #else returned_byte_count += src_coap_msg_ptr->payload_len; if (src_coap_msg_ptr->payload_len) { returned_byte_count ++; /* For payload marker */ } returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 0); #endif } return returned_byte_count; }
uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size) { (void)blockwise_payload_size; uint16_t returned_byte_count = 0; if (!src_coap_msg_ptr) { return 0; } /* * * * * HEADER * * * * */ /* Header size is fixed */ returned_byte_count = COAP_HEADER_LENGTH; /* * * * * OPTIONS * * * * */ /* If else than Reset message because Reset message must be empty */ if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET) { uint16_t repeatable_option_size = 0; /* TOKEN - Length is 1-8 bytes */ if (src_coap_msg_ptr->token_ptr != NULL) { if (src_coap_msg_ptr->token_len > 8 || src_coap_msg_ptr->token_len < 1) { /* Check that option is not longer than defined */ tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - token too large!"); return 0; } returned_byte_count += src_coap_msg_ptr->token_len; } /* URI PATH - Repeatable option. Length of one option is 0-255 */ if (src_coap_msg_ptr->uri_path_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->uri_path_len, src_coap_msg_ptr->uri_path_ptr, COAP_OPTION_URI_PATH); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri path size failed!"); return 0; } } uint16_t tempInt = 0; /* CONTENT FORMAT - An integer option, up to 2 bytes */ if (src_coap_msg_ptr->content_format != COAP_CT_NONE) { if ((uint32_t) src_coap_msg_ptr->content_format > 0xffff) { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - content format too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->content_format, COAP_OPTION_CONTENT_FORMAT, &tempInt); } /* If options list pointer exists */ if (src_coap_msg_ptr->options_list_ptr != NULL) { /* ACCEPT - An integer option, up to 2 bytes */ if (src_coap_msg_ptr->options_list_ptr->accept != COAP_CT_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->accept > 0xffff) { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - accept too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->accept, COAP_OPTION_ACCEPT, &tempInt); } /* MAX AGE - An integer option, omitted for default. Up to 4 bytes */ if (src_coap_msg_ptr->options_list_ptr->max_age != COAP_OPTION_MAX_AGE_DEFAULT) { returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->max_age, COAP_OPTION_MAX_AGE, &tempInt); } /* PROXY URI - Length of this option is 1-1034 bytes */ if (src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) { if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 1 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 12) { /* Add option header byte(s) - depending of option length */ returned_byte_count++; } else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 13 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 269) { returned_byte_count += 2; } else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 270 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 1034) { returned_byte_count += 3; } else { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - proxy uri too large!"); return 0; } /* Add needed memory for Option value */ returned_byte_count += src_coap_msg_ptr->options_list_ptr->proxy_uri_len; } /* ETAG - Repeatable option. Length of this option is 1-8 bytes*/ if (src_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->etag_len, src_coap_msg_ptr->options_list_ptr->etag_ptr, COAP_OPTION_ETAG); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - etag too large!"); return 0; } } /* URI HOST - Length of this option is 1-255 bytes */ if (src_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) { if (src_coap_msg_ptr->options_list_ptr->uri_host_len > 0 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 12) { returned_byte_count++; } else if (src_coap_msg_ptr->options_list_ptr->uri_host_len >= 13 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 255) { returned_byte_count += 2; } else { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri host too large!"); return 0; } returned_byte_count += src_coap_msg_ptr->options_list_ptr->uri_host_len; } /* LOCATION PATH - Repeatable option. Length of this option is 0-255 bytes*/ if (src_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_path_len, src_coap_msg_ptr->options_list_ptr->location_path_ptr, COAP_OPTION_LOCATION_PATH); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - location path too large!"); return 0; } } /* URI PORT - An integer option, up to 2 bytes */ if (src_coap_msg_ptr->options_list_ptr->uri_port != COAP_OPTION_URI_PORT_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->uri_port > 0xffff) { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri port too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->uri_port, COAP_OPTION_URI_PORT, &tempInt); } /* lOCATION QUERY - Repeatable option. Length of this option is 0-255 bytes */ if (src_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_query_len, src_coap_msg_ptr->options_list_ptr->location_query_ptr, COAP_OPTION_LOCATION_QUERY); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - location query too large!"); return 0; } } /* OBSERVE - An integer option, up to 3 bytes */ if (src_coap_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->observe > 0xffffff) { return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->observe, COAP_OPTION_OBSERVE, &tempInt); } /* URI QUERY - Repeatable option. Length of this option is 1-255 */ if (src_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) { repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->uri_query_len, src_coap_msg_ptr->options_list_ptr->uri_query_ptr, COAP_OPTION_URI_QUERY); if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - observe too large!"); return 0; } } /* BLOCK 1 - An integer option, up to 3 bytes */ if (src_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->block1 > 0xffffff) { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - block1 too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->block1, COAP_OPTION_BLOCK1, &tempInt); } /* SIZE1 - Length of this option is 0-4 bytes */ if (src_coap_msg_ptr->options_list_ptr->use_size1) { returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->size1, COAP_OPTION_SIZE1, &tempInt); } /* BLOCK 2 - An integer option, up to 3 bytes */ if (src_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->block2 > 0xffffff) { tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - block2 too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->block2, COAP_OPTION_BLOCK2, &tempInt); } /* SIZE2 - Length of this option is 0-4 bytes */ if (src_coap_msg_ptr->options_list_ptr->use_size2) { returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->size2, COAP_OPTION_SIZE2, &tempInt); } } #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE if ((src_coap_msg_ptr->payload_len > blockwise_payload_size) && (blockwise_payload_size > 0)) { returned_byte_count += blockwise_payload_size; } else { returned_byte_count += src_coap_msg_ptr->payload_len; } #else returned_byte_count += src_coap_msg_ptr->payload_len; #endif if (src_coap_msg_ptr->payload_len) { returned_byte_count ++; /* For payload marker */ } returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr/*, 0*/); } return returned_byte_count; }