57 #define LOG_MODULE "coap" 58 #define LOG_LEVEL LOG_LEVEL_COAP 63 static uint16_t current_mid = 0;
65 coap_status_t coap_status_code = NO_ERROR;
66 const char *coap_error_message =
"";
71 coap_log_2(uint16_t value)
80 return result ? result - 1 : result;
84 coap_parse_int_option(uint8_t *bytes,
size_t length)
97 coap_option_nibble(
unsigned int value)
101 }
else if(value <= 0xFF + 13) {
109 coap_set_option_header(
unsigned int delta,
size_t length, uint8_t *buffer)
113 buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
116 buffer[++written] = ((delta - 269) >> 8) & 0xff;
117 buffer[++written] = (delta - 269) & 0xff;
118 }
else if(delta > 12) {
119 buffer[++written] = (delta - 13);
123 buffer[++written] = ((length - 269) >> 8) & 0xff;
124 buffer[++written] = (length - 269) & 0xff;
125 }
else if(length > 12) {
126 buffer[++written] = (length - 13);
129 LOG_DBG(
"WRITTEN %zu B opt header\n", 1 + written);
135 coap_serialize_int_option(
unsigned int number,
unsigned int current_number,
136 uint8_t *buffer, uint32_t value)
140 if(0xFF000000 & value) {
143 if(0xFFFF0000 & value) {
146 if(0xFFFFFF00 & value) {
149 if(0xFFFFFFFF & value) {
152 LOG_DBG(
"OPTION %u (delta %u, len %zu)\n", number, number - current_number,
155 i = coap_set_option_header(number - current_number, i, buffer);
157 if(0xFF000000 & value) {
158 buffer[i++] = (uint8_t)(value >> 24);
160 if(0xFFFF0000 & value) {
161 buffer[i++] = (uint8_t)(value >> 16);
163 if(0xFFFFFF00 & value) {
164 buffer[i++] = (uint8_t)(value >> 8);
166 if(0xFFFFFFFF & value) {
167 buffer[i++] = (uint8_t)(value);
173 coap_serialize_array_option(
unsigned int number,
unsigned int current_number,
174 uint8_t *buffer, uint8_t *array,
size_t length,
179 LOG_DBG(
"ARRAY type %u, len %zu, full [", number, length);
180 LOG_DBG_COAP_STRING((
const char *)array, length);
183 if(split_char !=
'\0') {
185 uint8_t *part_start = array;
186 uint8_t *part_end = NULL;
189 for(j = 0; j <= length + 1; ++j) {
190 LOG_DBG(
"STEP %u/%zu (%c)\n", j, length, array[j]);
191 if(array[j] == split_char || j == length) {
192 part_end = array + j;
193 temp_length = part_end - part_start;
195 i += coap_set_option_header(number - current_number, temp_length,
197 memcpy(&buffer[i], part_start, temp_length);
200 LOG_DBG(
"OPTION type %u, delta %u, len %zu, part [", number,
201 number - current_number, i);
202 LOG_DBG_COAP_STRING((
const char *)part_start, temp_length);
205 current_number = number;
206 part_start = array + j;
210 i += coap_set_option_header(number - current_number, length, &buffer[i]);
211 memcpy(&buffer[i], array, length);
214 LOG_DBG(
"OPTION type %u, delta %u, len %zu\n", number,
215 number - current_number, length);
222 coap_merge_multi_option(
char **dst,
size_t *dst_len, uint8_t *option,
223 size_t option_len,
char separator)
228 (*dst)[*dst_len] = separator;
232 memmove((*dst) + (*dst_len), option, option_len);
234 *dst_len += option_len;
237 *dst = (
char *)option;
238 *dst_len = option_len;
243 coap_get_variable(
const char *buffer,
size_t length,
const char *name,
246 const char *
start = NULL;
247 const char *end = NULL;
248 const char *value_end = NULL;
254 name_len = strlen(name);
255 end = buffer + length;
257 for(start = buffer; start + name_len < end; ++
start) {
258 if((start == buffer || start[-1] ==
'&') && start[name_len] ==
'=' 259 && strncmp(name, start, name_len) == 0) {
262 start += name_len + 1;
265 value_end = (
const char *)memchr(start,
'&', end - start);
266 if(value_end == NULL) {
271 return value_end -
start;
280 coap_init_connection(
void)
283 current_mid = rand();
289 return ++current_mid;
293 coap_init_message(coap_message_t *coap_pkt, coap_message_type_t type,
294 uint8_t code, uint16_t mid)
297 memset(coap_pkt, 0,
sizeof(coap_message_t));
299 coap_pkt->type = type;
300 coap_pkt->code = code;
305 coap_serialize_message(coap_message_t *coap_pkt, uint8_t *buffer)
308 unsigned int current_number = 0;
311 coap_pkt->buffer = buffer;
312 coap_pkt->version = 1;
314 LOG_DBG(
"-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer);
317 coap_pkt->buffer[0] = 0x00;
318 coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK
319 & (coap_pkt->version) << COAP_HEADER_VERSION_POSITION;
320 coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK
321 & (coap_pkt->type) << COAP_HEADER_TYPE_POSITION;
322 coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK
323 & (coap_pkt->token_len) << COAP_HEADER_TOKEN_LEN_POSITION;
324 coap_pkt->buffer[1] = coap_pkt->code;
325 coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8);
326 coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid);
329 if(!coap_pkt->code) {
330 LOG_DBG_(
"-Done serializing empty message at %p-\n", coap_pkt->buffer);
335 LOG_DBG_(
"Token (len %u)", coap_pkt->token_len);
336 option = coap_pkt->buffer + COAP_HEADER_LEN;
337 for(current_number = 0; current_number < coap_pkt->token_len;
339 LOG_DBG_(
" %02X", coap_pkt->token[current_number]);
340 *option = coap_pkt->token[current_number];
348 LOG_DBG(
"-Serializing options at %p-\n", option);
351 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match,
"If-Match");
352 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host,
'\0',
354 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag,
"ETag");
355 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
360 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe,
"Observe");
361 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port,
"Uri-Port");
362 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path,
'/',
364 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path,
'/',
366 LOG_DBG(
"Serialize content format: %d\n", coap_pkt->content_format);
367 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
369 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age,
"Max-Age");
370 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query,
'&',
372 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT,
accept,
"Accept");
373 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
374 '&',
"Location-Query");
375 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2,
"Block2");
376 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1,
"Block1");
377 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2,
"Size2");
378 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri,
'\0',
380 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme,
'\0',
382 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1,
"Size1");
384 LOG_DBG(
"-Done serializing at %p----\n", option);
387 if((option - coap_pkt->buffer) <= COAP_MAX_HEADER_SIZE) {
389 if(coap_pkt->payload_len) {
393 memmove(option, coap_pkt->payload, coap_pkt->payload_len);
396 coap_pkt->buffer = NULL;
397 coap_error_message =
"Serialized header exceeds COAP_MAX_HEADER_SIZE";
401 LOG_DBG(
"-Done %u B (header len %u, payload len %u)-\n",
402 (
unsigned int)(coap_pkt->payload_len + option - buffer),
403 (
unsigned int)(option - buffer),
404 (
unsigned int)coap_pkt->payload_len);
406 LOG_DBG(
"Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
407 coap_pkt->buffer[0], coap_pkt->buffer[1], coap_pkt->buffer[2],
408 coap_pkt->buffer[3], coap_pkt->buffer[4], coap_pkt->buffer[5],
409 coap_pkt->buffer[6], coap_pkt->buffer[7]);
411 return (option - buffer) + coap_pkt->payload_len;
415 coap_parse_message(coap_message_t *coap_pkt, uint8_t *data, uint16_t data_len)
418 memset(coap_pkt, 0,
sizeof(coap_message_t));
421 coap_pkt->buffer = data;
424 coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])
425 >> COAP_HEADER_VERSION_POSITION;
426 coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])
427 >> COAP_HEADER_TYPE_POSITION;
428 coap_pkt->token_len = (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0])
429 >> COAP_HEADER_TOKEN_LEN_POSITION;
430 coap_pkt->code = coap_pkt->buffer[1];
431 coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3];
433 if(coap_pkt->version != 1) {
434 coap_error_message =
"CoAP version must be 1";
435 return BAD_REQUEST_4_00;
438 if(coap_pkt->token_len > COAP_TOKEN_LEN) {
439 coap_error_message =
"Token Length must not be more than 8";
440 return BAD_REQUEST_4_00;
443 uint8_t *current_option = data + COAP_HEADER_LEN;
445 memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
446 LOG_DBG(
"Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
447 coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1],
448 coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4],
449 coap_pkt->token[5], coap_pkt->token[6], coap_pkt->token[7]
453 memset(coap_pkt->options, 0,
sizeof(coap_pkt->options));
454 current_option += coap_pkt->token_len;
456 unsigned int option_number = 0;
457 unsigned int option_delta = 0;
458 size_t option_length = 0;
460 while(current_option < data + data_len) {
462 if((current_option[0] & 0xF0) == 0xF0) {
463 coap_pkt->payload = ++current_option;
464 coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
467 if(coap_pkt->payload_len > COAP_MAX_CHUNK_SIZE) {
468 coap_pkt->payload_len = COAP_MAX_CHUNK_SIZE;
471 coap_pkt->payload[coap_pkt->payload_len] =
'\0';
476 option_delta = current_option[0] >> 4;
477 option_length = current_option[0] & 0x0F;
480 if(option_delta == 13) {
481 option_delta += current_option[0];
483 }
else if(option_delta == 14) {
485 option_delta += current_option[0] << 8;
487 option_delta += current_option[0];
491 if(option_length == 13) {
492 option_length += current_option[0];
494 }
else if(option_length == 14) {
495 option_length += 255;
496 option_length += current_option[0] << 8;
498 option_length += current_option[0];
502 if(current_option + option_length > data + data_len) {
504 LOG_WARN(
"BAD REQUEST: options outside data message: %u > %u\n",
505 (
unsigned)(current_option + option_length - data), data_len);
506 return BAD_REQUEST_4_00;
509 option_number += option_delta;
511 if(option_number > COAP_OPTION_SIZE1) {
513 LOG_WARN(
"BAD REQUEST: option number too large: %u\n", option_number);
514 return BAD_REQUEST_4_00;
517 LOG_DBG(
"OPTION %u (delta %u, len %zu): ", option_number, option_delta,
520 coap_set_option(coap_pkt, option_number);
522 switch(option_number) {
523 case COAP_OPTION_CONTENT_FORMAT:
524 coap_pkt->content_format = coap_parse_int_option(current_option,
526 LOG_DBG_(
"Content-Format [%u]\n", coap_pkt->content_format);
528 case COAP_OPTION_MAX_AGE:
529 coap_pkt->max_age = coap_parse_int_option(current_option,
531 LOG_DBG_(
"Max-Age [%"PRIu32
"]\n", coap_pkt->max_age);
533 case COAP_OPTION_ETAG:
534 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
535 memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len);
536 LOG_DBG_(
"ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
537 coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
538 coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
539 coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
542 case COAP_OPTION_ACCEPT:
543 coap_pkt->accept = coap_parse_int_option(current_option, option_length);
544 LOG_DBG_(
"Accept [%u]\n", coap_pkt->accept);
546 case COAP_OPTION_IF_MATCH:
548 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
549 memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len);
550 LOG_DBG_(
"If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
551 coap_pkt->if_match_len, coap_pkt->if_match[0],
552 coap_pkt->if_match[1], coap_pkt->if_match[2],
553 coap_pkt->if_match[3], coap_pkt->if_match[4],
554 coap_pkt->if_match[5], coap_pkt->if_match[6],
555 coap_pkt->if_match[7]
558 case COAP_OPTION_IF_NONE_MATCH:
559 coap_pkt->if_none_match = 1;
560 LOG_DBG_(
"If-None-Match\n");
563 case COAP_OPTION_PROXY_URI:
564 #if COAP_PROXY_OPTION_PROCESSING 565 coap_pkt->proxy_uri = (
char *)current_option;
566 coap_pkt->proxy_uri_len = option_length;
568 LOG_DBG_(
"Proxy-Uri NOT IMPLEMENTED [");
569 LOG_DBG_COAP_STRING(coap_pkt->proxy_uri, coap_pkt->proxy_uri_len);
572 coap_error_message =
"This is a constrained server (Contiki)";
573 return PROXYING_NOT_SUPPORTED_5_05;
575 case COAP_OPTION_PROXY_SCHEME:
576 #if COAP_PROXY_OPTION_PROCESSING 577 coap_pkt->proxy_scheme = (
char *)current_option;
578 coap_pkt->proxy_scheme_len = option_length;
580 LOG_DBG_(
"Proxy-Scheme NOT IMPLEMENTED [");
581 LOG_DBG_COAP_STRING(coap_pkt->proxy_scheme, coap_pkt->proxy_scheme_len);
583 coap_error_message =
"This is a constrained server (Contiki)";
584 return PROXYING_NOT_SUPPORTED_5_05;
587 case COAP_OPTION_URI_HOST:
588 coap_pkt->uri_host = (
char *)current_option;
589 coap_pkt->uri_host_len = option_length;
590 LOG_DBG_(
"Uri-Host [");
591 LOG_DBG_COAP_STRING(coap_pkt->uri_host, coap_pkt->uri_host_len);
594 case COAP_OPTION_URI_PORT:
595 coap_pkt->uri_port = coap_parse_int_option(current_option,
597 LOG_DBG_(
"Uri-Port [%u]\n", coap_pkt->uri_port);
599 case COAP_OPTION_URI_PATH:
601 coap_merge_multi_option((
char **)&(coap_pkt->uri_path),
602 &(coap_pkt->uri_path_len), current_option,
604 LOG_DBG_(
"Uri-Path [");
605 LOG_DBG_COAP_STRING(coap_pkt->uri_path, coap_pkt->uri_path_len);
608 case COAP_OPTION_URI_QUERY:
610 coap_merge_multi_option((
char **)&(coap_pkt->uri_query),
611 &(coap_pkt->uri_query_len), current_option,
613 LOG_DBG_(
"Uri-Query[");
614 LOG_DBG_COAP_STRING(coap_pkt->uri_query, coap_pkt->uri_query_len);
618 case COAP_OPTION_LOCATION_PATH:
620 coap_merge_multi_option((
char **)&(coap_pkt->location_path),
621 &(coap_pkt->location_path_len), current_option,
624 LOG_DBG_(
"Location-Path [");
625 LOG_DBG_COAP_STRING(coap_pkt->location_path, coap_pkt->location_path_len);
628 case COAP_OPTION_LOCATION_QUERY:
630 coap_merge_multi_option((
char **)&(coap_pkt->location_query),
631 &(coap_pkt->location_query_len), current_option,
633 LOG_DBG_(
"Location-Query [");
634 LOG_DBG_COAP_STRING(coap_pkt->location_query, coap_pkt->location_query_len);
638 case COAP_OPTION_OBSERVE:
639 coap_pkt->observe = coap_parse_int_option(current_option,
641 LOG_DBG_(
"Observe [%"PRId32
"]\n", coap_pkt->observe);
643 case COAP_OPTION_BLOCK2:
644 coap_pkt->block2_num = coap_parse_int_option(current_option,
646 coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
647 coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
648 coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
649 << (coap_pkt->block2_num & 0x07);
650 coap_pkt->block2_num >>= 4;
651 LOG_DBG_(
"Block2 [%lu%s (%u B/blk)]\n",
652 (
unsigned long)coap_pkt->block2_num,
653 coap_pkt->block2_more ?
"+" :
"", coap_pkt->block2_size);
655 case COAP_OPTION_BLOCK1:
656 coap_pkt->block1_num = coap_parse_int_option(current_option,
658 coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
659 coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
660 coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
661 << (coap_pkt->block1_num & 0x07);
662 coap_pkt->block1_num >>= 4;
663 LOG_DBG_(
"Block1 [%lu%s (%u B/blk)]\n",
664 (
unsigned long)coap_pkt->block1_num,
665 coap_pkt->block1_more ?
"+" :
"", coap_pkt->block1_size);
667 case COAP_OPTION_SIZE2:
668 coap_pkt->size2 = coap_parse_int_option(current_option, option_length);
669 LOG_DBG_(
"Size2 [%"PRIu32
"]\n", coap_pkt->size2);
671 case COAP_OPTION_SIZE1:
672 coap_pkt->size1 = coap_parse_int_option(current_option, option_length);
673 LOG_DBG_(
"Size1 [%"PRIu32
"]\n", coap_pkt->size1);
676 LOG_DBG_(
"unknown (%u)\n", option_number);
678 if(option_number & 1) {
679 coap_error_message =
"Unsupported critical option";
680 return BAD_OPTION_4_02;
684 current_option += option_length;
686 LOG_DBG(
"-Done parsing-------\n");
694 coap_get_query_variable(coap_message_t *coap_pkt,
695 const char *name,
const char **output)
697 if(coap_is_option(coap_pkt, COAP_OPTION_URI_QUERY)) {
698 return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len,
704 coap_get_post_variable(coap_message_t *coap_pkt,
705 const char *name,
const char **output)
707 if(coap_pkt->payload_len) {
708 return coap_get_variable((
const char *)coap_pkt->payload,
709 coap_pkt->payload_len, name, output);
715 coap_set_status_code(coap_message_t *message,
unsigned int code)
718 message->code = (uint8_t)code;
726 coap_set_token(coap_message_t *coap_pkt,
const uint8_t *token,
size_t token_len)
728 coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
729 memcpy(coap_pkt->token, token, coap_pkt->token_len);
731 return coap_pkt->token_len;
737 coap_get_header_content_format(coap_message_t *coap_pkt,
unsigned int *format)
739 if(!coap_is_option(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) {
742 *format = coap_pkt->content_format;
746 coap_set_header_content_format(coap_message_t *coap_pkt,
unsigned int format)
748 coap_pkt->content_format = format;
749 coap_set_option(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
754 coap_get_header_accept(coap_message_t *coap_pkt,
unsigned int *
accept)
756 if(!coap_is_option(coap_pkt, COAP_OPTION_ACCEPT)) {
759 *accept = coap_pkt->accept;
763 coap_set_header_accept(coap_message_t *coap_pkt,
unsigned int accept)
765 coap_pkt->accept =
accept;
766 coap_set_option(coap_pkt, COAP_OPTION_ACCEPT);
771 coap_get_header_max_age(coap_message_t *coap_pkt, uint32_t *age)
773 if(!coap_is_option(coap_pkt, COAP_OPTION_MAX_AGE)) {
774 *age = COAP_DEFAULT_MAX_AGE;
776 *age = coap_pkt->max_age;
780 coap_set_header_max_age(coap_message_t *coap_pkt, uint32_t age)
782 coap_pkt->max_age = age;
783 coap_set_option(coap_pkt, COAP_OPTION_MAX_AGE);
788 coap_get_header_etag(coap_message_t *coap_pkt,
const uint8_t **etag)
790 if(!coap_is_option(coap_pkt, COAP_OPTION_ETAG)) {
793 *etag = coap_pkt->etag;
794 return coap_pkt->etag_len;
797 coap_set_header_etag(coap_message_t *coap_pkt,
const uint8_t *etag,
size_t etag_len)
799 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len);
800 memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
802 coap_set_option(coap_pkt, COAP_OPTION_ETAG);
803 return coap_pkt->etag_len;
808 coap_get_header_if_match(coap_message_t *coap_pkt,
const uint8_t **etag)
810 if(!coap_is_option(coap_pkt, COAP_OPTION_IF_MATCH)) {
813 *etag = coap_pkt->if_match;
814 return coap_pkt->if_match_len;
817 coap_set_header_if_match(coap_message_t *coap_pkt,
const uint8_t *etag,
size_t etag_len)
819 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len);
820 memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
822 coap_set_option(coap_pkt, COAP_OPTION_IF_MATCH);
823 return coap_pkt->if_match_len;
827 coap_get_header_if_none_match(coap_message_t *message)
829 return coap_is_option(message, COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
832 coap_set_header_if_none_match(coap_message_t *message)
834 coap_set_option(message, COAP_OPTION_IF_NONE_MATCH);
839 coap_get_header_proxy_uri(coap_message_t *coap_pkt,
const char **uri)
841 if(!coap_is_option(coap_pkt, COAP_OPTION_PROXY_URI)) {
844 *uri = coap_pkt->proxy_uri;
845 return coap_pkt->proxy_uri_len;
848 coap_set_header_proxy_uri(coap_message_t *coap_pkt,
const char *uri)
852 coap_pkt->proxy_uri = uri;
853 coap_pkt->proxy_uri_len = strlen(uri);
855 coap_set_option(coap_pkt, COAP_OPTION_PROXY_URI);
856 return coap_pkt->proxy_uri_len;
860 coap_get_header_uri_host(coap_message_t *coap_pkt,
const char **host)
862 if(!coap_is_option(coap_pkt, COAP_OPTION_URI_HOST)) {
865 *host = coap_pkt->uri_host;
866 return coap_pkt->uri_host_len;
869 coap_set_header_uri_host(coap_message_t *coap_pkt,
const char *host)
871 coap_pkt->uri_host = host;
872 coap_pkt->uri_host_len = strlen(host);
874 coap_set_option(coap_pkt, COAP_OPTION_URI_HOST);
875 return coap_pkt->uri_host_len;
879 coap_get_header_uri_path(coap_message_t *coap_pkt,
const char **path)
881 if(!coap_is_option(coap_pkt, COAP_OPTION_URI_PATH)) {
884 *path = coap_pkt->uri_path;
885 return coap_pkt->uri_path_len;
888 coap_set_header_uri_path(coap_message_t *coap_pkt,
const char *path)
890 while(path[0] ==
'/') {
894 coap_pkt->uri_path = path;
895 coap_pkt->uri_path_len = strlen(path);
897 coap_set_option(coap_pkt, COAP_OPTION_URI_PATH);
898 return coap_pkt->uri_path_len;
902 coap_get_header_uri_query(coap_message_t *coap_pkt,
const char **query)
904 if(!coap_is_option(coap_pkt, COAP_OPTION_URI_QUERY)) {
907 *query = coap_pkt->uri_query;
908 return coap_pkt->uri_query_len;
911 coap_set_header_uri_query(coap_message_t *coap_pkt,
const char *query)
913 while(query[0] ==
'?') {
917 coap_pkt->uri_query = query;
918 coap_pkt->uri_query_len = strlen(query);
920 coap_set_option(coap_pkt, COAP_OPTION_URI_QUERY);
921 return coap_pkt->uri_query_len;
925 coap_get_header_location_path(coap_message_t *coap_pkt,
const char **path)
927 if(!coap_is_option(coap_pkt, COAP_OPTION_LOCATION_PATH)) {
930 *path = coap_pkt->location_path;
931 return coap_pkt->location_path_len;
934 coap_set_header_location_path(coap_message_t *coap_pkt,
const char *path)
938 while(path[0] ==
'/') {
942 if((query = strchr(path,
'?'))) {
943 coap_set_header_location_query(coap_pkt, query + 1);
944 coap_pkt->location_path_len = query - path;
946 coap_pkt->location_path_len = strlen(path);
947 } coap_pkt->location_path = path;
949 if(coap_pkt->location_path_len > 0) {
950 coap_set_option(coap_pkt, COAP_OPTION_LOCATION_PATH);
952 return coap_pkt->location_path_len;
956 coap_get_header_location_query(coap_message_t *coap_pkt,
const char **query)
958 if(!coap_is_option(coap_pkt, COAP_OPTION_LOCATION_QUERY)) {
961 *query = coap_pkt->location_query;
962 return coap_pkt->location_query_len;
965 coap_set_header_location_query(coap_message_t *coap_pkt,
const char *query)
967 while(query[0] ==
'?') {
971 coap_pkt->location_query = query;
972 coap_pkt->location_query_len = strlen(query);
974 coap_set_option(coap_pkt, COAP_OPTION_LOCATION_QUERY);
975 return coap_pkt->location_query_len;
979 coap_get_header_observe(coap_message_t *coap_pkt, uint32_t *observe)
981 if(!coap_is_option(coap_pkt, COAP_OPTION_OBSERVE)) {
984 *observe = coap_pkt->observe;
988 coap_set_header_observe(coap_message_t *coap_pkt, uint32_t observe)
990 coap_pkt->observe = observe;
991 coap_set_option(coap_pkt, COAP_OPTION_OBSERVE);
996 coap_get_header_block2(coap_message_t *coap_pkt, uint32_t *num, uint8_t *more,
997 uint16_t *size, uint32_t *offset)
999 if(!coap_is_option(coap_pkt, COAP_OPTION_BLOCK2)) {
1004 *num = coap_pkt->block2_num;
1007 *more = coap_pkt->block2_more;
1010 *size = coap_pkt->block2_size;
1012 if(offset != NULL) {
1013 *offset = coap_pkt->block2_offset;
1018 coap_set_header_block2(coap_message_t *coap_pkt, uint32_t num, uint8_t more,
1027 if(num > 0x0FFFFF) {
1030 coap_pkt->block2_num = num;
1031 coap_pkt->block2_more = more ? 1 : 0;
1032 coap_pkt->block2_size = size;
1034 coap_set_option(coap_pkt, COAP_OPTION_BLOCK2);
1039 coap_get_header_block1(coap_message_t *coap_pkt, uint32_t *num, uint8_t *more,
1040 uint16_t *size, uint32_t *offset)
1042 if(!coap_is_option(coap_pkt, COAP_OPTION_BLOCK1)) {
1047 *num = coap_pkt->block1_num;
1050 *more = coap_pkt->block1_more;
1053 *size = coap_pkt->block1_size;
1055 if(offset != NULL) {
1056 *offset = coap_pkt->block1_offset;
1061 coap_set_header_block1(coap_message_t *coap_pkt, uint32_t num, uint8_t more,
1070 if(num > 0x0FFFFF) {
1073 coap_pkt->block1_num = num;
1074 coap_pkt->block1_more = more;
1075 coap_pkt->block1_size = size;
1077 coap_set_option(coap_pkt, COAP_OPTION_BLOCK1);
1082 coap_get_header_size2(coap_message_t *coap_pkt, uint32_t *size)
1084 if(!coap_is_option(coap_pkt, COAP_OPTION_SIZE2)) {
1087 *size = coap_pkt->size2;
1091 coap_set_header_size2(coap_message_t *coap_pkt, uint32_t size)
1093 coap_pkt->size2 = size;
1094 coap_set_option(coap_pkt, COAP_OPTION_SIZE2);
1099 coap_get_header_size1(coap_message_t *coap_pkt, uint32_t *size)
1101 if(!coap_is_option(coap_pkt, COAP_OPTION_SIZE1)) {
1104 *size = coap_pkt->size1;
1108 coap_set_header_size1(coap_message_t *coap_pkt, uint32_t size)
1110 coap_pkt->size1 = size;
1111 coap_set_option(coap_pkt, COAP_OPTION_SIZE1);
1116 coap_get_payload(coap_message_t *coap_pkt,
const uint8_t **payload)
1118 if(payload != NULL) {
1119 *payload = coap_pkt->payload;
1121 return coap_pkt->payload != NULL ? coap_pkt->payload_len : 0;
1124 coap_set_payload(coap_message_t *coap_pkt,
const void *payload,
size_t length)
1126 coap_pkt->payload = (uint8_t *)payload;
1127 coap_pkt->payload_len = MIN(COAP_MAX_CHUNK_SIZE, length);
1129 return coap_pkt->payload_len;
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.
static uint8_t accept(uint8_t in)
Processes an incoming or outgoing multicast message and determines whether it should be dropped or ac...
CoAP module for reliable transport
An implementation of the Constrained Application Protocol (RFC 7252).
Default definitions of C compiler quirk work-arounds.