sandbox / mbed-client-c

Fork of mbed-client-c by Christopher Haster

Revision:
4:5d91b0f5038c
Parent:
1:43f5c94c6771
--- a/source/libCoap/src/sn_coap_builder.c	Fri Feb 19 17:46:29 2016 +0000
+++ b/source/libCoap/src/sn_coap_builder.c	Sat Apr 02 00:39:03 2016 +0300
@@ -39,23 +39,15 @@
 static int8_t   sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr);
 static int8_t   sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr);
 static uint16_t sn_coap_builder_options_calc_option_size(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option);
-static int16_t  sn_coap_builder_options_build_add_one_option(uint8_t **dst_packet_data_pptr, uint16_t option_len, uint8_t *option_ptr, sn_coap_option_numbers_e option_number);
-static int16_t  sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number);
-static int16_t  sn_coap_builder_options_build_add_multiple_option(uint8_t **dst_packet_data_pptr, uint8_t **src_pptr, uint16_t *src_len_ptr, sn_coap_option_numbers_e option);
+static int16_t  sn_coap_builder_options_build_add_one_option(uint8_t **dst_packet_data_pptr, uint16_t option_len, uint8_t *option_ptr, sn_coap_option_numbers_e option_number, uint16_t *previous_option_number);
+static int16_t  sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number, uint16_t *previous_option_number);
+static int16_t  sn_coap_builder_options_build_add_multiple_option(uint8_t **dst_packet_data_pptr, uint8_t **src_pptr, uint16_t *src_len_ptr, sn_coap_option_numbers_e option, uint16_t *previous_option_number);
 static uint8_t  sn_coap_builder_options_get_option_part_count(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option);
 static uint16_t sn_coap_builder_options_get_option_part_length_from_whole_option_string(uint16_t query_len, uint8_t *query_ptr, uint8_t query_index, sn_coap_option_numbers_e option);
 static int16_t  sn_coap_builder_options_get_option_part_position(uint16_t query_len, uint8_t *query_ptr, uint8_t query_index, sn_coap_option_numbers_e option);
 static void     sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr);
 static uint8_t  sn_coap_builder_options_calculate_jump_need(sn_coap_hdr_s *src_coap_msg_ptr, uint8_t block_option);
 
-/* * * * GLOBAL DECLARATIONS * * * */
-static uint16_t global_previous_option_number = 0;      /* Previous Option number in CoAP message */
-
-/* * * * EXTERN VARIABLES * * * */
-#if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE
-extern uint16_t     sn_coap_block_data_size;                /* From sn_coap_protocol_ieft_draft_12.c */
-#endif
-
 sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code)
 {
     sn_coap_hdr_s *coap_res_ptr;
@@ -102,6 +94,11 @@
 
 int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr)
 {
+    return sn_coap_builder_2(dst_packet_data_ptr, src_coap_msg_ptr, YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE);
+}
+
+int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size)
+{
     uint8_t *base_packet_data_ptr = NULL;
 
     /* * * * Check given pointers  * * * */
@@ -110,7 +107,7 @@
     }
 
     /* Initialize given Packet data memory area with zero values */
-    uint16_t dst_byte_count_to_be_built = sn_coap_builder_calc_needed_packet_data_size(src_coap_msg_ptr);
+    uint16_t dst_byte_count_to_be_built = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_msg_ptr, blockwise_payload_size);
 
     if (!dst_byte_count_to_be_built) {
         return -1;
@@ -145,8 +142,12 @@
     /* * * * Return built Packet data length * * * */
     return (dst_packet_data_ptr - base_packet_data_ptr);
 }
+uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr)
+{
+    return sn_coap_builder_calc_needed_packet_data_size_2(src_coap_msg_ptr, YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE);
+}
 
-uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr)
+uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size)
 {
     uint16_t returned_byte_count = 0;
 
@@ -175,16 +176,20 @@
         }
 
         /* 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 {
-                return 0;
+        /* 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++;
@@ -346,8 +351,8 @@
         }
 
         /* * * * * PAYLOAD * * * * */
-#if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
-        if ((src_coap_msg_ptr->payload_len > sn_coap_block_data_size) && (sn_coap_block_data_size > 0)) {
+#if YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
+        if ((src_coap_msg_ptr->payload_len > blockwise_payload_size) && (blockwise_payload_size > 0)) {
             /* Two bytes for Block option */
             returned_byte_count += 2;
 
@@ -357,7 +362,7 @@
                 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 += sn_coap_block_data_size;
+            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);
@@ -495,7 +500,7 @@
             previous_option_number = (COAP_OPTION_CONTENT_FORMAT);
         }
 
