Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-client-c by
source/libCoap/src/sn_coap_parser.c@4:5d91b0f5038c, 2016-04-02 (annotated)
- Committer:
- Yogesh Pande
- Date:
- Sat Apr 02 00:39:03 2016 +0300
- Revision:
- 4:5d91b0f5038c
- Parent:
- 1:43f5c94c6771
Latest mbed-client-c sources from Github.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Christopher Haster |
1:43f5c94c6771 | 1 | /* |
Christopher Haster |
1:43f5c94c6771 | 2 | * Copyright (c) 2011-2015 ARM Limited. All rights reserved. |
Christopher Haster |
1:43f5c94c6771 | 3 | * SPDX-License-Identifier: Apache-2.0 |
Christopher Haster |
1:43f5c94c6771 | 4 | * Licensed under the Apache License, Version 2.0 (the License); you may |
Christopher Haster |
1:43f5c94c6771 | 5 | * not use this file except in compliance with the License. |
Christopher Haster |
1:43f5c94c6771 | 6 | * You may obtain a copy of the License at |
Christopher Haster |
1:43f5c94c6771 | 7 | * |
Christopher Haster |
1:43f5c94c6771 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
Christopher Haster |
1:43f5c94c6771 | 9 | * |
Christopher Haster |
1:43f5c94c6771 | 10 | * Unless required by applicable law or agreed to in writing, software |
Christopher Haster |
1:43f5c94c6771 | 11 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
Christopher Haster |
1:43f5c94c6771 | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Christopher Haster |
1:43f5c94c6771 | 13 | * See the License for the specific language governing permissions and |
Christopher Haster |
1:43f5c94c6771 | 14 | * limitations under the License. |
Christopher Haster |
1:43f5c94c6771 | 15 | */ |
Christopher Haster |
1:43f5c94c6771 | 16 | |
Christopher Haster |
1:43f5c94c6771 | 17 | /** |
Christopher Haster |
1:43f5c94c6771 | 18 | *\file sn_coap_parser.c |
Christopher Haster |
1:43f5c94c6771 | 19 | * |
Christopher Haster |
1:43f5c94c6771 | 20 | * \brief CoAP Header parser |
Christopher Haster |
1:43f5c94c6771 | 21 | * |
Christopher Haster |
1:43f5c94c6771 | 22 | * Functionality: Parses CoAP Header |
Christopher Haster |
1:43f5c94c6771 | 23 | * |
Christopher Haster |
1:43f5c94c6771 | 24 | */ |
Christopher Haster |
1:43f5c94c6771 | 25 | |
Christopher Haster |
1:43f5c94c6771 | 26 | /* * * * * * * * * * * * * * */ |
Christopher Haster |
1:43f5c94c6771 | 27 | /* * * * INCLUDE FILES * * * */ |
Christopher Haster |
1:43f5c94c6771 | 28 | /* * * * * * * * * * * * * * */ |
Christopher Haster |
1:43f5c94c6771 | 29 | |
Christopher Haster |
1:43f5c94c6771 | 30 | #include <stdio.h> |
Christopher Haster |
1:43f5c94c6771 | 31 | #include <string.h> /* For memset() and memcpy() */ |
Christopher Haster |
1:43f5c94c6771 | 32 | |
Christopher Haster |
1:43f5c94c6771 | 33 | #include "ns_types.h" |
Christopher Haster |
1:43f5c94c6771 | 34 | #include "sn_nsdl.h" |
Christopher Haster |
1:43f5c94c6771 | 35 | #include "sn_coap_header.h" |
Christopher Haster |
1:43f5c94c6771 | 36 | #include "sn_coap_protocol.h" |
Christopher Haster |
1:43f5c94c6771 | 37 | #include "sn_coap_header_internal.h" |
Christopher Haster |
1:43f5c94c6771 | 38 | #include "sn_coap_protocol_internal.h" |
Christopher Haster |
1:43f5c94c6771 | 39 | |
Christopher Haster |
1:43f5c94c6771 | 40 | /* * * * * * * * * * * * * * * * * * * * */ |
Christopher Haster |
1:43f5c94c6771 | 41 | /* * * * LOCAL FUNCTION PROTOTYPES * * * */ |
Christopher Haster |
1:43f5c94c6771 | 42 | /* * * * * * * * * * * * * * * * * * * * */ |
Christopher Haster |
1:43f5c94c6771 | 43 | |
Christopher Haster |
1:43f5c94c6771 | 44 | static void sn_coap_parser_header_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, coap_version_e *coap_version_ptr); |
Christopher Haster |
1:43f5c94c6771 | 45 | static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, uint8_t *packet_data_start_ptr, uint16_t packet_len); |
Christopher Haster |
1:43f5c94c6771 | 46 | static int8_t sn_coap_parser_options_parse_multiple_options(struct coap_s *handle, uint8_t **packet_data_pptr, uint16_t packet_left_len, uint8_t **dst_pptr, uint16_t *dst_len_ptr, sn_coap_option_numbers_e option, uint16_t option_number_len); |
Christopher Haster |
1:43f5c94c6771 | 47 | static int16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_t *packet_data_ptr, uint16_t packet_left_len, sn_coap_option_numbers_e option, uint16_t option_number_len); |
Christopher Haster |
1:43f5c94c6771 | 48 | static int8_t sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *packet_data_start_ptr, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr); |
Christopher Haster |
1:43f5c94c6771 | 49 | |
Christopher Haster |
1:43f5c94c6771 | 50 | sn_coap_hdr_s *sn_coap_parser(struct coap_s *handle, uint16_t packet_data_len, uint8_t *packet_data_ptr, coap_version_e *coap_version_ptr) |
Christopher Haster |
1:43f5c94c6771 | 51 | { |
Christopher Haster |
1:43f5c94c6771 | 52 | uint8_t *data_temp_ptr = packet_data_ptr; |
Christopher Haster |
1:43f5c94c6771 | 53 | sn_coap_hdr_s *parsed_and_returned_coap_msg_ptr = NULL; |
Christopher Haster |
1:43f5c94c6771 | 54 | |
Christopher Haster |
1:43f5c94c6771 | 55 | /* * * * Check given pointer * * * */ |
Christopher Haster |
1:43f5c94c6771 | 56 | if (packet_data_ptr == NULL || packet_data_len < 4 || handle == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 57 | return NULL; |
Christopher Haster |
1:43f5c94c6771 | 58 | } |
Christopher Haster |
1:43f5c94c6771 | 59 | |
Christopher Haster |
1:43f5c94c6771 | 60 | /* * * * Allocate memory for parsed and returned CoAP message and initialize allocated memory with with zero values * * * */ |
Christopher Haster |
1:43f5c94c6771 | 61 | parsed_and_returned_coap_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_coap_hdr_s)); |
Christopher Haster |
1:43f5c94c6771 | 62 | |
Christopher Haster |
1:43f5c94c6771 | 63 | if (parsed_and_returned_coap_msg_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 64 | return NULL; |
Christopher Haster |
1:43f5c94c6771 | 65 | } |
Christopher Haster |
1:43f5c94c6771 | 66 | |
Christopher Haster |
1:43f5c94c6771 | 67 | memset(parsed_and_returned_coap_msg_ptr, 0x00, sizeof(sn_coap_hdr_s)); |
Christopher Haster |
1:43f5c94c6771 | 68 | |
Christopher Haster |
1:43f5c94c6771 | 69 | |
Christopher Haster |
1:43f5c94c6771 | 70 | /* * * * Header parsing, move pointer over the header... * * * */ |
Christopher Haster |
1:43f5c94c6771 | 71 | sn_coap_parser_header_parse(&data_temp_ptr, parsed_and_returned_coap_msg_ptr, coap_version_ptr); |
Christopher Haster |
1:43f5c94c6771 | 72 | |
Christopher Haster |
1:43f5c94c6771 | 73 | /* * * * Options parsing, move pointer over the options... * * * */ |
Yogesh Pande |
4:5d91b0f5038c | 74 | if (sn_coap_parser_options_parse(handle, &data_temp_ptr, parsed_and_returned_coap_msg_ptr, packet_data_ptr, packet_data_len) != 0) { |
Yogesh Pande |
4:5d91b0f5038c | 75 | parsed_and_returned_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_ERROR_IN_HEADER; |
Yogesh Pande |
4:5d91b0f5038c | 76 | return parsed_and_returned_coap_msg_ptr; |
Christopher Haster |
1:43f5c94c6771 | 77 | } |
Christopher Haster |
1:43f5c94c6771 | 78 | |
Christopher Haster |
1:43f5c94c6771 | 79 | /* * * * Payload parsing * * * */ |
Christopher Haster |
1:43f5c94c6771 | 80 | if (sn_coap_parser_payload_parse(packet_data_len, packet_data_ptr, &data_temp_ptr, parsed_and_returned_coap_msg_ptr) == -1) { |
Yogesh Pande |
4:5d91b0f5038c | 81 | parsed_and_returned_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_ERROR_IN_HEADER; |
Yogesh Pande |
4:5d91b0f5038c | 82 | return parsed_and_returned_coap_msg_ptr; |
Christopher Haster |
1:43f5c94c6771 | 83 | } |
Yogesh Pande |
4:5d91b0f5038c | 84 | |
Christopher Haster |
1:43f5c94c6771 | 85 | /* * * * Return parsed CoAP message * * * * */ |
Christopher Haster |
1:43f5c94c6771 | 86 | return parsed_and_returned_coap_msg_ptr; |
Christopher Haster |
1:43f5c94c6771 | 87 | } |
Christopher Haster |
1:43f5c94c6771 | 88 | |
Christopher Haster |
1:43f5c94c6771 | 89 | void sn_coap_parser_release_allocated_coap_msg_mem(struct coap_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr) |
Christopher Haster |
1:43f5c94c6771 | 90 | { |
Christopher Haster |
1:43f5c94c6771 | 91 | if (handle == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 92 | return; |
Christopher Haster |
1:43f5c94c6771 | 93 | } |
Christopher Haster |
1:43f5c94c6771 | 94 | |
Christopher Haster |
1:43f5c94c6771 | 95 | if (freed_coap_msg_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 96 | if (freed_coap_msg_ptr->uri_path_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 97 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->uri_path_ptr); |
Christopher Haster |
1:43f5c94c6771 | 98 | } |
Christopher Haster |
1:43f5c94c6771 | 99 | |
Christopher Haster |
1:43f5c94c6771 | 100 | if (freed_coap_msg_ptr->token_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 101 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->token_ptr); |
Christopher Haster |
1:43f5c94c6771 | 102 | } |
Christopher Haster |
1:43f5c94c6771 | 103 | |
Christopher Haster |
1:43f5c94c6771 | 104 | if (freed_coap_msg_ptr->content_type_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 105 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->content_type_ptr); |
Christopher Haster |
1:43f5c94c6771 | 106 | } |
Christopher Haster |
1:43f5c94c6771 | 107 | |
Christopher Haster |
1:43f5c94c6771 | 108 | if (freed_coap_msg_ptr->options_list_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 109 | if (freed_coap_msg_ptr->options_list_ptr->max_age_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 110 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->max_age_ptr); |
Christopher Haster |
1:43f5c94c6771 | 111 | } |
Christopher Haster |
1:43f5c94c6771 | 112 | |
Christopher Haster |
1:43f5c94c6771 | 113 | if (freed_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 114 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->proxy_uri_ptr); |
Christopher Haster |
1:43f5c94c6771 | 115 | } |
Christopher Haster |
1:43f5c94c6771 | 116 | |
Christopher Haster |
1:43f5c94c6771 | 117 | if (freed_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 118 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->etag_ptr); |
Christopher Haster |
1:43f5c94c6771 | 119 | } |
Christopher Haster |
1:43f5c94c6771 | 120 | |
Christopher Haster |
1:43f5c94c6771 | 121 | if (freed_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 122 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->uri_host_ptr); |
Christopher Haster |
1:43f5c94c6771 | 123 | } |
Christopher Haster |
1:43f5c94c6771 | 124 | |
Christopher Haster |
1:43f5c94c6771 | 125 | if (freed_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 126 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->location_path_ptr); |
Christopher Haster |
1:43f5c94c6771 | 127 | } |
Christopher Haster |
1:43f5c94c6771 | 128 | |
Christopher Haster |
1:43f5c94c6771 | 129 | if (freed_coap_msg_ptr->options_list_ptr->uri_port_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 130 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->uri_port_ptr); |
Christopher Haster |
1:43f5c94c6771 | 131 | } |
Christopher Haster |
1:43f5c94c6771 | 132 | |
Christopher Haster |
1:43f5c94c6771 | 133 | if (freed_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 134 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->location_query_ptr); |
Christopher Haster |
1:43f5c94c6771 | 135 | } |
Christopher Haster |
1:43f5c94c6771 | 136 | |
Christopher Haster |
1:43f5c94c6771 | 137 | if (freed_coap_msg_ptr->options_list_ptr->observe_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 138 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->observe_ptr); |
Christopher Haster |
1:43f5c94c6771 | 139 | } |
Christopher Haster |
1:43f5c94c6771 | 140 | |
Christopher Haster |
1:43f5c94c6771 | 141 | if (freed_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 142 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->uri_query_ptr); |
Christopher Haster |
1:43f5c94c6771 | 143 | } |
Christopher Haster |
1:43f5c94c6771 | 144 | |
Christopher Haster |
1:43f5c94c6771 | 145 | if (freed_coap_msg_ptr->options_list_ptr->block2_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 146 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->block2_ptr); |
Christopher Haster |
1:43f5c94c6771 | 147 | } |
Christopher Haster |
1:43f5c94c6771 | 148 | |
Christopher Haster |
1:43f5c94c6771 | 149 | if (freed_coap_msg_ptr->options_list_ptr->block1_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 150 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->block1_ptr); |
Christopher Haster |
1:43f5c94c6771 | 151 | } |
Christopher Haster |
1:43f5c94c6771 | 152 | if (freed_coap_msg_ptr->options_list_ptr->accept_ptr != NULL) { |
Christopher Haster |
1:43f5c94c6771 | 153 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->accept_ptr); |
Christopher Haster |
1:43f5c94c6771 | 154 | } |
Christopher Haster |
1:43f5c94c6771 | 155 | |
Christopher Haster |
1:43f5c94c6771 | 156 | handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr); |
Christopher Haster |
1:43f5c94c6771 | 157 | } |
Christopher Haster |
1:43f5c94c6771 | 158 | |
Christopher Haster |
1:43f5c94c6771 | 159 | handle->sn_coap_protocol_free(freed_coap_msg_ptr); |
Christopher Haster |
1:43f5c94c6771 | 160 | } |
Christopher Haster |
1:43f5c94c6771 | 161 | } |
Christopher Haster |
1:43f5c94c6771 | 162 | |
Christopher Haster |
1:43f5c94c6771 | 163 | /** |
Christopher Haster |
1:43f5c94c6771 | 164 | * \fn static void sn_coap_parser_header_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, coap_version_e *coap_version_ptr) |
Christopher Haster |
1:43f5c94c6771 | 165 | * |
Christopher Haster |
1:43f5c94c6771 | 166 | * \brief Parses CoAP message's Header part from given Packet data |
Christopher Haster |
1:43f5c94c6771 | 167 | * |
Christopher Haster |
1:43f5c94c6771 | 168 | * \param **packet_data_ptr is source for Packet data to be parsed to CoAP message |
Christopher Haster |
1:43f5c94c6771 | 169 | * |
Christopher Haster |
1:43f5c94c6771 | 170 | * \param *dst_coap_msg_ptr is destination for parsed CoAP message |
Christopher Haster |
1:43f5c94c6771 | 171 | * |
Christopher Haster |
1:43f5c94c6771 | 172 | * \param *coap_version_ptr is destination for parsed CoAP specification version |
Christopher Haster |
1:43f5c94c6771 | 173 | */ |
Christopher Haster |
1:43f5c94c6771 | 174 | static void sn_coap_parser_header_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, coap_version_e *coap_version_ptr) |
Christopher Haster |
1:43f5c94c6771 | 175 | { |
Christopher Haster |
1:43f5c94c6771 | 176 | /* Parse CoAP Version and message type*/ |
Christopher Haster |
1:43f5c94c6771 | 177 | *coap_version_ptr = (coap_version_e)(**packet_data_pptr & COAP_HEADER_VERSION_MASK); |
Christopher Haster |
1:43f5c94c6771 | 178 | dst_coap_msg_ptr->msg_type = (sn_coap_msg_type_e)(**packet_data_pptr & COAP_HEADER_MSG_TYPE_MASK); |
Christopher Haster |
1:43f5c94c6771 | 179 | (*packet_data_pptr) += 1; |
Christopher Haster |
1:43f5c94c6771 | 180 | |
Christopher Haster |
1:43f5c94c6771 | 181 | /* Parse Message code */ |
Christopher Haster |
1:43f5c94c6771 | 182 | dst_coap_msg_ptr->msg_code = (sn_coap_msg_code_e) **packet_data_pptr; |
Christopher Haster |
1:43f5c94c6771 | 183 | (*packet_data_pptr) += 1; |
Christopher Haster |
1:43f5c94c6771 | 184 | |
Christopher Haster |
1:43f5c94c6771 | 185 | /* Parse Message ID */ |
Christopher Haster |
1:43f5c94c6771 | 186 | dst_coap_msg_ptr->msg_id = *(*packet_data_pptr + 1); |
Christopher Haster |
1:43f5c94c6771 | 187 | dst_coap_msg_ptr->msg_id += **packet_data_pptr << COAP_HEADER_MSG_ID_MSB_SHIFT; |
Christopher Haster |
1:43f5c94c6771 | 188 | (*packet_data_pptr) += 2; |
Christopher Haster |
1:43f5c94c6771 | 189 | |
Christopher Haster |
1:43f5c94c6771 | 190 | } |
Christopher Haster |
1:43f5c94c6771 | 191 | |
Christopher Haster |
1:43f5c94c6771 | 192 | /** |
Christopher Haster |
1:43f5c94c6771 | 193 | * \fn static uint8_t sn_coap_parser_options_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr) |
Christopher Haster |
1:43f5c94c6771 | 194 | * |
Christopher Haster |
1:43f5c94c6771 | 195 | * \brief Parses CoAP message's Options part from given Packet data |
Christopher Haster |
1:43f5c94c6771 | 196 | * |
Christopher Haster |
1:43f5c94c6771 | 197 | * \param **packet_data_pptr is source of Packet data to be parsed to CoAP message |
Christopher Haster |
1:43f5c94c6771 | 198 | * \param *dst_coap_msg_ptr is destination for parsed CoAP message |
Christopher Haster |
1:43f5c94c6771 | 199 | * |
Christopher Haster |
1:43f5c94c6771 | 200 | * \return Return value is 0 in ok case and -1 in failure case |
Christopher Haster |
1:43f5c94c6771 | 201 | */ |
Christopher Haster |
1:43f5c94c6771 | 202 | static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, uint8_t *packet_data_start_ptr, uint16_t packet_len) |
Christopher Haster |
1:43f5c94c6771 | 203 | { |
Christopher Haster |
1:43f5c94c6771 | 204 | uint8_t previous_option_number = 0; |
Christopher Haster |
1:43f5c94c6771 | 205 | uint8_t i = 0; |
Christopher Haster |
1:43f5c94c6771 | 206 | int8_t ret_status = 0; |
Christopher Haster |
1:43f5c94c6771 | 207 | uint16_t message_left = 0; |
Christopher Haster |
1:43f5c94c6771 | 208 | |
Christopher Haster |
1:43f5c94c6771 | 209 | /* Parse token, if exists */ |
Christopher Haster |
1:43f5c94c6771 | 210 | dst_coap_msg_ptr->token_len = *packet_data_start_ptr & COAP_HEADER_TOKEN_LENGTH_MASK; |
Christopher Haster |
1:43f5c94c6771 | 211 | |
Christopher Haster |
1:43f5c94c6771 | 212 | if (dst_coap_msg_ptr->token_len) { |
Christopher Haster |
1:43f5c94c6771 | 213 | if ((dst_coap_msg_ptr->token_len > 8) || dst_coap_msg_ptr->token_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 214 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 215 | } |
Christopher Haster |
1:43f5c94c6771 | 216 | |
Christopher Haster |
1:43f5c94c6771 | 217 | dst_coap_msg_ptr->token_ptr = handle->sn_coap_protocol_malloc(dst_coap_msg_ptr->token_len); |
Christopher Haster |
1:43f5c94c6771 | 218 | |
Christopher Haster |
1:43f5c94c6771 | 219 | if (dst_coap_msg_ptr->token_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 220 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 221 | } |
Christopher Haster |
1:43f5c94c6771 | 222 | |
Christopher Haster |
1:43f5c94c6771 | 223 | memcpy(dst_coap_msg_ptr->token_ptr, *packet_data_pptr, dst_coap_msg_ptr->token_len); |
Christopher Haster |
1:43f5c94c6771 | 224 | (*packet_data_pptr) += dst_coap_msg_ptr->token_len; |
Christopher Haster |
1:43f5c94c6771 | 225 | } |
Christopher Haster |
1:43f5c94c6771 | 226 | |
Christopher Haster |
1:43f5c94c6771 | 227 | message_left = packet_len - ((*packet_data_pptr) - packet_data_start_ptr); |
Christopher Haster |
1:43f5c94c6771 | 228 | |
Christopher Haster |
1:43f5c94c6771 | 229 | /* Loop all Options */ |
Christopher Haster |
1:43f5c94c6771 | 230 | while (message_left && (**packet_data_pptr != 0xff)) { |
Christopher Haster |
1:43f5c94c6771 | 231 | |
Christopher Haster |
1:43f5c94c6771 | 232 | /* Get option length WITHOUT extensions */ |
Christopher Haster |
1:43f5c94c6771 | 233 | uint16_t option_len = (**packet_data_pptr & 0x0F); |
Christopher Haster |
1:43f5c94c6771 | 234 | |
Christopher Haster |
1:43f5c94c6771 | 235 | /* Option number length 15 is reserved for the future use - ERROR */ |
Christopher Haster |
1:43f5c94c6771 | 236 | if (option_len == 15) { |
Christopher Haster |
1:43f5c94c6771 | 237 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 238 | } |
Christopher Haster |
1:43f5c94c6771 | 239 | |
Christopher Haster |
1:43f5c94c6771 | 240 | /* Resolve option delta */ |
Christopher Haster |
1:43f5c94c6771 | 241 | uint16_t option_number = (**packet_data_pptr >> COAP_OPTIONS_OPTION_NUMBER_SHIFT); |
Christopher Haster |
1:43f5c94c6771 | 242 | |
Christopher Haster |
1:43f5c94c6771 | 243 | if (option_number == 13) { |
Christopher Haster |
1:43f5c94c6771 | 244 | option_number = *(*packet_data_pptr + 1) + 13; |
Christopher Haster |
1:43f5c94c6771 | 245 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 246 | } else if (option_number == 14) { |
Christopher Haster |
1:43f5c94c6771 | 247 | option_number = *(*packet_data_pptr + 2); |
Christopher Haster |
1:43f5c94c6771 | 248 | option_number += (*(*packet_data_pptr + 1) << 8) + 269; |
Christopher Haster |
1:43f5c94c6771 | 249 | (*packet_data_pptr) += 2; |
Christopher Haster |
1:43f5c94c6771 | 250 | } |
Christopher Haster |
1:43f5c94c6771 | 251 | /* Option number 15 reserved for payload marker. This is handled as a error! */ |
Christopher Haster |
1:43f5c94c6771 | 252 | else if (option_number == 15) { |
Christopher Haster |
1:43f5c94c6771 | 253 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 254 | } |
Christopher Haster |
1:43f5c94c6771 | 255 | |
Christopher Haster |
1:43f5c94c6771 | 256 | /* Add previous option to option delta and get option number */ |
Christopher Haster |
1:43f5c94c6771 | 257 | option_number += previous_option_number; |
Christopher Haster |
1:43f5c94c6771 | 258 | |
Christopher Haster |
1:43f5c94c6771 | 259 | /* Add possible option length extension to resolve full length of the option */ |
Christopher Haster |
1:43f5c94c6771 | 260 | if (option_len == 13) { |
Christopher Haster |
1:43f5c94c6771 | 261 | option_len = *(*packet_data_pptr + 1) + 13; |
Christopher Haster |
1:43f5c94c6771 | 262 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 263 | } else if (option_len == 14) { |
Christopher Haster |
1:43f5c94c6771 | 264 | option_len = *(*packet_data_pptr + 2); |
Christopher Haster |
1:43f5c94c6771 | 265 | option_len += (*(*packet_data_pptr + 1) << 8) + 269; |
Christopher Haster |
1:43f5c94c6771 | 266 | (*packet_data_pptr) += 2; |
Christopher Haster |
1:43f5c94c6771 | 267 | } |
Christopher Haster |
1:43f5c94c6771 | 268 | |
Christopher Haster |
1:43f5c94c6771 | 269 | |
Christopher Haster |
1:43f5c94c6771 | 270 | /* * * Parse option itself * * */ |
Christopher Haster |
1:43f5c94c6771 | 271 | /* Some options are handled independently in own functions */ |
Christopher Haster |
1:43f5c94c6771 | 272 | previous_option_number = option_number; |
Christopher Haster |
1:43f5c94c6771 | 273 | |
Christopher Haster |
1:43f5c94c6771 | 274 | /* Allocate options_list_ptr if needed */ |
Christopher Haster |
1:43f5c94c6771 | 275 | switch (option_number) { |
Christopher Haster |
1:43f5c94c6771 | 276 | case COAP_OPTION_MAX_AGE: |
Christopher Haster |
1:43f5c94c6771 | 277 | case COAP_OPTION_PROXY_URI: |
Christopher Haster |
1:43f5c94c6771 | 278 | case COAP_OPTION_ETAG: |
Christopher Haster |
1:43f5c94c6771 | 279 | case COAP_OPTION_URI_HOST: |
Christopher Haster |
1:43f5c94c6771 | 280 | case COAP_OPTION_LOCATION_PATH: |
Christopher Haster |
1:43f5c94c6771 | 281 | case COAP_OPTION_URI_PORT: |
Christopher Haster |
1:43f5c94c6771 | 282 | case COAP_OPTION_LOCATION_QUERY: |
Christopher Haster |
1:43f5c94c6771 | 283 | case COAP_OPTION_OBSERVE: |
Christopher Haster |
1:43f5c94c6771 | 284 | case COAP_OPTION_URI_QUERY: |
Christopher Haster |
1:43f5c94c6771 | 285 | case COAP_OPTION_BLOCK2: |
Christopher Haster |
1:43f5c94c6771 | 286 | case COAP_OPTION_BLOCK1: |
Christopher Haster |
1:43f5c94c6771 | 287 | case COAP_OPTION_ACCEPT: |
Christopher Haster |
1:43f5c94c6771 | 288 | if (dst_coap_msg_ptr->options_list_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 289 | dst_coap_msg_ptr->options_list_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s)); |
Christopher Haster |
1:43f5c94c6771 | 290 | if (NULL == dst_coap_msg_ptr->options_list_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 291 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 292 | } |
Christopher Haster |
1:43f5c94c6771 | 293 | memset(dst_coap_msg_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s)); |
Christopher Haster |
1:43f5c94c6771 | 294 | } |
Christopher Haster |
1:43f5c94c6771 | 295 | break; |
Christopher Haster |
1:43f5c94c6771 | 296 | } |
Christopher Haster |
1:43f5c94c6771 | 297 | |
Christopher Haster |
1:43f5c94c6771 | 298 | /* Parse option */ |
Christopher Haster |
1:43f5c94c6771 | 299 | switch (option_number) { |
Christopher Haster |
1:43f5c94c6771 | 300 | case COAP_OPTION_CONTENT_FORMAT: |
Christopher Haster |
1:43f5c94c6771 | 301 | if ((option_len > 2) || (dst_coap_msg_ptr->content_type_ptr)) { |
Christopher Haster |
1:43f5c94c6771 | 302 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 303 | } |
Christopher Haster |
1:43f5c94c6771 | 304 | dst_coap_msg_ptr->content_type_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 305 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 306 | |
Christopher Haster |
1:43f5c94c6771 | 307 | if (option_len) { |
Christopher Haster |
1:43f5c94c6771 | 308 | dst_coap_msg_ptr->content_type_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 309 | |
Christopher Haster |
1:43f5c94c6771 | 310 | if (dst_coap_msg_ptr->content_type_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 311 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 312 | } |
Christopher Haster |
1:43f5c94c6771 | 313 | |
Christopher Haster |
1:43f5c94c6771 | 314 | memcpy(dst_coap_msg_ptr->content_type_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 315 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 316 | } |
Christopher Haster |
1:43f5c94c6771 | 317 | break; |
Christopher Haster |
1:43f5c94c6771 | 318 | |
Christopher Haster |
1:43f5c94c6771 | 319 | case COAP_OPTION_MAX_AGE: |
Christopher Haster |
1:43f5c94c6771 | 320 | if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->max_age_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 321 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 322 | } |
Christopher Haster |
1:43f5c94c6771 | 323 | dst_coap_msg_ptr->options_list_ptr->max_age_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 324 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 325 | |
Christopher Haster |
1:43f5c94c6771 | 326 | if (option_len) { |
Christopher Haster |
1:43f5c94c6771 | 327 | dst_coap_msg_ptr->options_list_ptr->max_age_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 328 | |
Christopher Haster |
1:43f5c94c6771 | 329 | if (dst_coap_msg_ptr->options_list_ptr->max_age_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 330 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 331 | } |
Christopher Haster |
1:43f5c94c6771 | 332 | |
Christopher Haster |
1:43f5c94c6771 | 333 | memcpy(dst_coap_msg_ptr->options_list_ptr->max_age_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 334 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 335 | } |
Christopher Haster |
1:43f5c94c6771 | 336 | break; |
Christopher Haster |
1:43f5c94c6771 | 337 | |
Christopher Haster |
1:43f5c94c6771 | 338 | case COAP_OPTION_PROXY_URI: |
Christopher Haster |
1:43f5c94c6771 | 339 | if ((option_len > 1034) || (option_len < 1) || dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 340 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 341 | } |
Christopher Haster |
1:43f5c94c6771 | 342 | dst_coap_msg_ptr->options_list_ptr->proxy_uri_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 343 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 344 | |
Christopher Haster |
1:43f5c94c6771 | 345 | dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 346 | |
Christopher Haster |
1:43f5c94c6771 | 347 | if (dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 348 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 349 | } |
Christopher Haster |
1:43f5c94c6771 | 350 | memcpy(dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 351 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 352 | |
Christopher Haster |
1:43f5c94c6771 | 353 | break; |
Christopher Haster |
1:43f5c94c6771 | 354 | |
Christopher Haster |
1:43f5c94c6771 | 355 | case COAP_OPTION_ETAG: |
Christopher Haster |
1:43f5c94c6771 | 356 | /* This is managed independently because User gives this option in one character table */ |
Christopher Haster |
1:43f5c94c6771 | 357 | |
Christopher Haster |
1:43f5c94c6771 | 358 | ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, |
Christopher Haster |
1:43f5c94c6771 | 359 | message_left, |
Christopher Haster |
1:43f5c94c6771 | 360 | &dst_coap_msg_ptr->options_list_ptr->etag_ptr, |
Christopher Haster |
1:43f5c94c6771 | 361 | (uint16_t *)&dst_coap_msg_ptr->options_list_ptr->etag_len, |
Christopher Haster |
1:43f5c94c6771 | 362 | COAP_OPTION_ETAG, option_len); |
Christopher Haster |
1:43f5c94c6771 | 363 | if (ret_status >= 0) { |
Christopher Haster |
1:43f5c94c6771 | 364 | i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ |
Christopher Haster |
1:43f5c94c6771 | 365 | } else { |
Christopher Haster |
1:43f5c94c6771 | 366 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 367 | } |
Christopher Haster |
1:43f5c94c6771 | 368 | break; |
Christopher Haster |
1:43f5c94c6771 | 369 | |
Christopher Haster |
1:43f5c94c6771 | 370 | case COAP_OPTION_URI_HOST: |
Christopher Haster |
1:43f5c94c6771 | 371 | if ((option_len > 255) || (option_len < 1) || dst_coap_msg_ptr->options_list_ptr->uri_host_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 372 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 373 | } |
Christopher Haster |
1:43f5c94c6771 | 374 | dst_coap_msg_ptr->options_list_ptr->uri_host_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 375 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 376 | |
Christopher Haster |
1:43f5c94c6771 | 377 | dst_coap_msg_ptr->options_list_ptr->uri_host_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 378 | |
Christopher Haster |
1:43f5c94c6771 | 379 | if (dst_coap_msg_ptr->options_list_ptr->uri_host_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 380 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 381 | } |
Christopher Haster |
1:43f5c94c6771 | 382 | memcpy(dst_coap_msg_ptr->options_list_ptr->uri_host_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 383 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 384 | |
Christopher Haster |
1:43f5c94c6771 | 385 | break; |
Christopher Haster |
1:43f5c94c6771 | 386 | |
Christopher Haster |
1:43f5c94c6771 | 387 | case COAP_OPTION_LOCATION_PATH: |
Christopher Haster |
1:43f5c94c6771 | 388 | if (dst_coap_msg_ptr->options_list_ptr->location_path_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 389 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 390 | } |
Christopher Haster |
1:43f5c94c6771 | 391 | /* This is managed independently because User gives this option in one character table */ |
Christopher Haster |
1:43f5c94c6771 | 392 | ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left, |
Christopher Haster |
1:43f5c94c6771 | 393 | &dst_coap_msg_ptr->options_list_ptr->location_path_ptr, &dst_coap_msg_ptr->options_list_ptr->location_path_len, |
Christopher Haster |
1:43f5c94c6771 | 394 | COAP_OPTION_LOCATION_PATH, option_len); |
Christopher Haster |
1:43f5c94c6771 | 395 | if (ret_status >= 0) { |
Christopher Haster |
1:43f5c94c6771 | 396 | i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ |
Christopher Haster |
1:43f5c94c6771 | 397 | } else { |
Christopher Haster |
1:43f5c94c6771 | 398 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 399 | } |
Christopher Haster |
1:43f5c94c6771 | 400 | |
Christopher Haster |
1:43f5c94c6771 | 401 | break; |
Christopher Haster |
1:43f5c94c6771 | 402 | |
Christopher Haster |
1:43f5c94c6771 | 403 | |
Christopher Haster |
1:43f5c94c6771 | 404 | case COAP_OPTION_URI_PORT: |
Christopher Haster |
1:43f5c94c6771 | 405 | if ((option_len > 2) || dst_coap_msg_ptr->options_list_ptr->uri_port_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 406 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 407 | } |
Christopher Haster |
1:43f5c94c6771 | 408 | dst_coap_msg_ptr->options_list_ptr->uri_port_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 409 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 410 | |
Christopher Haster |
1:43f5c94c6771 | 411 | if (option_len) { |
Christopher Haster |
1:43f5c94c6771 | 412 | dst_coap_msg_ptr->options_list_ptr->uri_port_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 413 | |
Christopher Haster |
1:43f5c94c6771 | 414 | if (dst_coap_msg_ptr->options_list_ptr->uri_port_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 415 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 416 | } |
Christopher Haster |
1:43f5c94c6771 | 417 | memcpy(dst_coap_msg_ptr->options_list_ptr->uri_port_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 418 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 419 | } |
Christopher Haster |
1:43f5c94c6771 | 420 | break; |
Christopher Haster |
1:43f5c94c6771 | 421 | |
Christopher Haster |
1:43f5c94c6771 | 422 | case COAP_OPTION_LOCATION_QUERY: |
Christopher Haster |
1:43f5c94c6771 | 423 | ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left, |
Christopher Haster |
1:43f5c94c6771 | 424 | &dst_coap_msg_ptr->options_list_ptr->location_query_ptr, &dst_coap_msg_ptr->options_list_ptr->location_query_len, |
Christopher Haster |
1:43f5c94c6771 | 425 | COAP_OPTION_LOCATION_QUERY, option_len); |
Christopher Haster |
1:43f5c94c6771 | 426 | if (ret_status >= 0) { |
Christopher Haster |
1:43f5c94c6771 | 427 | i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ |
Christopher Haster |
1:43f5c94c6771 | 428 | } else { |
Christopher Haster |
1:43f5c94c6771 | 429 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 430 | } |
Christopher Haster |
1:43f5c94c6771 | 431 | |
Christopher Haster |
1:43f5c94c6771 | 432 | break; |
Christopher Haster |
1:43f5c94c6771 | 433 | |
Christopher Haster |
1:43f5c94c6771 | 434 | case COAP_OPTION_URI_PATH: |
Christopher Haster |
1:43f5c94c6771 | 435 | ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left, |
Christopher Haster |
1:43f5c94c6771 | 436 | &dst_coap_msg_ptr->uri_path_ptr, &dst_coap_msg_ptr->uri_path_len, |
Christopher Haster |
1:43f5c94c6771 | 437 | COAP_OPTION_URI_PATH, option_len); |
Christopher Haster |
1:43f5c94c6771 | 438 | if (ret_status >= 0) { |
Christopher Haster |
1:43f5c94c6771 | 439 | i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ |
Christopher Haster |
1:43f5c94c6771 | 440 | } else { |
Christopher Haster |
1:43f5c94c6771 | 441 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 442 | } |
Christopher Haster |
1:43f5c94c6771 | 443 | |
Christopher Haster |
1:43f5c94c6771 | 444 | break; |
Christopher Haster |
1:43f5c94c6771 | 445 | |
Christopher Haster |
1:43f5c94c6771 | 446 | case COAP_OPTION_OBSERVE: |
Christopher Haster |
1:43f5c94c6771 | 447 | if ((option_len > 2) || dst_coap_msg_ptr->options_list_ptr->observe_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 448 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 449 | } |
Christopher Haster |
1:43f5c94c6771 | 450 | |
Christopher Haster |
1:43f5c94c6771 | 451 | dst_coap_msg_ptr->options_list_ptr->observe = 1; |
Christopher Haster |
1:43f5c94c6771 | 452 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 453 | |
Christopher Haster |
1:43f5c94c6771 | 454 | if (option_len) { |
Christopher Haster |
1:43f5c94c6771 | 455 | |
Christopher Haster |
1:43f5c94c6771 | 456 | dst_coap_msg_ptr->options_list_ptr->observe_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 457 | |
Christopher Haster |
1:43f5c94c6771 | 458 | dst_coap_msg_ptr->options_list_ptr->observe_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 459 | |
Christopher Haster |
1:43f5c94c6771 | 460 | if (dst_coap_msg_ptr->options_list_ptr->observe_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 461 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 462 | } |
Christopher Haster |
1:43f5c94c6771 | 463 | |
Christopher Haster |
1:43f5c94c6771 | 464 | memcpy(dst_coap_msg_ptr->options_list_ptr->observe_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 465 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 466 | } |
Christopher Haster |
1:43f5c94c6771 | 467 | |
Christopher Haster |
1:43f5c94c6771 | 468 | break; |
Christopher Haster |
1:43f5c94c6771 | 469 | |
Christopher Haster |
1:43f5c94c6771 | 470 | case COAP_OPTION_URI_QUERY: |
Christopher Haster |
1:43f5c94c6771 | 471 | ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left, |
Christopher Haster |
1:43f5c94c6771 | 472 | &dst_coap_msg_ptr->options_list_ptr->uri_query_ptr, &dst_coap_msg_ptr->options_list_ptr->uri_query_len, |
Christopher Haster |
1:43f5c94c6771 | 473 | COAP_OPTION_URI_QUERY, option_len); |
Christopher Haster |
1:43f5c94c6771 | 474 | if (ret_status >= 0) { |
Christopher Haster |
1:43f5c94c6771 | 475 | i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ |
Christopher Haster |
1:43f5c94c6771 | 476 | } else { |
Christopher Haster |
1:43f5c94c6771 | 477 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 478 | } |
Christopher Haster |
1:43f5c94c6771 | 479 | |
Christopher Haster |
1:43f5c94c6771 | 480 | break; |
Christopher Haster |
1:43f5c94c6771 | 481 | |
Christopher Haster |
1:43f5c94c6771 | 482 | case COAP_OPTION_BLOCK2: |
Christopher Haster |
1:43f5c94c6771 | 483 | if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->block2_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 484 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 485 | } |
Christopher Haster |
1:43f5c94c6771 | 486 | dst_coap_msg_ptr->options_list_ptr->block2_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 487 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 488 | |
Christopher Haster |
1:43f5c94c6771 | 489 | dst_coap_msg_ptr->options_list_ptr->block2_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 490 | |
Christopher Haster |
1:43f5c94c6771 | 491 | if (dst_coap_msg_ptr->options_list_ptr->block2_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 492 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 493 | } |
Christopher Haster |
1:43f5c94c6771 | 494 | |
Christopher Haster |
1:43f5c94c6771 | 495 | memcpy(dst_coap_msg_ptr->options_list_ptr->block2_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 496 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 497 | |
Christopher Haster |
1:43f5c94c6771 | 498 | break; |
Christopher Haster |
1:43f5c94c6771 | 499 | |
Christopher Haster |
1:43f5c94c6771 | 500 | case COAP_OPTION_BLOCK1: |
Christopher Haster |
1:43f5c94c6771 | 501 | if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->block1_ptr) { |
Christopher Haster |
1:43f5c94c6771 | 502 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 503 | } |
Christopher Haster |
1:43f5c94c6771 | 504 | dst_coap_msg_ptr->options_list_ptr->block1_len = option_len; |
Christopher Haster |
1:43f5c94c6771 | 505 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 506 | |
Christopher Haster |
1:43f5c94c6771 | 507 | dst_coap_msg_ptr->options_list_ptr->block1_ptr = handle->sn_coap_protocol_malloc(option_len); |
Christopher Haster |
1:43f5c94c6771 | 508 | |
Christopher Haster |
1:43f5c94c6771 | 509 | if (dst_coap_msg_ptr->options_list_ptr->block1_ptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 510 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 511 | } |
Christopher Haster |
1:43f5c94c6771 | 512 | |
Christopher Haster |
1:43f5c94c6771 | 513 | memcpy(dst_coap_msg_ptr->options_list_ptr->block1_ptr, *packet_data_pptr, option_len); |
Christopher Haster |
1:43f5c94c6771 | 514 | (*packet_data_pptr) += option_len; |
Christopher Haster |
1:43f5c94c6771 | 515 | |
Christopher Haster |
1:43f5c94c6771 | 516 | break; |
Christopher Haster |
1:43f5c94c6771 | 517 | |
Christopher Haster |
1:43f5c94c6771 | 518 | case COAP_OPTION_ACCEPT: |
Christopher Haster |
1:43f5c94c6771 | 519 | ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left, |
Christopher Haster |
1:43f5c94c6771 | 520 | &dst_coap_msg_ptr->options_list_ptr->accept_ptr, (uint16_t *)&dst_coap_msg_ptr->options_list_ptr->accept_len, |
Christopher Haster |
1:43f5c94c6771 | 521 | COAP_OPTION_ACCEPT, option_len); |
Christopher Haster |
1:43f5c94c6771 | 522 | if (ret_status >= 0) { |
Christopher Haster |
1:43f5c94c6771 | 523 | i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ |
Christopher Haster |
1:43f5c94c6771 | 524 | } else { |
Christopher Haster |
1:43f5c94c6771 | 525 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 526 | } |
Christopher Haster |
1:43f5c94c6771 | 527 | |
Christopher Haster |
1:43f5c94c6771 | 528 | break; |
Christopher Haster |
1:43f5c94c6771 | 529 | |
Christopher Haster |
1:43f5c94c6771 | 530 | default: |
Christopher Haster |
1:43f5c94c6771 | 531 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 532 | } |
Christopher Haster |
1:43f5c94c6771 | 533 | |
Christopher Haster |
1:43f5c94c6771 | 534 | /* Check for overflow */ |
Christopher Haster |
1:43f5c94c6771 | 535 | if ((*packet_data_pptr - packet_data_start_ptr) > packet_len) { |
Christopher Haster |
1:43f5c94c6771 | 536 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 537 | } |
Christopher Haster |
1:43f5c94c6771 | 538 | |
Christopher Haster |
1:43f5c94c6771 | 539 | message_left = packet_len - (*packet_data_pptr - packet_data_start_ptr); |
Christopher Haster |
1:43f5c94c6771 | 540 | |
Christopher Haster |
1:43f5c94c6771 | 541 | |
Christopher Haster |
1:43f5c94c6771 | 542 | } |
Christopher Haster |
1:43f5c94c6771 | 543 | |
Christopher Haster |
1:43f5c94c6771 | 544 | return 0; |
Christopher Haster |
1:43f5c94c6771 | 545 | } |
Christopher Haster |
1:43f5c94c6771 | 546 | |
Christopher Haster |
1:43f5c94c6771 | 547 | |
Christopher Haster |
1:43f5c94c6771 | 548 | /** |
Christopher Haster |
1:43f5c94c6771 | 549 | * \fn static int8_t sn_coap_parser_options_parse_multiple_options(uint8_t **packet_data_pptr, uint8_t options_count_left, uint8_t *previous_option_number_ptr, uint8_t **dst_pptr, |
Christopher Haster |
1:43f5c94c6771 | 550 | * uint16_t *dst_len_ptr, sn_coap_option_numbers_e option, uint16_t option_number_len) |
Christopher Haster |
1:43f5c94c6771 | 551 | * |
Christopher Haster |
1:43f5c94c6771 | 552 | * \brief Parses CoAP message's Uri-query options |
Christopher Haster |
1:43f5c94c6771 | 553 | * |
Christopher Haster |
1:43f5c94c6771 | 554 | * \param **packet_data_pptr is source for Packet data to be parsed to CoAP message |
Christopher Haster |
1:43f5c94c6771 | 555 | * |
Christopher Haster |
1:43f5c94c6771 | 556 | * \param *dst_coap_msg_ptr is destination for parsed CoAP message |
Christopher Haster |
1:43f5c94c6771 | 557 | * |
Christopher Haster |
1:43f5c94c6771 | 558 | * \param options_count_left tells how many options are unhandled in Packet data |
Christopher Haster |
1:43f5c94c6771 | 559 | * |
Christopher Haster |
1:43f5c94c6771 | 560 | * \param *previous_option_number_ptr is pointer to used and returned previous Option number |
Christopher Haster |
1:43f5c94c6771 | 561 | * |
Christopher Haster |
1:43f5c94c6771 | 562 | * \return Return value is count of Uri-query optios parsed. In failure case -1 is returned. |
Christopher Haster |
1:43f5c94c6771 | 563 | */ |
Christopher Haster |
1:43f5c94c6771 | 564 | static int8_t sn_coap_parser_options_parse_multiple_options(struct coap_s *handle, uint8_t **packet_data_pptr, uint16_t packet_left_len, uint8_t **dst_pptr, uint16_t *dst_len_ptr, sn_coap_option_numbers_e option, uint16_t option_number_len) |
Christopher Haster |
1:43f5c94c6771 | 565 | { |
Christopher Haster |
1:43f5c94c6771 | 566 | int16_t uri_query_needed_heap = sn_coap_parser_options_count_needed_memory_multiple_option(*packet_data_pptr, packet_left_len, option, option_number_len); |
Christopher Haster |
1:43f5c94c6771 | 567 | uint8_t *temp_parsed_uri_query_ptr = NULL; |
Christopher Haster |
1:43f5c94c6771 | 568 | uint8_t returned_option_counter = 0; |
Christopher Haster |
1:43f5c94c6771 | 569 | |
Christopher Haster |
1:43f5c94c6771 | 570 | if (uri_query_needed_heap == -1) { |
Christopher Haster |
1:43f5c94c6771 | 571 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 572 | } |
Christopher Haster |
1:43f5c94c6771 | 573 | |
Christopher Haster |
1:43f5c94c6771 | 574 | if (uri_query_needed_heap) { |
Christopher Haster |
1:43f5c94c6771 | 575 | *dst_pptr = (uint8_t *) handle->sn_coap_protocol_malloc(uri_query_needed_heap); |
Christopher Haster |
1:43f5c94c6771 | 576 | |
Christopher Haster |
1:43f5c94c6771 | 577 | if (*dst_pptr == NULL) { |
Christopher Haster |
1:43f5c94c6771 | 578 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 579 | } |
Christopher Haster |
1:43f5c94c6771 | 580 | } |
Christopher Haster |
1:43f5c94c6771 | 581 | |
Christopher Haster |
1:43f5c94c6771 | 582 | *dst_len_ptr = uri_query_needed_heap; |
Christopher Haster |
1:43f5c94c6771 | 583 | |
Christopher Haster |
1:43f5c94c6771 | 584 | temp_parsed_uri_query_ptr = *dst_pptr; |
Christopher Haster |
1:43f5c94c6771 | 585 | |
Christopher Haster |
1:43f5c94c6771 | 586 | /* Loop all Uri-Query options */ |
Christopher Haster |
1:43f5c94c6771 | 587 | while ((temp_parsed_uri_query_ptr - *dst_pptr) < uri_query_needed_heap) { |
Christopher Haster |
1:43f5c94c6771 | 588 | /* Check if this is first Uri-Query option */ |
Christopher Haster |
1:43f5c94c6771 | 589 | if (returned_option_counter > 0) { |
Christopher Haster |
1:43f5c94c6771 | 590 | /* Uri-Query is modified to following format: temp1'\0'temp2'\0'temp3 i.e. */ |
Christopher Haster |
1:43f5c94c6771 | 591 | /* Uri-Path is modified to following format: temp1\temp2\temp3 i.e. */ |
Christopher Haster |
1:43f5c94c6771 | 592 | if (option == COAP_OPTION_URI_QUERY || option == COAP_OPTION_LOCATION_QUERY || option == COAP_OPTION_ETAG || option == COAP_OPTION_ACCEPT) { |
Christopher Haster |
1:43f5c94c6771 | 593 | memset(temp_parsed_uri_query_ptr, '&', 1); |
Christopher Haster |
1:43f5c94c6771 | 594 | } else if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) { |
Christopher Haster |
1:43f5c94c6771 | 595 | memset(temp_parsed_uri_query_ptr, '/', 1); |
Christopher Haster |
1:43f5c94c6771 | 596 | } |
Christopher Haster |
1:43f5c94c6771 | 597 | |
Christopher Haster |
1:43f5c94c6771 | 598 | temp_parsed_uri_query_ptr++; |
Christopher Haster |
1:43f5c94c6771 | 599 | } |
Christopher Haster |
1:43f5c94c6771 | 600 | |
Christopher Haster |
1:43f5c94c6771 | 601 | returned_option_counter++; |
Christopher Haster |
1:43f5c94c6771 | 602 | |
Christopher Haster |
1:43f5c94c6771 | 603 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 604 | |
Christopher Haster |
1:43f5c94c6771 | 605 | if (((temp_parsed_uri_query_ptr - *dst_pptr) + option_number_len) > uri_query_needed_heap) { |
Christopher Haster |
1:43f5c94c6771 | 606 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 607 | } |
Christopher Haster |
1:43f5c94c6771 | 608 | |
Christopher Haster |
1:43f5c94c6771 | 609 | memcpy(temp_parsed_uri_query_ptr, *packet_data_pptr, option_number_len); |
Christopher Haster |
1:43f5c94c6771 | 610 | |
Christopher Haster |
1:43f5c94c6771 | 611 | (*packet_data_pptr) += option_number_len; |
Christopher Haster |
1:43f5c94c6771 | 612 | temp_parsed_uri_query_ptr += option_number_len; |
Christopher Haster |
1:43f5c94c6771 | 613 | |
Christopher Haster |
1:43f5c94c6771 | 614 | if ((temp_parsed_uri_query_ptr - *dst_pptr) >= uri_query_needed_heap || ((**packet_data_pptr >> COAP_OPTIONS_OPTION_NUMBER_SHIFT) != 0)) { |
Christopher Haster |
1:43f5c94c6771 | 615 | return returned_option_counter; |
Christopher Haster |
1:43f5c94c6771 | 616 | } |
Christopher Haster |
1:43f5c94c6771 | 617 | |
Christopher Haster |
1:43f5c94c6771 | 618 | option_number_len = (**packet_data_pptr & 0x0F); |
Christopher Haster |
1:43f5c94c6771 | 619 | if (option_number_len == 13) { |
Christopher Haster |
1:43f5c94c6771 | 620 | option_number_len = *(*packet_data_pptr + 1) + 13; |
Christopher Haster |
1:43f5c94c6771 | 621 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 622 | } else if (option_number_len == 14) { |
Christopher Haster |
1:43f5c94c6771 | 623 | option_number_len = *(*packet_data_pptr + 2); |
Christopher Haster |
1:43f5c94c6771 | 624 | option_number_len += (*(*packet_data_pptr + 1) << 8) + 269; |
Christopher Haster |
1:43f5c94c6771 | 625 | (*packet_data_pptr) += 2; |
Christopher Haster |
1:43f5c94c6771 | 626 | } |
Christopher Haster |
1:43f5c94c6771 | 627 | } |
Christopher Haster |
1:43f5c94c6771 | 628 | |
Christopher Haster |
1:43f5c94c6771 | 629 | return returned_option_counter; |
Christopher Haster |
1:43f5c94c6771 | 630 | } |
Christopher Haster |
1:43f5c94c6771 | 631 | |
Christopher Haster |
1:43f5c94c6771 | 632 | |
Christopher Haster |
1:43f5c94c6771 | 633 | |
Christopher Haster |
1:43f5c94c6771 | 634 | |
Christopher Haster |
1:43f5c94c6771 | 635 | /** |
Christopher Haster |
1:43f5c94c6771 | 636 | * \fn static uint16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_t *packet_data_ptr, uint8_t options_count_left, uint8_t previous_option_number, sn_coap_option_numbers_e option, uint16_t option_number_len) |
Christopher Haster |
1:43f5c94c6771 | 637 | * |
Christopher Haster |
1:43f5c94c6771 | 638 | * \brief Counts needed memory for uri query option |
Christopher Haster |
1:43f5c94c6771 | 639 | * |
Christopher Haster |
1:43f5c94c6771 | 640 | * \param *packet_data_ptr is start of source for Packet data to be parsed to CoAP message |
Christopher Haster |
1:43f5c94c6771 | 641 | * |
Christopher Haster |
1:43f5c94c6771 | 642 | * \param options_count_left tells how many options are unhandled in Packet data |
Christopher Haster |
1:43f5c94c6771 | 643 | * |
Christopher Haster |
1:43f5c94c6771 | 644 | * \param previous_option_number is previous Option number |
Christopher Haster |
1:43f5c94c6771 | 645 | * |
Christopher Haster |
1:43f5c94c6771 | 646 | * \param sn_coap_option_numbers_e option option number to be calculated |
Christopher Haster |
1:43f5c94c6771 | 647 | * |
Christopher Haster |
1:43f5c94c6771 | 648 | * \param uint16_t option_number_len length of the first option part |
Christopher Haster |
1:43f5c94c6771 | 649 | */ |
Christopher Haster |
1:43f5c94c6771 | 650 | static int16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_t *packet_data_ptr, uint16_t packet_left_len, sn_coap_option_numbers_e option, uint16_t option_number_len) |
Christopher Haster |
1:43f5c94c6771 | 651 | { |
Christopher Haster |
1:43f5c94c6771 | 652 | uint16_t ret_value = 0; |
Christopher Haster |
1:43f5c94c6771 | 653 | uint16_t i = 1; |
Christopher Haster |
1:43f5c94c6771 | 654 | |
Christopher Haster |
1:43f5c94c6771 | 655 | /* Loop all Uri-Query options */ |
Christopher Haster |
1:43f5c94c6771 | 656 | while (i < packet_left_len) { |
Christopher Haster |
1:43f5c94c6771 | 657 | if (option == COAP_OPTION_LOCATION_PATH && option_number_len > 255) { |
Christopher Haster |
1:43f5c94c6771 | 658 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 659 | } |
Christopher Haster |
1:43f5c94c6771 | 660 | if (option == COAP_OPTION_URI_PATH && option_number_len > 255) { |
Christopher Haster |
1:43f5c94c6771 | 661 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 662 | } |
Christopher Haster |
1:43f5c94c6771 | 663 | if (option == COAP_OPTION_URI_QUERY && option_number_len > 255) { |
Christopher Haster |
1:43f5c94c6771 | 664 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 665 | } |
Christopher Haster |
1:43f5c94c6771 | 666 | if (option == COAP_OPTION_LOCATION_QUERY && option_number_len > 255) { |
Christopher Haster |
1:43f5c94c6771 | 667 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 668 | } |
Christopher Haster |
1:43f5c94c6771 | 669 | if (option == COAP_OPTION_ACCEPT && option_number_len > 2) { |
Christopher Haster |
1:43f5c94c6771 | 670 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 671 | } |
Christopher Haster |
1:43f5c94c6771 | 672 | if (option == COAP_OPTION_ETAG && option_number_len > 8) { |
Christopher Haster |
1:43f5c94c6771 | 673 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 674 | } |
Christopher Haster |
1:43f5c94c6771 | 675 | |
Christopher Haster |
1:43f5c94c6771 | 676 | i += option_number_len; |
Christopher Haster |
1:43f5c94c6771 | 677 | ret_value += option_number_len + 1; /* + 1 is for separator */ |
Christopher Haster |
1:43f5c94c6771 | 678 | if(ret_value >= packet_left_len) |
Christopher Haster |
1:43f5c94c6771 | 679 | break; |
Christopher Haster |
1:43f5c94c6771 | 680 | |
Christopher Haster |
1:43f5c94c6771 | 681 | if(ret_value >= packet_left_len) |
Christopher Haster |
1:43f5c94c6771 | 682 | break; |
Christopher Haster |
1:43f5c94c6771 | 683 | |
Yogesh Pande |
4:5d91b0f5038c | 684 | if( i == packet_left_len ) |
Yogesh Pande |
4:5d91b0f5038c | 685 | break; |
Yogesh Pande |
4:5d91b0f5038c | 686 | |
Christopher Haster |
1:43f5c94c6771 | 687 | if ((*(packet_data_ptr + i) >> COAP_OPTIONS_OPTION_NUMBER_SHIFT) != 0) { |
Christopher Haster |
1:43f5c94c6771 | 688 | return (ret_value - 1); /* -1 because last Part path does not include separator */ |
Christopher Haster |
1:43f5c94c6771 | 689 | } |
Christopher Haster |
1:43f5c94c6771 | 690 | |
Christopher Haster |
1:43f5c94c6771 | 691 | option_number_len = (*(packet_data_ptr + i) & 0x0F); |
Christopher Haster |
1:43f5c94c6771 | 692 | |
Christopher Haster |
1:43f5c94c6771 | 693 | if (option_number_len == 13) { |
Christopher Haster |
1:43f5c94c6771 | 694 | i++; |
Christopher Haster |
1:43f5c94c6771 | 695 | option_number_len = *(packet_data_ptr + i) + 13; |
Christopher Haster |
1:43f5c94c6771 | 696 | } else if (option_number_len == 14) { |
Christopher Haster |
1:43f5c94c6771 | 697 | option_number_len = *(packet_data_ptr + i + 2); |
Christopher Haster |
1:43f5c94c6771 | 698 | option_number_len += (*(packet_data_ptr + i + 1) << 8) + 269; |
Christopher Haster |
1:43f5c94c6771 | 699 | i += 2; |
Christopher Haster |
1:43f5c94c6771 | 700 | } else if (option_number_len == 15) { |
Christopher Haster |
1:43f5c94c6771 | 701 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 702 | } |
Christopher Haster |
1:43f5c94c6771 | 703 | i++; |
Christopher Haster |
1:43f5c94c6771 | 704 | |
Christopher Haster |
1:43f5c94c6771 | 705 | } |
Christopher Haster |
1:43f5c94c6771 | 706 | |
Christopher Haster |
1:43f5c94c6771 | 707 | if (ret_value != 0) { |
Christopher Haster |
1:43f5c94c6771 | 708 | return (ret_value - 1); /* -1 because last Part path does not include separator */ |
Christopher Haster |
1:43f5c94c6771 | 709 | } else { |
Christopher Haster |
1:43f5c94c6771 | 710 | return 0; |
Christopher Haster |
1:43f5c94c6771 | 711 | } |
Christopher Haster |
1:43f5c94c6771 | 712 | } |
Christopher Haster |
1:43f5c94c6771 | 713 | |
Christopher Haster |
1:43f5c94c6771 | 714 | /** |
Christopher Haster |
1:43f5c94c6771 | 715 | * \fn static void sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *packet_data_ptr, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr) |
Christopher Haster |
1:43f5c94c6771 | 716 | * |
Christopher Haster |
1:43f5c94c6771 | 717 | * \brief Parses CoAP message's Payload part from given Packet data |
Christopher Haster |
1:43f5c94c6771 | 718 | * |
Christopher Haster |
1:43f5c94c6771 | 719 | * \param packet_data_len is length of given Packet data to be parsed to CoAP message |
Christopher Haster |
1:43f5c94c6771 | 720 | * |
Christopher Haster |
1:43f5c94c6771 | 721 | * \param *packet_data_ptr is start of source for Packet data to be parsed to CoAP message |
Christopher Haster |
1:43f5c94c6771 | 722 | * |
Christopher Haster |
1:43f5c94c6771 | 723 | * \param **packet_data_pptr is source for Packet data to be parsed to CoAP message |
Christopher Haster |
1:43f5c94c6771 | 724 | * |
Christopher Haster |
1:43f5c94c6771 | 725 | * \param *dst_coap_msg_ptr is destination for parsed CoAP message |
Christopher Haster |
1:43f5c94c6771 | 726 | *****************************************************************************/ |
Christopher Haster |
1:43f5c94c6771 | 727 | static int8_t sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *packet_data_start_ptr, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr) |
Christopher Haster |
1:43f5c94c6771 | 728 | { |
Christopher Haster |
1:43f5c94c6771 | 729 | /* If there is payload */ |
Christopher Haster |
1:43f5c94c6771 | 730 | if ((*packet_data_pptr - packet_data_start_ptr) < packet_data_len) { |
Christopher Haster |
1:43f5c94c6771 | 731 | if (**packet_data_pptr == 0xff) { |
Christopher Haster |
1:43f5c94c6771 | 732 | (*packet_data_pptr)++; |
Christopher Haster |
1:43f5c94c6771 | 733 | /* Parse Payload length */ |
Christopher Haster |
1:43f5c94c6771 | 734 | dst_coap_msg_ptr->payload_len = packet_data_len - (*packet_data_pptr - packet_data_start_ptr); |
Christopher Haster |
1:43f5c94c6771 | 735 | |
Christopher Haster |
1:43f5c94c6771 | 736 | /* The presence of a marker followed by a zero-length payload MUST be processed as a message format error */ |
Christopher Haster |
1:43f5c94c6771 | 737 | if (dst_coap_msg_ptr->payload_len == 0) { |
Christopher Haster |
1:43f5c94c6771 | 738 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 739 | } |
Christopher Haster |
1:43f5c94c6771 | 740 | |
Christopher Haster |
1:43f5c94c6771 | 741 | /* Parse Payload by setting CoAP message's payload_ptr to point Payload in Packet data */ |
Christopher Haster |
1:43f5c94c6771 | 742 | dst_coap_msg_ptr->payload_ptr = *packet_data_pptr; |
Christopher Haster |
1:43f5c94c6771 | 743 | } |
Christopher Haster |
1:43f5c94c6771 | 744 | /* No payload marker.. */ |
Christopher Haster |
1:43f5c94c6771 | 745 | else { |
Christopher Haster |
1:43f5c94c6771 | 746 | return -1; |
Christopher Haster |
1:43f5c94c6771 | 747 | } |
Christopher Haster |
1:43f5c94c6771 | 748 | } |
Christopher Haster |
1:43f5c94c6771 | 749 | return 0; |
Christopher Haster |
1:43f5c94c6771 | 750 | } |