pick up wakaama files from https://github.com/eclipse/wakaama

Committer:
terencez
Date:
Wed Apr 19 11:30:02 2017 +0000
Revision:
0:1fa43ab66921
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
terencez 0:1fa43ab66921 1 /*
terencez 0:1fa43ab66921 2 * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
terencez 0:1fa43ab66921 3 * All rights reserved.
terencez 0:1fa43ab66921 4 *
terencez 0:1fa43ab66921 5 * Redistribution and use in source and binary forms, with or without
terencez 0:1fa43ab66921 6 * modification, are permitted provided that the following conditions
terencez 0:1fa43ab66921 7 * are met:
terencez 0:1fa43ab66921 8 * 1. Redistributions of source code must retain the above copyright
terencez 0:1fa43ab66921 9 * notice, this list of conditions and the following disclaimer.
terencez 0:1fa43ab66921 10 * 2. Redistributions in binary form must reproduce the above copyright
terencez 0:1fa43ab66921 11 * notice, this list of conditions and the following disclaimer in the
terencez 0:1fa43ab66921 12 * documentation and/or other materials provided with the distribution.
terencez 0:1fa43ab66921 13 * 3. Neither the name of the Institute nor the names of its contributors
terencez 0:1fa43ab66921 14 * may be used to endorse or promote products derived from this software
terencez 0:1fa43ab66921 15 * without specific prior written permission.
terencez 0:1fa43ab66921 16 *
terencez 0:1fa43ab66921 17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
terencez 0:1fa43ab66921 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
terencez 0:1fa43ab66921 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
terencez 0:1fa43ab66921 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
terencez 0:1fa43ab66921 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
terencez 0:1fa43ab66921 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
terencez 0:1fa43ab66921 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
terencez 0:1fa43ab66921 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
terencez 0:1fa43ab66921 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
terencez 0:1fa43ab66921 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
terencez 0:1fa43ab66921 27 * SUCH DAMAGE.
terencez 0:1fa43ab66921 28 *
terencez 0:1fa43ab66921 29 * This file is part of the Contiki operating system.
terencez 0:1fa43ab66921 30 */
terencez 0:1fa43ab66921 31
terencez 0:1fa43ab66921 32 /**
terencez 0:1fa43ab66921 33 * \file
terencez 0:1fa43ab66921 34 * An implementation of the Constrained Application Protocol (draft 12)
terencez 0:1fa43ab66921 35 * \author
terencez 0:1fa43ab66921 36 * Matthias Kovatsch <kovatsch@inf.ethz.ch>
terencez 0:1fa43ab66921 37 * \contributors
terencez 0:1fa43ab66921 38 * David Navarro, Intel Corporation - Adapt to usage in liblwm2m
terencez 0:1fa43ab66921 39 */
terencez 0:1fa43ab66921 40
terencez 0:1fa43ab66921 41
terencez 0:1fa43ab66921 42 #include <stdlib.h>
terencez 0:1fa43ab66921 43
terencez 0:1fa43ab66921 44 #include <string.h>
terencez 0:1fa43ab66921 45 #include <stdio.h>
terencez 0:1fa43ab66921 46
terencez 0:1fa43ab66921 47 #include "er-coap-13.h"
terencez 0:1fa43ab66921 48
terencez 0:1fa43ab66921 49 #include "liblwm2m.h" /* for lwm2m_malloc() and lwm2m_free() */
terencez 0:1fa43ab66921 50
terencez 0:1fa43ab66921 51 #define DEBUG 0
terencez 0:1fa43ab66921 52 #if DEBUG
terencez 0:1fa43ab66921 53 #include <stdio.h>
terencez 0:1fa43ab66921 54 #define PRINTF(...) printf(__VA_ARGS__)
terencez 0:1fa43ab66921 55 #define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
terencez 0:1fa43ab66921 56 #define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5])
terencez 0:1fa43ab66921 57 #else
terencez 0:1fa43ab66921 58 #define PRINTF(...)
terencez 0:1fa43ab66921 59 #define PRINT6ADDR(addr)
terencez 0:1fa43ab66921 60 #define PRINTLLADDR(addr)
terencez 0:1fa43ab66921 61 #endif
terencez 0:1fa43ab66921 62
terencez 0:1fa43ab66921 63 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 64 /*- Variables -----------------------------------------------------------------------*/
terencez 0:1fa43ab66921 65 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 66 static uint16_t current_mid = 0;
terencez 0:1fa43ab66921 67
terencez 0:1fa43ab66921 68 coap_status_t coap_error_code = NO_ERROR;
terencez 0:1fa43ab66921 69 const char *coap_error_message = "";
terencez 0:1fa43ab66921 70 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 71 /*- LOCAL HELP FUNCTIONS ------------------------------------------------------------*/
terencez 0:1fa43ab66921 72 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 73 static
terencez 0:1fa43ab66921 74 uint16_t
terencez 0:1fa43ab66921 75 coap_log_2(uint16_t value)
terencez 0:1fa43ab66921 76 {
terencez 0:1fa43ab66921 77 uint16_t result = 0;
terencez 0:1fa43ab66921 78 do {
terencez 0:1fa43ab66921 79 value = value >> 1;
terencez 0:1fa43ab66921 80 result++;
terencez 0:1fa43ab66921 81 } while (value);
terencez 0:1fa43ab66921 82
terencez 0:1fa43ab66921 83 return result ? result - 1 : result;
terencez 0:1fa43ab66921 84 }
terencez 0:1fa43ab66921 85 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 86 static
terencez 0:1fa43ab66921 87 uint32_t
terencez 0:1fa43ab66921 88 coap_parse_int_option(uint8_t *bytes, size_t length)
terencez 0:1fa43ab66921 89 {
terencez 0:1fa43ab66921 90 uint32_t var = 0;
terencez 0:1fa43ab66921 91 size_t i = 0;
terencez 0:1fa43ab66921 92 while (i<length)
terencez 0:1fa43ab66921 93 {
terencez 0:1fa43ab66921 94 var <<= 8;
terencez 0:1fa43ab66921 95 var |= bytes[i++];
terencez 0:1fa43ab66921 96 }
terencez 0:1fa43ab66921 97 return var;
terencez 0:1fa43ab66921 98 }
terencez 0:1fa43ab66921 99 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 100 static
terencez 0:1fa43ab66921 101 uint8_t
terencez 0:1fa43ab66921 102 coap_option_nibble(unsigned int value)
terencez 0:1fa43ab66921 103 {
terencez 0:1fa43ab66921 104 if (value<13)
terencez 0:1fa43ab66921 105 {
terencez 0:1fa43ab66921 106 return value;
terencez 0:1fa43ab66921 107 }
terencez 0:1fa43ab66921 108 else if (value<=0xFF+13)
terencez 0:1fa43ab66921 109 {
terencez 0:1fa43ab66921 110 return 13;
terencez 0:1fa43ab66921 111 }
terencez 0:1fa43ab66921 112 else
terencez 0:1fa43ab66921 113 {
terencez 0:1fa43ab66921 114 return 14;
terencez 0:1fa43ab66921 115 }
terencez 0:1fa43ab66921 116 }
terencez 0:1fa43ab66921 117 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 118 static
terencez 0:1fa43ab66921 119 size_t
terencez 0:1fa43ab66921 120 coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
terencez 0:1fa43ab66921 121 {
terencez 0:1fa43ab66921 122 size_t written = 0;
terencez 0:1fa43ab66921 123 unsigned int *x = &delta;
terencez 0:1fa43ab66921 124
terencez 0:1fa43ab66921 125 buffer[0] = coap_option_nibble(delta)<<4 | coap_option_nibble(length);
terencez 0:1fa43ab66921 126
terencez 0:1fa43ab66921 127 /* avoids code duplication without function overhead */
terencez 0:1fa43ab66921 128 do
terencez 0:1fa43ab66921 129 {
terencez 0:1fa43ab66921 130 if (*x>268)
terencez 0:1fa43ab66921 131 {
terencez 0:1fa43ab66921 132 buffer[++written] = (*x-269)>>8;
terencez 0:1fa43ab66921 133 buffer[++written] = (*x-269);
terencez 0:1fa43ab66921 134 }
terencez 0:1fa43ab66921 135 else if (*x>12)
terencez 0:1fa43ab66921 136 {
terencez 0:1fa43ab66921 137 buffer[++written] = (*x-13);
terencez 0:1fa43ab66921 138 }
terencez 0:1fa43ab66921 139 }
terencez 0:1fa43ab66921 140 while (x!=(unsigned int *)&length && (x=(unsigned int *)&length));
terencez 0:1fa43ab66921 141
terencez 0:1fa43ab66921 142 PRINTF("WRITTEN %u B opt header\n", written);
terencez 0:1fa43ab66921 143
terencez 0:1fa43ab66921 144 return ++written;
terencez 0:1fa43ab66921 145 }
terencez 0:1fa43ab66921 146 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 147 static
terencez 0:1fa43ab66921 148 size_t
terencez 0:1fa43ab66921 149 coap_serialize_int_option(unsigned int number, unsigned int current_number, uint8_t *buffer, uint32_t value)
terencez 0:1fa43ab66921 150 {
terencez 0:1fa43ab66921 151 size_t i = 0;
terencez 0:1fa43ab66921 152
terencez 0:1fa43ab66921 153 if (0xFF000000 & value) ++i;
terencez 0:1fa43ab66921 154 if (0xFFFF0000 & value) ++i;
terencez 0:1fa43ab66921 155 if (0xFFFFFF00 & value) ++i;
terencez 0:1fa43ab66921 156 if (0xFFFFFFFF & value) ++i;
terencez 0:1fa43ab66921 157
terencez 0:1fa43ab66921 158 PRINTF("OPTION %u (delta %u, len %u)\n", number, number - current_number, i);
terencez 0:1fa43ab66921 159
terencez 0:1fa43ab66921 160 i = coap_set_option_header(number - current_number, i, buffer);
terencez 0:1fa43ab66921 161
terencez 0:1fa43ab66921 162 if (0xFF000000 & value) buffer[i++] = (uint8_t) (value>>24);
terencez 0:1fa43ab66921 163 if (0xFFFF0000 & value) buffer[i++] = (uint8_t) (value>>16);
terencez 0:1fa43ab66921 164 if (0xFFFFFF00 & value) buffer[i++] = (uint8_t) (value>>8);
terencez 0:1fa43ab66921 165 if (0xFFFFFFFF & value) buffer[i++] = (uint8_t) (value);
terencez 0:1fa43ab66921 166
terencez 0:1fa43ab66921 167 return i;
terencez 0:1fa43ab66921 168 }
terencez 0:1fa43ab66921 169 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 170 static
terencez 0:1fa43ab66921 171 size_t
terencez 0:1fa43ab66921 172 coap_serialize_array_option(unsigned int number, unsigned int current_number, uint8_t *buffer, uint8_t *array, size_t length, char split_char)
terencez 0:1fa43ab66921 173 {
terencez 0:1fa43ab66921 174 size_t i = 0;
terencez 0:1fa43ab66921 175
terencez 0:1fa43ab66921 176 if (split_char!='\0')
terencez 0:1fa43ab66921 177 {
terencez 0:1fa43ab66921 178 size_t j;
terencez 0:1fa43ab66921 179 uint8_t *part_start = array;
terencez 0:1fa43ab66921 180 uint8_t *part_end = NULL;
terencez 0:1fa43ab66921 181 size_t temp_length;
terencez 0:1fa43ab66921 182
terencez 0:1fa43ab66921 183 for (j = 0; j<=length; ++j)
terencez 0:1fa43ab66921 184 {
terencez 0:1fa43ab66921 185 if (array[j]==split_char || j==length)
terencez 0:1fa43ab66921 186 {
terencez 0:1fa43ab66921 187 part_end = array + j;
terencez 0:1fa43ab66921 188 temp_length = part_end-part_start;
terencez 0:1fa43ab66921 189
terencez 0:1fa43ab66921 190 i += coap_set_option_header(number - current_number, temp_length, &buffer[i]);
terencez 0:1fa43ab66921 191 memcpy(&buffer[i], part_start, temp_length);
terencez 0:1fa43ab66921 192 i += temp_length;
terencez 0:1fa43ab66921 193
terencez 0:1fa43ab66921 194 PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number, number - current_number, i, temp_length, part_start);
terencez 0:1fa43ab66921 195
terencez 0:1fa43ab66921 196 ++j; /* skip the splitter */
terencez 0:1fa43ab66921 197 current_number = number;
terencez 0:1fa43ab66921 198 part_start = array + j;
terencez 0:1fa43ab66921 199 }
terencez 0:1fa43ab66921 200 } /* for */
terencez 0:1fa43ab66921 201 }
terencez 0:1fa43ab66921 202 else
terencez 0:1fa43ab66921 203 {
terencez 0:1fa43ab66921 204 i += coap_set_option_header(number - current_number, length, &buffer[i]);
terencez 0:1fa43ab66921 205 memcpy(&buffer[i], array, length);
terencez 0:1fa43ab66921 206 i += length;
terencez 0:1fa43ab66921 207
terencez 0:1fa43ab66921 208 PRINTF("OPTION type %u, delta %u, len %u\n", number, number - current_number, length);
terencez 0:1fa43ab66921 209 }
terencez 0:1fa43ab66921 210
terencez 0:1fa43ab66921 211 return i;
terencez 0:1fa43ab66921 212 }
terencez 0:1fa43ab66921 213 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 214 static
terencez 0:1fa43ab66921 215 size_t
terencez 0:1fa43ab66921 216 coap_serialize_multi_option(unsigned int number, unsigned int current_number, uint8_t *buffer, multi_option_t *array)
terencez 0:1fa43ab66921 217 {
terencez 0:1fa43ab66921 218 size_t i = 0;
terencez 0:1fa43ab66921 219 multi_option_t * j;
terencez 0:1fa43ab66921 220
terencez 0:1fa43ab66921 221 for (j = array; j != NULL; j= j->next)
terencez 0:1fa43ab66921 222 {
terencez 0:1fa43ab66921 223 i += coap_set_option_header(number - current_number, j->len, &buffer[i]);
terencez 0:1fa43ab66921 224 current_number = number;
terencez 0:1fa43ab66921 225 memcpy(&buffer[i], j->data, j->len);
terencez 0:1fa43ab66921 226 i += j->len;
terencez 0:1fa43ab66921 227 } /* for */
terencez 0:1fa43ab66921 228
terencez 0:1fa43ab66921 229 return i;
terencez 0:1fa43ab66921 230 }
terencez 0:1fa43ab66921 231 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 232 static
terencez 0:1fa43ab66921 233 void
terencez 0:1fa43ab66921 234 coap_merge_multi_option(uint8_t **dst, size_t *dst_len, uint8_t *option, size_t option_len, char separator)
terencez 0:1fa43ab66921 235 {
terencez 0:1fa43ab66921 236 /* Merge multiple options. */
terencez 0:1fa43ab66921 237 if (*dst_len > 0)
terencez 0:1fa43ab66921 238 {
terencez 0:1fa43ab66921 239 /* dst already contains an option: concatenate */
terencez 0:1fa43ab66921 240 (*dst)[*dst_len] = separator;
terencez 0:1fa43ab66921 241 *dst_len += 1;
terencez 0:1fa43ab66921 242
terencez 0:1fa43ab66921 243 /* memmove handles 2-byte option headers */
terencez 0:1fa43ab66921 244 memmove((*dst)+(*dst_len), option, option_len);
terencez 0:1fa43ab66921 245
terencez 0:1fa43ab66921 246 *dst_len += option_len;
terencez 0:1fa43ab66921 247 }
terencez 0:1fa43ab66921 248 else
terencez 0:1fa43ab66921 249 {
terencez 0:1fa43ab66921 250 /* dst is empty: set to option */
terencez 0:1fa43ab66921 251 *dst = option;
terencez 0:1fa43ab66921 252 *dst_len = option_len;
terencez 0:1fa43ab66921 253 }
terencez 0:1fa43ab66921 254 }
terencez 0:1fa43ab66921 255
terencez 0:1fa43ab66921 256 void
terencez 0:1fa43ab66921 257 coap_add_multi_option(multi_option_t **dst, uint8_t *option, size_t option_len, uint8_t is_static)
terencez 0:1fa43ab66921 258 {
terencez 0:1fa43ab66921 259 multi_option_t *opt = (multi_option_t *)lwm2m_malloc(sizeof(multi_option_t));
terencez 0:1fa43ab66921 260
terencez 0:1fa43ab66921 261 if (opt)
terencez 0:1fa43ab66921 262 {
terencez 0:1fa43ab66921 263 opt->next = NULL;
terencez 0:1fa43ab66921 264 opt->len = (uint8_t)option_len;
terencez 0:1fa43ab66921 265 if (is_static)
terencez 0:1fa43ab66921 266 {
terencez 0:1fa43ab66921 267 opt->data = option;
terencez 0:1fa43ab66921 268 opt->is_static = 1;
terencez 0:1fa43ab66921 269 }
terencez 0:1fa43ab66921 270 else
terencez 0:1fa43ab66921 271 {
terencez 0:1fa43ab66921 272 opt->is_static = 0;
terencez 0:1fa43ab66921 273 opt->data = (uint8_t *)lwm2m_malloc(option_len);
terencez 0:1fa43ab66921 274 if (opt->data == NULL)
terencez 0:1fa43ab66921 275 {
terencez 0:1fa43ab66921 276 lwm2m_free(opt);
terencez 0:1fa43ab66921 277 return;
terencez 0:1fa43ab66921 278 }
terencez 0:1fa43ab66921 279 memcpy(opt->data, option, option_len);
terencez 0:1fa43ab66921 280 }
terencez 0:1fa43ab66921 281
terencez 0:1fa43ab66921 282 if (*dst)
terencez 0:1fa43ab66921 283 {
terencez 0:1fa43ab66921 284 multi_option_t * i = *dst;
terencez 0:1fa43ab66921 285 while (i->next)
terencez 0:1fa43ab66921 286 {
terencez 0:1fa43ab66921 287 i = i->next;
terencez 0:1fa43ab66921 288 }
terencez 0:1fa43ab66921 289 i->next = opt;
terencez 0:1fa43ab66921 290 }
terencez 0:1fa43ab66921 291 else
terencez 0:1fa43ab66921 292 {
terencez 0:1fa43ab66921 293 *dst = opt;
terencez 0:1fa43ab66921 294 }
terencez 0:1fa43ab66921 295 }
terencez 0:1fa43ab66921 296 }
terencez 0:1fa43ab66921 297
terencez 0:1fa43ab66921 298 void
terencez 0:1fa43ab66921 299 free_multi_option(multi_option_t *dst)
terencez 0:1fa43ab66921 300 {
terencez 0:1fa43ab66921 301 if (dst)
terencez 0:1fa43ab66921 302 {
terencez 0:1fa43ab66921 303 multi_option_t *n = dst->next;
terencez 0:1fa43ab66921 304 dst->next = NULL;
terencez 0:1fa43ab66921 305 if (dst->is_static == 0)
terencez 0:1fa43ab66921 306 {
terencez 0:1fa43ab66921 307 lwm2m_free(dst->data);
terencez 0:1fa43ab66921 308 }
terencez 0:1fa43ab66921 309 lwm2m_free(dst);
terencez 0:1fa43ab66921 310 free_multi_option(n);
terencez 0:1fa43ab66921 311 }
terencez 0:1fa43ab66921 312 }
terencez 0:1fa43ab66921 313
terencez 0:1fa43ab66921 314 char * coap_get_multi_option_as_string(multi_option_t * option)
terencez 0:1fa43ab66921 315 {
terencez 0:1fa43ab66921 316 size_t len = 0;
terencez 0:1fa43ab66921 317 multi_option_t * opt;
terencez 0:1fa43ab66921 318 char * output;
terencez 0:1fa43ab66921 319
terencez 0:1fa43ab66921 320 for (opt = option; opt != NULL; opt = opt->next)
terencez 0:1fa43ab66921 321 {
terencez 0:1fa43ab66921 322 len += opt->len + 1; // for separator
terencez 0:1fa43ab66921 323 }
terencez 0:1fa43ab66921 324
terencez 0:1fa43ab66921 325 output = lwm2m_malloc(len + 1); // for String terminator
terencez 0:1fa43ab66921 326 if (output != NULL)
terencez 0:1fa43ab66921 327 {
terencez 0:1fa43ab66921 328 size_t i = 0;
terencez 0:1fa43ab66921 329
terencez 0:1fa43ab66921 330 for (opt = option; opt != NULL; opt = opt->next)
terencez 0:1fa43ab66921 331 {
terencez 0:1fa43ab66921 332 output[i] = '/';
terencez 0:1fa43ab66921 333 i += 1;
terencez 0:1fa43ab66921 334
terencez 0:1fa43ab66921 335 memmove(output + i, opt->data, opt->len);
terencez 0:1fa43ab66921 336 i += opt->len;
terencez 0:1fa43ab66921 337 }
terencez 0:1fa43ab66921 338 output[i] = 0;
terencez 0:1fa43ab66921 339 }
terencez 0:1fa43ab66921 340
terencez 0:1fa43ab66921 341 return output;
terencez 0:1fa43ab66921 342 }
terencez 0:1fa43ab66921 343
terencez 0:1fa43ab66921 344 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 345 static
terencez 0:1fa43ab66921 346 int
terencez 0:1fa43ab66921 347 coap_get_variable(const uint8_t *buffer, size_t length, const char *name, const char **output)
terencez 0:1fa43ab66921 348 {
terencez 0:1fa43ab66921 349 const uint8_t *start = NULL;
terencez 0:1fa43ab66921 350 const uint8_t *end = NULL;
terencez 0:1fa43ab66921 351 const uint8_t *value_end = NULL;
terencez 0:1fa43ab66921 352 size_t name_len = 0;
terencez 0:1fa43ab66921 353
terencez 0:1fa43ab66921 354 /*initialize the output buffer first*/
terencez 0:1fa43ab66921 355 *output = 0;
terencez 0:1fa43ab66921 356
terencez 0:1fa43ab66921 357 name_len = strlen(name);
terencez 0:1fa43ab66921 358 end = buffer + length;
terencez 0:1fa43ab66921 359
terencez 0:1fa43ab66921 360 for (start = buffer; start + name_len < end; ++start){
terencez 0:1fa43ab66921 361 if ((start == buffer || start[-1] == '&') && start[name_len] == '=' &&
terencez 0:1fa43ab66921 362 strncmp(name, (char *)start, name_len)==0) {
terencez 0:1fa43ab66921 363
terencez 0:1fa43ab66921 364 /* Point start to variable value */
terencez 0:1fa43ab66921 365 start += name_len + 1;
terencez 0:1fa43ab66921 366
terencez 0:1fa43ab66921 367 /* Point end to the end of the value */
terencez 0:1fa43ab66921 368 value_end = (const uint8_t *) memchr(start, '&', end - start);
terencez 0:1fa43ab66921 369 if (value_end == NULL) {
terencez 0:1fa43ab66921 370 value_end = end;
terencez 0:1fa43ab66921 371 }
terencez 0:1fa43ab66921 372
terencez 0:1fa43ab66921 373 *output = (char *)start;
terencez 0:1fa43ab66921 374
terencez 0:1fa43ab66921 375 return (value_end - start);
terencez 0:1fa43ab66921 376 }
terencez 0:1fa43ab66921 377 }
terencez 0:1fa43ab66921 378
terencez 0:1fa43ab66921 379 return 0;
terencez 0:1fa43ab66921 380 }
terencez 0:1fa43ab66921 381
terencez 0:1fa43ab66921 382 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 383 uint16_t
terencez 0:1fa43ab66921 384 coap_get_mid()
terencez 0:1fa43ab66921 385 {
terencez 0:1fa43ab66921 386 return ++current_mid;
terencez 0:1fa43ab66921 387 }
terencez 0:1fa43ab66921 388 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 389 /*- MEASSAGE PROCESSING -------------------------------------------------------------*/
terencez 0:1fa43ab66921 390 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 391 void
terencez 0:1fa43ab66921 392 coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid)
terencez 0:1fa43ab66921 393 {
terencez 0:1fa43ab66921 394 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 395
terencez 0:1fa43ab66921 396 /* Important thing */
terencez 0:1fa43ab66921 397 memset(coap_pkt, 0, sizeof(coap_packet_t));
terencez 0:1fa43ab66921 398
terencez 0:1fa43ab66921 399 coap_pkt->type = type;
terencez 0:1fa43ab66921 400 coap_pkt->code = code;
terencez 0:1fa43ab66921 401 coap_pkt->mid = mid;
terencez 0:1fa43ab66921 402 }
terencez 0:1fa43ab66921 403
terencez 0:1fa43ab66921 404 void
terencez 0:1fa43ab66921 405 coap_free_header(void *packet)
terencez 0:1fa43ab66921 406 {
terencez 0:1fa43ab66921 407 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 408
terencez 0:1fa43ab66921 409 free_multi_option(coap_pkt->uri_path);
terencez 0:1fa43ab66921 410 free_multi_option(coap_pkt->uri_query);
terencez 0:1fa43ab66921 411 free_multi_option(coap_pkt->location_path);
terencez 0:1fa43ab66921 412 coap_pkt->uri_path = NULL;
terencez 0:1fa43ab66921 413 coap_pkt->uri_query = NULL;
terencez 0:1fa43ab66921 414 coap_pkt->location_path = NULL;
terencez 0:1fa43ab66921 415 }
terencez 0:1fa43ab66921 416
terencez 0:1fa43ab66921 417 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 418 size_t coap_serialize_get_size(void *packet)
terencez 0:1fa43ab66921 419 {
terencez 0:1fa43ab66921 420 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 421 size_t length = 0;
terencez 0:1fa43ab66921 422
terencez 0:1fa43ab66921 423 length = COAP_HEADER_LEN + coap_pkt->payload_len + coap_pkt->token_len;
terencez 0:1fa43ab66921 424
terencez 0:1fa43ab66921 425 if (IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH))
terencez 0:1fa43ab66921 426 {
terencez 0:1fa43ab66921 427 length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->if_match_len;
terencez 0:1fa43ab66921 428 }
terencez 0:1fa43ab66921 429 if (IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST))
terencez 0:1fa43ab66921 430 {
terencez 0:1fa43ab66921 431 length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->uri_host_len;
terencez 0:1fa43ab66921 432 }
terencez 0:1fa43ab66921 433 if (IS_OPTION(coap_pkt, COAP_OPTION_ETAG))
terencez 0:1fa43ab66921 434 {
terencez 0:1fa43ab66921 435 length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->etag_len;
terencez 0:1fa43ab66921 436 }
terencez 0:1fa43ab66921 437 if (IS_OPTION(coap_pkt, COAP_OPTION_IF_NONE_MATCH))
terencez 0:1fa43ab66921 438 {
terencez 0:1fa43ab66921 439 // can be stored in extended fields
terencez 0:1fa43ab66921 440 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 441 }
terencez 0:1fa43ab66921 442 if (IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE))
terencez 0:1fa43ab66921 443 {
terencez 0:1fa43ab66921 444 // can be stored in extended fields
terencez 0:1fa43ab66921 445 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 446 }
terencez 0:1fa43ab66921 447 if (IS_OPTION(coap_pkt, COAP_OPTION_URI_PORT))
terencez 0:1fa43ab66921 448 {
terencez 0:1fa43ab66921 449 // can be stored in extended fields
terencez 0:1fa43ab66921 450 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 451 }
terencez 0:1fa43ab66921 452 if (IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH))
terencez 0:1fa43ab66921 453 {
terencez 0:1fa43ab66921 454 multi_option_t * optP;
terencez 0:1fa43ab66921 455
terencez 0:1fa43ab66921 456 for (optP = coap_pkt->location_path ; optP != NULL ; optP = optP->next)
terencez 0:1fa43ab66921 457 {
terencez 0:1fa43ab66921 458 length += COAP_MAX_OPTION_HEADER_LEN + optP->len;
terencez 0:1fa43ab66921 459 }
terencez 0:1fa43ab66921 460 }
terencez 0:1fa43ab66921 461 if (IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH))
terencez 0:1fa43ab66921 462 {
terencez 0:1fa43ab66921 463 multi_option_t * optP;
terencez 0:1fa43ab66921 464
terencez 0:1fa43ab66921 465 for (optP = coap_pkt->uri_path ; optP != NULL ; optP = optP->next)
terencez 0:1fa43ab66921 466 {
terencez 0:1fa43ab66921 467 length += COAP_MAX_OPTION_HEADER_LEN + optP->len;
terencez 0:1fa43ab66921 468 }
terencez 0:1fa43ab66921 469 }
terencez 0:1fa43ab66921 470 if (IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE))
terencez 0:1fa43ab66921 471 {
terencez 0:1fa43ab66921 472 // can be stored in extended fields
terencez 0:1fa43ab66921 473 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 474 }
terencez 0:1fa43ab66921 475 if (IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE))
terencez 0:1fa43ab66921 476 {
terencez 0:1fa43ab66921 477 // can be stored in extended fields
terencez 0:1fa43ab66921 478 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 479 }
terencez 0:1fa43ab66921 480 if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY))
terencez 0:1fa43ab66921 481 {
terencez 0:1fa43ab66921 482 multi_option_t * optP;
terencez 0:1fa43ab66921 483
terencez 0:1fa43ab66921 484 for (optP = coap_pkt->uri_query ; optP != NULL ; optP = optP->next)
terencez 0:1fa43ab66921 485 {
terencez 0:1fa43ab66921 486 length += COAP_MAX_OPTION_HEADER_LEN + optP->len;
terencez 0:1fa43ab66921 487 }
terencez 0:1fa43ab66921 488 }
terencez 0:1fa43ab66921 489 if (IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT))
terencez 0:1fa43ab66921 490 {
terencez 0:1fa43ab66921 491 length += coap_pkt->accept_num * COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 492 }
terencez 0:1fa43ab66921 493 if (IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY))
terencez 0:1fa43ab66921 494 {
terencez 0:1fa43ab66921 495 length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->location_query_len;
terencez 0:1fa43ab66921 496 }
terencez 0:1fa43ab66921 497 if (IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2))
terencez 0:1fa43ab66921 498 {
terencez 0:1fa43ab66921 499 // can be stored in extended fields
terencez 0:1fa43ab66921 500 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 501 }
terencez 0:1fa43ab66921 502 if (IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1))
terencez 0:1fa43ab66921 503 {
terencez 0:1fa43ab66921 504 // can be stored in extended fields
terencez 0:1fa43ab66921 505 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 506 }
terencez 0:1fa43ab66921 507 if (IS_OPTION(coap_pkt, COAP_OPTION_SIZE))
terencez 0:1fa43ab66921 508 {
terencez 0:1fa43ab66921 509 // can be stored in extended fields
terencez 0:1fa43ab66921 510 length += COAP_MAX_OPTION_HEADER_LEN;
terencez 0:1fa43ab66921 511 }
terencez 0:1fa43ab66921 512 if (IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI))
terencez 0:1fa43ab66921 513 {
terencez 0:1fa43ab66921 514 length += COAP_MAX_OPTION_HEADER_LEN + coap_pkt->proxy_uri_len;
terencez 0:1fa43ab66921 515 }
terencez 0:1fa43ab66921 516
terencez 0:1fa43ab66921 517 return length;
terencez 0:1fa43ab66921 518 }
terencez 0:1fa43ab66921 519
terencez 0:1fa43ab66921 520 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 521 size_t
terencez 0:1fa43ab66921 522 coap_serialize_message(void *packet, uint8_t *buffer)
terencez 0:1fa43ab66921 523 {
terencez 0:1fa43ab66921 524 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 525 uint8_t *option;
terencez 0:1fa43ab66921 526 unsigned int current_number = 0;
terencez 0:1fa43ab66921 527
terencez 0:1fa43ab66921 528 /* Initialize */
terencez 0:1fa43ab66921 529 coap_pkt->buffer = buffer;
terencez 0:1fa43ab66921 530 coap_pkt->version = 1;
terencez 0:1fa43ab66921 531
terencez 0:1fa43ab66921 532 PRINTF("-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer);
terencez 0:1fa43ab66921 533
terencez 0:1fa43ab66921 534 /* set header fields */
terencez 0:1fa43ab66921 535 coap_pkt->buffer[0] = 0x00;
terencez 0:1fa43ab66921 536 coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK & (coap_pkt->version)<<COAP_HEADER_VERSION_POSITION;
terencez 0:1fa43ab66921 537 coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK & (coap_pkt->type)<<COAP_HEADER_TYPE_POSITION;
terencez 0:1fa43ab66921 538 coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK & (coap_pkt->token_len)<<COAP_HEADER_TOKEN_LEN_POSITION;
terencez 0:1fa43ab66921 539 coap_pkt->buffer[1] = coap_pkt->code;
terencez 0:1fa43ab66921 540 coap_pkt->buffer[2] = (uint8_t) ((coap_pkt->mid)>>8);
terencez 0:1fa43ab66921 541 coap_pkt->buffer[3] = (uint8_t) (coap_pkt->mid);
terencez 0:1fa43ab66921 542
terencez 0:1fa43ab66921 543 /* set Token */
terencez 0:1fa43ab66921 544 PRINTF("Token (len %u)", coap_pkt->token_len);
terencez 0:1fa43ab66921 545 option = coap_pkt->buffer + COAP_HEADER_LEN;
terencez 0:1fa43ab66921 546 for (current_number=0; current_number<coap_pkt->token_len; ++current_number)
terencez 0:1fa43ab66921 547 {
terencez 0:1fa43ab66921 548 PRINTF(" %02X", coap_pkt->token[current_number]);
terencez 0:1fa43ab66921 549 *option = coap_pkt->token[current_number];
terencez 0:1fa43ab66921 550 ++option;
terencez 0:1fa43ab66921 551 }
terencez 0:1fa43ab66921 552 PRINTF("-\n");
terencez 0:1fa43ab66921 553
terencez 0:1fa43ab66921 554 /* Serialize options */
terencez 0:1fa43ab66921 555 current_number = 0;
terencez 0:1fa43ab66921 556
terencez 0:1fa43ab66921 557 PRINTF("-Serializing options at %p-\n", option);
terencez 0:1fa43ab66921 558
terencez 0:1fa43ab66921 559 /* The options must be serialized in the order of their number */
terencez 0:1fa43ab66921 560 COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_IF_MATCH, if_match, "If-Match")
terencez 0:1fa43ab66921 561 COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_HOST, uri_host, '\0', "Uri-Host")
terencez 0:1fa43ab66921 562 COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_ETAG, etag, "ETag")
terencez 0:1fa43ab66921 563 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_IF_NONE_MATCH, content_type-coap_pkt->content_type, "If-None-Match") /* hack to get a zero field */
terencez 0:1fa43ab66921 564 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_OBSERVE, observe, "Observe")
terencez 0:1fa43ab66921 565 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_URI_PORT, uri_port, "Uri-Port")
terencez 0:1fa43ab66921 566 COAP_SERIALIZE_MULTI_OPTION( COAP_OPTION_LOCATION_PATH, location_path, "Location-Path")
terencez 0:1fa43ab66921 567 COAP_SERIALIZE_MULTI_OPTION( COAP_OPTION_URI_PATH, uri_path, "Uri-Path")
terencez 0:1fa43ab66921 568 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_CONTENT_TYPE, content_type, "Content-Format")
terencez 0:1fa43ab66921 569 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_MAX_AGE, max_age, "Max-Age")
terencez 0:1fa43ab66921 570 COAP_SERIALIZE_MULTI_OPTION( COAP_OPTION_URI_QUERY, uri_query, "Uri-Query")
terencez 0:1fa43ab66921 571 COAP_SERIALIZE_ACCEPT_OPTION( COAP_OPTION_ACCEPT, accept, "Accept")
terencez 0:1fa43ab66921 572 COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_LOCATION_QUERY, location_query, '&', "Location-Query")
terencez 0:1fa43ab66921 573 COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK2, block2, "Block2")
terencez 0:1fa43ab66921 574 COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK1, block1, "Block1")
terencez 0:1fa43ab66921 575 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_SIZE, size, "Size")
terencez 0:1fa43ab66921 576 COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_PROXY_URI, proxy_uri, '\0', "Proxy-Uri")
terencez 0:1fa43ab66921 577
terencez 0:1fa43ab66921 578 PRINTF("-Done serializing at %p----\n", option);
terencez 0:1fa43ab66921 579
terencez 0:1fa43ab66921 580 /* Free allocated header fields */
terencez 0:1fa43ab66921 581 coap_free_header(packet);
terencez 0:1fa43ab66921 582
terencez 0:1fa43ab66921 583 /* Pack payload */
terencez 0:1fa43ab66921 584 /* Payload marker */
terencez 0:1fa43ab66921 585 if (coap_pkt->payload_len)
terencez 0:1fa43ab66921 586 {
terencez 0:1fa43ab66921 587 *option = 0xFF;
terencez 0:1fa43ab66921 588 ++option;
terencez 0:1fa43ab66921 589 }
terencez 0:1fa43ab66921 590
terencez 0:1fa43ab66921 591 memmove(option, coap_pkt->payload, coap_pkt->payload_len);
terencez 0:1fa43ab66921 592
terencez 0:1fa43ab66921 593 PRINTF("-Done %u B (header len %u, payload len %u)-\n", coap_pkt->payload_len + option - buffer, option - buffer, coap_pkt->payload_len);
terencez 0:1fa43ab66921 594
terencez 0:1fa43ab66921 595 PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
terencez 0:1fa43ab66921 596 coap_pkt->buffer[0],
terencez 0:1fa43ab66921 597 coap_pkt->buffer[1],
terencez 0:1fa43ab66921 598 coap_pkt->buffer[2],
terencez 0:1fa43ab66921 599 coap_pkt->buffer[3],
terencez 0:1fa43ab66921 600 coap_pkt->buffer[4],
terencez 0:1fa43ab66921 601 coap_pkt->buffer[5],
terencez 0:1fa43ab66921 602 coap_pkt->buffer[6],
terencez 0:1fa43ab66921 603 coap_pkt->buffer[7]
terencez 0:1fa43ab66921 604 );
terencez 0:1fa43ab66921 605
terencez 0:1fa43ab66921 606 return (option - buffer) + coap_pkt->payload_len; /* packet length */
terencez 0:1fa43ab66921 607 }
terencez 0:1fa43ab66921 608 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 609 coap_status_t
terencez 0:1fa43ab66921 610 coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
terencez 0:1fa43ab66921 611 {
terencez 0:1fa43ab66921 612 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 613 uint8_t *current_option;
terencez 0:1fa43ab66921 614 unsigned int option_number = 0;
terencez 0:1fa43ab66921 615 unsigned int option_delta = 0;
terencez 0:1fa43ab66921 616 size_t option_length = 0;
terencez 0:1fa43ab66921 617 unsigned int *x;
terencez 0:1fa43ab66921 618
terencez 0:1fa43ab66921 619 /* Initialize packet */
terencez 0:1fa43ab66921 620 memset(coap_pkt, 0, sizeof(coap_packet_t));
terencez 0:1fa43ab66921 621
terencez 0:1fa43ab66921 622 /* pointer to packet bytes */
terencez 0:1fa43ab66921 623 coap_pkt->buffer = data;
terencez 0:1fa43ab66921 624
terencez 0:1fa43ab66921 625 /* parse header fields */
terencez 0:1fa43ab66921 626 coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])>>COAP_HEADER_VERSION_POSITION;
terencez 0:1fa43ab66921 627 coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])>>COAP_HEADER_TYPE_POSITION;
terencez 0:1fa43ab66921 628 coap_pkt->token_len = MIN(COAP_TOKEN_LEN, (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0])>>COAP_HEADER_TOKEN_LEN_POSITION);
terencez 0:1fa43ab66921 629 coap_pkt->code = coap_pkt->buffer[1];
terencez 0:1fa43ab66921 630 coap_pkt->mid = coap_pkt->buffer[2]<<8 | coap_pkt->buffer[3];
terencez 0:1fa43ab66921 631
terencez 0:1fa43ab66921 632 if (coap_pkt->version != 1)
terencez 0:1fa43ab66921 633 {
terencez 0:1fa43ab66921 634 coap_error_message = "CoAP version must be 1";
terencez 0:1fa43ab66921 635 return BAD_REQUEST_4_00;
terencez 0:1fa43ab66921 636 }
terencez 0:1fa43ab66921 637
terencez 0:1fa43ab66921 638 current_option = data + COAP_HEADER_LEN;
terencez 0:1fa43ab66921 639
terencez 0:1fa43ab66921 640 if (coap_pkt->token_len != 0)
terencez 0:1fa43ab66921 641 {
terencez 0:1fa43ab66921 642 memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
terencez 0:1fa43ab66921 643 SET_OPTION(coap_pkt, COAP_OPTION_TOKEN);
terencez 0:1fa43ab66921 644
terencez 0:1fa43ab66921 645 PRINTF("Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->token_len,
terencez 0:1fa43ab66921 646 coap_pkt->token[0],
terencez 0:1fa43ab66921 647 coap_pkt->token[1],
terencez 0:1fa43ab66921 648 coap_pkt->token[2],
terencez 0:1fa43ab66921 649 coap_pkt->token[3],
terencez 0:1fa43ab66921 650 coap_pkt->token[4],
terencez 0:1fa43ab66921 651 coap_pkt->token[5],
terencez 0:1fa43ab66921 652 coap_pkt->token[6],
terencez 0:1fa43ab66921 653 coap_pkt->token[7]
terencez 0:1fa43ab66921 654 ); /*FIXME always prints 8 bytes */
terencez 0:1fa43ab66921 655 }
terencez 0:1fa43ab66921 656
terencez 0:1fa43ab66921 657 /* parse options */
terencez 0:1fa43ab66921 658 current_option += coap_pkt->token_len;
terencez 0:1fa43ab66921 659
terencez 0:1fa43ab66921 660 while (current_option < data+data_len)
terencez 0:1fa43ab66921 661 {
terencez 0:1fa43ab66921 662 /* Payload marker 0xFF, currently only checking for 0xF* because rest is reserved */
terencez 0:1fa43ab66921 663 if ((current_option[0] & 0xF0)==0xF0)
terencez 0:1fa43ab66921 664 {
terencez 0:1fa43ab66921 665 coap_pkt->payload = ++current_option;
terencez 0:1fa43ab66921 666 coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
terencez 0:1fa43ab66921 667
terencez 0:1fa43ab66921 668 break;
terencez 0:1fa43ab66921 669 }
terencez 0:1fa43ab66921 670
terencez 0:1fa43ab66921 671 option_delta = current_option[0]>>4;
terencez 0:1fa43ab66921 672 option_length = current_option[0] & 0x0F;
terencez 0:1fa43ab66921 673 ++current_option;
terencez 0:1fa43ab66921 674
terencez 0:1fa43ab66921 675 /* avoids code duplication without function overhead */
terencez 0:1fa43ab66921 676 x = &option_delta;
terencez 0:1fa43ab66921 677 do
terencez 0:1fa43ab66921 678 {
terencez 0:1fa43ab66921 679 if (*x==13)
terencez 0:1fa43ab66921 680 {
terencez 0:1fa43ab66921 681 *x += current_option[0];
terencez 0:1fa43ab66921 682 ++current_option;
terencez 0:1fa43ab66921 683 }
terencez 0:1fa43ab66921 684 else if (*x==14)
terencez 0:1fa43ab66921 685 {
terencez 0:1fa43ab66921 686 *x += 255;
terencez 0:1fa43ab66921 687 *x += current_option[0]<<8;
terencez 0:1fa43ab66921 688 ++current_option;
terencez 0:1fa43ab66921 689 *x += current_option[0];
terencez 0:1fa43ab66921 690 ++current_option;
terencez 0:1fa43ab66921 691 }
terencez 0:1fa43ab66921 692 }
terencez 0:1fa43ab66921 693 while (x!=(unsigned int *)&option_length && (x=(unsigned int *)&option_length));
terencez 0:1fa43ab66921 694
terencez 0:1fa43ab66921 695 option_number += option_delta;
terencez 0:1fa43ab66921 696
terencez 0:1fa43ab66921 697 PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, option_length);
terencez 0:1fa43ab66921 698
terencez 0:1fa43ab66921 699 SET_OPTION(coap_pkt, option_number);
terencez 0:1fa43ab66921 700
terencez 0:1fa43ab66921 701 switch (option_number)
terencez 0:1fa43ab66921 702 {
terencez 0:1fa43ab66921 703 case COAP_OPTION_CONTENT_TYPE:
terencez 0:1fa43ab66921 704 coap_pkt->content_type = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 705 PRINTF("Content-Format [%u]\n", coap_pkt->content_type);
terencez 0:1fa43ab66921 706 break;
terencez 0:1fa43ab66921 707 case COAP_OPTION_MAX_AGE:
terencez 0:1fa43ab66921 708 coap_pkt->max_age = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 709 PRINTF("Max-Age [%lu]\n", coap_pkt->max_age);
terencez 0:1fa43ab66921 710 break;
terencez 0:1fa43ab66921 711 case COAP_OPTION_ETAG:
terencez 0:1fa43ab66921 712 coap_pkt->etag_len = (uint8_t)(MIN(COAP_ETAG_LEN, option_length));
terencez 0:1fa43ab66921 713 memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len);
terencez 0:1fa43ab66921 714 PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len,
terencez 0:1fa43ab66921 715 coap_pkt->etag[0],
terencez 0:1fa43ab66921 716 coap_pkt->etag[1],
terencez 0:1fa43ab66921 717 coap_pkt->etag[2],
terencez 0:1fa43ab66921 718 coap_pkt->etag[3],
terencez 0:1fa43ab66921 719 coap_pkt->etag[4],
terencez 0:1fa43ab66921 720 coap_pkt->etag[5],
terencez 0:1fa43ab66921 721 coap_pkt->etag[6],
terencez 0:1fa43ab66921 722 coap_pkt->etag[7]
terencez 0:1fa43ab66921 723 ); /*FIXME always prints 8 bytes */
terencez 0:1fa43ab66921 724 break;
terencez 0:1fa43ab66921 725 case COAP_OPTION_ACCEPT:
terencez 0:1fa43ab66921 726 if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM)
terencez 0:1fa43ab66921 727 {
terencez 0:1fa43ab66921 728 coap_pkt->accept[coap_pkt->accept_num] = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 729 coap_pkt->accept_num += 1;
terencez 0:1fa43ab66921 730 PRINTF("Accept [%u]\n", coap_pkt->content_type);
terencez 0:1fa43ab66921 731 }
terencez 0:1fa43ab66921 732 break;
terencez 0:1fa43ab66921 733 case COAP_OPTION_IF_MATCH:
terencez 0:1fa43ab66921 734 /*FIXME support multiple ETags */
terencez 0:1fa43ab66921 735 coap_pkt->if_match_len = (uint8_t)(MIN(COAP_ETAG_LEN, option_length));
terencez 0:1fa43ab66921 736 memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len);
terencez 0:1fa43ab66921 737 PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->if_match_len,
terencez 0:1fa43ab66921 738 coap_pkt->if_match[0],
terencez 0:1fa43ab66921 739 coap_pkt->if_match[1],
terencez 0:1fa43ab66921 740 coap_pkt->if_match[2],
terencez 0:1fa43ab66921 741 coap_pkt->if_match[3],
terencez 0:1fa43ab66921 742 coap_pkt->if_match[4],
terencez 0:1fa43ab66921 743 coap_pkt->if_match[5],
terencez 0:1fa43ab66921 744 coap_pkt->if_match[6],
terencez 0:1fa43ab66921 745 coap_pkt->if_match[7]
terencez 0:1fa43ab66921 746 ); /*FIXME always prints 8 bytes */
terencez 0:1fa43ab66921 747 break;
terencez 0:1fa43ab66921 748 case COAP_OPTION_IF_NONE_MATCH:
terencez 0:1fa43ab66921 749 coap_pkt->if_none_match = 1;
terencez 0:1fa43ab66921 750 PRINTF("If-None-Match\n");
terencez 0:1fa43ab66921 751 break;
terencez 0:1fa43ab66921 752
terencez 0:1fa43ab66921 753 case COAP_OPTION_URI_HOST:
terencez 0:1fa43ab66921 754 coap_pkt->uri_host = current_option;
terencez 0:1fa43ab66921 755 coap_pkt->uri_host_len = option_length;
terencez 0:1fa43ab66921 756 PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host);
terencez 0:1fa43ab66921 757 break;
terencez 0:1fa43ab66921 758 case COAP_OPTION_URI_PORT:
terencez 0:1fa43ab66921 759 coap_pkt->uri_port = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 760 PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port);
terencez 0:1fa43ab66921 761 break;
terencez 0:1fa43ab66921 762 case COAP_OPTION_URI_PATH:
terencez 0:1fa43ab66921 763 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:1fa43ab66921 764 // coap_merge_multi_option( (char **) &(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_length, 0);
terencez 0:1fa43ab66921 765 coap_add_multi_option( &(coap_pkt->uri_path), current_option, option_length, 1);
terencez 0:1fa43ab66921 766 PRINTF("Uri-Path [%.*s]\n", option_length, current_option);
terencez 0:1fa43ab66921 767 break;
terencez 0:1fa43ab66921 768 case COAP_OPTION_URI_QUERY:
terencez 0:1fa43ab66921 769 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:1fa43ab66921 770 // coap_merge_multi_option( (char **) &(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_length, '&');
terencez 0:1fa43ab66921 771 coap_add_multi_option( &(coap_pkt->uri_query), current_option, option_length, 1);
terencez 0:1fa43ab66921 772 PRINTF("Uri-Query [%.*s]\n", option_length, current_option);
terencez 0:1fa43ab66921 773 break;
terencez 0:1fa43ab66921 774
terencez 0:1fa43ab66921 775 case COAP_OPTION_LOCATION_PATH:
terencez 0:1fa43ab66921 776 coap_add_multi_option( &(coap_pkt->location_path), current_option, option_length, 1);
terencez 0:1fa43ab66921 777 break;
terencez 0:1fa43ab66921 778 case COAP_OPTION_LOCATION_QUERY:
terencez 0:1fa43ab66921 779 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:1fa43ab66921 780 coap_merge_multi_option( &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_length, '&');
terencez 0:1fa43ab66921 781 PRINTF("Location-Query [%.*s]\n", option_length, current_option);
terencez 0:1fa43ab66921 782 break;
terencez 0:1fa43ab66921 783
terencez 0:1fa43ab66921 784 case COAP_OPTION_PROXY_URI:
terencez 0:1fa43ab66921 785 /*FIXME check for own end-point */
terencez 0:1fa43ab66921 786 coap_pkt->proxy_uri = current_option;
terencez 0:1fa43ab66921 787 coap_pkt->proxy_uri_len = option_length;
terencez 0:1fa43ab66921 788 /*TODO length > 270 not implemented (actually not required) */
terencez 0:1fa43ab66921 789 PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri);
terencez 0:1fa43ab66921 790 coap_error_message = "This is a constrained server (Contiki)";
terencez 0:1fa43ab66921 791 return PROXYING_NOT_SUPPORTED_5_05;
terencez 0:1fa43ab66921 792 break;
terencez 0:1fa43ab66921 793
terencez 0:1fa43ab66921 794 case COAP_OPTION_OBSERVE:
terencez 0:1fa43ab66921 795 coap_pkt->observe = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 796 PRINTF("Observe [%lu]\n", coap_pkt->observe);
terencez 0:1fa43ab66921 797 break;
terencez 0:1fa43ab66921 798 case COAP_OPTION_BLOCK2:
terencez 0:1fa43ab66921 799 coap_pkt->block2_num = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 800 coap_pkt->block2_more = (coap_pkt->block2_num & 0x08)>>3;
terencez 0:1fa43ab66921 801 coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
terencez 0:1fa43ab66921 802 coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)<<(coap_pkt->block2_num & 0x07);
terencez 0:1fa43ab66921 803 coap_pkt->block2_num >>= 4;
terencez 0:1fa43ab66921 804 PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
terencez 0:1fa43ab66921 805 break;
terencez 0:1fa43ab66921 806 case COAP_OPTION_BLOCK1:
terencez 0:1fa43ab66921 807 coap_pkt->block1_num = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 808 coap_pkt->block1_more = (coap_pkt->block1_num & 0x08)>>3;
terencez 0:1fa43ab66921 809 coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
terencez 0:1fa43ab66921 810 coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)<<(coap_pkt->block1_num & 0x07);
terencez 0:1fa43ab66921 811 coap_pkt->block1_num >>= 4;
terencez 0:1fa43ab66921 812 PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
terencez 0:1fa43ab66921 813 break;
terencez 0:1fa43ab66921 814 case COAP_OPTION_SIZE:
terencez 0:1fa43ab66921 815 coap_pkt->size = coap_parse_int_option(current_option, option_length);
terencez 0:1fa43ab66921 816 PRINTF("Size [%lu]\n", coap_pkt->size);
terencez 0:1fa43ab66921 817 break;
terencez 0:1fa43ab66921 818 default:
terencez 0:1fa43ab66921 819 PRINTF("unknown (%u)\n", option_number);
terencez 0:1fa43ab66921 820 /* Check if critical (odd) */
terencez 0:1fa43ab66921 821 if (option_number & 1)
terencez 0:1fa43ab66921 822 {
terencez 0:1fa43ab66921 823 coap_error_message = "Unsupported critical option";
terencez 0:1fa43ab66921 824 return BAD_OPTION_4_02;
terencez 0:1fa43ab66921 825 }
terencez 0:1fa43ab66921 826 }
terencez 0:1fa43ab66921 827
terencez 0:1fa43ab66921 828 current_option += option_length;
terencez 0:1fa43ab66921 829 } /* for */
terencez 0:1fa43ab66921 830 PRINTF("-Done parsing-------\n");
terencez 0:1fa43ab66921 831
terencez 0:1fa43ab66921 832
terencez 0:1fa43ab66921 833
terencez 0:1fa43ab66921 834 return NO_ERROR;
terencez 0:1fa43ab66921 835 }
terencez 0:1fa43ab66921 836 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 837 /*- REST FRAMEWORK FUNCTIONS --------------------------------------------------------*/
terencez 0:1fa43ab66921 838 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 839 int
terencez 0:1fa43ab66921 840 coap_get_query_variable(void *packet, const char *name, const char **output)
terencez 0:1fa43ab66921 841 {
terencez 0:1fa43ab66921 842 /*
terencez 0:1fa43ab66921 843 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 844
terencez 0:1fa43ab66921 845 if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
terencez 0:1fa43ab66921 846 return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, name, output);
terencez 0:1fa43ab66921 847 }
terencez 0:1fa43ab66921 848 */
terencez 0:1fa43ab66921 849 return 0;
terencez 0:1fa43ab66921 850 }
terencez 0:1fa43ab66921 851
terencez 0:1fa43ab66921 852 int
terencez 0:1fa43ab66921 853 coap_get_post_variable(void *packet, const char *name, const char **output)
terencez 0:1fa43ab66921 854 {
terencez 0:1fa43ab66921 855 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 856
terencez 0:1fa43ab66921 857 if (coap_pkt->payload_len) {
terencez 0:1fa43ab66921 858 return coap_get_variable(coap_pkt->payload, coap_pkt->payload_len, name, output);
terencez 0:1fa43ab66921 859 }
terencez 0:1fa43ab66921 860 return 0;
terencez 0:1fa43ab66921 861 }
terencez 0:1fa43ab66921 862 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 863 int
terencez 0:1fa43ab66921 864 coap_set_status_code(void *packet, unsigned int code)
terencez 0:1fa43ab66921 865 {
terencez 0:1fa43ab66921 866 if (code <= 0xFF)
terencez 0:1fa43ab66921 867 {
terencez 0:1fa43ab66921 868 ((coap_packet_t *)packet)->code = (uint8_t) code;
terencez 0:1fa43ab66921 869 return 1;
terencez 0:1fa43ab66921 870 }
terencez 0:1fa43ab66921 871 else
terencez 0:1fa43ab66921 872 {
terencez 0:1fa43ab66921 873 return 0;
terencez 0:1fa43ab66921 874 }
terencez 0:1fa43ab66921 875 }
terencez 0:1fa43ab66921 876 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 877 /*- HEADER OPTION GETTERS AND SETTERS -----------------------------------------------*/
terencez 0:1fa43ab66921 878 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 879 unsigned int
terencez 0:1fa43ab66921 880 coap_get_header_content_type(void *packet)
terencez 0:1fa43ab66921 881 {
terencez 0:1fa43ab66921 882 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 883
terencez 0:1fa43ab66921 884 if (!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) return -1;
terencez 0:1fa43ab66921 885
terencez 0:1fa43ab66921 886 return coap_pkt->content_type;
terencez 0:1fa43ab66921 887 }
terencez 0:1fa43ab66921 888
terencez 0:1fa43ab66921 889 int
terencez 0:1fa43ab66921 890 coap_set_header_content_type(void *packet, unsigned int content_type)
terencez 0:1fa43ab66921 891 {
terencez 0:1fa43ab66921 892 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 893
terencez 0:1fa43ab66921 894 coap_pkt->content_type = (coap_content_type_t) content_type;
terencez 0:1fa43ab66921 895 SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE);
terencez 0:1fa43ab66921 896 return 1;
terencez 0:1fa43ab66921 897 }
terencez 0:1fa43ab66921 898 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 899 int
terencez 0:1fa43ab66921 900 coap_get_header_accept(void *packet, const uint16_t **accept)
terencez 0:1fa43ab66921 901 {
terencez 0:1fa43ab66921 902 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 903
terencez 0:1fa43ab66921 904 if (!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) return 0;
terencez 0:1fa43ab66921 905
terencez 0:1fa43ab66921 906 *accept = coap_pkt->accept;
terencez 0:1fa43ab66921 907 return coap_pkt->accept_num;
terencez 0:1fa43ab66921 908 }
terencez 0:1fa43ab66921 909
terencez 0:1fa43ab66921 910 int
terencez 0:1fa43ab66921 911 coap_set_header_accept(void *packet, uint16_t accept)
terencez 0:1fa43ab66921 912 {
terencez 0:1fa43ab66921 913 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 914
terencez 0:1fa43ab66921 915 if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM)
terencez 0:1fa43ab66921 916 {
terencez 0:1fa43ab66921 917 coap_pkt->accept[coap_pkt->accept_num] = accept;
terencez 0:1fa43ab66921 918 coap_pkt->accept_num += 1;
terencez 0:1fa43ab66921 919
terencez 0:1fa43ab66921 920 SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
terencez 0:1fa43ab66921 921 }
terencez 0:1fa43ab66921 922 return coap_pkt->accept_num;
terencez 0:1fa43ab66921 923 }
terencez 0:1fa43ab66921 924 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 925 int
terencez 0:1fa43ab66921 926 coap_get_header_max_age(void *packet, uint32_t *age)
terencez 0:1fa43ab66921 927 {
terencez 0:1fa43ab66921 928 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 929
terencez 0:1fa43ab66921 930 if (!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) {
terencez 0:1fa43ab66921 931 *age = COAP_DEFAULT_MAX_AGE;
terencez 0:1fa43ab66921 932 } else {
terencez 0:1fa43ab66921 933 *age = coap_pkt->max_age;
terencez 0:1fa43ab66921 934 }
terencez 0:1fa43ab66921 935 return 1;
terencez 0:1fa43ab66921 936 }
terencez 0:1fa43ab66921 937
terencez 0:1fa43ab66921 938 int
terencez 0:1fa43ab66921 939 coap_set_header_max_age(void *packet, uint32_t age)
terencez 0:1fa43ab66921 940 {
terencez 0:1fa43ab66921 941 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 942
terencez 0:1fa43ab66921 943 coap_pkt->max_age = age;
terencez 0:1fa43ab66921 944 SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE);
terencez 0:1fa43ab66921 945 return 1;
terencez 0:1fa43ab66921 946 }
terencez 0:1fa43ab66921 947 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 948 int
terencez 0:1fa43ab66921 949 coap_get_header_etag(void *packet, const uint8_t **etag)
terencez 0:1fa43ab66921 950 {
terencez 0:1fa43ab66921 951 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 952
terencez 0:1fa43ab66921 953 if (!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) return 0;
terencez 0:1fa43ab66921 954
terencez 0:1fa43ab66921 955 *etag = coap_pkt->etag;
terencez 0:1fa43ab66921 956 return coap_pkt->etag_len;
terencez 0:1fa43ab66921 957 }
terencez 0:1fa43ab66921 958
terencez 0:1fa43ab66921 959 int
terencez 0:1fa43ab66921 960 coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len)
terencez 0:1fa43ab66921 961 {
terencez 0:1fa43ab66921 962 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 963
terencez 0:1fa43ab66921 964 coap_pkt->etag_len = (uint8_t)(MIN(COAP_ETAG_LEN, etag_len));
terencez 0:1fa43ab66921 965 memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
terencez 0:1fa43ab66921 966
terencez 0:1fa43ab66921 967 SET_OPTION(coap_pkt, COAP_OPTION_ETAG);
terencez 0:1fa43ab66921 968 return coap_pkt->etag_len;
terencez 0:1fa43ab66921 969 }
terencez 0:1fa43ab66921 970 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 971 /*FIXME support multiple ETags */
terencez 0:1fa43ab66921 972 int
terencez 0:1fa43ab66921 973 coap_get_header_if_match(void *packet, const uint8_t **etag)
terencez 0:1fa43ab66921 974 {
terencez 0:1fa43ab66921 975 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 976
terencez 0:1fa43ab66921 977 if (!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) return 0;
terencez 0:1fa43ab66921 978
terencez 0:1fa43ab66921 979 *etag = coap_pkt->if_match;
terencez 0:1fa43ab66921 980 return coap_pkt->if_match_len;
terencez 0:1fa43ab66921 981 }
terencez 0:1fa43ab66921 982
terencez 0:1fa43ab66921 983 int
terencez 0:1fa43ab66921 984 coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len)
terencez 0:1fa43ab66921 985 {
terencez 0:1fa43ab66921 986 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 987
terencez 0:1fa43ab66921 988 coap_pkt->if_match_len = (uint8_t)(MIN(COAP_ETAG_LEN, etag_len));
terencez 0:1fa43ab66921 989 memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
terencez 0:1fa43ab66921 990
terencez 0:1fa43ab66921 991 SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH);
terencez 0:1fa43ab66921 992 return coap_pkt->if_match_len;
terencez 0:1fa43ab66921 993 }
terencez 0:1fa43ab66921 994 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 995 int
terencez 0:1fa43ab66921 996 coap_get_header_if_none_match(void *packet)
terencez 0:1fa43ab66921 997 {
terencez 0:1fa43ab66921 998 return IS_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
terencez 0:1fa43ab66921 999 }
terencez 0:1fa43ab66921 1000
terencez 0:1fa43ab66921 1001 int
terencez 0:1fa43ab66921 1002 coap_set_header_if_none_match(void *packet)
terencez 0:1fa43ab66921 1003 {
terencez 0:1fa43ab66921 1004 SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH);
terencez 0:1fa43ab66921 1005 return 1;
terencez 0:1fa43ab66921 1006 }
terencez 0:1fa43ab66921 1007 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1008 int
terencez 0:1fa43ab66921 1009 coap_get_header_token(void *packet, const uint8_t **token)
terencez 0:1fa43ab66921 1010 {
terencez 0:1fa43ab66921 1011 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1012
terencez 0:1fa43ab66921 1013 if (!IS_OPTION(coap_pkt, COAP_OPTION_TOKEN)) return 0;
terencez 0:1fa43ab66921 1014
terencez 0:1fa43ab66921 1015 *token = coap_pkt->token;
terencez 0:1fa43ab66921 1016 return coap_pkt->token_len;
terencez 0:1fa43ab66921 1017 }
terencez 0:1fa43ab66921 1018
terencez 0:1fa43ab66921 1019 int
terencez 0:1fa43ab66921 1020 coap_set_header_token(void *packet, const uint8_t *token, size_t token_len)
terencez 0:1fa43ab66921 1021 {
terencez 0:1fa43ab66921 1022 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1023
terencez 0:1fa43ab66921 1024 coap_pkt->token_len = (uint8_t)(MIN(COAP_TOKEN_LEN, token_len));
terencez 0:1fa43ab66921 1025 memcpy(coap_pkt->token, token, coap_pkt->token_len);
terencez 0:1fa43ab66921 1026
terencez 0:1fa43ab66921 1027 SET_OPTION(coap_pkt, COAP_OPTION_TOKEN);
terencez 0:1fa43ab66921 1028 return coap_pkt->token_len;
terencez 0:1fa43ab66921 1029 }
terencez 0:1fa43ab66921 1030 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1031 int
terencez 0:1fa43ab66921 1032 coap_get_header_proxy_uri(void *packet, const char **uri)
terencez 0:1fa43ab66921 1033 {
terencez 0:1fa43ab66921 1034 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1035
terencez 0:1fa43ab66921 1036 if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0;
terencez 0:1fa43ab66921 1037
terencez 0:1fa43ab66921 1038 *uri = (const char *)coap_pkt->proxy_uri;
terencez 0:1fa43ab66921 1039 return coap_pkt->proxy_uri_len;
terencez 0:1fa43ab66921 1040 }
terencez 0:1fa43ab66921 1041
terencez 0:1fa43ab66921 1042 int
terencez 0:1fa43ab66921 1043 coap_set_header_proxy_uri(void *packet, const char *uri)
terencez 0:1fa43ab66921 1044 {
terencez 0:1fa43ab66921 1045 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1046
terencez 0:1fa43ab66921 1047 coap_pkt->proxy_uri = (uint8_t *)uri;
terencez 0:1fa43ab66921 1048 coap_pkt->proxy_uri_len = strlen(uri);
terencez 0:1fa43ab66921 1049
terencez 0:1fa43ab66921 1050 SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI);
terencez 0:1fa43ab66921 1051 return coap_pkt->proxy_uri_len;
terencez 0:1fa43ab66921 1052 }
terencez 0:1fa43ab66921 1053 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1054 int
terencez 0:1fa43ab66921 1055 coap_get_header_uri_host(void *packet, const char **host)
terencez 0:1fa43ab66921 1056 {
terencez 0:1fa43ab66921 1057 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1058
terencez 0:1fa43ab66921 1059 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) return 0;
terencez 0:1fa43ab66921 1060
terencez 0:1fa43ab66921 1061 *host = (char *)coap_pkt->uri_host;
terencez 0:1fa43ab66921 1062 return coap_pkt->uri_host_len;
terencez 0:1fa43ab66921 1063 }
terencez 0:1fa43ab66921 1064
terencez 0:1fa43ab66921 1065 int
terencez 0:1fa43ab66921 1066 coap_set_header_uri_host(void *packet, const char *host)
terencez 0:1fa43ab66921 1067 {
terencez 0:1fa43ab66921 1068 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1069
terencez 0:1fa43ab66921 1070 coap_pkt->uri_host = (uint8_t *)host;
terencez 0:1fa43ab66921 1071 coap_pkt->uri_host_len = strlen(host);
terencez 0:1fa43ab66921 1072
terencez 0:1fa43ab66921 1073 SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST);
terencez 0:1fa43ab66921 1074 return coap_pkt->uri_host_len;
terencez 0:1fa43ab66921 1075 }
terencez 0:1fa43ab66921 1076 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1077 int
terencez 0:1fa43ab66921 1078 coap_get_header_uri_path(void *packet, const char **path)
terencez 0:1fa43ab66921 1079 {
terencez 0:1fa43ab66921 1080 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1081
terencez 0:1fa43ab66921 1082 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) return 0;
terencez 0:1fa43ab66921 1083
terencez 0:1fa43ab66921 1084 *path = NULL; //coap_pkt->uri_path;
terencez 0:1fa43ab66921 1085 return 0; //coap_pkt->uri_path_len;
terencez 0:1fa43ab66921 1086 }
terencez 0:1fa43ab66921 1087
terencez 0:1fa43ab66921 1088 int
terencez 0:1fa43ab66921 1089 coap_set_header_uri_path(void *packet, const char *path)
terencez 0:1fa43ab66921 1090 {
terencez 0:1fa43ab66921 1091 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1092 int length = 0;
terencez 0:1fa43ab66921 1093
terencez 0:1fa43ab66921 1094 free_multi_option(coap_pkt->uri_path);
terencez 0:1fa43ab66921 1095 coap_pkt->uri_path = NULL;
terencez 0:1fa43ab66921 1096
terencez 0:1fa43ab66921 1097 if (path[0]=='/') ++path;
terencez 0:1fa43ab66921 1098
terencez 0:1fa43ab66921 1099 do
terencez 0:1fa43ab66921 1100 {
terencez 0:1fa43ab66921 1101 int i = 0;
terencez 0:1fa43ab66921 1102
terencez 0:1fa43ab66921 1103 while (path[i] != 0 && path[i] != '/') i++;
terencez 0:1fa43ab66921 1104 coap_add_multi_option(&(coap_pkt->uri_path), (uint8_t *)path, i, 0);
terencez 0:1fa43ab66921 1105
terencez 0:1fa43ab66921 1106 if (path[i] == '/') i++;
terencez 0:1fa43ab66921 1107 path += i;
terencez 0:1fa43ab66921 1108 length += i;
terencez 0:1fa43ab66921 1109 } while (path[0] != 0);
terencez 0:1fa43ab66921 1110
terencez 0:1fa43ab66921 1111 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
terencez 0:1fa43ab66921 1112 return length;
terencez 0:1fa43ab66921 1113 }
terencez 0:1fa43ab66921 1114
terencez 0:1fa43ab66921 1115 int
terencez 0:1fa43ab66921 1116 coap_set_header_uri_path_segment(void *packet, const char *segment)
terencez 0:1fa43ab66921 1117 {
terencez 0:1fa43ab66921 1118 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1119 int length;
terencez 0:1fa43ab66921 1120
terencez 0:1fa43ab66921 1121 if (segment == NULL || segment[0] == 0)
terencez 0:1fa43ab66921 1122 {
terencez 0:1fa43ab66921 1123 coap_add_multi_option(&(coap_pkt->uri_path), NULL, 0, 1);
terencez 0:1fa43ab66921 1124 length = 0;
terencez 0:1fa43ab66921 1125 }
terencez 0:1fa43ab66921 1126 else
terencez 0:1fa43ab66921 1127 {
terencez 0:1fa43ab66921 1128 length = strlen(segment);
terencez 0:1fa43ab66921 1129 coap_add_multi_option(&(coap_pkt->uri_path), (uint8_t *)segment, length, 0);
terencez 0:1fa43ab66921 1130 }
terencez 0:1fa43ab66921 1131
terencez 0:1fa43ab66921 1132 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
terencez 0:1fa43ab66921 1133 return length;
terencez 0:1fa43ab66921 1134 }
terencez 0:1fa43ab66921 1135 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1136 int
terencez 0:1fa43ab66921 1137 coap_get_header_uri_query(void *packet, const char **query)
terencez 0:1fa43ab66921 1138 {
terencez 0:1fa43ab66921 1139 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1140
terencez 0:1fa43ab66921 1141 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) return 0;
terencez 0:1fa43ab66921 1142
terencez 0:1fa43ab66921 1143 *query = NULL; //coap_pkt->uri_query;
terencez 0:1fa43ab66921 1144 return 0; //coap_pkt->uri_query_len;
terencez 0:1fa43ab66921 1145 }
terencez 0:1fa43ab66921 1146
terencez 0:1fa43ab66921 1147 int
terencez 0:1fa43ab66921 1148 coap_set_header_uri_query(void *packet, const char *query)
terencez 0:1fa43ab66921 1149 {
terencez 0:1fa43ab66921 1150 int length = 0;
terencez 0:1fa43ab66921 1151 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1152
terencez 0:1fa43ab66921 1153 free_multi_option(coap_pkt->uri_query);
terencez 0:1fa43ab66921 1154 coap_pkt->uri_query = NULL;
terencez 0:1fa43ab66921 1155
terencez 0:1fa43ab66921 1156 if (query[0]=='?') ++query;
terencez 0:1fa43ab66921 1157
terencez 0:1fa43ab66921 1158 do
terencez 0:1fa43ab66921 1159 {
terencez 0:1fa43ab66921 1160 int i = 0;
terencez 0:1fa43ab66921 1161
terencez 0:1fa43ab66921 1162 while (query[i] != 0 && query[i] != '&') i++;
terencez 0:1fa43ab66921 1163 coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t *)query, i, 0);
terencez 0:1fa43ab66921 1164
terencez 0:1fa43ab66921 1165 if (query[i] == '&') i++;
terencez 0:1fa43ab66921 1166 query += i;
terencez 0:1fa43ab66921 1167 length += i;
terencez 0:1fa43ab66921 1168 } while (query[0] != 0);
terencez 0:1fa43ab66921 1169
terencez 0:1fa43ab66921 1170 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
terencez 0:1fa43ab66921 1171 return length;
terencez 0:1fa43ab66921 1172 }
terencez 0:1fa43ab66921 1173 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1174 int
terencez 0:1fa43ab66921 1175 coap_get_header_location_path(void *packet, const char **path)
terencez 0:1fa43ab66921 1176 {
terencez 0:1fa43ab66921 1177 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1178
terencez 0:1fa43ab66921 1179 if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) return 0;
terencez 0:1fa43ab66921 1180
terencez 0:1fa43ab66921 1181 *path = NULL; //coap_pkt->location_path;
terencez 0:1fa43ab66921 1182 return 0; //coap_pkt->location_path_len;
terencez 0:1fa43ab66921 1183 }
terencez 0:1fa43ab66921 1184
terencez 0:1fa43ab66921 1185 int
terencez 0:1fa43ab66921 1186 coap_set_header_location_path(void *packet, const char *path)
terencez 0:1fa43ab66921 1187 {
terencez 0:1fa43ab66921 1188 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1189 int length = 0;
terencez 0:1fa43ab66921 1190
terencez 0:1fa43ab66921 1191 free_multi_option(coap_pkt->location_path);
terencez 0:1fa43ab66921 1192 coap_pkt->location_path = NULL;
terencez 0:1fa43ab66921 1193
terencez 0:1fa43ab66921 1194 if (path[0]=='/') ++path;
terencez 0:1fa43ab66921 1195
terencez 0:1fa43ab66921 1196 do
terencez 0:1fa43ab66921 1197 {
terencez 0:1fa43ab66921 1198 int i = 0;
terencez 0:1fa43ab66921 1199
terencez 0:1fa43ab66921 1200 while (path[i] != 0 && path[i] != '/') i++;
terencez 0:1fa43ab66921 1201 coap_add_multi_option(&(coap_pkt->location_path), (uint8_t *)path, i, 0);
terencez 0:1fa43ab66921 1202
terencez 0:1fa43ab66921 1203 if (path[i] == '/') i++;
terencez 0:1fa43ab66921 1204 path += i;
terencez 0:1fa43ab66921 1205 length += i;
terencez 0:1fa43ab66921 1206 } while (path[0] != 0);
terencez 0:1fa43ab66921 1207
terencez 0:1fa43ab66921 1208 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH);
terencez 0:1fa43ab66921 1209 return length;
terencez 0:1fa43ab66921 1210 }
terencez 0:1fa43ab66921 1211 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1212 int
terencez 0:1fa43ab66921 1213 coap_get_header_location_query(void *packet, const char **query)
terencez 0:1fa43ab66921 1214 {
terencez 0:1fa43ab66921 1215 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1216
terencez 0:1fa43ab66921 1217 if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0;
terencez 0:1fa43ab66921 1218
terencez 0:1fa43ab66921 1219 *query = (const char*)coap_pkt->location_query;
terencez 0:1fa43ab66921 1220 return coap_pkt->location_query_len;
terencez 0:1fa43ab66921 1221 }
terencez 0:1fa43ab66921 1222
terencez 0:1fa43ab66921 1223 int
terencez 0:1fa43ab66921 1224 coap_set_header_location_query(void *packet, char *query)
terencez 0:1fa43ab66921 1225 {
terencez 0:1fa43ab66921 1226 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1227
terencez 0:1fa43ab66921 1228 while (query[0]=='?') ++query;
terencez 0:1fa43ab66921 1229
terencez 0:1fa43ab66921 1230 coap_pkt->location_query = (uint8_t *)query;
terencez 0:1fa43ab66921 1231 coap_pkt->location_query_len = strlen(query);
terencez 0:1fa43ab66921 1232
terencez 0:1fa43ab66921 1233 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY);
terencez 0:1fa43ab66921 1234 return coap_pkt->location_query_len;
terencez 0:1fa43ab66921 1235 }
terencez 0:1fa43ab66921 1236 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1237 int
terencez 0:1fa43ab66921 1238 coap_get_header_observe(void *packet, uint32_t *observe)
terencez 0:1fa43ab66921 1239 {
terencez 0:1fa43ab66921 1240 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1241
terencez 0:1fa43ab66921 1242 if (!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) return 0;
terencez 0:1fa43ab66921 1243
terencez 0:1fa43ab66921 1244 *observe = coap_pkt->observe;
terencez 0:1fa43ab66921 1245 return 1;
terencez 0:1fa43ab66921 1246 }
terencez 0:1fa43ab66921 1247
terencez 0:1fa43ab66921 1248 int
terencez 0:1fa43ab66921 1249 coap_set_header_observe(void *packet, uint32_t observe)
terencez 0:1fa43ab66921 1250 {
terencez 0:1fa43ab66921 1251 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1252
terencez 0:1fa43ab66921 1253 coap_pkt->observe = 0x00FFFFFF & observe;
terencez 0:1fa43ab66921 1254 SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE);
terencez 0:1fa43ab66921 1255 return 1;
terencez 0:1fa43ab66921 1256 }
terencez 0:1fa43ab66921 1257 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1258 int
terencez 0:1fa43ab66921 1259 coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset)
terencez 0:1fa43ab66921 1260 {
terencez 0:1fa43ab66921 1261 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1262
terencez 0:1fa43ab66921 1263 if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) return 0;
terencez 0:1fa43ab66921 1264
terencez 0:1fa43ab66921 1265 /* pointers may be NULL to get only specific block parameters */
terencez 0:1fa43ab66921 1266 if (num!=NULL) *num = coap_pkt->block2_num;
terencez 0:1fa43ab66921 1267 if (more!=NULL) *more = coap_pkt->block2_more;
terencez 0:1fa43ab66921 1268 if (size!=NULL) *size = coap_pkt->block2_size;
terencez 0:1fa43ab66921 1269 if (offset!=NULL) *offset = coap_pkt->block2_offset;
terencez 0:1fa43ab66921 1270
terencez 0:1fa43ab66921 1271 return 1;
terencez 0:1fa43ab66921 1272 }
terencez 0:1fa43ab66921 1273
terencez 0:1fa43ab66921 1274 int
terencez 0:1fa43ab66921 1275 coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size)
terencez 0:1fa43ab66921 1276 {
terencez 0:1fa43ab66921 1277 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1278
terencez 0:1fa43ab66921 1279 if (size<16) return 0;
terencez 0:1fa43ab66921 1280 if (size>2048) return 0;
terencez 0:1fa43ab66921 1281 if (num>0x0FFFFF) return 0;
terencez 0:1fa43ab66921 1282
terencez 0:1fa43ab66921 1283 coap_pkt->block2_num = num;
terencez 0:1fa43ab66921 1284 coap_pkt->block2_more = more ? 1 : 0;
terencez 0:1fa43ab66921 1285 coap_pkt->block2_size = size;
terencez 0:1fa43ab66921 1286
terencez 0:1fa43ab66921 1287 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2);
terencez 0:1fa43ab66921 1288 return 1;
terencez 0:1fa43ab66921 1289 }
terencez 0:1fa43ab66921 1290 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1291 int
terencez 0:1fa43ab66921 1292 coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset)
terencez 0:1fa43ab66921 1293 {
terencez 0:1fa43ab66921 1294 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1295
terencez 0:1fa43ab66921 1296 if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) return 0;
terencez 0:1fa43ab66921 1297
terencez 0:1fa43ab66921 1298 /* pointers may be NULL to get only specific block parameters */
terencez 0:1fa43ab66921 1299 if (num!=NULL) *num = coap_pkt->block1_num;
terencez 0:1fa43ab66921 1300 if (more!=NULL) *more = coap_pkt->block1_more;
terencez 0:1fa43ab66921 1301 if (size!=NULL) *size = coap_pkt->block1_size;
terencez 0:1fa43ab66921 1302 if (offset!=NULL) *offset = coap_pkt->block1_offset;
terencez 0:1fa43ab66921 1303
terencez 0:1fa43ab66921 1304 return 1;
terencez 0:1fa43ab66921 1305 }
terencez 0:1fa43ab66921 1306
terencez 0:1fa43ab66921 1307 int
terencez 0:1fa43ab66921 1308 coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size)
terencez 0:1fa43ab66921 1309 {
terencez 0:1fa43ab66921 1310 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1311
terencez 0:1fa43ab66921 1312 if (size<16) return 0;
terencez 0:1fa43ab66921 1313 if (size>2048) return 0;
terencez 0:1fa43ab66921 1314 if (num>0x0FFFFF) return 0;
terencez 0:1fa43ab66921 1315
terencez 0:1fa43ab66921 1316 coap_pkt->block1_num = num;
terencez 0:1fa43ab66921 1317 coap_pkt->block1_more = more;
terencez 0:1fa43ab66921 1318 coap_pkt->block1_size = size;
terencez 0:1fa43ab66921 1319
terencez 0:1fa43ab66921 1320 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1);
terencez 0:1fa43ab66921 1321 return 1;
terencez 0:1fa43ab66921 1322 }
terencez 0:1fa43ab66921 1323 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1324 int
terencez 0:1fa43ab66921 1325 coap_get_header_size(void *packet, uint32_t *size)
terencez 0:1fa43ab66921 1326 {
terencez 0:1fa43ab66921 1327 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1328
terencez 0:1fa43ab66921 1329 if (!IS_OPTION(coap_pkt, COAP_OPTION_SIZE)) return 0;
terencez 0:1fa43ab66921 1330
terencez 0:1fa43ab66921 1331 *size = coap_pkt->size;
terencez 0:1fa43ab66921 1332 return 1;
terencez 0:1fa43ab66921 1333 }
terencez 0:1fa43ab66921 1334
terencez 0:1fa43ab66921 1335 int
terencez 0:1fa43ab66921 1336 coap_set_header_size(void *packet, uint32_t size)
terencez 0:1fa43ab66921 1337 {
terencez 0:1fa43ab66921 1338 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1339
terencez 0:1fa43ab66921 1340 coap_pkt->size = size;
terencez 0:1fa43ab66921 1341 SET_OPTION(coap_pkt, COAP_OPTION_SIZE);
terencez 0:1fa43ab66921 1342 return 1;
terencez 0:1fa43ab66921 1343 }
terencez 0:1fa43ab66921 1344 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1345 /*- PAYLOAD -------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1346 /*-----------------------------------------------------------------------------------*/
terencez 0:1fa43ab66921 1347 int
terencez 0:1fa43ab66921 1348 coap_get_payload(void *packet, const uint8_t **payload)
terencez 0:1fa43ab66921 1349 {
terencez 0:1fa43ab66921 1350 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1351
terencez 0:1fa43ab66921 1352 if (coap_pkt->payload) {
terencez 0:1fa43ab66921 1353 *payload = coap_pkt->payload;
terencez 0:1fa43ab66921 1354 return coap_pkt->payload_len;
terencez 0:1fa43ab66921 1355 } else {
terencez 0:1fa43ab66921 1356 *payload = NULL;
terencez 0:1fa43ab66921 1357 return 0;
terencez 0:1fa43ab66921 1358 }
terencez 0:1fa43ab66921 1359 }
terencez 0:1fa43ab66921 1360
terencez 0:1fa43ab66921 1361 int
terencez 0:1fa43ab66921 1362 coap_set_payload(void *packet, const void *payload, size_t length)
terencez 0:1fa43ab66921 1363 {
terencez 0:1fa43ab66921 1364 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:1fa43ab66921 1365
terencez 0:1fa43ab66921 1366 coap_pkt->payload = (uint8_t *) payload;
terencez 0:1fa43ab66921 1367 coap_pkt->payload_len = (uint16_t)(length);
terencez 0:1fa43ab66921 1368
terencez 0:1fa43ab66921 1369 return coap_pkt->payload_len;
terencez 0:1fa43ab66921 1370 }
terencez 0:1fa43ab66921 1371 /*-----------------------------------------------------------------------------------*/