52 #include "lib/random.h" 59 #define LOG_MODULE "coap" 60 #define LOG_LEVEL LOG_LEVEL_COAP 65 static uint16_t current_mid = 0;
67 coap_status_t coap_status_code = NO_ERROR;
68 const char *coap_error_message =
"";
73 coap_log_2(uint16_t value)
82 return result ? result - 1 : result;
86 coap_parse_int_option(uint8_t *bytes,
size_t length)
99 coap_option_nibble(
unsigned int value)
103 }
else if(value <= 0xFF + 13) {
111 coap_set_option_header(
unsigned int delta,
size_t length, uint8_t *buffer)
115 buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
118 buffer[++written] = ((delta - 269) >> 8) & 0xff;
119 buffer[++written] = (delta - 269) & 0xff;
120 }
else if(delta > 12) {
121 buffer[++written] = (delta - 13);
125 buffer[++written] = ((length - 269) >> 8) & 0xff;
126 buffer[++written] = (length - 269) & 0xff;
127 }
else if(length > 12) {
128 buffer[++written] = (length - 13);
131 LOG_DBG(
"WRITTEN %zu B opt header\n", 1 + written);
137 coap_serialize_int_option(
unsigned int number,
unsigned int current_number,
138 uint8_t *buffer, uint32_t value)
142 if(0xFF000000 & value) {
145 if(0xFFFF0000 & value) {
148 if(0xFFFFFF00 & value) {
151 if(0xFFFFFFFF & value) {
154 LOG_DBG(
"OPTION %u (delta %u, len %zu)\n", number, number - current_number,
157 i = coap_set_option_header(number - current_number, i, buffer);
159 if(0xFF000000 & value) {
160 buffer[i++] = (uint8_t)(value >> 24);
162 if(0xFFFF0000 & value) {
163 buffer[i++] = (uint8_t)(value >> 16);
165 if(0xFFFFFF00 & value) {
166 buffer[i++] = (uint8_t)(value >> 8);
168 if(0xFFFFFFFF & value) {
169 buffer[i++] = (uint8_t)(value);
175 coap_serialize_array_option(
unsigned int number,
unsigned int current_number,
176 uint8_t *buffer, uint8_t *array,
size_t length,
181 LOG_DBG(
"ARRAY type %u, len %zu, full [", number, length);
182 LOG_DBG_COAP_STRING((
const char *)array, length);
185 if(split_char !=
'\0') {
187 uint8_t *part_start = array;
188 uint8_t *part_end = NULL;
191 for(j = 0; j <= length + 1; ++j) {
192 LOG_DBG(
"STEP %u/%zu (%c)\n", j, length, array[j]);
193 if(array[j] == split_char || j == length) {
194 part_end = array + j;
195 temp_length = part_end - part_start;
197 i += coap_set_option_header(number - current_number, temp_length,
199 memcpy(&buffer[i], part_start, temp_length);
202 LOG_DBG(
"OPTION type %u, delta %u, len %zu, part [", number,
203 number - current_number, i);
204 LOG_DBG_COAP_STRING((
const char *)part_start, temp_length);
207 current_number = number;
208 part_start = array + j;
212 i += coap_set_option_header(number - current_number, length, &buffer[i]);
213 memcpy(&buffer[i], array, length);
216 LOG_DBG(
"OPTION type %u, delta %u, len %zu\n", number,
217 number - current_number, length);
224 coap_merge_multi_option(
char **dst,
size_t *dst_len, uint8_t *option,
225 size_t option_len,
char separator)
230 (*dst)[*dst_len] = separator;
234 memmove((*dst) + (*dst_len), option, option_len);
236 *dst_len += option_len;
239 *dst = (
char *)option;
240 *dst_len = option_len;
245 coap_get_variable(
const char *buffer,
size_t length,
const char *name,
248 const char *
start = NULL;
249 const char *end = NULL;
250 const char *value_end = NULL;
256 name_len = strlen(name);
257 end = buffer + length;
259 for(start = buffer; start + name_len < end; ++
start) {
260 if((start == buffer || start[-1] ==
'&') && start[name_len] ==
'=' 261 && strncmp(name, start, name_len) == 0) {
264 start += name_len + 1;
267 value_end = (
const char *)memchr(start,
'&', end - start);
268 if(value_end == NULL) {
273 return value_end -
start;
282 coap_init_connection(
void)
291 return ++current_mid;
295 coap_init_message(coap_message_t *coap_pkt, coap_message_type_t type,
296 uint8_t code, uint16_t mid)
299 memset(coap_pkt, 0,
sizeof(coap_message_t));
301 coap_pkt->type = type;
302 coap_pkt->code = code;
307 coap_serialize_message(coap_message_t *coap_pkt, uint8_t *buffer)
310 unsigned int current_number = 0;
313 coap_pkt->buffer = buffer;
314 coap_pkt->version = 1;
316 LOG_DBG(
"-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer);
319 coap_pkt->buffer[0] = 0x00;
320 coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK
321 & (coap_pkt->version) << COAP_HEADER_VERSION_POSITION;
322 coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK
323 & (coap_pkt->type) << COAP_HEADER_TYPE_POSITION;
324 coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK
325 & (coap_pkt->token_len) << COAP_HEADER_TOKEN_LEN_POSITION;
326 coap_pkt->buffer[1] = coap_pkt->code;
327 coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8);
328 coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid);
331 if(!coap_pkt->code) {
332 LOG_DBG_(
"-Done serializing empty message at %p-\n", coap_pkt->buffer);
337 LOG_DBG_(
"Token (len %u)", coap_pkt->token_len);
338 option = coap_pkt->buffer + COAP_HEADER_LEN;
339 for(current_number = 0; current_number < coap_pkt->token_len;
341 LOG_DBG_(
" %02X", coap_pkt->token[current_number]);
342 *option = coap_pkt->token[current_number];
350 LOG_DBG(
"-Serializing options at %p-\n", option);
353 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match,
"If-Match");
354 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host,
'\0',
356 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag,
"ETag");
357 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
362 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe,
"Observe");
363 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port,
"Uri-Port");
364 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path,
'/',
366 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path,
'/',
368 LOG_DBG(
"Serialize content format: %d\n", coap_pkt->content_format);
369 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
371 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age,
"Max-Age");
372 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query,
'&',
374 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT,
accept,
"Accept");
375 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
376 '&',
"Location-Query");
377 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2,
"Block2");
378 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1,
"Block1");
379 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2,
"Size2");
380 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri,
'\0',
382 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme,
'\0',
384 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1,
"Size1");
386 LOG_DBG(
"-Done serializing at %p----\n", option);
389 if((option - coap_pkt->buffer) <= COAP_MAX_HEADER_SIZE) {
391 if(coap_pkt->payload_len) {
395 memmove(option, coap_pkt->payload, coap_pkt->payload_len);
398 coap_pkt->buffer = NULL;
399 coap_error_message =
"Serialized header exceeds COAP_MAX_HEADER_SIZE";
403 LOG_DBG(
"-Done %u B (header len %u, payload len %u)-\n",
404 (
unsigned int)(coap_pkt->payload_len + option - buffer),
405 (
unsigned int)(option - buffer),
406 (
unsigned int)coap_pkt->payload_len);
408 LOG_DBG(
"Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
409 coap_pkt->buffer[0], coap_pkt->buffer[1], coap_pkt->buffer[2],
410 coap_pkt->buffer[3], coap_pkt->buffer[4], coap_pkt->buffer[5],
411 coap_pkt->buffer[6], coap_pkt->buffer[7]);
413 return (option - buffer) + coap_pkt->payload_len;
417 coap_parse_message(coap_message_t *coap_pkt, uint8_t *data, uint16_t data_len)
420 memset(coap_pkt, 0,
sizeof(coap_message_t));
423 coap_pkt->buffer = data;
426 coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])
427 >> COAP_HEADER_VERSION_POSITION;
428 coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])
429 >> COAP_HEADER_TYPE_POSITION;
430 coap_pkt->token_len = (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0])
431 >> COAP_HEADER_TOKEN_LEN_POSITION;
432 coap_pkt->code = coap_pkt->buffer[1];
433 coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3];
435 if(coap_pkt->version != 1) {
436 coap_error_message =
"CoAP version must be 1";
437 return BAD_REQUEST_4_00;
440 if(coap_pkt->token_len > COAP_TOKEN_LEN) {
441 coap_error_message =
"Token Length must not be more than 8";
442 return BAD_REQUEST_4_00;
445 uint8_t *current_option = data + COAP_HEADER_LEN;
447 memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
448 LOG_DBG(
"Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
449 coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1],
450 coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4],
451 coap_pkt->token[5], coap_pkt->token[6], coap_pkt->token[7]
455 memset(coap_pkt->options, 0,
sizeof(coap_pkt->options));
456 current_option += coap_pkt->token_len;
458 unsigned int option_number = 0;
459 unsigned int option_delta = 0;
460 size_t option_length = 0;
462 while(current_option < data + data_len) {
464 if((current_option[0] & 0xF0) == 0xF0) {
465 coap_pkt->payload = ++current_option;
466 coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
469 if(coap_pkt->payload_len > COAP_MAX_CHUNK_SIZE) {
470 coap_pkt->payload_len = COAP_MAX_CHUNK_SIZE;
473 coap_pkt->payload[coap_pkt->payload_len] =
'\0';
478 option_delta = current_option[0] >> 4;
479 option_length = current_option[0] & 0x0F;
482 if(option_delta == 13) {
483 option_delta += current_option[0];
485 }
else if(option_delta == 14) {
487 option_delta += current_option[0] << 8;
489 option_delta += current_option[0];
493 if(option_length == 13) {
494 option_length += current_option[0];
496 }
else if(option_length == 14) {
497 option_length += 255;
498 option_length += current_option[0] << 8;
500 option_length += current_option[0];
504 if(current_option + option_length > data + data_len) {
506 LOG_WARN(
"BAD REQUEST: options outside data message: %u > %u\n",
507 (
unsigned)(current_option + option_length - data), data_len);
508 return BAD_REQUEST_4_00;
511 option_number += option_delta;
513 if(option_number > COAP_OPTION_SIZE1) {
515 LOG_WARN(
"BAD REQUEST: option number too large: %u\n", option_number);
516 return BAD_REQUEST_4_00;
519 LOG_DBG(
"OPTION %u (delta %u, len %zu): ", option_number, option_delta,
522 coap_set_option(coap_pkt, option_number);
524 switch(option_number) {
525 case COAP_OPTION_CONTENT_FORMAT:
526 coap_pkt->content_format = coap_parse_int_option(current_option,
528 LOG_DBG_(
"Content-Format [%u]\n", coap_pkt->content_format);
530 case COAP_OPTION_MAX_AGE:
531 coap_pkt->max_age = coap_parse_int_option(current_option,
533 LOG_DBG_(
"Max-Age [%"PRIu32
"]\n", coap_pkt->max_age);
535 case COAP_OPTION_ETAG:
536 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
537 memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len);
538 LOG_DBG_(
"ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
539 coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
540 coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
541 coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
544 case COAP_OPTION_ACCEPT:
545 coap_pkt->accept = coap_parse_int_option(current_option, option_length);
546 LOG_DBG_(
"Accept [%u]\n", coap_pkt->accept);
548 case COAP_OPTION_IF_MATCH:
550 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
551 memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len);
552 LOG_DBG_(
"If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
553 coap_pkt->if_match_len, coap_pkt->if_match[0],
554 coap_pkt->if_match[1], coap_pkt->if_match[2],
555 coap_pkt->if_match[3], coap_pkt->if_match[4],
556 coap_pkt->if_match[5], coap_pkt->if_match[6],
557 coap_pkt->if_match[7]
560 case COAP_OPTION_IF_NONE_MATCH:
561 coap_pkt->if_none_match = 1;
562 LOG_DBG_(
"If-None-Match\n");
565 case COAP_OPTION_PROXY_URI:
566 #if COAP_PROXY_OPTION_PROCESSING 567 coap_pkt->proxy_uri = (
char *)current_option;
568 coap_pkt->proxy_uri_len = option_length;
570 LOG_DBG_(
"Proxy-Uri NOT IMPLEMENTED [");
571 LOG_DBG_COAP_STRING(coap_pkt->proxy_uri, coap_pkt->proxy_uri_len);
574 coap_error_message =
"This is a constrained server (Contiki)";
575 return PROXYING_NOT_SUPPORTED_5_05;
577 case COAP_OPTION_PROXY_SCHEME:
578 #if COAP_PROXY_OPTION_PROCESSING 579 coap_pkt->proxy_scheme = (
char *)current_option;
580 coap_pkt->proxy_scheme_len = option_length;
582 LOG_DBG_(
"Proxy-Scheme NOT IMPLEMENTED [");
583 LOG_DBG_COAP_STRING(coap_pkt->proxy_scheme, coap_pkt->proxy_scheme_len);
585 coap_error_message =
"This is a constrained server (Contiki)";
586 return PROXYING_NOT_SUPPORTED_5_05;
589 case COAP_OPTION_URI_HOST:
590 coap_pkt->uri_host = (
char *)current_option;
591 coap_pkt->uri_host_len = option_length;
592 LOG_DBG_(
"Uri-Host [");
593 LOG_DBG_COAP_STRING(coap_pkt->uri_host, coap_pkt->uri_host_len);
596 case COAP_OPTION_URI_PORT:
597 coap_pkt->uri_port = coap_parse_int_option(current_option,
599 LOG_DBG_(
"Uri-Port [%u]\n", coap_pkt->uri_port);
601 case COAP_OPTION_URI_PATH:
603 coap_merge_multi_option((
char **)&(coap_pkt->uri_path),
604 &(coap_pkt->uri_path_len), current_option,
606 LOG_DBG_(
"Uri-Path [");
607 LOG_DBG_COAP_STRING(coap_pkt->uri_path, coap_pkt->uri_path_len);
610 case COAP_OPTION_URI_QUERY:
612 coap_merge_multi_option((
char **)&(coap_pkt->uri_query),
613 &(coap_pkt->uri_query_len), current_option,
615 LOG_DBG_(
"Uri-Query[");
616 LOG_DBG_COAP_STRING(coap_pkt->uri_query, coap_pkt->uri_query_len);
620 case COAP_OPTION_LOCATION_PATH:
622 coap_merge_multi_option((
char **)&(coap_pkt->location_path),
623 &(coap_pkt->location_path_len), current_option,
626 LOG_DBG_(
"Location-Path [");
627 LOG_DBG_COAP_STRING(coap_pkt->location_path, coap_pkt->location_path_len);
630 case COAP_OPTION_LOCATION_QUERY:
632 coap_merge_multi_option((
char **)&(coap_pkt->location_query),
633 &(coap_pkt->location_query_len), current_option,
635 LOG_DBG_(
"Location-Query [");
636 LOG_DBG_COAP_STRING(coap_pkt->location_query, coap_pkt->location_query_len);
640 case COAP_OPTION_OBSERVE:
641 coap_pkt->observe = coap_parse_int_option(current_option,
643 LOG_DBG_(
"Observe [%"PRId32
"]\n", coap_pkt->observe);
645 case COAP_OPTION_BLOCK2:
646 coap_pkt->block2_num = coap_parse_int_option(current_option,
648 coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
649 coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
650 coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
651 << (coap_pkt->block2_num & 0x07);
652 coap_pkt->block2_num >>= 4;
653 LOG_DBG_(
"Block2 [%lu%s (%u B/blk)]\n",
654 (
unsigned long)coap_pkt->block2_num,
655 coap_pkt->block2_more ?
"+" :
"", coap_pkt->block2_size);
657 case COAP_OPTION_BLOCK1:
658 coap_pkt->block1_num = coap_parse_int_option(current_option,
660 coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
661 coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
662 coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
663 << (coap_pkt->block1_num & 0x07);
664 coap_pkt->block1_num >>= 4;
665 LOG_DBG_(
"Block1 [%lu%s (%u B/blk)]\n",
666 (
unsigned long)coap_pkt->block1_num,
667 coap_pkt->block1_more ?
"+" :
"", coap_pkt->block1_size);
669 case COAP_OPTION_SIZE2:
670 coap_pkt->size2 = coap_parse_int_option(current_option, option_length);
671 LOG_DBG_(
"Size2 [%"PRIu32
"]\n", coap_pkt->size2);
673 case COAP_OPTION_SIZE1:
674 coap_pkt->size1 = coap_parse_int_option(current_option, option_length);
675 LOG_DBG_(
"Size1 [%"PRIu32
"]\n", coap_pkt->size1);
678 LOG_DBG_(
"unknown (%u)\n", option_number);
680 if(option_number & 1) {
681 coap_error_message =
"Unsupported critical option";
682 return BAD_OPTION_4_02;
686 current_option += option_length;
688 LOG_DBG(
"-Done parsing-------\n");
696 coap_get_query_variable(coap_message_t *coap_pkt,
697 const char *name,
const char **output)
699 if(coap_is_option(coap_pkt, COAP_OPTION_URI_QUERY)) {
700 return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len,
706 coap_get_post_variable(coap_message_t *coap_pkt,
707 const char *name,
const char **output)
709 if(coap_pkt->payload_len) {
710 return coap_get_variable((
const char *)coap_pkt->payload,
711 coap_pkt->payload_len, name, output);
717 coap_set_status_code(coap_message_t *message,
unsigned int code)
720 message->code = (uint8_t)code;
728 coap_set_token(coap_message_t *coap_pkt,
const uint8_t *token,
size_t token_len)
730 coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
731 memcpy(coap_pkt->token, token, coap_pkt->token_len);
733 return coap_pkt->token_len;
739 coap_get_header_content_format(coap_message_t *coap_pkt,
unsigned int *format)
741 if(!coap_is_option(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) {
744 *format = coap_pkt->content_format;
748 coap_set_header_content_format(coap_message_t *coap_pkt,
unsigned int format)
750 coap_pkt->content_format = format;
751 coap_set_option(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
756 coap_get_header_accept(coap_message_t *coap_pkt,
unsigned int *
accept)
758 if(!coap_is_option(coap_pkt, COAP_OPTION_ACCEPT)) {
761 *accept = coap_pkt->accept;
765 coap_set_header_accept(coap_message_t *coap_pkt,
unsigned int accept)
767 coap_pkt->accept =
accept;
768 coap_set_option(coap_pkt, COAP_OPTION_ACCEPT);
773 coap_get_header_max_age(coap_message_t *coap_pkt, uint32_t *age)
775 if(!coap_is_option(coap_pkt, COAP_OPTION_MAX_AGE)) {
776 *age = COAP_DEFAULT_MAX_AGE;
778 *age = coap_pkt->max_age;
782 coap_set_header_max_age(coap_message_t *coap_pkt, uint32_t age)
784 coap_pkt->max_age = age;
785 coap_set_option(coap_pkt, COAP_OPTION_MAX_AGE);
790 coap_get_header_etag(coap_message_t *coap_pkt,
const uint8_t **etag)
792 if(!coap_is_option(coap_pkt, COAP_OPTION_ETAG)) {
795 *etag = coap_pkt->etag;
796 return coap_pkt->etag_len;
799 coap_set_header_etag(coap_message_t *coap_pkt,
const uint8_t *etag,
size_t etag_len)
801 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len);
802 memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
804 coap_set_option(coap_pkt, COAP_OPTION_ETAG);
805 return coap_pkt->etag_len;
810 coap_get_header_if_match(coap_message_t *coap_pkt,
const uint8_t **etag)
812 if(!coap_is_option(coap_pkt, COAP_OPTION_IF_MATCH)) {
815 *etag = coap_pkt->if_match;
816 return coap_pkt->if_match_len;
819 coap_set_header_if_match(coap_message_t *coap_pkt,
const uint8_t *etag,
size_t etag_len)
821 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len);
822 memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
824 coap_set_option(coap_pkt, COAP_OPTION_IF_MATCH);
825 return coap_pkt->if_match_len;
829 coap_get_header_if_none_match(coap_message_t *message)
831 return coap_is_option(message, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
834 coap_set_header_if_none_match(coap_message_t *message)
836 coap_set_option(message, COAP_OPTION_IF_NONE_MATCH);
841 coap_get_header_proxy_uri(coap_message_t *coap_pkt,
const char **uri)
843 if(!coap_is_option(coap_pkt, COAP_OPTION_PROXY_URI)) {
846 *uri = coap_pkt->proxy_uri;
847 return coap_pkt->proxy_uri_len;
850 coap_set_header_proxy_uri(coap_message_t *coap_pkt,
const char *uri)
854 coap_pkt->proxy_uri = uri;
855 coap_pkt->proxy_uri_len = strlen(uri);
857 coap_set_option(coap_pkt, COAP_OPTION_PROXY_URI);
858 return coap_pkt->proxy_uri_len;
862 coap_get_header_uri_host(coap_message_t *coap_pkt,
const char **host)
864 if(!coap_is_option(coap_pkt, COAP_OPTION_URI_HOST)) {
867 *host = coap_pkt->uri_host;
868 return coap_pkt->uri_host_len;
871 coap_set_header_uri_host(coap_message_t *coap_pkt,
const char *host)
873 coap_pkt->uri_host = host;
874 coap_pkt->uri_host_len = strlen(host);
876 coap_set_option(coap_pkt, COAP_OPTION_URI_HOST);
877 return coap_pkt->uri_host_len;
881 coap_get_header_uri_path(coap_message_t *coap_pkt,
const char **path)
883 if(!coap_is_option(coap_pkt, COAP_OPTION_URI_PATH)) {
886 *path = coap_pkt->uri_path;
887 return coap_pkt->uri_path_len;
890 coap_set_header_uri_path(coap_message_t *coap_pkt,
const char *path)
892 while(path[0] ==
'/') {
896 coap_pkt->uri_path = path;
897 coap_pkt->uri_path_len = strlen(path);
899 coap_set_option(coap_pkt, COAP_OPTION_URI_PATH);
900 return coap_pkt->uri_path_len;
904 coap_get_header_uri_query(coap_message_t *coap_pkt,
const char **query)
906 if(!coap_is_option(coap_pkt, COAP_OPTION_URI_QUERY)) {
909 *query = coap_pkt->uri_query;
910 return coap_pkt->uri_query_len;
913 coap_set_header_uri_query(coap_message_t *coap_pkt,
const char *query)
915 while(query[0] ==
'?') {
919 coap_pkt->uri_query = query;
920 coap_pkt->uri_query_len = strlen(query);
922 coap_set_option(coap_pkt, COAP_OPTION_URI_QUERY);
923 return coap_pkt->uri_query_len;
927 coap_get_header_location_path(coap_message_t *coap_pkt,
const char **path)
929 if(!coap_is_option(coap_pkt, COAP_OPTION_LOCATION_PATH)) {
932 *path = coap_pkt->location_path;
933 return coap_pkt->location_path_len;
936 coap_set_header_location_path(coap_message_t *coap_pkt,
const char *path)
940 while(path[0] ==
'/') {
944 if((query = strchr(path,
'?'))) {
945 coap_set_header_location_query(coap_pkt, query + 1);
946 coap_pkt->location_path_len = query - path;
948 coap_pkt->location_path_len = strlen(path);
949 } coap_pkt->location_path = path;
951 if(coap_pkt->location_path_len > 0) {
952 coap_set_option(coap_pkt, COAP_OPTION_LOCATION_PATH);
954 return coap_pkt->location_path_len;
958 coap_get_header_location_query(coap_message_t *coap_pkt,
const char **query)
960 if(!coap_is_option(coap_pkt, COAP_OPTION_LOCATION_QUERY)) {
963 *query = coap_pkt->location_query;
964 return coap_pkt->location_query_len;
967 coap_set_header_location_query(coap_message_t *coap_pkt,
const char *query)
969 while(query[0] ==
'?') {
973 coap_pkt->location_query = query;
974 coap_pkt->location_query_len = strlen(query);
976 coap_set_option(coap_pkt, COAP_OPTION_LOCATION_QUERY);
977 return coap_pkt->location_query_len;
981 coap_get_header_observe(coap_message_t *coap_pkt, uint32_t *observe)
983 if(!coap_is_option(coap_pkt, COAP_OPTION_OBSERVE)) {
986 *observe = coap_pkt->observe;
990 coap_set_header_observe(coap_message_t *coap_pkt, uint32_t observe)
992 coap_pkt->observe = observe;
993 coap_set_option(coap_pkt, COAP_OPTION_OBSERVE);
998 coap_get_header_block2(coap_message_t *coap_pkt, uint32_t *num, uint8_t *more,
999 uint16_t *size, uint32_t *offset)
1001 if(!coap_is_option(coap_pkt, COAP_OPTION_BLOCK2)) {
1006 *num = coap_pkt->block2_num;
1009 *more = coap_pkt->block2_more;
1012 *size = coap_pkt->block2_size;
1014 if(offset != NULL) {
1015 *offset = coap_pkt->block2_offset;
1020 coap_set_header_block2(coap_message_t *coap_pkt, uint32_t num, uint8_t more,
1029 if(num > 0x0FFFFF) {
1032 coap_pkt->block2_num = num;
1033 coap_pkt->block2_more = more ? 1 : 0;
1034 coap_pkt->block2_size = size;
1036 coap_set_option(coap_pkt, COAP_OPTION_BLOCK2);
1041 coap_get_header_block1(coap_message_t *coap_pkt, uint32_t *num, uint8_t *more,
1042 uint16_t *size, uint32_t *offset)
1044 if(!coap_is_option(coap_pkt, COAP_OPTION_BLOCK1)) {
1049 *num = coap_pkt->block1_num;
1052 *more = coap_pkt->block1_more;
1055 *size = coap_pkt->block1_size;
1057 if(offset != NULL) {
1058 *offset = coap_pkt->block1_offset;
1063 coap_set_header_block1(coap_message_t *coap_pkt, uint32_t num, uint8_t more,
1072 if(num > 0x0FFFFF) {
1075 coap_pkt->block1_num = num;
1076 coap_pkt->block1_more = more;
1077 coap_pkt->block1_size = size;
1079 coap_set_option(coap_pkt, COAP_OPTION_BLOCK1);
1084 coap_get_header_size2(coap_message_t *coap_pkt, uint32_t *size)
1086 if(!coap_is_option(coap_pkt, COAP_OPTION_SIZE2)) {
1089 *size = coap_pkt->size2;
1093 coap_set_header_size2(coap_message_t *coap_pkt, uint32_t size)
1095 coap_pkt->size2 = size;
1096 coap_set_option(coap_pkt, COAP_OPTION_SIZE2);
1101 coap_get_header_size1(coap_message_t *coap_pkt, uint32_t *size)
1103 if(!coap_is_option(coap_pkt, COAP_OPTION_SIZE1)) {
1106 *size = coap_pkt->size1;
1110 coap_set_header_size1(coap_message_t *coap_pkt, uint32_t size)
1112 coap_pkt->size1 = size;
1113 coap_set_option(coap_pkt, COAP_OPTION_SIZE1);
1118 coap_get_payload(coap_message_t *coap_pkt,
const uint8_t **payload)
1120 if(payload != NULL) {
1121 *payload = coap_pkt->payload;
1123 return coap_pkt->payload != NULL ? coap_pkt->payload_len : 0;
1126 coap_set_payload(coap_message_t *coap_pkt,
const void *payload,
size_t length)
1128 coap_pkt->payload = (uint8_t *)payload;
1129 coap_pkt->payload_len = MIN(COAP_MAX_CHUNK_SIZE, length);
1131 return coap_pkt->payload_len;
static uint8_t accept(uint8_t in)
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
static void start(void)
Start measurement.
CoAP module for reliable transport
An implementation of the Constrained Application Protocol (RFC 7252).
Default definitions of C compiler quirk work-arounds.
unsigned short random_rand(void)
Generates a new random number using the cc2538 RNG.