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;
}
Exemple #2
0
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;
}