42 #include "contiki-net.h"
50 #define PRINTF(...) printf(__VA_ARGS__)
51 #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])
52 #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])
55 #define PRINT6ADDR(addr)
56 #define PRINTLLADDR(addr)
63 static uint16_t current_mid = 0;
65 coap_status_t erbium_status_code = NO_ERROR;
66 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 unsigned int *x = δ
120 buffer[++written] = (*x - 269) >> 8;
121 buffer[++written] = (*x - 269);
123 buffer[++written] = (*x - 13);
125 }
while(x != &length && (x = &length));
127 PRINTF(
"WRITTEN %u B opt header\n", 1 + written);
133 coap_serialize_int_option(
unsigned int number,
unsigned int current_number,
134 uint8_t *buffer, uint32_t value)
138 if(0xFF000000 & value) {
141 if(0xFFFF0000 & value) {
144 if(0xFFFFFF00 & value) {
147 if(0xFFFFFFFF & value) {
150 PRINTF(
"OPTION %u (delta %u, len %u)\n", number, number - current_number,
153 i = coap_set_option_header(number - current_number, i, buffer);
155 if(0xFF000000 & value) {
156 buffer[i++] = (uint8_t)(value >> 24);
158 if(0xFFFF0000 & value) {
159 buffer[i++] = (uint8_t)(value >> 16);
161 if(0xFFFFFF00 & value) {
162 buffer[i++] = (uint8_t)(value >> 8);
164 if(0xFFFFFFFF & value) {
165 buffer[i++] = (uint8_t)(value);
171 coap_serialize_array_option(
unsigned int number,
unsigned int current_number,
172 uint8_t *buffer, uint8_t *array,
size_t length,
177 PRINTF(
"ARRAY type %u, len %u, full [%.*s]\n", number, length, length,
180 if(split_char !=
'\0') {
182 uint8_t *part_start = array;
183 uint8_t *part_end =
NULL;
186 for(j = 0; j <= length + 1; ++j) {
187 PRINTF(
"STEP %u/%u (%c)\n", j, length, array[j]);
188 if(array[j] == split_char || j == length) {
189 part_end = array + j;
190 temp_length = part_end - part_start;
192 i += coap_set_option_header(number - current_number, temp_length,
194 memcpy(&buffer[i], part_start, temp_length);
197 PRINTF(
"OPTION type %u, delta %u, len %u, part [%.*s]\n", number,
198 number - current_number, i, temp_length, part_start);
201 current_number = number;
202 part_start = array + j;
206 i += coap_set_option_header(number - current_number, length, &buffer[i]);
207 memcpy(&buffer[i], array, length);
210 PRINTF(
"OPTION type %u, delta %u, len %u\n", number,
211 number - current_number, length);
218 coap_merge_multi_option(
char **dst,
size_t *dst_len, uint8_t *option,
219 size_t option_len,
char separator)
224 (*dst)[*dst_len] = separator;
228 memmove((*dst) + (*dst_len), option, option_len);
230 *dst_len += option_len;
233 *dst = (
char *)option;
234 *dst_len = option_len;
239 coap_get_variable(
const char *buffer,
size_t length,
const char *name,
242 const char *start =
NULL;
243 const char *end =
NULL;
244 const char *value_end =
NULL;
250 name_len = strlen(name);
251 end = buffer + length;
253 for(start = buffer; start + name_len < end; ++start) {
254 if((start == buffer || start[-1] ==
'&') && start[name_len] ==
'='
255 && strncmp(name, start, name_len) == 0) {
258 start += name_len + 1;
261 value_end = (
const char *)memchr(start,
'&', end - start);
262 if(value_end ==
NULL) {
267 return value_end - start;
276 coap_init_connection(uint16_t port)
281 PRINTF(
"Listening on port %u\n", uip_ntohs(udp_conn->
lport));
290 return ++current_mid;
294 coap_init_message(
void *packet, coap_message_type_t type, uint8_t code,
297 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
300 memset(coap_pkt, 0,
sizeof(coap_packet_t));
302 coap_pkt->type = type;
303 coap_pkt->code = code;
308 coap_serialize_message(
void *packet, uint8_t *buffer)
310 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
312 unsigned int current_number = 0;
315 coap_pkt->buffer = buffer;
316 coap_pkt->version = 1;
318 PRINTF(
"-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer);
321 coap_pkt->buffer[0] = 0x00;
322 coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK
323 & (coap_pkt->version) << COAP_HEADER_VERSION_POSITION;
324 coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK
325 & (coap_pkt->type) << COAP_HEADER_TYPE_POSITION;
326 coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK
327 & (coap_pkt->token_len) << COAP_HEADER_TOKEN_LEN_POSITION;
328 coap_pkt->buffer[1] = coap_pkt->code;
329 coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8);
330 coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid);
333 if(!coap_pkt->code) {
334 PRINTF(
"-Done serializing empty message at %p-\n", option);
339 PRINTF(
"Token (len %u)", coap_pkt->token_len);
340 option = coap_pkt->buffer + COAP_HEADER_LEN;
341 for(current_number = 0; current_number < coap_pkt->token_len;
343 PRINTF(
" %02X", coap_pkt->token[current_number]);
344 *option = coap_pkt->token[current_number];
352 PRINTF(
"-Serializing options at %p-\n", option);
355 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match,
"If-Match");
356 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host,
'\0',
358 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag,
"ETag");
359 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
364 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe,
"Observe");
365 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port,
"Uri-Port");
366 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path,
'/',
368 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path,
'/',
370 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
372 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age,
"Max-Age");
373 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query,
'&',
375 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT, accept,
"Accept");
376 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
377 '&',
"Location-Query");
378 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2,
"Block2");
379 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1,
"Block1");
380 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2,
"Size2");
381 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri,
'\0',
383 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme,
'\0',
385 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1,
"Size1");
387 PRINTF(
"-Done serializing at %p----\n", option);
390 if((option - coap_pkt->buffer) <= COAP_MAX_HEADER_SIZE) {
392 if(coap_pkt->payload_len) {
396 memmove(option, coap_pkt->payload, coap_pkt->payload_len);
399 coap_pkt->buffer =
NULL;
400 coap_error_message =
"Serialized header exceeds COAP_MAX_HEADER_SIZE";
404 PRINTF(
"-Done %u B (header len %u, payload len %u)-\n",
405 coap_pkt->payload_len + option - buffer, option - buffer,
406 coap_pkt->payload_len);
408 PRINTF(
"Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
414 coap_pkt->buffer[5], coap_pkt->buffer[6], coap_pkt->buffer[7]
417 return (option - buffer) + coap_pkt->payload_len;
421 coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data,
426 udp_conn->
rport = port;
428 uip_udp_packet_send(udp_conn, data, length);
430 PRINTF(
"-sent UDP datagram (%u)-\n", length);
438 coap_parse_message(
void *packet, uint8_t *data, uint16_t data_len)
440 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
443 memset(coap_pkt, 0,
sizeof(coap_packet_t));
446 coap_pkt->buffer = data;
449 coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])
450 >> COAP_HEADER_VERSION_POSITION;
451 coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])
452 >> COAP_HEADER_TYPE_POSITION;
453 coap_pkt->token_len =
455 (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->
456 buffer[0]) >> COAP_HEADER_TOKEN_LEN_POSITION);
457 coap_pkt->code = coap_pkt->buffer[1];
458 coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3];
460 if(coap_pkt->version != 1) {
461 coap_error_message =
"CoAP version must be 1";
462 return BAD_REQUEST_4_00;
465 uint8_t *current_option = data + COAP_HEADER_LEN;
467 memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
468 PRINTF(
"Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
469 coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1],
470 coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4],
471 coap_pkt->token[5], coap_pkt->token[6], coap_pkt->token[7]
475 memset(coap_pkt->options, 0,
sizeof(coap_pkt->options));
476 current_option += coap_pkt->token_len;
478 unsigned int option_number = 0;
479 unsigned int option_delta = 0;
480 size_t option_length = 0;
482 while(current_option < data + data_len) {
484 if((current_option[0] & 0xF0) == 0xF0) {
485 coap_pkt->payload = ++current_option;
486 coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
489 if(coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) {
490 coap_pkt->payload_len = REST_MAX_CHUNK_SIZE;
493 coap_pkt->payload[coap_pkt->payload_len] =
'\0';
498 option_delta = current_option[0] >> 4;
499 option_length = current_option[0] & 0x0F;
503 unsigned int *x = &option_delta;
507 *x += current_option[0];
509 }
else if(*x == 14) {
511 *x += current_option[0] << 8;
513 *x += current_option[0];
516 }
while(x != &option_length && (x = &option_length));
518 option_number += option_delta;
520 PRINTF(
"OPTION %u (delta %u, len %u): ", option_number, option_delta,
523 SET_OPTION(coap_pkt, option_number);
525 switch(option_number) {
526 case COAP_OPTION_CONTENT_FORMAT:
527 coap_pkt->content_format = coap_parse_int_option(current_option,
529 PRINTF(
"Content-Format [%u]\n", coap_pkt->content_format);
531 case COAP_OPTION_MAX_AGE:
532 coap_pkt->max_age = coap_parse_int_option(current_option,
534 PRINTF(
"Max-Age [%lu]\n", coap_pkt->max_age);
536 case COAP_OPTION_ETAG:
537 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
538 memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len);
539 PRINTF(
"ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
540 coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
541 coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
542 coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
545 case COAP_OPTION_ACCEPT:
546 coap_pkt->accept = coap_parse_int_option(current_option, option_length);
547 PRINTF(
"Accept [%u]\n", coap_pkt->accept);
549 case COAP_OPTION_IF_MATCH:
551 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
552 memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len);
553 PRINTF(
"If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
554 coap_pkt->if_match_len, coap_pkt->if_match[0],
555 coap_pkt->if_match[1], coap_pkt->if_match[2],
556 coap_pkt->if_match[3], coap_pkt->if_match[4],
557 coap_pkt->if_match[5], coap_pkt->if_match[6],
558 coap_pkt->if_match[7]
561 case COAP_OPTION_IF_NONE_MATCH:
562 coap_pkt->if_none_match = 1;
563 PRINTF(
"If-None-Match\n");
566 case COAP_OPTION_PROXY_URI:
567 #if COAP_PROXY_OPTION_PROCESSING
568 coap_pkt->proxy_uri = (
char *)current_option;
569 coap_pkt->proxy_uri_len = option_length;
571 PRINTF(
"Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len,
572 coap_pkt->proxy_uri);
573 coap_error_message =
"This is a constrained server (Contiki)";
574 return PROXYING_NOT_SUPPORTED_5_05;
576 case COAP_OPTION_PROXY_SCHEME:
577 #if COAP_PROXY_OPTION_PROCESSING
578 coap_pkt->proxy_scheme = (
char *)current_option;
579 coap_pkt->proxy_scheme_len = option_length;
581 PRINTF(
"Proxy-Scheme NOT IMPLEMENTED [%.*s]\n",
582 coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme);
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 PRINTF(
"Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host);
592 case COAP_OPTION_URI_PORT:
593 coap_pkt->uri_port = coap_parse_int_option(current_option,
595 PRINTF(
"Uri-Port [%u]\n", coap_pkt->uri_port);
597 case COAP_OPTION_URI_PATH:
599 coap_merge_multi_option((
char **)&(coap_pkt->uri_path),
600 &(coap_pkt->uri_path_len), current_option,
602 PRINTF(
"Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path);
604 case COAP_OPTION_URI_QUERY:
606 coap_merge_multi_option((
char **)&(coap_pkt->uri_query),
607 &(coap_pkt->uri_query_len), current_option,
609 PRINTF(
"Uri-Query [%.*s]\n", coap_pkt->uri_query_len,
610 coap_pkt->uri_query);
613 case COAP_OPTION_LOCATION_PATH:
615 coap_merge_multi_option((
char **)&(coap_pkt->location_path),
616 &(coap_pkt->location_path_len), current_option,
618 PRINTF(
"Location-Path [%.*s]\n", coap_pkt->location_path_len,
619 coap_pkt->location_path);
621 case COAP_OPTION_LOCATION_QUERY:
623 coap_merge_multi_option((
char **)&(coap_pkt->location_query),
624 &(coap_pkt->location_query_len), current_option,
626 PRINTF(
"Location-Query [%.*s]\n", coap_pkt->location_query_len,
627 coap_pkt->location_query);
630 case COAP_OPTION_OBSERVE:
631 coap_pkt->observe = coap_parse_int_option(current_option,
633 PRINTF(
"Observe [%lu]\n", coap_pkt->observe);
635 case COAP_OPTION_BLOCK2:
636 coap_pkt->block2_num = coap_parse_int_option(current_option,
638 coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
639 coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
640 coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
641 << (coap_pkt->block2_num & 0x07);
642 coap_pkt->block2_num >>= 4;
643 PRINTF(
"Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num,
644 coap_pkt->block2_more ?
"+" :
"", coap_pkt->block2_size);
646 case COAP_OPTION_BLOCK1:
647 coap_pkt->block1_num = coap_parse_int_option(current_option,
649 coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
650 coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
651 coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
652 << (coap_pkt->block1_num & 0x07);
653 coap_pkt->block1_num >>= 4;
654 PRINTF(
"Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num,
655 coap_pkt->block1_more ?
"+" :
"", coap_pkt->block1_size);
657 case COAP_OPTION_SIZE2:
658 coap_pkt->size2 = coap_parse_int_option(current_option, option_length);
659 PRINTF(
"Size2 [%lu]\n", coap_pkt->size2);
661 case COAP_OPTION_SIZE1:
662 coap_pkt->size1 = coap_parse_int_option(current_option, option_length);
663 PRINTF(
"Size1 [%lu]\n", coap_pkt->size1);
666 PRINTF(
"unknown (%u)\n", option_number);
668 if(option_number & 1) {
669 coap_error_message =
"Unsupported critical option";
670 return BAD_OPTION_4_02;
674 current_option += option_length;
676 PRINTF(
"-Done parsing-------\n");
684 coap_get_query_variable(
void *packet,
const char *name,
const char **output)
686 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
688 if(IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
689 return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len,
695 coap_get_post_variable(
void *packet,
const char *name,
const char **output)
697 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
699 if(coap_pkt->payload_len) {
700 return coap_get_variable((
const char *)coap_pkt->payload,
701 coap_pkt->payload_len, name, output);
707 coap_set_status_code(
void *packet,
unsigned int code)
710 ((coap_packet_t *)packet)->code = (uint8_t)code;
718 coap_set_token(
void *packet,
const uint8_t *token,
size_t token_len)
720 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
722 coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
723 memcpy(coap_pkt->token, token, coap_pkt->token_len);
725 return coap_pkt->token_len;
731 coap_get_header_content_format(
void *packet,
unsigned int *format)
733 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
735 if(!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) {
738 *format = coap_pkt->content_format;
742 coap_set_header_content_format(
void *packet,
unsigned int format)
744 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
746 coap_pkt->content_format = (coap_content_format_t)format;
747 SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
752 coap_get_header_accept(
void *packet,
unsigned int *accept)
754 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
756 if(!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) {
759 *accept = coap_pkt->accept;
763 coap_set_header_accept(
void *packet,
unsigned int accept)
765 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
767 coap_pkt->accept = (coap_content_format_t)accept;
768 SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
773 coap_get_header_max_age(
void *packet, uint32_t *age)
775 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
777 if(!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) {
778 *age = COAP_DEFAULT_MAX_AGE;
780 *age = coap_pkt->max_age;
784 coap_set_header_max_age(
void *packet, uint32_t age)
786 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
788 coap_pkt->max_age = age;
789 SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE);
794 coap_get_header_etag(
void *packet,
const uint8_t **etag)
796 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
798 if(!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
801 *etag = coap_pkt->etag;
802 return coap_pkt->etag_len;
805 coap_set_header_etag(
void *packet,
const uint8_t *etag,
size_t etag_len)
807 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
809 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len);
810 memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
812 SET_OPTION(coap_pkt, COAP_OPTION_ETAG);
813 return coap_pkt->etag_len;
818 coap_get_header_if_match(
void *packet,
const uint8_t **etag)
820 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
822 if(!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) {
825 *etag = coap_pkt->if_match;
826 return coap_pkt->if_match_len;
829 coap_set_header_if_match(
void *packet,
const uint8_t *etag,
size_t etag_len)
831 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
833 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len);
834 memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
836 SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH);
837 return coap_pkt->if_match_len;
841 coap_get_header_if_none_match(
void *packet)
843 return IS_OPTION((coap_packet_t *)packet,
844 COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
847 coap_set_header_if_none_match(
void *packet)
849 SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH);
854 coap_get_header_proxy_uri(
void *packet,
const char **uri)
856 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
858 if(!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) {
861 *uri = coap_pkt->proxy_uri;
862 return coap_pkt->proxy_uri_len;
865 coap_set_header_proxy_uri(
void *packet,
const char *uri)
867 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
871 coap_pkt->proxy_uri = uri;
872 coap_pkt->proxy_uri_len = strlen(uri);
874 SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI);
875 return coap_pkt->proxy_uri_len;
879 coap_get_header_uri_host(
void *packet,
const char **host)
881 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
883 if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) {
886 *host = coap_pkt->uri_host;
887 return coap_pkt->uri_host_len;
890 coap_set_header_uri_host(
void *packet,
const char *host)
892 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
894 coap_pkt->uri_host = host;
895 coap_pkt->uri_host_len = strlen(host);
897 SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST);
898 return coap_pkt->uri_host_len;
902 coap_get_header_uri_path(
void *packet,
const char **path)
904 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
906 if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) {
909 *path = coap_pkt->uri_path;
910 return coap_pkt->uri_path_len;
913 coap_set_header_uri_path(
void *packet,
const char *path)
915 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
917 while(path[0] ==
'/')
920 coap_pkt->uri_path = path;
921 coap_pkt->uri_path_len = strlen(path);
923 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
924 return coap_pkt->uri_path_len;
928 coap_get_header_uri_query(
void *packet,
const char **query)
930 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
932 if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
935 *query = coap_pkt->uri_query;
936 return coap_pkt->uri_query_len;
939 coap_set_header_uri_query(
void *packet,
const char *query)
941 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
943 while(query[0] ==
'?')
946 coap_pkt->uri_query = query;
947 coap_pkt->uri_query_len = strlen(query);
949 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
950 return coap_pkt->uri_query_len;
954 coap_get_header_location_path(
void *packet,
const char **path)
956 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
958 if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) {
961 *path = coap_pkt->location_path;
962 return coap_pkt->location_path_len;
965 coap_set_header_location_path(
void *packet,
const char *path)
967 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
971 while(path[0] ==
'/')
974 if((query = strchr(path,
'?'))) {
975 coap_set_header_location_query(packet, query + 1);
976 coap_pkt->location_path_len = query - path;
978 coap_pkt->location_path_len = strlen(path);
979 } coap_pkt->location_path = path;
981 if(coap_pkt->location_path_len > 0) {
982 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH);
984 return coap_pkt->location_path_len;
988 coap_get_header_location_query(
void *packet,
const char **query)
990 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
992 if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) {
995 *query = coap_pkt->location_query;
996 return coap_pkt->location_query_len;
999 coap_set_header_location_query(
void *packet,
const char *query)
1001 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1003 while(query[0] ==
'?')
1006 coap_pkt->location_query = query;
1007 coap_pkt->location_query_len = strlen(query);
1009 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY);
1010 return coap_pkt->location_query_len;
1014 coap_get_header_observe(
void *packet, uint32_t *observe)
1016 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1018 if(!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
1021 *observe = coap_pkt->observe;
1025 coap_set_header_observe(
void *packet, uint32_t observe)
1027 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1029 coap_pkt->observe = observe;
1030 SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE);
1035 coap_get_header_block2(
void *packet, uint32_t *num, uint8_t *more,
1036 uint16_t *size, uint32_t *offset)
1038 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1040 if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) {
1045 *num = coap_pkt->block2_num;
1048 *more = coap_pkt->block2_more;
1051 *size = coap_pkt->block2_size;
1053 if(offset !=
NULL) {
1054 *offset = coap_pkt->block2_offset;
1059 coap_set_header_block2(
void *packet, uint32_t num, uint8_t more,
1062 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1070 if(num > 0x0FFFFF) {
1073 coap_pkt->block2_num = num;
1074 coap_pkt->block2_more = more ? 1 : 0;
1075 coap_pkt->block2_size = size;
1077 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2);
1082 coap_get_header_block1(
void *packet, uint32_t *num, uint8_t *more,
1083 uint16_t *size, uint32_t *offset)
1085 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1087 if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) {
1092 *num = coap_pkt->block1_num;
1095 *more = coap_pkt->block1_more;
1098 *size = coap_pkt->block1_size;
1100 if(offset !=
NULL) {
1101 *offset = coap_pkt->block1_offset;
1106 coap_set_header_block1(
void *packet, uint32_t num, uint8_t more,
1109 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1117 if(num > 0x0FFFFF) {
1120 coap_pkt->block1_num = num;
1121 coap_pkt->block1_more = more;
1122 coap_pkt->block1_size = size;
1124 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1);
1129 coap_get_header_size2(
void *packet, uint32_t *size)
1131 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1133 if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE2)) {
1136 *size = coap_pkt->size2;
1140 coap_set_header_size2(
void *packet, uint32_t size)
1142 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1144 coap_pkt->size2 = size;
1145 SET_OPTION(coap_pkt, COAP_OPTION_SIZE2);
1150 coap_get_header_size1(
void *packet, uint32_t *size)
1152 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1154 if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE1)) {
1157 *size = coap_pkt->size1;
1161 coap_set_header_size1(
void *packet, uint32_t size)
1163 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1165 coap_pkt->size1 = size;
1166 SET_OPTION(coap_pkt, COAP_OPTION_SIZE1);
1171 coap_get_payload(
void *packet,
const uint8_t **payload)
1173 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1175 if(coap_pkt->payload) {
1176 *payload = coap_pkt->payload;
1177 return coap_pkt->payload_len;
1184 coap_set_payload(
void *packet,
const void *payload,
size_t length)
1186 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1188 coap_pkt->payload = (uint8_t *)payload;
1189 coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
1191 return coap_pkt->payload_len;
uint16_t rport
The remote port number in network byte order.
CCIF struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
#define NULL
The null pointer.
uint16_t lport
The local port number in network byte order.
An implementation of the Constrained Application Protocol (RFC).
uip_ipaddr_t ripaddr
The IP address of the remote peer.
CoAP module for reliable transport
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
Representation of a uIP UDP connection.
unsigned short random_rand(void)
Generate the next state and return the upper part of it.