sandbox / mbed-client-c

Fork of mbed-client-c by Christopher Haster

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?

UserRevisionLine numberNew 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 }