mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Committer:
mbedAustin
Date:
Thu Jun 09 17:08:36 2016 +0000
Revision:
11:cada08fc8a70
Commit for public Consumption

Who changed what in which revision?

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