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

Dependencies:   C12832 LM75B

Committer:
terencez
Date:
Mon Apr 24 23:03:31 2017 +0000
Revision:
0:f9d13e09cf11
Child:
2:5a8853c481ad
Child:
8:e290882bfd4f
The first compiled submit.

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 0:f9d13e09cf11 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 0:f9d13e09cf11 69 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 0:f9d13e09cf11 91 int 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 0:f9d13e09cf11 123
terencez 0:f9d13e09cf11 124 buffer[0] = coap_option_nibble(delta)<<4 | coap_option_nibble(length);
terencez 0:f9d13e09cf11 125
terencez 0:f9d13e09cf11 126 /* avoids code duplication without function overhead */
terencez 0:f9d13e09cf11 127 unsigned int *x = &delta;
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 0:f9d13e09cf11 178 int 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 0:f9d13e09cf11 234 coap_merge_multi_option(char **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 0:f9d13e09cf11 251 *dst = (char *) 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 static
terencez 0:f9d13e09cf11 257 void
terencez 0:f9d13e09cf11 258 coap_add_multi_option(multi_option_t **dst, uint8_t *option, size_t option_len, uint8_t is_static)
terencez 0:f9d13e09cf11 259 {
terencez 0:f9d13e09cf11 260 multi_option_t *opt = (multi_option_t *)lwm2m_malloc(sizeof(multi_option_t));
terencez 0:f9d13e09cf11 261
terencez 0:f9d13e09cf11 262 if (opt)
terencez 0:f9d13e09cf11 263 {
terencez 0:f9d13e09cf11 264 opt->next = NULL;
terencez 0:f9d13e09cf11 265 opt->len = option_len;
terencez 0:f9d13e09cf11 266 if (is_static)
terencez 0:f9d13e09cf11 267 {
terencez 0:f9d13e09cf11 268 opt->data = option;
terencez 0:f9d13e09cf11 269 opt->is_static = 1;
terencez 0:f9d13e09cf11 270 }
terencez 0:f9d13e09cf11 271 else
terencez 0:f9d13e09cf11 272 {
terencez 0:f9d13e09cf11 273 opt->is_static = 0;
terencez 0:f9d13e09cf11 274 opt->data = (char *)lwm2m_malloc(option_len);
terencez 0:f9d13e09cf11 275 if (opt->data == NULL)
terencez 0:f9d13e09cf11 276 {
terencez 0:f9d13e09cf11 277 lwm2m_free(opt);
terencez 0:f9d13e09cf11 278 return;
terencez 0:f9d13e09cf11 279 }
terencez 0:f9d13e09cf11 280 memcpy(opt->data, option, option_len);
terencez 0:f9d13e09cf11 281 }
terencez 0:f9d13e09cf11 282
terencez 0:f9d13e09cf11 283 if (*dst)
terencez 0:f9d13e09cf11 284 {
terencez 0:f9d13e09cf11 285 multi_option_t * i = *dst;
terencez 0:f9d13e09cf11 286 while (i->next)
terencez 0:f9d13e09cf11 287 {
terencez 0:f9d13e09cf11 288 i = i->next;
terencez 0:f9d13e09cf11 289 }
terencez 0:f9d13e09cf11 290 i->next = opt;
terencez 0:f9d13e09cf11 291 }
terencez 0:f9d13e09cf11 292 else
terencez 0:f9d13e09cf11 293 {
terencez 0:f9d13e09cf11 294 *dst = opt;
terencez 0:f9d13e09cf11 295 }
terencez 0:f9d13e09cf11 296 }
terencez 0:f9d13e09cf11 297 }
terencez 0:f9d13e09cf11 298
terencez 0:f9d13e09cf11 299 static
terencez 0:f9d13e09cf11 300 void
terencez 0:f9d13e09cf11 301 free_multi_option(multi_option_t *dst)
terencez 0:f9d13e09cf11 302 {
terencez 0:f9d13e09cf11 303 if (dst)
terencez 0:f9d13e09cf11 304 {
terencez 0:f9d13e09cf11 305 multi_option_t *n = dst->next;
terencez 0:f9d13e09cf11 306 if (dst->is_static == 0)
terencez 0:f9d13e09cf11 307 {
terencez 0:f9d13e09cf11 308 lwm2m_free(dst->data);
terencez 0:f9d13e09cf11 309 }
terencez 0:f9d13e09cf11 310 lwm2m_free(dst);
terencez 0:f9d13e09cf11 311 free_multi_option(n);
terencez 0:f9d13e09cf11 312 }
terencez 0:f9d13e09cf11 313 }
terencez 0:f9d13e09cf11 314
terencez 0:f9d13e09cf11 315 char * coap_get_multi_option_as_string(multi_option_t * option)
terencez 0:f9d13e09cf11 316 {
terencez 0:f9d13e09cf11 317 size_t len = 0;
terencez 0:f9d13e09cf11 318 multi_option_t * opt;
terencez 0:f9d13e09cf11 319 char * output;
terencez 0:f9d13e09cf11 320
terencez 0:f9d13e09cf11 321 for (opt = option; opt != NULL; opt = opt->next)
terencez 0:f9d13e09cf11 322 {
terencez 0:f9d13e09cf11 323 len += opt->len + 1; // for separator
terencez 0:f9d13e09cf11 324 }
terencez 0:f9d13e09cf11 325
terencez 0:f9d13e09cf11 326 output = lwm2m_malloc(len + 1); // for String terminator
terencez 0:f9d13e09cf11 327 if (output != NULL)
terencez 0:f9d13e09cf11 328 {
terencez 0:f9d13e09cf11 329 size_t i = 0;
terencez 0:f9d13e09cf11 330
terencez 0:f9d13e09cf11 331 for (opt = option; opt != NULL; opt = opt->next)
terencez 0:f9d13e09cf11 332 {
terencez 0:f9d13e09cf11 333 output[i] = '/';
terencez 0:f9d13e09cf11 334 i += 1;
terencez 0:f9d13e09cf11 335
terencez 0:f9d13e09cf11 336 memmove(output + i, opt->data, opt->len);
terencez 0:f9d13e09cf11 337 i += opt->len;
terencez 0:f9d13e09cf11 338 }
terencez 0:f9d13e09cf11 339 output[i] = 0;
terencez 0:f9d13e09cf11 340 }
terencez 0:f9d13e09cf11 341
terencez 0:f9d13e09cf11 342 return output;
terencez 0:f9d13e09cf11 343 }
terencez 0:f9d13e09cf11 344
terencez 0:f9d13e09cf11 345 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 346 static
terencez 0:f9d13e09cf11 347 int
terencez 0:f9d13e09cf11 348 coap_get_variable(const char *buffer, size_t length, const char *name, const char **output)
terencez 0:f9d13e09cf11 349 {
terencez 0:f9d13e09cf11 350 const char *start = NULL;
terencez 0:f9d13e09cf11 351 const char *end = NULL;
terencez 0:f9d13e09cf11 352 const char *value_end = NULL;
terencez 0:f9d13e09cf11 353 size_t name_len = 0;
terencez 0:f9d13e09cf11 354
terencez 0:f9d13e09cf11 355 /*initialize the output buffer first*/
terencez 0:f9d13e09cf11 356 *output = 0;
terencez 0:f9d13e09cf11 357
terencez 0:f9d13e09cf11 358 name_len = strlen(name);
terencez 0:f9d13e09cf11 359 end = buffer + length;
terencez 0:f9d13e09cf11 360
terencez 0:f9d13e09cf11 361 for (start = buffer; start + name_len < end; ++start){
terencez 0:f9d13e09cf11 362 if ((start == buffer || start[-1] == '&') && start[name_len] == '=' &&
terencez 0:f9d13e09cf11 363 strncmp(name, start, name_len)==0) {
terencez 0:f9d13e09cf11 364
terencez 0:f9d13e09cf11 365 /* Point start to variable value */
terencez 0:f9d13e09cf11 366 start += name_len + 1;
terencez 0:f9d13e09cf11 367
terencez 0:f9d13e09cf11 368 /* Point end to the end of the value */
terencez 0:f9d13e09cf11 369 value_end = (const char *) memchr(start, '&', end - start);
terencez 0:f9d13e09cf11 370 if (value_end == NULL) {
terencez 0:f9d13e09cf11 371 value_end = end;
terencez 0:f9d13e09cf11 372 }
terencez 0:f9d13e09cf11 373
terencez 0:f9d13e09cf11 374 *output = start;
terencez 0:f9d13e09cf11 375
terencez 0:f9d13e09cf11 376 return (value_end - start);
terencez 0:f9d13e09cf11 377 }
terencez 0:f9d13e09cf11 378 }
terencez 0:f9d13e09cf11 379
terencez 0:f9d13e09cf11 380 return 0;
terencez 0:f9d13e09cf11 381 }
terencez 0:f9d13e09cf11 382
terencez 0:f9d13e09cf11 383 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 384 uint16_t
terencez 0:f9d13e09cf11 385 coap_get_mid()
terencez 0:f9d13e09cf11 386 {
terencez 0:f9d13e09cf11 387 return ++current_mid;
terencez 0:f9d13e09cf11 388 }
terencez 0:f9d13e09cf11 389 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 390 /*- MEASSAGE PROCESSING -------------------------------------------------------------*/
terencez 0:f9d13e09cf11 391 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 392 void
terencez 0:f9d13e09cf11 393 coap_init_message(void *packet, coap_message_type_t type, uint8_t code, uint16_t mid)
terencez 0:f9d13e09cf11 394 {
terencez 0:f9d13e09cf11 395 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 396
terencez 0:f9d13e09cf11 397 /* Important thing */
terencez 0:f9d13e09cf11 398 memset(coap_pkt, 0, sizeof(coap_packet_t));
terencez 0:f9d13e09cf11 399
terencez 0:f9d13e09cf11 400 coap_pkt->type = type;
terencez 0:f9d13e09cf11 401 coap_pkt->code = code;
terencez 0:f9d13e09cf11 402 coap_pkt->mid = mid;
terencez 0:f9d13e09cf11 403 }
terencez 0:f9d13e09cf11 404
terencez 0:f9d13e09cf11 405 void
terencez 0:f9d13e09cf11 406 coap_free_header(void *packet)
terencez 0:f9d13e09cf11 407 {
terencez 0:f9d13e09cf11 408 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 409
terencez 0:f9d13e09cf11 410 free_multi_option(coap_pkt->uri_path);
terencez 0:f9d13e09cf11 411 free_multi_option(coap_pkt->uri_query);
terencez 0:f9d13e09cf11 412 free_multi_option(coap_pkt->location_path);
terencez 0:f9d13e09cf11 413 }
terencez 0:f9d13e09cf11 414
terencez 0:f9d13e09cf11 415 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 416 size_t
terencez 0:f9d13e09cf11 417 coap_serialize_message(void *packet, uint8_t *buffer)
terencez 0:f9d13e09cf11 418 {
terencez 0:f9d13e09cf11 419 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 420 uint8_t *option;
terencez 0:f9d13e09cf11 421 unsigned int current_number = 0;
terencez 0:f9d13e09cf11 422
terencez 0:f9d13e09cf11 423 /* Initialize */
terencez 0:f9d13e09cf11 424 coap_pkt->buffer = buffer;
terencez 0:f9d13e09cf11 425 coap_pkt->version = 1;
terencez 0:f9d13e09cf11 426
terencez 0:f9d13e09cf11 427 PRINTF("-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer);
terencez 0:f9d13e09cf11 428
terencez 0:f9d13e09cf11 429 /* set header fields */
terencez 0:f9d13e09cf11 430 coap_pkt->buffer[0] = 0x00;
terencez 0:f9d13e09cf11 431 coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK & (coap_pkt->version)<<COAP_HEADER_VERSION_POSITION;
terencez 0:f9d13e09cf11 432 coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK & (coap_pkt->type)<<COAP_HEADER_TYPE_POSITION;
terencez 0:f9d13e09cf11 433 coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK & (coap_pkt->token_len)<<COAP_HEADER_TOKEN_LEN_POSITION;
terencez 0:f9d13e09cf11 434 coap_pkt->buffer[1] = coap_pkt->code;
terencez 0:f9d13e09cf11 435 coap_pkt->buffer[2] = (uint8_t) ((coap_pkt->mid)>>8);
terencez 0:f9d13e09cf11 436 coap_pkt->buffer[3] = (uint8_t) (coap_pkt->mid);
terencez 0:f9d13e09cf11 437
terencez 0:f9d13e09cf11 438 /* set Token */
terencez 0:f9d13e09cf11 439 PRINTF("Token (len %u)", coap_pkt->token_len);
terencez 0:f9d13e09cf11 440 option = coap_pkt->buffer + COAP_HEADER_LEN;
terencez 0:f9d13e09cf11 441 for (current_number=0; current_number<coap_pkt->token_len; ++current_number)
terencez 0:f9d13e09cf11 442 {
terencez 0:f9d13e09cf11 443 PRINTF(" %02X", coap_pkt->token[current_number]);
terencez 0:f9d13e09cf11 444 *option = coap_pkt->token[current_number];
terencez 0:f9d13e09cf11 445 ++option;
terencez 0:f9d13e09cf11 446 }
terencez 0:f9d13e09cf11 447 PRINTF("-\n");
terencez 0:f9d13e09cf11 448
terencez 0:f9d13e09cf11 449 /* Serialize options */
terencez 0:f9d13e09cf11 450 current_number = 0;
terencez 0:f9d13e09cf11 451
terencez 0:f9d13e09cf11 452 PRINTF("-Serializing options at %p-\n", option);
terencez 0:f9d13e09cf11 453
terencez 0:f9d13e09cf11 454 /* The options must be serialized in the order of their number */
terencez 0:f9d13e09cf11 455 COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_IF_MATCH, if_match, "If-Match")
terencez 0:f9d13e09cf11 456 COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_URI_HOST, uri_host, '\0', "Uri-Host")
terencez 0:f9d13e09cf11 457 COAP_SERIALIZE_BYTE_OPTION( COAP_OPTION_ETAG, etag, "ETag")
terencez 0:f9d13e09cf11 458 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 459 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_OBSERVE, observe, "Observe")
terencez 0:f9d13e09cf11 460 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_URI_PORT, uri_port, "Uri-Port")
terencez 0:f9d13e09cf11 461 COAP_SERIALIZE_MULTI_OPTION( COAP_OPTION_LOCATION_PATH, location_path, "Location-Path")
terencez 0:f9d13e09cf11 462 COAP_SERIALIZE_MULTI_OPTION( COAP_OPTION_URI_PATH, uri_path, "Uri-Path")
terencez 0:f9d13e09cf11 463 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_CONTENT_TYPE, content_type, "Content-Format")
terencez 0:f9d13e09cf11 464 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_MAX_AGE, max_age, "Max-Age")
terencez 0:f9d13e09cf11 465 COAP_SERIALIZE_MULTI_OPTION( COAP_OPTION_URI_QUERY, uri_query, "Uri-Query")
terencez 0:f9d13e09cf11 466 COAP_SERIALIZE_ACCEPT_OPTION( COAP_OPTION_ACCEPT, accept, "Accept")
terencez 0:f9d13e09cf11 467 COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_LOCATION_QUERY, location_query, '&', "Location-Query")
terencez 0:f9d13e09cf11 468 COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK2, block2, "Block2")
terencez 0:f9d13e09cf11 469 COAP_SERIALIZE_BLOCK_OPTION( COAP_OPTION_BLOCK1, block1, "Block1")
terencez 0:f9d13e09cf11 470 COAP_SERIALIZE_INT_OPTION( COAP_OPTION_SIZE, size, "Size")
terencez 0:f9d13e09cf11 471 COAP_SERIALIZE_STRING_OPTION( COAP_OPTION_PROXY_URI, proxy_uri, '\0', "Proxy-Uri")
terencez 0:f9d13e09cf11 472
terencez 0:f9d13e09cf11 473 PRINTF("-Done serializing at %p----\n", option);
terencez 0:f9d13e09cf11 474
terencez 0:f9d13e09cf11 475 /* Free allocated header fields */
terencez 0:f9d13e09cf11 476 coap_free_header(packet);
terencez 0:f9d13e09cf11 477
terencez 0:f9d13e09cf11 478 /* Pack payload */
terencez 0:f9d13e09cf11 479 if ((option - coap_pkt->buffer)<=COAP_MAX_HEADER_SIZE)
terencez 0:f9d13e09cf11 480 {
terencez 0:f9d13e09cf11 481 /* Payload marker */
terencez 0:f9d13e09cf11 482 if (coap_pkt->payload_len)
terencez 0:f9d13e09cf11 483 {
terencez 0:f9d13e09cf11 484 *option = 0xFF;
terencez 0:f9d13e09cf11 485 ++option;
terencez 0:f9d13e09cf11 486 }
terencez 0:f9d13e09cf11 487
terencez 0:f9d13e09cf11 488 memmove(option, coap_pkt->payload, coap_pkt->payload_len);
terencez 0:f9d13e09cf11 489 }
terencez 0:f9d13e09cf11 490 else
terencez 0:f9d13e09cf11 491 {
terencez 0:f9d13e09cf11 492 /* An error occured. Caller must check for !=0. */
terencez 0:f9d13e09cf11 493 coap_pkt->buffer = NULL;
terencez 0:f9d13e09cf11 494 coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE";
terencez 0:f9d13e09cf11 495 return 0;
terencez 0:f9d13e09cf11 496 }
terencez 0:f9d13e09cf11 497
terencez 0:f9d13e09cf11 498 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 499
terencez 0:f9d13e09cf11 500 PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
terencez 0:f9d13e09cf11 501 coap_pkt->buffer[0],
terencez 0:f9d13e09cf11 502 coap_pkt->buffer[1],
terencez 0:f9d13e09cf11 503 coap_pkt->buffer[2],
terencez 0:f9d13e09cf11 504 coap_pkt->buffer[3],
terencez 0:f9d13e09cf11 505 coap_pkt->buffer[4],
terencez 0:f9d13e09cf11 506 coap_pkt->buffer[5],
terencez 0:f9d13e09cf11 507 coap_pkt->buffer[6],
terencez 0:f9d13e09cf11 508 coap_pkt->buffer[7]
terencez 0:f9d13e09cf11 509 );
terencez 0:f9d13e09cf11 510
terencez 0:f9d13e09cf11 511 return (option - buffer) + coap_pkt->payload_len; /* packet length */
terencez 0:f9d13e09cf11 512 }
terencez 0:f9d13e09cf11 513 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 514 coap_status_t
terencez 0:f9d13e09cf11 515 coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
terencez 0:f9d13e09cf11 516 {
terencez 0:f9d13e09cf11 517 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 518
terencez 0:f9d13e09cf11 519 /* Initialize packet */
terencez 0:f9d13e09cf11 520 memset(coap_pkt, 0, sizeof(coap_packet_t));
terencez 0:f9d13e09cf11 521
terencez 0:f9d13e09cf11 522 /* pointer to packet bytes */
terencez 0:f9d13e09cf11 523 coap_pkt->buffer = data;
terencez 0:f9d13e09cf11 524
terencez 0:f9d13e09cf11 525 /* parse header fields */
terencez 0:f9d13e09cf11 526 coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])>>COAP_HEADER_VERSION_POSITION;
terencez 0:f9d13e09cf11 527 coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])>>COAP_HEADER_TYPE_POSITION;
terencez 0:f9d13e09cf11 528 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 529 coap_pkt->code = coap_pkt->buffer[1];
terencez 0:f9d13e09cf11 530 coap_pkt->mid = coap_pkt->buffer[2]<<8 | coap_pkt->buffer[3];
terencez 0:f9d13e09cf11 531
terencez 0:f9d13e09cf11 532 if (coap_pkt->version != 1)
terencez 0:f9d13e09cf11 533 {
terencez 0:f9d13e09cf11 534 coap_error_message = "CoAP version must be 1";
terencez 0:f9d13e09cf11 535 return BAD_REQUEST_4_00;
terencez 0:f9d13e09cf11 536 }
terencez 0:f9d13e09cf11 537
terencez 0:f9d13e09cf11 538 uint8_t *current_option = data + COAP_HEADER_LEN;
terencez 0:f9d13e09cf11 539
terencez 0:f9d13e09cf11 540 if (coap_pkt->token_len != 0)
terencez 0:f9d13e09cf11 541 {
terencez 0:f9d13e09cf11 542 memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
terencez 0:f9d13e09cf11 543 SET_OPTION(coap_pkt, COAP_OPTION_TOKEN);
terencez 0:f9d13e09cf11 544
terencez 0:f9d13e09cf11 545 PRINTF("Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->token_len,
terencez 0:f9d13e09cf11 546 coap_pkt->token[0],
terencez 0:f9d13e09cf11 547 coap_pkt->token[1],
terencez 0:f9d13e09cf11 548 coap_pkt->token[2],
terencez 0:f9d13e09cf11 549 coap_pkt->token[3],
terencez 0:f9d13e09cf11 550 coap_pkt->token[4],
terencez 0:f9d13e09cf11 551 coap_pkt->token[5],
terencez 0:f9d13e09cf11 552 coap_pkt->token[6],
terencez 0:f9d13e09cf11 553 coap_pkt->token[7]
terencez 0:f9d13e09cf11 554 ); /*FIXME always prints 8 bytes */
terencez 0:f9d13e09cf11 555 }
terencez 0:f9d13e09cf11 556
terencez 0:f9d13e09cf11 557 /* parse options */
terencez 0:f9d13e09cf11 558 current_option += coap_pkt->token_len;
terencez 0:f9d13e09cf11 559
terencez 0:f9d13e09cf11 560 unsigned int option_number = 0;
terencez 0:f9d13e09cf11 561 unsigned int option_delta = 0;
terencez 0:f9d13e09cf11 562 size_t option_length = 0;
terencez 0:f9d13e09cf11 563
terencez 0:f9d13e09cf11 564 while (current_option < data+data_len)
terencez 0:f9d13e09cf11 565 {
terencez 0:f9d13e09cf11 566 /* Payload marker 0xFF, currently only checking for 0xF* because rest is reserved */
terencez 0:f9d13e09cf11 567 if ((current_option[0] & 0xF0)==0xF0)
terencez 0:f9d13e09cf11 568 {
terencez 0:f9d13e09cf11 569 coap_pkt->payload = ++current_option;
terencez 0:f9d13e09cf11 570 coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
terencez 0:f9d13e09cf11 571
terencez 0:f9d13e09cf11 572 /* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */
terencez 0:f9d13e09cf11 573 if (coap_pkt->payload_len > REST_MAX_CHUNK_SIZE)
terencez 0:f9d13e09cf11 574 {
terencez 0:f9d13e09cf11 575 coap_pkt->payload_len = REST_MAX_CHUNK_SIZE;
terencez 0:f9d13e09cf11 576 }
terencez 0:f9d13e09cf11 577
terencez 0:f9d13e09cf11 578 break;
terencez 0:f9d13e09cf11 579 }
terencez 0:f9d13e09cf11 580
terencez 0:f9d13e09cf11 581 option_delta = current_option[0]>>4;
terencez 0:f9d13e09cf11 582 option_length = current_option[0] & 0x0F;
terencez 0:f9d13e09cf11 583 ++current_option;
terencez 0:f9d13e09cf11 584
terencez 0:f9d13e09cf11 585 /* avoids code duplication without function overhead */
terencez 0:f9d13e09cf11 586 unsigned int *x = &option_delta;
terencez 0:f9d13e09cf11 587 do
terencez 0:f9d13e09cf11 588 {
terencez 0:f9d13e09cf11 589 if (*x==13)
terencez 0:f9d13e09cf11 590 {
terencez 0:f9d13e09cf11 591 *x += current_option[0];
terencez 0:f9d13e09cf11 592 ++current_option;
terencez 0:f9d13e09cf11 593 }
terencez 0:f9d13e09cf11 594 else if (*x==14)
terencez 0:f9d13e09cf11 595 {
terencez 0:f9d13e09cf11 596 *x += 255;
terencez 0:f9d13e09cf11 597 *x += current_option[0]<<8;
terencez 0:f9d13e09cf11 598 ++current_option;
terencez 0:f9d13e09cf11 599 *x += current_option[0];
terencez 0:f9d13e09cf11 600 ++current_option;
terencez 0:f9d13e09cf11 601 }
terencez 0:f9d13e09cf11 602 }
terencez 0:f9d13e09cf11 603 while (x!=(unsigned int *)&option_length && (x=(unsigned int *)&option_length));
terencez 0:f9d13e09cf11 604
terencez 0:f9d13e09cf11 605 option_number += option_delta;
terencez 0:f9d13e09cf11 606
terencez 0:f9d13e09cf11 607 PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, option_length);
terencez 0:f9d13e09cf11 608
terencez 0:f9d13e09cf11 609 SET_OPTION(coap_pkt, option_number);
terencez 0:f9d13e09cf11 610
terencez 0:f9d13e09cf11 611 switch (option_number)
terencez 0:f9d13e09cf11 612 {
terencez 0:f9d13e09cf11 613 case COAP_OPTION_CONTENT_TYPE:
terencez 0:f9d13e09cf11 614 coap_pkt->content_type = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 615 PRINTF("Content-Format [%u]\n", coap_pkt->content_type);
terencez 0:f9d13e09cf11 616 break;
terencez 0:f9d13e09cf11 617 case COAP_OPTION_MAX_AGE:
terencez 0:f9d13e09cf11 618 coap_pkt->max_age = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 619 PRINTF("Max-Age [%lu]\n", coap_pkt->max_age);
terencez 0:f9d13e09cf11 620 break;
terencez 0:f9d13e09cf11 621 case COAP_OPTION_ETAG:
terencez 0:f9d13e09cf11 622 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
terencez 0:f9d13e09cf11 623 memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len);
terencez 0:f9d13e09cf11 624 PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->etag_len,
terencez 0:f9d13e09cf11 625 coap_pkt->etag[0],
terencez 0:f9d13e09cf11 626 coap_pkt->etag[1],
terencez 0:f9d13e09cf11 627 coap_pkt->etag[2],
terencez 0:f9d13e09cf11 628 coap_pkt->etag[3],
terencez 0:f9d13e09cf11 629 coap_pkt->etag[4],
terencez 0:f9d13e09cf11 630 coap_pkt->etag[5],
terencez 0:f9d13e09cf11 631 coap_pkt->etag[6],
terencez 0:f9d13e09cf11 632 coap_pkt->etag[7]
terencez 0:f9d13e09cf11 633 ); /*FIXME always prints 8 bytes */
terencez 0:f9d13e09cf11 634 break;
terencez 0:f9d13e09cf11 635 case COAP_OPTION_ACCEPT:
terencez 0:f9d13e09cf11 636 if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM)
terencez 0:f9d13e09cf11 637 {
terencez 0:f9d13e09cf11 638 coap_pkt->accept[coap_pkt->accept_num] = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 639 coap_pkt->accept_num += 1;
terencez 0:f9d13e09cf11 640 PRINTF("Accept [%u]\n", coap_pkt->content_type);
terencez 0:f9d13e09cf11 641 }
terencez 0:f9d13e09cf11 642 break;
terencez 0:f9d13e09cf11 643 case COAP_OPTION_IF_MATCH:
terencez 0:f9d13e09cf11 644 /*FIXME support multiple ETags */
terencez 0:f9d13e09cf11 645 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
terencez 0:f9d13e09cf11 646 memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len);
terencez 0:f9d13e09cf11 647 PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->if_match_len,
terencez 0:f9d13e09cf11 648 coap_pkt->if_match[0],
terencez 0:f9d13e09cf11 649 coap_pkt->if_match[1],
terencez 0:f9d13e09cf11 650 coap_pkt->if_match[2],
terencez 0:f9d13e09cf11 651 coap_pkt->if_match[3],
terencez 0:f9d13e09cf11 652 coap_pkt->if_match[4],
terencez 0:f9d13e09cf11 653 coap_pkt->if_match[5],
terencez 0:f9d13e09cf11 654 coap_pkt->if_match[6],
terencez 0:f9d13e09cf11 655 coap_pkt->if_match[7]
terencez 0:f9d13e09cf11 656 ); /*FIXME always prints 8 bytes */
terencez 0:f9d13e09cf11 657 break;
terencez 0:f9d13e09cf11 658 case COAP_OPTION_IF_NONE_MATCH:
terencez 0:f9d13e09cf11 659 coap_pkt->if_none_match = 1;
terencez 0:f9d13e09cf11 660 PRINTF("If-None-Match\n");
terencez 0:f9d13e09cf11 661 break;
terencez 0:f9d13e09cf11 662
terencez 0:f9d13e09cf11 663 case COAP_OPTION_URI_HOST:
terencez 0:f9d13e09cf11 664 coap_pkt->uri_host = (char *) current_option;
terencez 0:f9d13e09cf11 665 coap_pkt->uri_host_len = option_length;
terencez 0:f9d13e09cf11 666 PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host);
terencez 0:f9d13e09cf11 667 break;
terencez 0:f9d13e09cf11 668 case COAP_OPTION_URI_PORT:
terencez 0:f9d13e09cf11 669 coap_pkt->uri_port = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 670 PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port);
terencez 0:f9d13e09cf11 671 break;
terencez 0:f9d13e09cf11 672 case COAP_OPTION_URI_PATH:
terencez 0:f9d13e09cf11 673 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:f9d13e09cf11 674 // coap_merge_multi_option( (char **) &(coap_pkt->uri_path), &(coap_pkt->uri_path_len), current_option, option_length, 0);
terencez 0:f9d13e09cf11 675 coap_add_multi_option( &(coap_pkt->uri_path), current_option, option_length, 1);
terencez 0:f9d13e09cf11 676 PRINTF("Uri-Path [%.*s]\n", sizeof(multi_option_t), coap_pkt->uri_path);
terencez 0:f9d13e09cf11 677 break;
terencez 0:f9d13e09cf11 678 case COAP_OPTION_URI_QUERY:
terencez 0:f9d13e09cf11 679 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:f9d13e09cf11 680 // coap_merge_multi_option( (char **) &(coap_pkt->uri_query), &(coap_pkt->uri_query_len), current_option, option_length, '&');
terencez 0:f9d13e09cf11 681 coap_add_multi_option( &(coap_pkt->uri_query), current_option, option_length, 1);
terencez 0:f9d13e09cf11 682 PRINTF("Uri-Query [%.*s]\n", sizeof(multi_option_t), coap_pkt->uri_query);
terencez 0:f9d13e09cf11 683 break;
terencez 0:f9d13e09cf11 684
terencez 0:f9d13e09cf11 685 case COAP_OPTION_LOCATION_PATH:
terencez 0:f9d13e09cf11 686 coap_add_multi_option( &(coap_pkt->location_path), current_option, option_length, 1);
terencez 0:f9d13e09cf11 687 break;
terencez 0:f9d13e09cf11 688 case COAP_OPTION_LOCATION_QUERY:
terencez 0:f9d13e09cf11 689 /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
terencez 0:f9d13e09cf11 690 coap_merge_multi_option( (char **) &(coap_pkt->location_query), &(coap_pkt->location_query_len), current_option, option_length, '&');
terencez 0:f9d13e09cf11 691 PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, coap_pkt->location_query);
terencez 0:f9d13e09cf11 692 break;
terencez 0:f9d13e09cf11 693
terencez 0:f9d13e09cf11 694 case COAP_OPTION_PROXY_URI:
terencez 0:f9d13e09cf11 695 /*FIXME check for own end-point */
terencez 0:f9d13e09cf11 696 coap_pkt->proxy_uri = (char *) current_option;
terencez 0:f9d13e09cf11 697 coap_pkt->proxy_uri_len = option_length;
terencez 0:f9d13e09cf11 698 /*TODO length > 270 not implemented (actually not required) */
terencez 0:f9d13e09cf11 699 PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, coap_pkt->proxy_uri);
terencez 0:f9d13e09cf11 700 coap_error_message = "This is a constrained server (Contiki)";
terencez 0:f9d13e09cf11 701 return PROXYING_NOT_SUPPORTED_5_05;
terencez 0:f9d13e09cf11 702 break;
terencez 0:f9d13e09cf11 703
terencez 0:f9d13e09cf11 704 case COAP_OPTION_OBSERVE:
terencez 0:f9d13e09cf11 705 coap_pkt->observe = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 706 PRINTF("Observe [%lu]\n", coap_pkt->observe);
terencez 0:f9d13e09cf11 707 break;
terencez 0:f9d13e09cf11 708 case COAP_OPTION_BLOCK2:
terencez 0:f9d13e09cf11 709 coap_pkt->block2_num = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 710 coap_pkt->block2_more = (coap_pkt->block2_num & 0x08)>>3;
terencez 0:f9d13e09cf11 711 coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
terencez 0:f9d13e09cf11 712 coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)<<(coap_pkt->block2_num & 0x07);
terencez 0:f9d13e09cf11 713 coap_pkt->block2_num >>= 4;
terencez 0:f9d13e09cf11 714 PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
terencez 0:f9d13e09cf11 715 break;
terencez 0:f9d13e09cf11 716 case COAP_OPTION_BLOCK1:
terencez 0:f9d13e09cf11 717 coap_pkt->block1_num = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 718 coap_pkt->block1_more = (coap_pkt->block1_num & 0x08)>>3;
terencez 0:f9d13e09cf11 719 coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
terencez 0:f9d13e09cf11 720 coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)<<(coap_pkt->block1_num & 0x07);
terencez 0:f9d13e09cf11 721 coap_pkt->block1_num >>= 4;
terencez 0:f9d13e09cf11 722 PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
terencez 0:f9d13e09cf11 723 break;
terencez 0:f9d13e09cf11 724 case COAP_OPTION_SIZE:
terencez 0:f9d13e09cf11 725 coap_pkt->size = coap_parse_int_option(current_option, option_length);
terencez 0:f9d13e09cf11 726 PRINTF("Size [%lu]\n", coap_pkt->size);
terencez 0:f9d13e09cf11 727 break;
terencez 0:f9d13e09cf11 728 default:
terencez 0:f9d13e09cf11 729 PRINTF("unknown (%u)\n", option_number);
terencez 0:f9d13e09cf11 730 /* Check if critical (odd) */
terencez 0:f9d13e09cf11 731 if (option_number & 1)
terencez 0:f9d13e09cf11 732 {
terencez 0:f9d13e09cf11 733 coap_error_message = "Unsupported critical option";
terencez 0:f9d13e09cf11 734 return BAD_OPTION_4_02;
terencez 0:f9d13e09cf11 735 }
terencez 0:f9d13e09cf11 736 }
terencez 0:f9d13e09cf11 737
terencez 0:f9d13e09cf11 738 current_option += option_length;
terencez 0:f9d13e09cf11 739 } /* for */
terencez 0:f9d13e09cf11 740 PRINTF("-Done parsing-------\n");
terencez 0:f9d13e09cf11 741
terencez 0:f9d13e09cf11 742
terencez 0:f9d13e09cf11 743
terencez 0:f9d13e09cf11 744 return NO_ERROR;
terencez 0:f9d13e09cf11 745 }
terencez 0:f9d13e09cf11 746 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 747 /*- REST FRAMEWORK FUNCTIONS --------------------------------------------------------*/
terencez 0:f9d13e09cf11 748 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 749 int
terencez 0:f9d13e09cf11 750 coap_get_query_variable(void *packet, const char *name, const char **output)
terencez 0:f9d13e09cf11 751 {
terencez 0:f9d13e09cf11 752 /*
terencez 0:f9d13e09cf11 753 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 754
terencez 0:f9d13e09cf11 755 if (IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
terencez 0:f9d13e09cf11 756 return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len, name, output);
terencez 0:f9d13e09cf11 757 }
terencez 0:f9d13e09cf11 758 */
terencez 0:f9d13e09cf11 759 return 0;
terencez 0:f9d13e09cf11 760 }
terencez 0:f9d13e09cf11 761
terencez 0:f9d13e09cf11 762 int
terencez 0:f9d13e09cf11 763 coap_get_post_variable(void *packet, const char *name, const char **output)
terencez 0:f9d13e09cf11 764 {
terencez 0:f9d13e09cf11 765 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 766
terencez 0:f9d13e09cf11 767 if (coap_pkt->payload_len) {
terencez 0:f9d13e09cf11 768 return coap_get_variable((const char *)coap_pkt->payload, coap_pkt->payload_len, name, output);
terencez 0:f9d13e09cf11 769 }
terencez 0:f9d13e09cf11 770 return 0;
terencez 0:f9d13e09cf11 771 }
terencez 0:f9d13e09cf11 772 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 773 int
terencez 0:f9d13e09cf11 774 coap_set_status_code(void *packet, unsigned int code)
terencez 0:f9d13e09cf11 775 {
terencez 0:f9d13e09cf11 776 if (code <= 0xFF)
terencez 0:f9d13e09cf11 777 {
terencez 0:f9d13e09cf11 778 ((coap_packet_t *)packet)->code = (uint8_t) code;
terencez 0:f9d13e09cf11 779 return 1;
terencez 0:f9d13e09cf11 780 }
terencez 0:f9d13e09cf11 781 else
terencez 0:f9d13e09cf11 782 {
terencez 0:f9d13e09cf11 783 return 0;
terencez 0:f9d13e09cf11 784 }
terencez 0:f9d13e09cf11 785 }
terencez 0:f9d13e09cf11 786 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 787 /*- HEADER OPTION GETTERS AND SETTERS -----------------------------------------------*/
terencez 0:f9d13e09cf11 788 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 789 unsigned int
terencez 0:f9d13e09cf11 790 coap_get_header_content_type(void *packet)
terencez 0:f9d13e09cf11 791 {
terencez 0:f9d13e09cf11 792 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 793
terencez 0:f9d13e09cf11 794 if (!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE)) return -1;
terencez 0:f9d13e09cf11 795
terencez 0:f9d13e09cf11 796 return coap_pkt->content_type;
terencez 0:f9d13e09cf11 797 }
terencez 0:f9d13e09cf11 798
terencez 0:f9d13e09cf11 799 int
terencez 0:f9d13e09cf11 800 coap_set_header_content_type(void *packet, unsigned int content_type)
terencez 0:f9d13e09cf11 801 {
terencez 0:f9d13e09cf11 802 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 803
terencez 0:f9d13e09cf11 804 coap_pkt->content_type = (coap_content_type_t) content_type;
terencez 0:f9d13e09cf11 805 SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_TYPE);
terencez 0:f9d13e09cf11 806 return 1;
terencez 0:f9d13e09cf11 807 }
terencez 0:f9d13e09cf11 808 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 809 int
terencez 0:f9d13e09cf11 810 coap_get_header_accept(void *packet, const uint16_t **accept)
terencez 0:f9d13e09cf11 811 {
terencez 0:f9d13e09cf11 812 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 813
terencez 0:f9d13e09cf11 814 if (!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) return 0;
terencez 0:f9d13e09cf11 815
terencez 0:f9d13e09cf11 816 *accept = coap_pkt->accept;
terencez 0:f9d13e09cf11 817 return coap_pkt->accept_num;
terencez 0:f9d13e09cf11 818 }
terencez 0:f9d13e09cf11 819
terencez 0:f9d13e09cf11 820 int
terencez 0:f9d13e09cf11 821 coap_set_header_accept(void *packet, uint16_t accept)
terencez 0:f9d13e09cf11 822 {
terencez 0:f9d13e09cf11 823 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 824
terencez 0:f9d13e09cf11 825 if (coap_pkt->accept_num < COAP_MAX_ACCEPT_NUM)
terencez 0:f9d13e09cf11 826 {
terencez 0:f9d13e09cf11 827 coap_pkt->accept[coap_pkt->accept_num] = accept;
terencez 0:f9d13e09cf11 828 coap_pkt->accept_num += 1;
terencez 0:f9d13e09cf11 829
terencez 0:f9d13e09cf11 830 SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
terencez 0:f9d13e09cf11 831 }
terencez 0:f9d13e09cf11 832 return coap_pkt->accept_num;
terencez 0:f9d13e09cf11 833 }
terencez 0:f9d13e09cf11 834 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 835 int
terencez 0:f9d13e09cf11 836 coap_get_header_max_age(void *packet, uint32_t *age)
terencez 0:f9d13e09cf11 837 {
terencez 0:f9d13e09cf11 838 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 839
terencez 0:f9d13e09cf11 840 if (!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) {
terencez 0:f9d13e09cf11 841 *age = COAP_DEFAULT_MAX_AGE;
terencez 0:f9d13e09cf11 842 } else {
terencez 0:f9d13e09cf11 843 *age = coap_pkt->max_age;
terencez 0:f9d13e09cf11 844 }
terencez 0:f9d13e09cf11 845 return 1;
terencez 0:f9d13e09cf11 846 }
terencez 0:f9d13e09cf11 847
terencez 0:f9d13e09cf11 848 int
terencez 0:f9d13e09cf11 849 coap_set_header_max_age(void *packet, uint32_t age)
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 coap_pkt->max_age = age;
terencez 0:f9d13e09cf11 854 SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE);
terencez 0:f9d13e09cf11 855 return 1;
terencez 0:f9d13e09cf11 856 }
terencez 0:f9d13e09cf11 857 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 858 int
terencez 0:f9d13e09cf11 859 coap_get_header_etag(void *packet, const uint8_t **etag)
terencez 0:f9d13e09cf11 860 {
terencez 0:f9d13e09cf11 861 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 862
terencez 0:f9d13e09cf11 863 if (!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) return 0;
terencez 0:f9d13e09cf11 864
terencez 0:f9d13e09cf11 865 *etag = coap_pkt->etag;
terencez 0:f9d13e09cf11 866 return coap_pkt->etag_len;
terencez 0:f9d13e09cf11 867 }
terencez 0:f9d13e09cf11 868
terencez 0:f9d13e09cf11 869 int
terencez 0:f9d13e09cf11 870 coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len)
terencez 0:f9d13e09cf11 871 {
terencez 0:f9d13e09cf11 872 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 873
terencez 0:f9d13e09cf11 874 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len);
terencez 0:f9d13e09cf11 875 memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
terencez 0:f9d13e09cf11 876
terencez 0:f9d13e09cf11 877 SET_OPTION(coap_pkt, COAP_OPTION_ETAG);
terencez 0:f9d13e09cf11 878 return coap_pkt->etag_len;
terencez 0:f9d13e09cf11 879 }
terencez 0:f9d13e09cf11 880 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 881 /*FIXME support multiple ETags */
terencez 0:f9d13e09cf11 882 int
terencez 0:f9d13e09cf11 883 coap_get_header_if_match(void *packet, const uint8_t **etag)
terencez 0:f9d13e09cf11 884 {
terencez 0:f9d13e09cf11 885 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 886
terencez 0:f9d13e09cf11 887 if (!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) return 0;
terencez 0:f9d13e09cf11 888
terencez 0:f9d13e09cf11 889 *etag = coap_pkt->if_match;
terencez 0:f9d13e09cf11 890 return coap_pkt->if_match_len;
terencez 0:f9d13e09cf11 891 }
terencez 0:f9d13e09cf11 892
terencez 0:f9d13e09cf11 893 int
terencez 0:f9d13e09cf11 894 coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len)
terencez 0:f9d13e09cf11 895 {
terencez 0:f9d13e09cf11 896 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 897
terencez 0:f9d13e09cf11 898 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len);
terencez 0:f9d13e09cf11 899 memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
terencez 0:f9d13e09cf11 900
terencez 0:f9d13e09cf11 901 SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH);
terencez 0:f9d13e09cf11 902 return coap_pkt->if_match_len;
terencez 0:f9d13e09cf11 903 }
terencez 0:f9d13e09cf11 904 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 905 int
terencez 0:f9d13e09cf11 906 coap_get_header_if_none_match(void *packet)
terencez 0:f9d13e09cf11 907 {
terencez 0:f9d13e09cf11 908 return IS_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
terencez 0:f9d13e09cf11 909 }
terencez 0:f9d13e09cf11 910
terencez 0:f9d13e09cf11 911 int
terencez 0:f9d13e09cf11 912 coap_set_header_if_none_match(void *packet)
terencez 0:f9d13e09cf11 913 {
terencez 0:f9d13e09cf11 914 SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH);
terencez 0:f9d13e09cf11 915 return 1;
terencez 0:f9d13e09cf11 916 }
terencez 0:f9d13e09cf11 917 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 918 int
terencez 0:f9d13e09cf11 919 coap_get_header_token(void *packet, const uint8_t **token)
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 (!IS_OPTION(coap_pkt, COAP_OPTION_TOKEN)) return 0;
terencez 0:f9d13e09cf11 924
terencez 0:f9d13e09cf11 925 *token = coap_pkt->token;
terencez 0:f9d13e09cf11 926 return coap_pkt->token_len;
terencez 0:f9d13e09cf11 927 }
terencez 0:f9d13e09cf11 928
terencez 0:f9d13e09cf11 929 int
terencez 0:f9d13e09cf11 930 coap_set_header_token(void *packet, const uint8_t *token, size_t token_len)
terencez 0:f9d13e09cf11 931 {
terencez 0:f9d13e09cf11 932 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 933
terencez 0:f9d13e09cf11 934 coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
terencez 0:f9d13e09cf11 935 memcpy(coap_pkt->token, token, coap_pkt->token_len);
terencez 0:f9d13e09cf11 936
terencez 0:f9d13e09cf11 937 SET_OPTION(coap_pkt, COAP_OPTION_TOKEN);
terencez 0:f9d13e09cf11 938 return coap_pkt->token_len;
terencez 0:f9d13e09cf11 939 }
terencez 0:f9d13e09cf11 940 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 941 int
terencez 0:f9d13e09cf11 942 coap_get_header_proxy_uri(void *packet, const char **uri)
terencez 0:f9d13e09cf11 943 {
terencez 0:f9d13e09cf11 944 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 945
terencez 0:f9d13e09cf11 946 if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0;
terencez 0:f9d13e09cf11 947
terencez 0:f9d13e09cf11 948 *uri = coap_pkt->proxy_uri;
terencez 0:f9d13e09cf11 949 return coap_pkt->proxy_uri_len;
terencez 0:f9d13e09cf11 950 }
terencez 0:f9d13e09cf11 951
terencez 0:f9d13e09cf11 952 int
terencez 0:f9d13e09cf11 953 coap_set_header_proxy_uri(void *packet, const char *uri)
terencez 0:f9d13e09cf11 954 {
terencez 0:f9d13e09cf11 955 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 956
terencez 0:f9d13e09cf11 957 coap_pkt->proxy_uri = uri;
terencez 0:f9d13e09cf11 958 coap_pkt->proxy_uri_len = strlen(uri);
terencez 0:f9d13e09cf11 959
terencez 0:f9d13e09cf11 960 SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI);
terencez 0:f9d13e09cf11 961 return coap_pkt->proxy_uri_len;
terencez 0:f9d13e09cf11 962 }
terencez 0:f9d13e09cf11 963 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 964 int
terencez 0:f9d13e09cf11 965 coap_get_header_uri_host(void *packet, const char **host)
terencez 0:f9d13e09cf11 966 {
terencez 0:f9d13e09cf11 967 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 968
terencez 0:f9d13e09cf11 969 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) return 0;
terencez 0:f9d13e09cf11 970
terencez 0:f9d13e09cf11 971 *host = coap_pkt->uri_host;
terencez 0:f9d13e09cf11 972 return coap_pkt->uri_host_len;
terencez 0:f9d13e09cf11 973 }
terencez 0:f9d13e09cf11 974
terencez 0:f9d13e09cf11 975 int
terencez 0:f9d13e09cf11 976 coap_set_header_uri_host(void *packet, const char *host)
terencez 0:f9d13e09cf11 977 {
terencez 0:f9d13e09cf11 978 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 979
terencez 0:f9d13e09cf11 980 coap_pkt->uri_host = host;
terencez 0:f9d13e09cf11 981 coap_pkt->uri_host_len = strlen(host);
terencez 0:f9d13e09cf11 982
terencez 0:f9d13e09cf11 983 SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST);
terencez 0:f9d13e09cf11 984 return coap_pkt->uri_host_len;
terencez 0:f9d13e09cf11 985 }
terencez 0:f9d13e09cf11 986 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 987 int
terencez 0:f9d13e09cf11 988 coap_get_header_uri_path(void *packet, const char **path)
terencez 0:f9d13e09cf11 989 {
terencez 0:f9d13e09cf11 990 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 991
terencez 0:f9d13e09cf11 992 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) return 0;
terencez 0:f9d13e09cf11 993
terencez 0:f9d13e09cf11 994 *path = NULL; //coap_pkt->uri_path;
terencez 0:f9d13e09cf11 995 return 0; //coap_pkt->uri_path_len;
terencez 0:f9d13e09cf11 996 }
terencez 0:f9d13e09cf11 997
terencez 0:f9d13e09cf11 998 int
terencez 0:f9d13e09cf11 999 coap_set_header_uri_path(void *packet, const char *path)
terencez 0:f9d13e09cf11 1000 {
terencez 0:f9d13e09cf11 1001 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1002 int length = 0;
terencez 0:f9d13e09cf11 1003
terencez 0:f9d13e09cf11 1004 free_multi_option(coap_pkt->uri_path);
terencez 0:f9d13e09cf11 1005 coap_pkt->uri_path = NULL;
terencez 0:f9d13e09cf11 1006
terencez 0:f9d13e09cf11 1007 if (path[0]=='/') ++path;
terencez 0:f9d13e09cf11 1008
terencez 0:f9d13e09cf11 1009 do
terencez 0:f9d13e09cf11 1010 {
terencez 0:f9d13e09cf11 1011 int i = 0;
terencez 0:f9d13e09cf11 1012
terencez 0:f9d13e09cf11 1013 while (path[i] != 0 && path[i] != '/') i++;
terencez 0:f9d13e09cf11 1014 coap_add_multi_option(&(coap_pkt->uri_path), (uint8_t *)path, i, 0);
terencez 0:f9d13e09cf11 1015
terencez 0:f9d13e09cf11 1016 if (path[i] == '/') i++;
terencez 0:f9d13e09cf11 1017 path += i;
terencez 0:f9d13e09cf11 1018 length += i;
terencez 0:f9d13e09cf11 1019 } while (path[0] != 0);
terencez 0:f9d13e09cf11 1020
terencez 0:f9d13e09cf11 1021 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
terencez 0:f9d13e09cf11 1022 return length;
terencez 0:f9d13e09cf11 1023 }
terencez 0:f9d13e09cf11 1024
terencez 0:f9d13e09cf11 1025 int
terencez 0:f9d13e09cf11 1026 coap_set_header_uri_path_segment(void *packet, const char *segment)
terencez 0:f9d13e09cf11 1027 {
terencez 0:f9d13e09cf11 1028 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1029 int length;
terencez 0:f9d13e09cf11 1030
terencez 0:f9d13e09cf11 1031 if (segment == NULL || segment[0] == 0)
terencez 0:f9d13e09cf11 1032 {
terencez 0:f9d13e09cf11 1033 coap_add_multi_option(&(coap_pkt->uri_path), NULL, 0, 1);
terencez 0:f9d13e09cf11 1034 length = 0;
terencez 0:f9d13e09cf11 1035 }
terencez 0:f9d13e09cf11 1036 else
terencez 0:f9d13e09cf11 1037 {
terencez 0:f9d13e09cf11 1038 length = strlen(segment);
terencez 0:f9d13e09cf11 1039 coap_add_multi_option(&(coap_pkt->uri_path), (uint8_t *)segment, length, 0);
terencez 0:f9d13e09cf11 1040 }
terencez 0:f9d13e09cf11 1041
terencez 0:f9d13e09cf11 1042 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
terencez 0:f9d13e09cf11 1043 return length;
terencez 0:f9d13e09cf11 1044 }
terencez 0:f9d13e09cf11 1045 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1046 int
terencez 0:f9d13e09cf11 1047 coap_get_header_uri_query(void *packet, const char **query)
terencez 0:f9d13e09cf11 1048 {
terencez 0:f9d13e09cf11 1049 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1050
terencez 0:f9d13e09cf11 1051 if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) return 0;
terencez 0:f9d13e09cf11 1052
terencez 0:f9d13e09cf11 1053 *query = NULL; //coap_pkt->uri_query;
terencez 0:f9d13e09cf11 1054 return 0; //coap_pkt->uri_query_len;
terencez 0:f9d13e09cf11 1055 }
terencez 0:f9d13e09cf11 1056
terencez 0:f9d13e09cf11 1057 int
terencez 0:f9d13e09cf11 1058 coap_set_header_uri_query(void *packet, const char *query)
terencez 0:f9d13e09cf11 1059 {
terencez 0:f9d13e09cf11 1060 int length = 0;
terencez 0:f9d13e09cf11 1061 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1062
terencez 0:f9d13e09cf11 1063 free_multi_option(coap_pkt->uri_query);
terencez 0:f9d13e09cf11 1064 coap_pkt->uri_query = NULL;
terencez 0:f9d13e09cf11 1065
terencez 0:f9d13e09cf11 1066 if (query[0]=='?') ++query;
terencez 0:f9d13e09cf11 1067
terencez 0:f9d13e09cf11 1068 do
terencez 0:f9d13e09cf11 1069 {
terencez 0:f9d13e09cf11 1070 int i = 0;
terencez 0:f9d13e09cf11 1071
terencez 0:f9d13e09cf11 1072 while (query[i] != 0 && query[i] != '&') i++;
terencez 0:f9d13e09cf11 1073 coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t *)query, i, 0);
terencez 0:f9d13e09cf11 1074
terencez 0:f9d13e09cf11 1075 if (query[i] == '&') i++;
terencez 0:f9d13e09cf11 1076 query += i;
terencez 0:f9d13e09cf11 1077 length += i;
terencez 0:f9d13e09cf11 1078 } while (query[0] != 0);
terencez 0:f9d13e09cf11 1079
terencez 0:f9d13e09cf11 1080 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
terencez 0:f9d13e09cf11 1081 return length;
terencez 0:f9d13e09cf11 1082 }
terencez 0:f9d13e09cf11 1083 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1084 int
terencez 0:f9d13e09cf11 1085 coap_get_header_location_path(void *packet, const char **path)
terencez 0:f9d13e09cf11 1086 {
terencez 0:f9d13e09cf11 1087 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1088
terencez 0:f9d13e09cf11 1089 if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) return 0;
terencez 0:f9d13e09cf11 1090
terencez 0:f9d13e09cf11 1091 *path = NULL; //coap_pkt->location_path;
terencez 0:f9d13e09cf11 1092 return 0; //coap_pkt->location_path_len;
terencez 0:f9d13e09cf11 1093 }
terencez 0:f9d13e09cf11 1094
terencez 0:f9d13e09cf11 1095 int
terencez 0:f9d13e09cf11 1096 coap_set_header_location_path(void *packet, const char *path)
terencez 0:f9d13e09cf11 1097 {
terencez 0:f9d13e09cf11 1098 coap_packet_t *coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1099 int length = 0;
terencez 0:f9d13e09cf11 1100
terencez 0:f9d13e09cf11 1101 free_multi_option(coap_pkt->location_path);
terencez 0:f9d13e09cf11 1102 coap_pkt->location_path = NULL;
terencez 0:f9d13e09cf11 1103
terencez 0:f9d13e09cf11 1104 if (path[0]=='/') ++path;
terencez 0:f9d13e09cf11 1105
terencez 0:f9d13e09cf11 1106 do
terencez 0:f9d13e09cf11 1107 {
terencez 0:f9d13e09cf11 1108 int i = 0;
terencez 0:f9d13e09cf11 1109
terencez 0:f9d13e09cf11 1110 while (path[i] != 0 && path[i] != '/') i++;
terencez 0:f9d13e09cf11 1111 coap_add_multi_option(&(coap_pkt->location_path), (uint8_t *)path, i, 0);
terencez 0:f9d13e09cf11 1112
terencez 0:f9d13e09cf11 1113 if (path[i] == '/') i++;
terencez 0:f9d13e09cf11 1114 path += i;
terencez 0:f9d13e09cf11 1115 length += i;
terencez 0:f9d13e09cf11 1116 } while (path[0] != 0);
terencez 0:f9d13e09cf11 1117
terencez 0:f9d13e09cf11 1118 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH);
terencez 0:f9d13e09cf11 1119 return length;
terencez 0:f9d13e09cf11 1120 }
terencez 0:f9d13e09cf11 1121 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1122 int
terencez 0:f9d13e09cf11 1123 coap_get_header_location_query(void *packet, const char **query)
terencez 0:f9d13e09cf11 1124 {
terencez 0:f9d13e09cf11 1125 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1126
terencez 0:f9d13e09cf11 1127 if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0;
terencez 0:f9d13e09cf11 1128
terencez 0:f9d13e09cf11 1129 *query = coap_pkt->location_query;
terencez 0:f9d13e09cf11 1130 return coap_pkt->location_query_len;
terencez 0:f9d13e09cf11 1131 }
terencez 0:f9d13e09cf11 1132
terencez 0:f9d13e09cf11 1133 int
terencez 0:f9d13e09cf11 1134 coap_set_header_location_query(void *packet, const char *query)
terencez 0:f9d13e09cf11 1135 {
terencez 0:f9d13e09cf11 1136 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1137
terencez 0:f9d13e09cf11 1138 while (query[0]=='?') ++query;
terencez 0:f9d13e09cf11 1139
terencez 0:f9d13e09cf11 1140 coap_pkt->location_query = query;
terencez 0:f9d13e09cf11 1141 coap_pkt->location_query_len = strlen(query);
terencez 0:f9d13e09cf11 1142
terencez 0:f9d13e09cf11 1143 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY);
terencez 0:f9d13e09cf11 1144 return coap_pkt->location_query_len;
terencez 0:f9d13e09cf11 1145 }
terencez 0:f9d13e09cf11 1146 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1147 int
terencez 0:f9d13e09cf11 1148 coap_get_header_observe(void *packet, uint32_t *observe)
terencez 0:f9d13e09cf11 1149 {
terencez 0:f9d13e09cf11 1150 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1151
terencez 0:f9d13e09cf11 1152 if (!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) return 0;
terencez 0:f9d13e09cf11 1153
terencez 0:f9d13e09cf11 1154 *observe = coap_pkt->observe;
terencez 0:f9d13e09cf11 1155 return 1;
terencez 0:f9d13e09cf11 1156 }
terencez 0:f9d13e09cf11 1157
terencez 0:f9d13e09cf11 1158 int
terencez 0:f9d13e09cf11 1159 coap_set_header_observe(void *packet, uint32_t observe)
terencez 0:f9d13e09cf11 1160 {
terencez 0:f9d13e09cf11 1161 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1162
terencez 0:f9d13e09cf11 1163 coap_pkt->observe = 0x00FFFFFF & observe;
terencez 0:f9d13e09cf11 1164 SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE);
terencez 0:f9d13e09cf11 1165 return 1;
terencez 0:f9d13e09cf11 1166 }
terencez 0:f9d13e09cf11 1167 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1168 int
terencez 0:f9d13e09cf11 1169 coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset)
terencez 0:f9d13e09cf11 1170 {
terencez 0:f9d13e09cf11 1171 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1172
terencez 0:f9d13e09cf11 1173 if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) return 0;
terencez 0:f9d13e09cf11 1174
terencez 0:f9d13e09cf11 1175 /* pointers may be NULL to get only specific block parameters */
terencez 0:f9d13e09cf11 1176 if (num!=NULL) *num = coap_pkt->block2_num;
terencez 0:f9d13e09cf11 1177 if (more!=NULL) *more = coap_pkt->block2_more;
terencez 0:f9d13e09cf11 1178 if (size!=NULL) *size = coap_pkt->block2_size;
terencez 0:f9d13e09cf11 1179 if (offset!=NULL) *offset = coap_pkt->block2_offset;
terencez 0:f9d13e09cf11 1180
terencez 0:f9d13e09cf11 1181 return 1;
terencez 0:f9d13e09cf11 1182 }
terencez 0:f9d13e09cf11 1183
terencez 0:f9d13e09cf11 1184 int
terencez 0:f9d13e09cf11 1185 coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size)
terencez 0:f9d13e09cf11 1186 {
terencez 0:f9d13e09cf11 1187 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1188
terencez 0:f9d13e09cf11 1189 if (size<16) return 0;
terencez 0:f9d13e09cf11 1190 if (size>2048) return 0;
terencez 0:f9d13e09cf11 1191 if (num>0x0FFFFF) return 0;
terencez 0:f9d13e09cf11 1192
terencez 0:f9d13e09cf11 1193 coap_pkt->block2_num = num;
terencez 0:f9d13e09cf11 1194 coap_pkt->block2_more = more ? 1 : 0;
terencez 0:f9d13e09cf11 1195 coap_pkt->block2_size = size;
terencez 0:f9d13e09cf11 1196
terencez 0:f9d13e09cf11 1197 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2);
terencez 0:f9d13e09cf11 1198 return 1;
terencez 0:f9d13e09cf11 1199 }
terencez 0:f9d13e09cf11 1200 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1201 int
terencez 0:f9d13e09cf11 1202 coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more, uint16_t *size, uint32_t *offset)
terencez 0:f9d13e09cf11 1203 {
terencez 0:f9d13e09cf11 1204 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1205
terencez 0:f9d13e09cf11 1206 if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) return 0;
terencez 0:f9d13e09cf11 1207
terencez 0:f9d13e09cf11 1208 /* pointers may be NULL to get only specific block parameters */
terencez 0:f9d13e09cf11 1209 if (num!=NULL) *num = coap_pkt->block1_num;
terencez 0:f9d13e09cf11 1210 if (more!=NULL) *more = coap_pkt->block1_more;
terencez 0:f9d13e09cf11 1211 if (size!=NULL) *size = coap_pkt->block1_size;
terencez 0:f9d13e09cf11 1212 if (offset!=NULL) *offset = coap_pkt->block1_offset;
terencez 0:f9d13e09cf11 1213
terencez 0:f9d13e09cf11 1214 return 1;
terencez 0:f9d13e09cf11 1215 }
terencez 0:f9d13e09cf11 1216
terencez 0:f9d13e09cf11 1217 int
terencez 0:f9d13e09cf11 1218 coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size)
terencez 0:f9d13e09cf11 1219 {
terencez 0:f9d13e09cf11 1220 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1221
terencez 0:f9d13e09cf11 1222 if (size<16) return 0;
terencez 0:f9d13e09cf11 1223 if (size>2048) return 0;
terencez 0:f9d13e09cf11 1224 if (num>0x0FFFFF) return 0;
terencez 0:f9d13e09cf11 1225
terencez 0:f9d13e09cf11 1226 coap_pkt->block1_num = num;
terencez 0:f9d13e09cf11 1227 coap_pkt->block1_more = more;
terencez 0:f9d13e09cf11 1228 coap_pkt->block1_size = size;
terencez 0:f9d13e09cf11 1229
terencez 0:f9d13e09cf11 1230 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1);
terencez 0:f9d13e09cf11 1231 return 1;
terencez 0:f9d13e09cf11 1232 }
terencez 0:f9d13e09cf11 1233 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1234 int
terencez 0:f9d13e09cf11 1235 coap_get_header_size(void *packet, uint32_t *size)
terencez 0:f9d13e09cf11 1236 {
terencez 0:f9d13e09cf11 1237 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1238
terencez 0:f9d13e09cf11 1239 if (!IS_OPTION(coap_pkt, COAP_OPTION_SIZE)) return 0;
terencez 0:f9d13e09cf11 1240
terencez 0:f9d13e09cf11 1241 *size = coap_pkt->size;
terencez 0:f9d13e09cf11 1242 return 1;
terencez 0:f9d13e09cf11 1243 }
terencez 0:f9d13e09cf11 1244
terencez 0:f9d13e09cf11 1245 int
terencez 0:f9d13e09cf11 1246 coap_set_header_size(void *packet, uint32_t size)
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 coap_pkt->size = size;
terencez 0:f9d13e09cf11 1251 SET_OPTION(coap_pkt, COAP_OPTION_SIZE);
terencez 0:f9d13e09cf11 1252 return 1;
terencez 0:f9d13e09cf11 1253 }
terencez 0:f9d13e09cf11 1254 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1255 /*- PAYLOAD -------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1256 /*-----------------------------------------------------------------------------------*/
terencez 0:f9d13e09cf11 1257 int
terencez 0:f9d13e09cf11 1258 coap_get_payload(void *packet, const uint8_t **payload)
terencez 0:f9d13e09cf11 1259 {
terencez 0:f9d13e09cf11 1260 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1261
terencez 0:f9d13e09cf11 1262 if (coap_pkt->payload) {
terencez 0:f9d13e09cf11 1263 *payload = coap_pkt->payload;
terencez 0:f9d13e09cf11 1264 return coap_pkt->payload_len;
terencez 0:f9d13e09cf11 1265 } else {
terencez 0:f9d13e09cf11 1266 *payload = NULL;
terencez 0:f9d13e09cf11 1267 return 0;
terencez 0:f9d13e09cf11 1268 }
terencez 0:f9d13e09cf11 1269 }
terencez 0:f9d13e09cf11 1270
terencez 0:f9d13e09cf11 1271 int
terencez 0:f9d13e09cf11 1272 coap_set_payload(void *packet, const void *payload, size_t length)
terencez 0:f9d13e09cf11 1273 {
terencez 0:f9d13e09cf11 1274 coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
terencez 0:f9d13e09cf11 1275
terencez 0:f9d13e09cf11 1276 //PRINTF("setting payload (%u/%u)\n", length, REST_MAX_CHUNK_SIZE);
terencez 0:f9d13e09cf11 1277
terencez 0:f9d13e09cf11 1278 coap_pkt->payload = (uint8_t *) payload;
terencez 0:f9d13e09cf11 1279 coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
terencez 0:f9d13e09cf11 1280
terencez 0:f9d13e09cf11 1281 return coap_pkt->payload_len;
terencez 0:f9d13e09cf11 1282 }
terencez 0:f9d13e09cf11 1283 /*-----------------------------------------------------------------------------------*/