-#if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE //block_option 1 & 2 only used if this maro is defined
+#if YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE //block_option 1 & 2 only used if this maro is defined
         if (block_option == 2) {
             if ((COAP_OPTION_BLOCK2 - previous_option_number) > 12) {
                 needed_space += 1;
@@ -585,7 +590,7 @@
     /* Then build rest of the options */
 
     /* * * * Initialize previous Option number for new built message * * * */
-    global_previous_option_number = 0;
+    uint16_t previous_option_number = 0;
 
     //missing: COAP_OPTION_IF_MATCH, COAP_OPTION_IF_NONE_MATCH, COAP_OPTION_SIZE
 
@@ -593,65 +598,73 @@
     if (src_coap_msg_ptr->options_list_ptr != NULL) {
         /* * * * Build Uri-Host option * * * */
         sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->uri_host_len,
-                     src_coap_msg_ptr->options_list_ptr->uri_host_ptr, COAP_OPTION_URI_HOST);
+                     src_coap_msg_ptr->options_list_ptr->uri_host_ptr, COAP_OPTION_URI_HOST, &previous_option_number);
 
         /* * * * Build ETag option  * * * */
         sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->etag_ptr,
-                     (uint16_t *)&src_coap_msg_ptr->options_list_ptr->etag_len, COAP_OPTION_ETAG);
+                     (uint16_t *)&src_coap_msg_ptr->options_list_ptr->etag_len, COAP_OPTION_ETAG, &previous_option_number);
 
         /* * * * Build Observe option  * * * * */
         ret_status = sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->observe_len,
-                     src_coap_msg_ptr->options_list_ptr->observe_ptr, COAP_OPTION_OBSERVE);
+                     src_coap_msg_ptr->options_list_ptr->observe_ptr, COAP_OPTION_OBSERVE, &previous_option_number);
         if (ret_status == 0) {
-            sn_coap_builder_options_build_add_zero_length_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->observe_len, src_coap_msg_ptr->options_list_ptr->observe, COAP_OPTION_OBSERVE);
+            sn_coap_builder_options_build_add_zero_length_option(dst_packet_data_pptr,
+                                                                 src_coap_msg_ptr->options_list_ptr->observe_len,
+                                                                 src_coap_msg_ptr->options_list_ptr->observe,
+                                                                 COAP_OPTION_OBSERVE,
+                                                                 &previous_option_number);
         }
 
         /* * * * Build Uri-Port option * * * */
         sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->uri_port_len,
-                     src_coap_msg_ptr->options_list_ptr->uri_port_ptr, COAP_OPTION_URI_PORT);
+                     src_coap_msg_ptr->options_list_ptr->uri_port_ptr, COAP_OPTION_URI_PORT, &previous_option_number);
 
         /* * * * Build Location-Path option  * * * */
         sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->location_path_ptr,
-                     &src_coap_msg_ptr->options_list_ptr->location_path_len, COAP_OPTION_LOCATION_PATH);
+                     &src_coap_msg_ptr->options_list_ptr->location_path_len, COAP_OPTION_LOCATION_PATH, &previous_option_number);
     }
     /* * * * Build Uri-Path option * * * */
-    sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->uri_path_ptr,
-                 &src_coap_msg_ptr->uri_path_len, COAP_OPTION_URI_PATH);
+    /* 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))
+        sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->uri_path_ptr,
+                 &src_coap_msg_ptr->uri_path_len, COAP_OPTION_URI_PATH, &previous_option_number);
 
     /* * * * Build Content-Type option * * * */
     sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->content_type_len,
-                 src_coap_msg_ptr->content_type_ptr, COAP_OPTION_CONTENT_FORMAT);
+                 src_coap_msg_ptr->content_type_ptr, COAP_OPTION_CONTENT_FORMAT, &previous_option_number);
 
     if (src_coap_msg_ptr->options_list_ptr != NULL) {
         /* * * * Build Max-Age option  * * * */
         sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->max_age_len,
-                     src_coap_msg_ptr->options_list_ptr->max_age_ptr, COAP_OPTION_MAX_AGE);
+                     src_coap_msg_ptr->options_list_ptr->max_age_ptr, COAP_OPTION_MAX_AGE, &previous_option_number);
 
         /* * * * Build Uri-Query option  * * * * */
         sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->uri_query_ptr,
-                     &src_coap_msg_ptr->options_list_ptr->uri_query_len, COAP_OPTION_URI_QUERY);
+                     &src_coap_msg_ptr->options_list_ptr->uri_query_len, COAP_OPTION_URI_QUERY, &previous_option_number);
 
         /* * * * Build Accept option  * * * * */
         sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->accept_ptr,
