terence zhang / Mbed OS mbed-os-example-wakaama

Dependencies:   C12832 LM75B

Committer:
terencez
Date:
Fri Apr 28 09:53:26 2017 +0000
Revision:
2:5a8853c481ad
Parent:
0:f9d13e09cf11
Child:
10:df97539c6ddd
Update the coap to the latest version.

Who changed what in which revision?

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