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

Dependencies:   C12832 LM75B

Committer:
terencez
Date:
Thu May 11 12:40:25 2017 +0000
Revision:
16:31c387e94b6d
Parent:
10:df97539c6ddd
Added a demo temperature object based on sensor LM75B.

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 16:31c387e94b6d 51 #define DEBUG 0
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 10:df97539c6ddd 697 PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, option_length);
terencez 0:f9d13e09cf11 698
terencez 0:f9d13e09cf11 699 SET_OPTION(coap_pkt, option_number);
terencez 0:f9d13e09cf11 700
terencez 0:f9d13e09cf11 701 switch (option_number)
terencez 0:f9d13e09cf11 702 {
terencez 0:f9d13e09cf11 703 case COAP_OPTION_CONTENT_TYPE:
terencez 0:f9d13e09cf11 704 coap_pkt->content_type = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 705 PRINTF("Content-Format [%u]\n", coap_pkt->content_type);
terencez 0:f9d13e09cf11 706 break;
terencez 0:f9d13e09cf11 707 case COAP_OPTION_MAX_AGE:
terencez 0:f9d13e09cf11 708 coap_pkt->max_age = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 709 PRINTF("Max-Age [%lu]\n", coap_pkt->max_age);
terencez 0:f9d13e09cf11 710 break;
terencez 0:f9d13e09cf11 711 case COAP_OPTION_ETAG:
terencez 2:5a8853c481ad 712 coap_pkt->etag_len = (uint8_t)(MIN(COAP_ETAG_LEN, option_length));
terencez 0:f9d13e09cf11 713 memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len);
terencez 0:f9d13e09cf11 714 PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len,
terencez 0:f9d13e09cf11 715 coap_pkt->etag[0],
terencez 0:f9d13e09cf11 716 coap_pkt->etag[1],
terencez 0:f9d13e09cf11 717 coap_pkt->etag[2],
terencez 0:f9d13e09cf11 718 coap_pkt->etag[3],
terencez 0:f9d13e09cf11 719 coap_pkt->etag[4],
terencez 0:f9d13e09cf11 720 coap_pkt->etag[5],
terencez 0:f9d13e09cf11 721 coap_pkt->etag[6],
terencez 0:f9d13e09cf11 722 coap_pkt->etag[7]
terencez 0:f9d13e09cf11 723 ); /*FIXME always prints 8 bytes */
terencez 0:f9d13e09cf11 724 break;
terencez 0:f9d13e09cf11 725 case COAP_OPTION_ACCEPT:
terencez 0:f9d13e09cf11 726 if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM)
terencez 0:f9d13e09cf11 727 {
terencez 0:f9d13e09cf11 728 coap_pkt->accept[coap_pkt->accept_num] = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 729 coap_pkt->accept_num += 1;
terencez 0:f9d13e09cf11 730 PRINTF("Accept [%u]\n", coap_pkt->content_type);
terencez 0:f9d13e09cf11 731 }
terencez 0:f9d13e09cf11 732 break;
terencez 0:f9d13e09cf11 733 case COAP_OPTION_IF_MATCH:
terencez 0:f9d13e09cf11 734 /*FIXME support multiple ETags */
terencez 2:5a8853c481ad 735 coap_pkt->if_match_len = (uint8_t)(MIN(COAP_ETAG_LEN, option_length));
terencez 0:f9d13e09cf11 736 memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len);
terencez 0:f9d13e09cf11 737 PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->if_match_len,
terencez 0:f9d13e09cf11 738 coap_pkt->if_match[0],
terencez 0:f9d13e09cf11 739 coap_pkt->if_match[1],
terencez 0:f9d13e09cf11 740 coap_pkt->if_match[2],
terencez 0:f9d13e09cf11 741 coap_pkt->if_match[3],
terencez 0:f9d13e09cf11 742 coap_pkt->if_match[4],
terencez 0:f9d13e09cf11 743 coap_pkt->if_match[5],
terencez 0:f9d13e09cf11 744 coap_pkt->if_match[6],
terencez 0:f9d13e09cf11 745 coap_pkt->if_match[7]
terencez 0:f9d13e09cf11 746 ); /*FIXME always prints 8 bytes */
terencez 0:f9d13e09cf11 747 break;
terencez 0:f9d13e09cf11 748 case COAP_OPTION_IF_NONE_MATCH:
terencez 0:f9d13e09cf11 749 coap_pkt->if_none_match = 1;
terencez 0:f9d13e09cf11 750 PRINTF("If-None-Match\n");
terencez 0:f9d13e09cf11 751 break;
terencez 0:f9d13e09cf11 752
terencez 0:f9d13e09cf11 753 case COAP_OPTION_URI_HOST:
terencez 2:5a8853c481ad 754 coap_pkt->uri_host = current_option;
terencez 0:f9d13e09cf11 755 coap_pkt->uri_host_len = option_length;
terencez 0:f9d13e09cf11 756 PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host);
terencez 0:f9d13e09cf11 757 break;
terencez 0:f9d13e09cf11 758 case COAP_OPTION_URI_PORT:
terencez 0:f9d13e09cf11 759 coap_pkt->uri_port = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 760 PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port);
terencez 0:f9d13e09cf11 761 break;
terencez 0:f9d13e09cf11 762 case COAP_OPTION_URI_PATH:
terencez 0:f9d13e09cf11 763 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:f9d13e09cf11 764 // coap_merge_multi_option( (char **) &(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_length, 0);
terencez 0:f9d13e09cf11 765 coap_add_multi_option( &(coap_pkt->uri_path), current_option, option_length, 1);
terencez 2:5a8853c481ad 766 PRINTF("Uri-Path [%.*s]\n", option_length, current_option);
terencez 0:f9d13e09cf11 767 break;
terencez 0:f9d13e09cf11 768 case COAP_OPTION_URI_QUERY:
terencez 0:f9d13e09cf11 769 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:f9d13e09cf11 770 // coap_merge_multi_option( (char **) &(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_length, '&');
terencez 0:f9d13e09cf11 771 coap_add_multi_option( &(coap_pkt->uri_query), current_option, option_length, 1);
terencez 2:5a8853c481ad 772 PRINTF("Uri-Query [%.*s]\n", option_length, current_option);
terencez 0:f9d13e09cf11 773 break;
terencez 0:f9d13e09cf11 774
terencez 0:f9d13e09cf11 775 case COAP_OPTION_LOCATION_PATH:
terencez 0:f9d13e09cf11 776 coap_add_multi_option( &(coap_pkt->location_path), current_option, option_length, 1);
terencez 0:f9d13e09cf11 777 break;
terencez 0:f9d13e09cf11 778 case COAP_OPTION_LOCATION_QUERY:
terencez 0:f9d13e09cf11 779 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 2:5a8853c481ad 780 coap_merge_multi_option( &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_length, '&');
terencez 2:5a8853c481ad 781 PRINTF("Location-Query [%.*s]\n", option_length, current_option);
terencez 0:f9d13e09cf11 782 break;
terencez 0:f9d13e09cf11 783
terencez 0:f9d13e09cf11 784 case COAP_OPTION_PROXY_URI:
terencez 0:f9d13e09cf11 785 /*FIXME check for own end-point */
terencez 2:5a8853c481ad 786 coap_pkt->proxy_uri = current_option;
terencez 0:f9d13e09cf11 787 coap_pkt->proxy_uri_len = option_length;
terencez 0:f9d13e09cf11 788 /*TODO length > 270 not implemented (actually not required) */
terencez 0:f9d13e09cf11 789 PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri);
terencez 0:f9d13e09cf11 790 coap_error_message = "This is a constrained server (Contiki)";
terencez 0:f9d13e09cf11 791 return PROXYING_NOT_SUPPORTED_5_05;
terencez 0:f9d13e09cf11 792 break;
terencez 0:f9d13e09cf11 793
terencez 0:f9d13e09cf11 794 case COAP_OPTION_OBSERVE:
terencez 0:f9d13e09cf11 795 coap_pkt->observe = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 796 PRINTF("Observe [%lu]\n", coap_pkt->observe);
terencez 0:f9d13e09cf11 797 break;
terencez 0:f9d13e09cf11 798 case COAP_OPTION_BLOCK2:
terencez 0:f9d13e09cf11 799 coap_pkt->block2_num = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 800 coap_pkt->block2_more = (coap_pkt->block2_num & 0x08)>>3;
terencez 0:f9d13e09cf11 801 coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
terencez 0:f9d13e09cf11 802 coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)<<(coap_pkt->block2_num & 0x07);
terencez 0:f9d13e09cf11 803 coap_pkt->block2_num >>= 4;
terencez 0:f9d13e09cf11 804 PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
terencez 0:f9d13e09cf11 805 break;
terencez 0:f9d13e09cf11 806 case COAP_OPTION_BLOCK1:
terencez 0:f9d13e09cf11 807 coap_pkt->block1_num = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 808 coap_pkt->block1_more = (coap_pkt->block1_num & 0x08)>>3;
terencez 0:f9d13e09cf11 809 coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
terencez 0:f9d13e09cf11 810 coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)<<(coap_pkt->block1_num & 0x07);
terencez 0:f9d13e09cf11 811 coap_pkt->block1_num >>= 4;
terencez 0:f9d13e09cf11 812 PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
terencez 0:f9d13e09cf11 813 break;
terencez 0:f9d13e09cf11 814 case COAP_OPTION_SIZE:
terencez 0:f9d13e09cf11 815 coap_pkt->size = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 816 PRINTF("Size [%lu]\n", coap_pkt->size);
terencez 0:f9d13e09cf11 817 break;
terencez 0:f9d13e09cf11 818 default:
terencez 0:f9d13e09cf11 819 PRINTF("unknown (%u)\n", option_number);
terencez 0:f9d13e09cf11 820 /* Check if critical (odd) */
terencez 0:f9d13e09cf11 821 if (option_number & 1)
terencez 0:f9d13e09cf11 822 {
terencez 0:f9d13e09cf11 823 coap_error_message = "Unsupported critical option";
terencez 0:f9d13e09cf11 824 return BAD_OPTION_4_02;
terencez 0:f9d13e09cf11 825 }
terencez 0:f9d13e09cf11 826 }
terencez 0:f9d13e09cf11 827
terencez 0:f9d13e09cf11 828 current_option += option_length;
terencez 0:f9d13e09cf11 829 } /* for */
terencez 0:f9d13e09cf11 830 PRINTF("-Done parsing-------\n");
terencez 0:f9d13e09cf11 831
terencez 0:f9d13e09cf11 832
terencez 0:f9d13e09cf11 833
terencez 0:f9d13e09cf11 834 return NO_ERROR;
terencez 0:f9d13e09cf11 835 }
terencez 0:f9d13e09cf11 836 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 837 /*- REST FRAMEWORK FUNCTIONS --------------------------------------------------------*/
terencez 0:f9d13e09cf11 838 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 839 int
terencez 0:f9d13e09cf11 840 coap_get_query_variable(void *packet, const char *name, const char **output)
terencez 0:f9d13e09cf11 841 {
terencez 0:f9d13e09cf11 842 /*
terencez 0:f9d13e09cf11 843 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 844
terencez 0:f9d13e09cf11 845 if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
terencez 0:f9d13e09cf11 846 return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, name, output);
terencez 0:f9d13e09cf11 847 }
terencez 0:f9d13e09cf11 848 */
terencez 0:f9d13e09cf11 849 return 0;
terencez 0:f9d13e09cf11 850 }
terencez 0:f9d13e09cf11 851
terencez 0:f9d13e09cf11 852 int
terencez 0:f9d13e09cf11 853 coap_get_post_variable(void *packet, const char *name, const char **output)
terencez 0:f9d13e09cf11 854 {
terencez 0:f9d13e09cf11 855 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 856
terencez 0:f9d13e09cf11 857 if (coap_pkt->payload_len) {
terencez 2:5a8853c481ad 858 return coap_get_variable(coap_pkt->payload, coap_pkt->payload_len, name, output);
terencez 0:f9d13e09cf11 859 }
terencez 0:f9d13e09cf11 860 return 0;
terencez 0:f9d13e09cf11 861 }
terencez 0:f9d13e09cf11 862 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 863 int
terencez 0:f9d13e09cf11 864 coap_set_status_code(void *packet, unsigned int code)
terencez 0:f9d13e09cf11 865 {
terencez 0:f9d13e09cf11 866 if (code <= 0xFF)
terencez 0:f9d13e09cf11 867 {
terencez 0:f9d13e09cf11 868 ((coap_packet_t *)packet)->code = (uint8_t) code;
terencez 0:f9d13e09cf11 869 return 1;
terencez 0:f9d13e09cf11 870 }
terencez 0:f9d13e09cf11 871 else
terencez 0:f9d13e09cf11 872 {
terencez 0:f9d13e09cf11 873 return 0;
terencez 0:f9d13e09cf11 874 }
terencez 0:f9d13e09cf11 875 }
terencez 0:f9d13e09cf11 876 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 877 /*- HEADER OPTION GETTERS AND SETTERS -----------------------------------------------*/
terencez 0:f9d13e09cf11 878 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 879 unsigned int
terencez 0:f9d13e09cf11 880 coap_get_header_content_type(void *packet)
terencez 0:f9d13e09cf11 881 {
terencez 0:f9d13e09cf11 882 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 883
terencez 0:f9d13e09cf11 884 if (!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) return -1;
terencez 0:f9d13e09cf11 885
terencez 0:f9d13e09cf11 886 return coap_pkt->content_type;
terencez 0:f9d13e09cf11 887 }
terencez 0:f9d13e09cf11 888
terencez 0:f9d13e09cf11 889 int
terencez 0:f9d13e09cf11 890 coap_set_header_content_type(void *packet, unsigned int content_type)
terencez 0:f9d13e09cf11 891 {
terencez 0:f9d13e09cf11 892 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 893
terencez 0:f9d13e09cf11 894 coap_pkt->content_type = (coap_content_type_t) content_type;
terencez 0:f9d13e09cf11 895 SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE);
terencez 0:f9d13e09cf11 896 return 1;
terencez 0:f9d13e09cf11 897 }
terencez 0:f9d13e09cf11 898 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 899 int
terencez 0:f9d13e09cf11 900 coap_get_header_accept(void *packet, const uint16_t **accept)
terencez 0:f9d13e09cf11 901 {
terencez 0:f9d13e09cf11 902 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 903
terencez 0:f9d13e09cf11 904 if (!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) return 0;
terencez 0:f9d13e09cf11 905
terencez 0:f9d13e09cf11 906 *accept = coap_pkt->accept;
terencez 0:f9d13e09cf11 907 return coap_pkt->accept_num;
terencez 0:f9d13e09cf11 908 }
terencez 0:f9d13e09cf11 909
terencez 0:f9d13e09cf11 910 int
terencez 0:f9d13e09cf11 911 coap_set_header_accept(void *packet, uint16_t accept)
terencez 0:f9d13e09cf11 912 {
terencez 0:f9d13e09cf11 913 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 914
terencez 0:f9d13e09cf11 915 if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM)
terencez 0:f9d13e09cf11 916 {
terencez 0:f9d13e09cf11 917 coap_pkt->accept[coap_pkt->accept_num] = accept;
terencez 0:f9d13e09cf11 918 coap_pkt->accept_num += 1;
terencez 0:f9d13e09cf11 919
terencez 0:f9d13e09cf11 920 SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
terencez 0:f9d13e09cf11 921 }
terencez 0:f9d13e09cf11 922 return coap_pkt->accept_num;
terencez 0:f9d13e09cf11 923 }
terencez 0:f9d13e09cf11 924 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 925 int
terencez 0:f9d13e09cf11 926 coap_get_header_max_age(void *packet, uint32_t *age)
terencez 0:f9d13e09cf11 927 {
terencez 0:f9d13e09cf11 928 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 929
terencez 0:f9d13e09cf11 930 if (!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) {
terencez 0:f9d13e09cf11 931 *age = COAP_DEFAULT_MAX_AGE;
terencez 0:f9d13e09cf11 932 } else {
terencez 0:f9d13e09cf11 933 *age = coap_pkt->max_age;
terencez 0:f9d13e09cf11 934 }
terencez 0:f9d13e09cf11 935 return 1;
terencez 0:f9d13e09cf11 936 }
terencez 0:f9d13e09cf11 937
terencez 0:f9d13e09cf11 938 int
terencez 0:f9d13e09cf11 939 coap_set_header_max_age(void *packet, uint32_t age)
terencez 0:f9d13e09cf11 940 {
terencez 0:f9d13e09cf11 941 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 942
terencez 0:f9d13e09cf11 943 coap_pkt->max_age = age;
terencez 0:f9d13e09cf11 944 SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE);
terencez 0:f9d13e09cf11 945 return 1;
terencez 0:f9d13e09cf11 946 }
terencez 0:f9d13e09cf11 947 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 948 int
terencez 0:f9d13e09cf11 949 coap_get_header_etag(void *packet, const uint8_t **etag)
terencez 0:f9d13e09cf11 950 {
terencez 0:f9d13e09cf11 951 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 952
terencez 0:f9d13e09cf11 953 if (!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) return 0;
terencez 0:f9d13e09cf11 954
terencez 0:f9d13e09cf11 955 *etag = coap_pkt->etag;
terencez 0:f9d13e09cf11 956 return coap_pkt->etag_len;
terencez 0:f9d13e09cf11 957 }
terencez 0:f9d13e09cf11 958
terencez 0:f9d13e09cf11 959 int
terencez 0:f9d13e09cf11 960 coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len)
terencez 0:f9d13e09cf11 961 {
terencez 0:f9d13e09cf11 962 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 963
terencez 2:5a8853c481ad 964 coap_pkt->etag_len = (uint8_t)(MIN(COAP_ETAG_LEN, etag_len));
terencez 0:f9d13e09cf11 965 memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
terencez 0:f9d13e09cf11 966
terencez 0:f9d13e09cf11 967 SET_OPTION(coap_pkt, COAP_OPTION_ETAG);
terencez 0:f9d13e09cf11 968 return coap_pkt->etag_len;
terencez 0:f9d13e09cf11 969 }
terencez 0:f9d13e09cf11 970 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 971 /*FIXME support multiple ETags */
terencez 0:f9d13e09cf11 972 int
terencez 0:f9d13e09cf11 973 coap_get_header_if_match(void *packet, const uint8_t **etag)
terencez 0:f9d13e09cf11 974 {
terencez 0:f9d13e09cf11 975 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 976
terencez 0:f9d13e09cf11 977 if (!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) return 0;
terencez 0:f9d13e09cf11 978
terencez 0:f9d13e09cf11 979 *etag = coap_pkt->if_match;
terencez 0:f9d13e09cf11 980 return coap_pkt->if_match_len;
terencez 0:f9d13e09cf11 981 }
terencez 0:f9d13e09cf11 982
terencez 0:f9d13e09cf11 983 int
terencez 0:f9d13e09cf11 984 coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len)
terencez 0:f9d13e09cf11 985 {
terencez 0:f9d13e09cf11 986 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 987
terencez 2:5a8853c481ad 988 coap_pkt->if_match_len = (uint8_t)(MIN(COAP_ETAG_LEN, etag_len));
terencez 0:f9d13e09cf11 989 memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
terencez 0:f9d13e09cf11 990
terencez 0:f9d13e09cf11 991 SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH);
terencez 0:f9d13e09cf11 992 return coap_pkt->if_match_len;
terencez 0:f9d13e09cf11 993 }
terencez 0:f9d13e09cf11 994 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 995 int
terencez 0:f9d13e09cf11 996 coap_get_header_if_none_match(void *packet)
terencez 0:f9d13e09cf11 997 {
terencez 0:f9d13e09cf11 998 return IS_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
terencez 0:f9d13e09cf11 999 }
terencez 0:f9d13e09cf11 1000
terencez 0:f9d13e09cf11 1001 int
terencez 0:f9d13e09cf11 1002 coap_set_header_if_none_match(void *packet)
terencez 0:f9d13e09cf11 1003 {
terencez 0:f9d13e09cf11 1004 SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH);
terencez 0:f9d13e09cf11 1005 return 1;
terencez 0:f9d13e09cf11 1006 }
terencez 0:f9d13e09cf11 1007 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1008 int
terencez 0:f9d13e09cf11 1009 coap_get_header_token(void *packet, const uint8_t **token)
terencez 0:f9d13e09cf11 1010 {
terencez 0:f9d13e09cf11 1011 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1012
terencez 0:f9d13e09cf11 1013 if (!IS_OPTION(coap_pkt, COAP_OPTION_TOKEN)) return 0;
terencez 0:f9d13e09cf11 1014
terencez 0:f9d13e09cf11 1015 *token = coap_pkt->token;
terencez 0:f9d13e09cf11 1016 return coap_pkt->token_len;
terencez 0:f9d13e09cf11 1017 }
terencez 0:f9d13e09cf11 1018
terencez 0:f9d13e09cf11 1019 int
terencez 0:f9d13e09cf11 1020 coap_set_header_token(void *packet, const uint8_t *token, size_t token_len)
terencez 0:f9d13e09cf11 1021 {
terencez 0:f9d13e09cf11 1022 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1023
terencez 2:5a8853c481ad 1024 coap_pkt->token_len = (uint8_t)(MIN(COAP_TOKEN_LEN, token_len));
terencez 0:f9d13e09cf11 1025 memcpy(coap_pkt->token, token, coap_pkt->token_len);
terencez 0:f9d13e09cf11 1026
terencez 0:f9d13e09cf11 1027 SET_OPTION(coap_pkt, COAP_OPTION_TOKEN);
terencez 0:f9d13e09cf11 1028 return coap_pkt->token_len;
terencez 0:f9d13e09cf11 1029 }
terencez 0:f9d13e09cf11 1030 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1031 int
terencez 0:f9d13e09cf11 1032 coap_get_header_proxy_uri(void *packet, const char **uri)
terencez 0:f9d13e09cf11 1033 {
terencez 0:f9d13e09cf11 1034 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1035
terencez 0:f9d13e09cf11 1036 if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0;
terencez 0:f9d13e09cf11 1037
terencez 2:5a8853c481ad 1038 *uri = (const char *)coap_pkt->proxy_uri;
terencez 0:f9d13e09cf11 1039 return coap_pkt->proxy_uri_len;
terencez 0:f9d13e09cf11 1040 }
terencez 0:f9d13e09cf11 1041
terencez 0:f9d13e09cf11 1042 int
terencez 0:f9d13e09cf11 1043 coap_set_header_proxy_uri(void *packet, const char *uri)
terencez 0:f9d13e09cf11 1044 {
terencez 0:f9d13e09cf11 1045 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1046
terencez 2:5a8853c481ad 1047 coap_pkt->proxy_uri = (uint8_t *)uri;
terencez 0:f9d13e09cf11 1048 coap_pkt->proxy_uri_len = strlen(uri);
terencez 0:f9d13e09cf11 1049
terencez 0:f9d13e09cf11 1050 SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI);
terencez 0:f9d13e09cf11 1051 return coap_pkt->proxy_uri_len;
terencez 0:f9d13e09cf11 1052 }
terencez 0:f9d13e09cf11 1053 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1054 int
terencez 0:f9d13e09cf11 1055 coap_get_header_uri_host(void *packet, const char **host)
terencez 0:f9d13e09cf11 1056 {
terencez 0:f9d13e09cf11 1057 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1058
terencez 0:f9d13e09cf11 1059 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) return 0;
terencez 0:f9d13e09cf11 1060
terencez 2:5a8853c481ad 1061 *host = (char *)coap_pkt->uri_host;
terencez 0:f9d13e09cf11 1062 return coap_pkt->uri_host_len;
terencez 0:f9d13e09cf11 1063 }
terencez 0:f9d13e09cf11 1064
terencez 0:f9d13e09cf11 1065 int
terencez 0:f9d13e09cf11 1066 coap_set_header_uri_host(void *packet, const char *host)
terencez 0:f9d13e09cf11 1067 {
terencez 0:f9d13e09cf11 1068 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1069
terencez 2:5a8853c481ad 1070 coap_pkt->uri_host = (uint8_t *)host;
terencez 0:f9d13e09cf11 1071 coap_pkt->uri_host_len = strlen(host);
terencez 0:f9d13e09cf11 1072
terencez 0:f9d13e09cf11 1073 SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST);
terencez 0:f9d13e09cf11 1074 return coap_pkt->uri_host_len;
terencez 0:f9d13e09cf11 1075 }
terencez 0:f9d13e09cf11 1076 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1077 int
terencez 0:f9d13e09cf11 1078 coap_get_header_uri_path(void *packet, const char **path)
terencez 0:f9d13e09cf11 1079 {
terencez 0:f9d13e09cf11 1080 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1081
terencez 0:f9d13e09cf11 1082 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) return 0;
terencez 0:f9d13e09cf11 1083
terencez 0:f9d13e09cf11 1084 *path = NULL; //coap_pkt->uri_path;
terencez 0:f9d13e09cf11 1085 return 0; //coap_pkt->uri_path_len;
terencez 0:f9d13e09cf11 1086 }
terencez 0:f9d13e09cf11 1087
terencez 0:f9d13e09cf11 1088 int
terencez 0:f9d13e09cf11 1089 coap_set_header_uri_path(void *packet, const char *path)
terencez 0:f9d13e09cf11 1090 {
terencez 0:f9d13e09cf11 1091 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1092 int length = 0;
terencez 0:f9d13e09cf11 1093
terencez 0:f9d13e09cf11 1094 free_multi_option(coap_pkt->uri_path);
terencez 0:f9d13e09cf11 1095 coap_pkt->uri_path = NULL;
terencez 0:f9d13e09cf11 1096
terencez 0:f9d13e09cf11 1097 if (path[0]=='/') ++path;
terencez 0:f9d13e09cf11 1098
terencez 0:f9d13e09cf11 1099 do
terencez 0:f9d13e09cf11 1100 {
terencez 0:f9d13e09cf11 1101 int i = 0;
terencez 0:f9d13e09cf11 1102
terencez 0:f9d13e09cf11 1103 while (path[i] != 0 && path[i] != '/') i++;
terencez 0:f9d13e09cf11 1104 coap_add_multi_option(&(coap_pkt->uri_path), (uint8_t *)path, i, 0);
terencez 0:f9d13e09cf11 1105
terencez 0:f9d13e09cf11 1106 if (path[i] == '/') i++;
terencez 0:f9d13e09cf11 1107 path += i;
terencez 0:f9d13e09cf11 1108 length += i;
terencez 0:f9d13e09cf11 1109 } while (path[0] != 0);
terencez 0:f9d13e09cf11 1110
terencez 0:f9d13e09cf11 1111 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
terencez 0:f9d13e09cf11 1112 return length;
terencez 0:f9d13e09cf11 1113 }
terencez 0:f9d13e09cf11 1114
terencez 0:f9d13e09cf11 1115 int
terencez 0:f9d13e09cf11 1116 coap_set_header_uri_path_segment(void *packet, const char *segment)
terencez 0:f9d13e09cf11 1117 {
terencez 0:f9d13e09cf11 1118 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1119 int length;
terencez 0:f9d13e09cf11 1120
terencez 0:f9d13e09cf11 1121 if (segment == NULL || segment[0] == 0)
terencez 0:f9d13e09cf11 1122 {
terencez 0:f9d13e09cf11 1123 coap_add_multi_option(&(coap_pkt->uri_path), NULL, 0, 1);
terencez 0:f9d13e09cf11 1124 length = 0;
terencez 0:f9d13e09cf11 1125 }
terencez 0:f9d13e09cf11 1126 else
terencez 0:f9d13e09cf11 1127 {
terencez 0:f9d13e09cf11 1128 length = strlen(segment);
terencez 0:f9d13e09cf11 1129 coap_add_multi_option(&(coap_pkt->uri_path), (uint8_t *)segment, length, 0);
terencez 0:f9d13e09cf11 1130 }
terencez 0:f9d13e09cf11 1131
terencez 0:f9d13e09cf11 1132 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
terencez 0:f9d13e09cf11 1133 return length;
terencez 0:f9d13e09cf11 1134 }
terencez 0:f9d13e09cf11 1135 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1136 int
terencez 0:f9d13e09cf11 1137 coap_get_header_uri_query(void *packet, const char **query)
terencez 0:f9d13e09cf11 1138 {
terencez 0:f9d13e09cf11 1139 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1140
terencez 0:f9d13e09cf11 1141 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) return 0;
terencez 0:f9d13e09cf11 1142
terencez 0:f9d13e09cf11 1143 *query = NULL; //coap_pkt->uri_query;
terencez 0:f9d13e09cf11 1144 return 0; //coap_pkt->uri_query_len;
terencez 0:f9d13e09cf11 1145 }
terencez 0:f9d13e09cf11 1146
terencez 0:f9d13e09cf11 1147 int
terencez 0:f9d13e09cf11 1148 coap_set_header_uri_query(void *packet, const char *query)
terencez 0:f9d13e09cf11 1149 {
terencez 0:f9d13e09cf11 1150 int length = 0;
terencez 0:f9d13e09cf11 1151 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1152
terencez 0:f9d13e09cf11 1153 free_multi_option(coap_pkt->uri_query);
terencez 0:f9d13e09cf11 1154 coap_pkt->uri_query = NULL;
terencez 0:f9d13e09cf11 1155
terencez 0:f9d13e09cf11 1156 if (query[0]=='?') ++query;
terencez 0:f9d13e09cf11 1157
terencez 0:f9d13e09cf11 1158 do
terencez 0:f9d13e09cf11 1159 {
terencez 0:f9d13e09cf11 1160 int i = 0;
terencez 0:f9d13e09cf11 1161
terencez 0:f9d13e09cf11 1162 while (query[i] != 0 && query[i] != '&') i++;
terencez 0:f9d13e09cf11 1163 coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t *)query, i, 0);
terencez 0:f9d13e09cf11 1164
terencez 0:f9d13e09cf11 1165 if (query[i] == '&') i++;
terencez 0:f9d13e09cf11 1166 query += i;
terencez 0:f9d13e09cf11 1167 length += i;
terencez 0:f9d13e09cf11 1168 } while (query[0] != 0);
terencez 0:f9d13e09cf11 1169
terencez 0:f9d13e09cf11 1170 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
terencez 0:f9d13e09cf11 1171 return length;
terencez 0:f9d13e09cf11 1172 }
terencez 0:f9d13e09cf11 1173 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1174 int
terencez 0:f9d13e09cf11 1175 coap_get_header_location_path(void *packet, const char **path)
terencez 0:f9d13e09cf11 1176 {
terencez 0:f9d13e09cf11 1177 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1178
terencez 0:f9d13e09cf11 1179 if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) return 0;
terencez 0:f9d13e09cf11 1180
terencez 0:f9d13e09cf11 1181 *path = NULL; //coap_pkt->location_path;
terencez 0:f9d13e09cf11 1182 return 0; //coap_pkt->location_path_len;
terencez 0:f9d13e09cf11 1183 }
terencez 0:f9d13e09cf11 1184
terencez 0:f9d13e09cf11 1185 int
terencez 0:f9d13e09cf11 1186 coap_set_header_location_path(void *packet, const char *path)
terencez 0:f9d13e09cf11 1187 {
terencez 0:f9d13e09cf11 1188 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1189 int length = 0;
terencez 0:f9d13e09cf11 1190
terencez 0:f9d13e09cf11 1191 free_multi_option(coap_pkt->location_path);
terencez 0:f9d13e09cf11 1192 coap_pkt->location_path = NULL;
terencez 0:f9d13e09cf11 1193
terencez 0:f9d13e09cf11 1194 if (path[0]=='/') ++path;
terencez 0:f9d13e09cf11 1195
terencez 0:f9d13e09cf11 1196 do
terencez 0:f9d13e09cf11 1197 {
terencez 0:f9d13e09cf11 1198 int i = 0;
terencez 0:f9d13e09cf11 1199
terencez 0:f9d13e09cf11 1200 while (path[i] != 0 && path[i] != '/') i++;
terencez 0:f9d13e09cf11 1201 coap_add_multi_option(&(coap_pkt->location_path), (uint8_t *)path, i, 0);
terencez 0:f9d13e09cf11 1202
terencez 0:f9d13e09cf11 1203 if (path[i] == '/') i++;
terencez 0:f9d13e09cf11 1204 path += i;
terencez 0:f9d13e09cf11 1205 length += i;
terencez 0:f9d13e09cf11 1206 } while (path[0] != 0);
terencez 0:f9d13e09cf11 1207
terencez 0:f9d13e09cf11 1208 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH);
terencez 0:f9d13e09cf11 1209 return length;
terencez 0:f9d13e09cf11 1210 }
terencez 0:f9d13e09cf11 1211 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1212 int
terencez 0:f9d13e09cf11 1213 coap_get_header_location_query(void *packet, const char **query)
terencez 0:f9d13e09cf11 1214 {
terencez 0:f9d13e09cf11 1215 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1216
terencez 0:f9d13e09cf11 1217 if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0;
terencez 0:f9d13e09cf11 1218
terencez 2:5a8853c481ad 1219 *query = (const char*)coap_pkt->location_query;
terencez 0:f9d13e09cf11 1220 return coap_pkt->location_query_len;
terencez 0:f9d13e09cf11 1221 }
terencez 0:f9d13e09cf11 1222
terencez 0:f9d13e09cf11 1223 int
terencez 2:5a8853c481ad 1224 coap_set_header_location_query(void *packet, char *query)
terencez 0:f9d13e09cf11 1225 {
terencez 0:f9d13e09cf11 1226 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1227
terencez 0:f9d13e09cf11 1228 while (query[0]=='?') ++query;
terencez 0:f9d13e09cf11 1229
terencez 2:5a8853c481ad 1230 coap_pkt->location_query = (uint8_t *)query;
terencez 0:f9d13e09cf11 1231 coap_pkt->location_query_len = strlen(query);
terencez 0:f9d13e09cf11 1232
terencez 0:f9d13e09cf11 1233 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY);
terencez 0:f9d13e09cf11 1234 return coap_pkt->location_query_len;
terencez 0:f9d13e09cf11 1235 }
terencez 0:f9d13e09cf11 1236 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1237 int
terencez 0:f9d13e09cf11 1238 coap_get_header_observe(void *packet, uint32_t *observe)
terencez 0:f9d13e09cf11 1239 {
terencez 0:f9d13e09cf11 1240 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1241
terencez 0:f9d13e09cf11 1242 if (!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) return 0;
terencez 0:f9d13e09cf11 1243
terencez 0:f9d13e09cf11 1244 *observe = coap_pkt->observe;
terencez 0:f9d13e09cf11 1245 return 1;
terencez 0:f9d13e09cf11 1246 }
terencez 0:f9d13e09cf11 1247
terencez 0:f9d13e09cf11 1248 int
terencez 0:f9d13e09cf11 1249 coap_set_header_observe(void *packet, uint32_t observe)
terencez 0:f9d13e09cf11 1250 {
terencez 0:f9d13e09cf11 1251 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1252
terencez 0:f9d13e09cf11 1253 coap_pkt->observe = 0x00FFFFFF & observe;
terencez 0:f9d13e09cf11 1254 SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE);
terencez 0:f9d13e09cf11 1255 return 1;
terencez 0:f9d13e09cf11 1256 }
terencez 0:f9d13e09cf11 1257 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1258 int
terencez 0:f9d13e09cf11 1259 coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset)
terencez 0:f9d13e09cf11 1260 {
terencez 0:f9d13e09cf11 1261 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1262
terencez 0:f9d13e09cf11 1263 if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) return 0;
terencez 0:f9d13e09cf11 1264
terencez 0:f9d13e09cf11 1265 /* pointers may be NULL to get only specific block parameters */
terencez 0:f9d13e09cf11 1266 if (num!=NULL) *num = coap_pkt->block2_num;
terencez 0:f9d13e09cf11 1267 if (more!=NULL) *more = coap_pkt->block2_more;
terencez 0:f9d13e09cf11 1268 if (size!=NULL) *size = coap_pkt->block2_size;
terencez 0:f9d13e09cf11 1269 if (offset!=NULL) *offset = coap_pkt->block2_offset;
terencez 0:f9d13e09cf11 1270
terencez 0:f9d13e09cf11 1271 return 1;
terencez 0:f9d13e09cf11 1272 }
terencez 0:f9d13e09cf11 1273
terencez 0:f9d13e09cf11 1274 int
terencez 0:f9d13e09cf11 1275 coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size)
terencez 0:f9d13e09cf11 1276 {
terencez 0:f9d13e09cf11 1277 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1278
terencez 0:f9d13e09cf11 1279 if (size<16) return 0;
terencez 0:f9d13e09cf11 1280 if (size>2048) return 0;
terencez 0:f9d13e09cf11 1281 if (num>0x0FFFFF) return 0;
terencez 0:f9d13e09cf11 1282
terencez 0:f9d13e09cf11 1283 coap_pkt->block2_num = num;
terencez 0:f9d13e09cf11 1284 coap_pkt->block2_more = more ? 1 : 0;
terencez 0:f9d13e09cf11 1285 coap_pkt->block2_size = size;
terencez 0:f9d13e09cf11 1286
terencez 0:f9d13e09cf11 1287 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2);
terencez 0:f9d13e09cf11 1288 return 1;
terencez 0:f9d13e09cf11 1289 }
terencez 0:f9d13e09cf11 1290 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1291 int
terencez 0:f9d13e09cf11 1292 coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset)
terencez 0:f9d13e09cf11 1293 {
terencez 0:f9d13e09cf11 1294 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1295
terencez 0:f9d13e09cf11 1296 if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) return 0;
terencez 0:f9d13e09cf11 1297
terencez 0:f9d13e09cf11 1298 /* pointers may be NULL to get only specific block parameters */
terencez 0:f9d13e09cf11 1299 if (num!=NULL) *num = coap_pkt->block1_num;
terencez 0:f9d13e09cf11 1300 if (more!=NULL) *more = coap_pkt->block1_more;
terencez 0:f9d13e09cf11 1301 if (size!=NULL) *size = coap_pkt->block1_size;
terencez 0:f9d13e09cf11 1302 if (offset!=NULL) *offset = coap_pkt->block1_offset;
terencez 0:f9d13e09cf11 1303
terencez 0:f9d13e09cf11 1304 return 1;
terencez 0:f9d13e09cf11 1305 }
terencez 0:f9d13e09cf11 1306
terencez 0:f9d13e09cf11 1307 int
terencez 0:f9d13e09cf11 1308 coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size)
terencez 0:f9d13e09cf11 1309 {
terencez 0:f9d13e09cf11 1310 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1311
terencez 0:f9d13e09cf11 1312 if (size<16) return 0;
terencez 0:f9d13e09cf11 1313 if (size>2048) return 0;
terencez 0:f9d13e09cf11 1314 if (num>0x0FFFFF) return 0;
terencez 0:f9d13e09cf11 1315
terencez 0:f9d13e09cf11 1316 coap_pkt->block1_num = num;
terencez 0:f9d13e09cf11 1317 coap_pkt->block1_more = more;
terencez 0:f9d13e09cf11 1318 coap_pkt->block1_size = size;
terencez 0:f9d13e09cf11 1319
terencez 0:f9d13e09cf11 1320 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1);
terencez 0:f9d13e09cf11 1321 return 1;
terencez 0:f9d13e09cf11 1322 }
terencez 0:f9d13e09cf11 1323 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1324 int
terencez 0:f9d13e09cf11 1325 coap_get_header_size(void *packet, uint32_t *size)
terencez 0:f9d13e09cf11 1326 {
terencez 0:f9d13e09cf11 1327 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1328
terencez 0:f9d13e09cf11 1329 if (!IS_OPTION(coap_pkt, COAP_OPTION_SIZE)) return 0;
terencez 0:f9d13e09cf11 1330
terencez 0:f9d13e09cf11 1331 *size = coap_pkt->size;
terencez 0:f9d13e09cf11 1332 return 1;
terencez 0:f9d13e09cf11 1333 }
terencez 0:f9d13e09cf11 1334
terencez 0:f9d13e09cf11 1335 int
terencez 0:f9d13e09cf11 1336 coap_set_header_size(void *packet, uint32_t size)
terencez 0:f9d13e09cf11 1337 {
terencez 0:f9d13e09cf11 1338 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1339
terencez 0:f9d13e09cf11 1340 coap_pkt->size = size;
terencez 0:f9d13e09cf11 1341 SET_OPTION(coap_pkt, COAP_OPTION_SIZE);
terencez 0:f9d13e09cf11 1342 return 1;
terencez 0:f9d13e09cf11 1343 }
terencez 0:f9d13e09cf11 1344 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1345 /*- PAYLOAD -------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1346 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1347 int
terencez 0:f9d13e09cf11 1348 coap_get_payload(void *packet, const uint8_t **payload)
terencez 0:f9d13e09cf11 1349 {
terencez 0:f9d13e09cf11 1350 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1351
terencez 0:f9d13e09cf11 1352 if (coap_pkt->payload) {
terencez 0:f9d13e09cf11 1353 *payload = coap_pkt->payload;
terencez 0:f9d13e09cf11 1354 return coap_pkt->payload_len;
terencez 0:f9d13e09cf11 1355 } else {
terencez 0:f9d13e09cf11 1356 *payload = NULL;
terencez 0:f9d13e09cf11 1357 return 0;
terencez 0:f9d13e09cf11 1358 }
terencez 0:f9d13e09cf11 1359 }
terencez 0:f9d13e09cf11 1360
terencez 0:f9d13e09cf11 1361 int
terencez 0:f9d13e09cf11 1362 coap_set_payload(void *packet, const void *payload, size_t length)
terencez 0:f9d13e09cf11 1363 {
terencez 0:f9d13e09cf11 1364 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1365
terencez 0:f9d13e09cf11 1366 coap_pkt->payload = (uint8_t *) payload;
terencez 2:5a8853c481ad 1367 coap_pkt->payload_len = (uint16_t)(length);
terencez 0:f9d13e09cf11 1368
terencez 0:f9d13e09cf11 1369 return coap_pkt->payload_len;
terencez 0:f9d13e09cf11 1370 }
terencez 0:f9d13e09cf11 1371 /*-----------------------------------------------------------------------------------*/