-                     (uint16_t *)&src_coap_msg_ptr->options_list_ptr->accept_len, COAP_OPTION_ACCEPT);
+                     (uint16_t *)&src_coap_msg_ptr->options_list_ptr->accept_len, COAP_OPTION_ACCEPT, &previous_option_number);
     }
 
     if (src_coap_msg_ptr->options_list_ptr != NULL) {
         /* * * * Build Location-Query option * * * */
         sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->location_query_ptr,
-                     &src_coap_msg_ptr->options_list_ptr->location_query_len, COAP_OPTION_LOCATION_QUERY);
+                     &src_coap_msg_ptr->options_list_ptr->location_query_len, COAP_OPTION_LOCATION_QUERY, &previous_option_number);
 
         /* * * * Build Block2 option * * * * */
         sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->block2_len,
-                     src_coap_msg_ptr->options_list_ptr->block2_ptr, COAP_OPTION_BLOCK2);
+                     src_coap_msg_ptr->options_list_ptr->block2_ptr, COAP_OPTION_BLOCK2, &previous_option_number);
 
         /* * * * Build Block1 option * * * * */
         sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->block1_len,
-                     src_coap_msg_ptr->options_list_ptr->block1_ptr, COAP_OPTION_BLOCK1);
+                     src_coap_msg_ptr->options_list_ptr->block1_ptr, COAP_OPTION_BLOCK1, &previous_option_number);
 
         /* * * * Build Proxy-Uri option * * * */
         sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->proxy_uri_len,
-                     src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr, COAP_OPTION_PROXY_URI);
+                     src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr, COAP_OPTION_PROXY_URI, &previous_option_number);
     }
 
     /* Success */
@@ -674,13 +687,13 @@
  * \return Return value is 0 if option was not added, 1 if added
  */
 static int16_t sn_coap_builder_options_build_add_one_option(uint8_t **dst_packet_data_pptr, uint16_t option_len,
-        uint8_t *option_ptr, sn_coap_option_numbers_e option_number)
+        uint8_t *option_ptr, sn_coap_option_numbers_e option_number, uint16_t *previous_option_number)
 {
     /* Check if there is option at all */
     if (option_ptr != NULL) {
         uint16_t option_delta;
 
-        option_delta = (option_number - global_previous_option_number);
+        option_delta = (option_number - *previous_option_number);
 
         /* * * Build option header * * */
 
@@ -732,7 +745,7 @@
             *dst_packet_data_pptr += 2;
         }
 
-        global_previous_option_number = option_number;
+        *previous_option_number = option_number;
 
         /* Write Option value */
         memcpy(*dst_packet_data_pptr, option_ptr, option_len);
@@ -750,12 +763,16 @@
 /*
  * @return 1 if was added 0 otherwise
 */
-int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number)
+int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr,
+                                                             uint8_t option_length,
+                                                             uint8_t option_exist,
+                                                             sn_coap_option_numbers_e option_number,
+                                                             uint16_t *previous_option_number)
 {
     if ((option_exist != 0) && (option_length == 0)) {
         uint16_t option_delta;
 
-        option_delta = (option_number - global_previous_option_number);
+        option_delta = (option_number - *previous_option_number);
 
         /* * * Build option header * * */
 
@@ -786,7 +803,7 @@
         }
         //<-- Cannot happen currently
 
-        global_previous_option_number = option_number;
+        *previous_option_number = option_number;
 
         return 1;
     }
@@ -808,7 +825,7 @@
  *
  * \return Return value is 0 always
  */
-static int16_t sn_coap_builder_options_build_add_multiple_option(uint8_t **dst_packet_data_pptr, uint8_t **src_pptr, uint16_t *src_len_ptr, sn_coap_option_numbers_e option)
+static int16_t sn_coap_builder_options_build_add_multiple_option(uint8_t **dst_packet_data_pptr, uint8_t **src_pptr, uint16_t *src_len_ptr, sn_coap_option_numbers_e option, uint16_t *previous_option_number)
 {
     /* Check if there is option at all */
     if (*src_pptr != NULL) {
@@ -830,7 +847,7 @@
             query_part_offset = sn_coap_builder_options_get_option_part_position(query_len, query_ptr, i, option);
 
             /* Add Uri-query's one part to Options */
-            sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, one_query_part_len, *src_pptr + query_part_offset, option);
+            sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, one_query_part_len, *src_pptr + query_part_offset, option, previous_option_number);
         }
     }
     /* Success */
@@ -1086,7 +1103,7 @@
 static void sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr)
 {
     /* Check if Payload is used at all */
-    if (src_coap_msg_ptr->payload_ptr != NULL) {
+    if (src_coap_msg_ptr->payload_len && src_coap_msg_ptr->payload_ptr != NULL) {
         /* Write Payload marker */
 
         **dst_packet_data_pptr = 0xff;
@@ -1099,4 +1116,3 @@
         (*dst_packet_data_pptr) += src_coap_msg_ptr->payload_len;
     }
 }
-