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

Committer:
terencez
Date:
Wed Apr 19 11:27:34 2017 +0000
Revision:
0:c2dff8cbb91a
Initial commit

Who changed what in which revision?

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