43 #include "contiki-net.h"
51 #define PRINTF(...) printf(__VA_ARGS__)
52 #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])
53 #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])
56 #define PRINT6ADDR(addr)
57 #define PRINTLLADDR(addr)
64 static uint16_t current_mid = 0;
66 coap_status_t erbium_status_code = NO_ERROR;
67 char *coap_error_message =
"";
72 coap_log_2(uint16_t value)
81 return result ? result - 1 : result;
85 coap_parse_int_option(uint8_t *bytes,
size_t length)
98 coap_option_nibble(
unsigned int value)
102 }
else if(value <= 0xFF + 13) {
110 coap_set_option_header(
unsigned int delta,
size_t length, uint8_t *buffer)
114 buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
117 buffer[++written] = ((delta - 269) >> 8) & 0xff;
118 buffer[++written] = (delta - 269) & 0xff;
119 }
else if(delta > 12) {
120 buffer[++written] = (delta - 13);
124 buffer[++written] = ((length - 269) >> 8) & 0xff;
125 buffer[++written] = (length - 269) & 0xff;
126 }
else if(length > 12) {
127 buffer[++written] = (length - 13);
130 PRINTF(
"WRITTEN %zu B opt header\n", 1 + written);
136 coap_serialize_int_option(
unsigned int number,
unsigned int current_number,
137 uint8_t *buffer, uint32_t value)
141 if(0xFF000000 & value) {
144 if(0xFFFF0000 & value) {
147 if(0xFFFFFF00 & value) {
150 if(0xFFFFFFFF & value) {
153 PRINTF(
"OPTION %u (delta %u, len %zu)\n", number, number - current_number,
156 i = coap_set_option_header(number - current_number, i, buffer);
158 if(0xFF000000 & value) {
159 buffer[i++] = (uint8_t)(value >> 24);
161 if(0xFFFF0000 & value) {
162 buffer[i++] = (uint8_t)(value >> 16);
164 if(0xFFFFFF00 & value) {
165 buffer[i++] = (uint8_t)(value >> 8);
167 if(0xFFFFFFFF & value) {
168 buffer[i++] = (uint8_t)(value);
174 coap_serialize_array_option(
unsigned int number,
unsigned int current_number,
175 uint8_t *buffer, uint8_t *array,
size_t length,
180 PRINTF(
"ARRAY type %u, len %zu, full [%.*s]\n", number, 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 PRINTF(
"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 PRINTF(
"OPTION type %u, delta %u, len %zu, part [%.*s]\n", number,
201 number - current_number, i, (
int)temp_length, part_start);
204 current_number = number;
205 part_start = array + j;
209 i += coap_set_option_header(number - current_number, length, &buffer[i]);
210 memcpy(&buffer[i], array, length);
213 PRINTF(
"OPTION type %u, delta %u, len %zu\n", number,
214 number - current_number, length);
221 coap_merge_multi_option(
char **dst,
size_t *dst_len, uint8_t *option,
222 size_t option_len,
char separator)
227 (*dst)[*dst_len] = separator;
231 memmove((*dst) + (*dst_len), option, option_len);
233 *dst_len += option_len;
236 *dst = (
char *)option;
237 *dst_len = option_len;
242 coap_get_variable(
const char *buffer,
size_t length,
const char *name,
246 const char *end =
NULL;
247 const char *value_end =
NULL;
253 name_len = strlen(name);
254 end = buffer + length;
256 for(start = buffer; start + name_len < end; ++
start) {
257 if((start == buffer || start[-1] ==
'&') && start[name_len] ==
'='
258 && strncmp(name, start, name_len) == 0) {
261 start += name_len + 1;
264 value_end = (
const char *)memchr(start,
'&', end - start);
265 if(value_end ==
NULL) {
270 return value_end -
start;
279 coap_init_connection(uint16_t port)
284 PRINTF(
"Listening on port %u\n", uip_ntohs(udp_conn->
lport));
293 return ++current_mid;
297 coap_init_message(
void *packet, coap_message_type_t type, uint8_t code,
300 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
303 memset(coap_pkt, 0,
sizeof(coap_packet_t));
305 coap_pkt->type = type;
306 coap_pkt->code = code;
311 coap_serialize_message(
void *packet, uint8_t *buffer)
313 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
315 unsigned int current_number = 0;
318 coap_pkt->buffer = buffer;
319 coap_pkt->version = 1;
321 PRINTF(
"-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer);
324 coap_pkt->buffer[0] = 0x00;
325 coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK
326 & (coap_pkt->version) << COAP_HEADER_VERSION_POSITION;
327 coap_pkt->buffer[0] |= COAP_HEADER_TYPE_MASK
328 & (coap_pkt->type) << COAP_HEADER_TYPE_POSITION;
329 coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK
330 & (coap_pkt->token_len) << COAP_HEADER_TOKEN_LEN_POSITION;
331 coap_pkt->buffer[1] = coap_pkt->code;
332 coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8);
333 coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid);
336 if(!coap_pkt->code) {
337 PRINTF(
"-Done serializing empty message at %p-\n", coap_pkt->buffer);
342 PRINTF(
"Token (len %u)", coap_pkt->token_len);
343 option = coap_pkt->buffer + COAP_HEADER_LEN;
344 for(current_number = 0; current_number < coap_pkt->token_len;
346 PRINTF(
" %02X", coap_pkt->token[current_number]);
347 *option = coap_pkt->token[current_number];
355 PRINTF(
"-Serializing options at %p-\n", option);
358 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match,
"If-Match");
359 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host,
'\0',
361 COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag,
"ETag");
362 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
367 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe,
"Observe");
368 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port,
"Uri-Port");
369 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path,
'/',
371 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path,
'/',
373 PRINTF(
"Serialize content format: %d\n", coap_pkt->content_format);
374 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
376 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age,
"Max-Age");
377 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query,
'&',
379 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT,
accept,
"Accept");
380 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
381 '&',
"Location-Query");
382 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2,
"Block2");
383 COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1,
"Block1");
384 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2,
"Size2");
385 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri,
'\0',
387 COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme,
'\0',
389 COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1,
"Size1");
391 PRINTF(
"-Done serializing at %p----\n", option);
394 if((option - coap_pkt->buffer) <= COAP_MAX_HEADER_SIZE) {
396 if(coap_pkt->payload_len) {
400 memmove(option, coap_pkt->payload, coap_pkt->payload_len);
403 coap_pkt->buffer =
NULL;
404 coap_error_message =
"Serialized header exceeds COAP_MAX_HEADER_SIZE";
408 PRINTF(
"-Done %u B (header len %u, payload len %u)-\n",
409 (
unsigned int)(coap_pkt->payload_len + option - buffer),
410 (
unsigned int)(option - buffer),
411 (
unsigned int)coap_pkt->payload_len);
413 PRINTF(
"Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
419 coap_pkt->buffer[5], coap_pkt->buffer[6], coap_pkt->buffer[7]
422 return (option - buffer) + coap_pkt->payload_len;
426 coap_send_message(uip_ipaddr_t *
addr, uint16_t port, uint8_t *data,
431 udp_conn->
rport = port;
433 uip_udp_packet_send(udp_conn, data, length);
435 PRINTF(
"-sent UDP datagram (%u)-\n", length);
443 coap_parse_message(
void *packet, uint8_t *data, uint16_t data_len)
445 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
448 memset(coap_pkt, 0,
sizeof(coap_packet_t));
451 coap_pkt->buffer = data;
454 coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0])
455 >> COAP_HEADER_VERSION_POSITION;
456 coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])
457 >> COAP_HEADER_TYPE_POSITION;
458 coap_pkt->token_len = (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0])
459 >> COAP_HEADER_TOKEN_LEN_POSITION;
460 coap_pkt->code = coap_pkt->buffer[1];
461 coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3];
463 if(coap_pkt->version != 1) {
464 coap_error_message =
"CoAP version must be 1";
465 return BAD_REQUEST_4_00;
468 if(coap_pkt->token_len > COAP_TOKEN_LEN) {
469 coap_error_message =
"Token Length must not be more than 8";
470 return BAD_REQUEST_4_00;
473 uint8_t *current_option = data + COAP_HEADER_LEN;
475 memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
476 PRINTF(
"Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
477 coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1],
478 coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4],
479 coap_pkt->token[5], coap_pkt->token[6], coap_pkt->token[7]
483 memset(coap_pkt->options, 0,
sizeof(coap_pkt->options));
484 current_option += coap_pkt->token_len;
486 unsigned int option_number = 0;
487 unsigned int option_delta = 0;
488 size_t option_length = 0;
490 while(current_option < data + data_len) {
492 if((current_option[0] & 0xF0) == 0xF0) {
493 coap_pkt->payload = ++current_option;
494 coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
497 if(coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) {
498 coap_pkt->payload_len = REST_MAX_CHUNK_SIZE;
501 coap_pkt->payload[coap_pkt->payload_len] =
'\0';
506 option_delta = current_option[0] >> 4;
507 option_length = current_option[0] & 0x0F;
510 if(option_delta == 13) {
511 option_delta += current_option[0];
513 }
else if(option_delta == 14) {
515 option_delta += current_option[0] << 8;
517 option_delta += current_option[0];
521 if(option_length == 13) {
522 option_length += current_option[0];
524 }
else if(option_length == 14) {
525 option_length += 255;
526 option_length += current_option[0] << 8;
528 option_length += current_option[0];
532 option_number += option_delta;
534 PRINTF(
"OPTION %u (delta %u, len %zu): ", option_number, option_delta,
537 SET_OPTION(coap_pkt, option_number);
539 switch(option_number) {
540 case COAP_OPTION_CONTENT_FORMAT:
541 coap_pkt->content_format = coap_parse_int_option(current_option,
543 PRINTF(
"Content-Format [%u]\n", coap_pkt->content_format);
545 case COAP_OPTION_MAX_AGE:
546 coap_pkt->max_age = coap_parse_int_option(current_option,
548 PRINTF(
"Max-Age [%lu]\n", (
unsigned long)coap_pkt->max_age);
550 case COAP_OPTION_ETAG:
551 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
552 memcpy(coap_pkt->etag, current_option, coap_pkt->etag_len);
553 PRINTF(
"ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
554 coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
555 coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
556 coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
559 case COAP_OPTION_ACCEPT:
560 coap_pkt->accept = coap_parse_int_option(current_option, option_length);
561 PRINTF(
"Accept [%u]\n", coap_pkt->accept);
563 case COAP_OPTION_IF_MATCH:
565 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
566 memcpy(coap_pkt->if_match, current_option, coap_pkt->if_match_len);
567 PRINTF(
"If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
568 coap_pkt->if_match_len, coap_pkt->if_match[0],
569 coap_pkt->if_match[1], coap_pkt->if_match[2],
570 coap_pkt->if_match[3], coap_pkt->if_match[4],
571 coap_pkt->if_match[5], coap_pkt->if_match[6],
572 coap_pkt->if_match[7]
575 case COAP_OPTION_IF_NONE_MATCH:
576 coap_pkt->if_none_match = 1;
577 PRINTF(
"If-None-Match\n");
580 case COAP_OPTION_PROXY_URI:
581 #if COAP_PROXY_OPTION_PROCESSING
582 coap_pkt->proxy_uri = (
char *)current_option;
583 coap_pkt->proxy_uri_len = option_length;
585 PRINTF(
"Proxy-Uri NOT IMPLEMENTED [%.*s]\n", (
int)coap_pkt->proxy_uri_len,
586 coap_pkt->proxy_uri);
587 coap_error_message =
"This is a constrained server (Contiki)";
588 return PROXYING_NOT_SUPPORTED_5_05;
590 case COAP_OPTION_PROXY_SCHEME:
591 #if COAP_PROXY_OPTION_PROCESSING
592 coap_pkt->proxy_scheme = (
char *)current_option;
593 coap_pkt->proxy_scheme_len = option_length;
595 PRINTF(
"Proxy-Scheme NOT IMPLEMENTED [%.*s]\n",
596 (
int)coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme);
597 coap_error_message =
"This is a constrained server (Contiki)";
598 return PROXYING_NOT_SUPPORTED_5_05;
601 case COAP_OPTION_URI_HOST:
602 coap_pkt->uri_host = (
char *)current_option;
603 coap_pkt->uri_host_len = option_length;
604 PRINTF(
"Uri-Host [%.*s]\n", (
int)coap_pkt->uri_host_len,
607 case COAP_OPTION_URI_PORT:
608 coap_pkt->uri_port = coap_parse_int_option(current_option,
610 PRINTF(
"Uri-Port [%u]\n", coap_pkt->uri_port);
612 case COAP_OPTION_URI_PATH:
614 coap_merge_multi_option((
char **)&(coap_pkt->uri_path),
615 &(coap_pkt->uri_path_len), current_option,
617 PRINTF(
"Uri-Path [%.*s]\n", (
int)coap_pkt->uri_path_len, coap_pkt->uri_path);
619 case COAP_OPTION_URI_QUERY:
621 coap_merge_multi_option((
char **)&(coap_pkt->uri_query),
622 &(coap_pkt->uri_query_len), current_option,
624 PRINTF(
"Uri-Query [%.*s]\n", (
int)coap_pkt->uri_query_len,
625 coap_pkt->uri_query);
628 case COAP_OPTION_LOCATION_PATH:
630 coap_merge_multi_option((
char **)&(coap_pkt->location_path),
631 &(coap_pkt->location_path_len), current_option,
633 PRINTF(
"Location-Path [%.*s]\n", (
int)coap_pkt->location_path_len,
634 coap_pkt->location_path);
636 case COAP_OPTION_LOCATION_QUERY:
638 coap_merge_multi_option((
char **)&(coap_pkt->location_query),
639 &(coap_pkt->location_query_len), current_option,
641 PRINTF(
"Location-Query [%.*s]\n", (
int)coap_pkt->location_query_len,
642 coap_pkt->location_query);
645 case COAP_OPTION_OBSERVE:
646 coap_pkt->observe = coap_parse_int_option(current_option,
648 PRINTF(
"Observe [%lu]\n", (
unsigned long)coap_pkt->observe);
650 case COAP_OPTION_BLOCK2:
651 coap_pkt->block2_num = coap_parse_int_option(current_option,
653 coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
654 coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
655 coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
656 << (coap_pkt->block2_num & 0x07);
657 coap_pkt->block2_num >>= 4;
658 PRINTF(
"Block2 [%lu%s (%u B/blk)]\n",
659 (
unsigned long)coap_pkt->block2_num,
660 coap_pkt->block2_more ?
"+" :
"", coap_pkt->block2_size);
662 case COAP_OPTION_BLOCK1:
663 coap_pkt->block1_num = coap_parse_int_option(current_option,
665 coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
666 coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
667 coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
668 << (coap_pkt->block1_num & 0x07);
669 coap_pkt->block1_num >>= 4;
670 PRINTF(
"Block1 [%lu%s (%u B/blk)]\n",
671 (
unsigned long)coap_pkt->block1_num,
672 coap_pkt->block1_more ?
"+" :
"", coap_pkt->block1_size);
674 case COAP_OPTION_SIZE2:
675 coap_pkt->size2 = coap_parse_int_option(current_option, option_length);
676 PRINTF(
"Size2 [%lu]\n", (
unsigned long)coap_pkt->size2);
678 case COAP_OPTION_SIZE1:
679 coap_pkt->size1 = coap_parse_int_option(current_option, option_length);
680 PRINTF(
"Size1 [%lu]\n", (
unsigned long)coap_pkt->size1);
683 PRINTF(
"unknown (%u)\n", option_number);
685 if(option_number & 1) {
686 coap_error_message =
"Unsupported critical option";
687 return BAD_OPTION_4_02;
691 current_option += option_length;
693 PRINTF(
"-Done parsing-------\n");
701 coap_get_query_variable(
void *packet,
const char *name,
const char **output)
703 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
705 if(IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
706 return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len,
712 coap_get_post_variable(
void *packet,
const char *name,
const char **output)
714 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
716 if(coap_pkt->payload_len) {
717 return coap_get_variable((
const char *)coap_pkt->payload,
718 coap_pkt->payload_len, name, output);
724 coap_set_status_code(
void *packet,
unsigned int code)
727 ((coap_packet_t *)packet)->code = (uint8_t)code;
735 coap_set_token(
void *packet,
const uint8_t *token,
size_t token_len)
737 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
739 coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
740 memcpy(coap_pkt->token, token, coap_pkt->token_len);
742 return coap_pkt->token_len;
748 coap_get_header_content_format(
void *packet,
unsigned int *format)
750 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
752 if(!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) {
755 *format = coap_pkt->content_format;
759 coap_set_header_content_format(
void *packet,
unsigned int format)
761 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
763 coap_pkt->content_format = format;
764 SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
769 coap_get_header_accept(
void *packet,
unsigned int *
accept)
771 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
773 if(!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) {
776 *accept = coap_pkt->accept;
780 coap_set_header_accept(
void *packet,
unsigned int accept)
782 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
784 coap_pkt->accept =
accept;
785 SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
790 coap_get_header_max_age(
void *packet, uint32_t *age)
792 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
794 if(!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) {
795 *age = COAP_DEFAULT_MAX_AGE;
797 *age = coap_pkt->max_age;
801 coap_set_header_max_age(
void *packet, uint32_t age)
803 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
805 coap_pkt->max_age = age;
806 SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE);
811 coap_get_header_etag(
void *packet,
const uint8_t **etag)
813 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
815 if(!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
818 *etag = coap_pkt->etag;
819 return coap_pkt->etag_len;
822 coap_set_header_etag(
void *packet,
const uint8_t *etag,
size_t etag_len)
824 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
826 coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len);
827 memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
829 SET_OPTION(coap_pkt, COAP_OPTION_ETAG);
830 return coap_pkt->etag_len;
835 coap_get_header_if_match(
void *packet,
const uint8_t **etag)
837 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
839 if(!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) {
842 *etag = coap_pkt->if_match;
843 return coap_pkt->if_match_len;
846 coap_set_header_if_match(
void *packet,
const uint8_t *etag,
size_t etag_len)
848 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
850 coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len);
851 memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
853 SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH);
854 return coap_pkt->if_match_len;
858 coap_get_header_if_none_match(
void *packet)
860 return IS_OPTION((coap_packet_t *)packet,
861 COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
864 coap_set_header_if_none_match(
void *packet)
866 SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH);
871 coap_get_header_proxy_uri(
void *packet,
const char **uri)
873 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
875 if(!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) {
878 *uri = coap_pkt->proxy_uri;
879 return coap_pkt->proxy_uri_len;
882 coap_set_header_proxy_uri(
void *packet,
const char *uri)
884 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
888 coap_pkt->proxy_uri = uri;
889 coap_pkt->proxy_uri_len = strlen(uri);
891 SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI);
892 return coap_pkt->proxy_uri_len;
896 coap_get_header_uri_host(
void *packet,
const char **host)
898 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
900 if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) {
903 *host = coap_pkt->uri_host;
904 return coap_pkt->uri_host_len;
907 coap_set_header_uri_host(
void *packet,
const char *host)
909 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
911 coap_pkt->uri_host = host;
912 coap_pkt->uri_host_len = strlen(host);
914 SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST);
915 return coap_pkt->uri_host_len;
919 coap_get_header_uri_path(
void *packet,
const char **path)
921 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
923 if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) {
926 *path = coap_pkt->uri_path;
927 return coap_pkt->uri_path_len;
930 coap_set_header_uri_path(
void *packet,
const char *path)
932 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
934 while(path[0] ==
'/')
937 coap_pkt->uri_path = path;
938 coap_pkt->uri_path_len = strlen(path);
940 SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
941 return coap_pkt->uri_path_len;
945 coap_get_header_uri_query(
void *packet,
const char **query)
947 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
949 if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
952 *query = coap_pkt->uri_query;
953 return coap_pkt->uri_query_len;
956 coap_set_header_uri_query(
void *packet,
const char *query)
958 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
960 while(query[0] ==
'?')
963 coap_pkt->uri_query = query;
964 coap_pkt->uri_query_len = strlen(query);
966 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
967 return coap_pkt->uri_query_len;
971 coap_get_header_location_path(
void *packet,
const char **path)
973 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
975 if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) {
978 *path = coap_pkt->location_path;
979 return coap_pkt->location_path_len;
982 coap_set_header_location_path(
void *packet,
const char *path)
984 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
988 while(path[0] ==
'/')
991 if((query = strchr(path,
'?'))) {
992 coap_set_header_location_query(packet, query + 1);
993 coap_pkt->location_path_len = query - path;
995 coap_pkt->location_path_len = strlen(path);
996 } coap_pkt->location_path = path;
998 if(coap_pkt->location_path_len > 0) {
999 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH);
1001 return coap_pkt->location_path_len;
1005 coap_get_header_location_query(
void *packet,
const char **query)
1007 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1009 if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) {
1012 *query = coap_pkt->location_query;
1013 return coap_pkt->location_query_len;
1016 coap_set_header_location_query(
void *packet,
const char *query)
1018 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1020 while(query[0] ==
'?')
1023 coap_pkt->location_query = query;
1024 coap_pkt->location_query_len = strlen(query);
1026 SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY);
1027 return coap_pkt->location_query_len;
1031 coap_get_header_observe(
void *packet, uint32_t *observe)
1033 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1035 if(!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
1038 *observe = coap_pkt->observe;
1042 coap_set_header_observe(
void *packet, uint32_t observe)
1044 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1046 coap_pkt->observe = observe;
1047 SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE);
1052 coap_get_header_block2(
void *packet, uint32_t *num, uint8_t *more,
1053 uint16_t *size, uint32_t *offset)
1055 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1057 if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) {
1062 *num = coap_pkt->block2_num;
1065 *more = coap_pkt->block2_more;
1068 *size = coap_pkt->block2_size;
1070 if(offset !=
NULL) {
1071 *offset = coap_pkt->block2_offset;
1076 coap_set_header_block2(
void *packet, uint32_t num, uint8_t more,
1079 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1087 if(num > 0x0FFFFF) {
1090 coap_pkt->block2_num = num;
1091 coap_pkt->block2_more = more ? 1 : 0;
1092 coap_pkt->block2_size = size;
1094 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2);
1099 coap_get_header_block1(
void *packet, uint32_t *num, uint8_t *more,
1100 uint16_t *size, uint32_t *offset)
1102 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1104 if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) {
1109 *num = coap_pkt->block1_num;
1112 *more = coap_pkt->block1_more;
1115 *size = coap_pkt->block1_size;
1117 if(offset !=
NULL) {
1118 *offset = coap_pkt->block1_offset;
1123 coap_set_header_block1(
void *packet, uint32_t num, uint8_t more,
1126 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1134 if(num > 0x0FFFFF) {
1137 coap_pkt->block1_num = num;
1138 coap_pkt->block1_more = more;
1139 coap_pkt->block1_size = size;
1141 SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1);
1146 coap_get_header_size2(
void *packet, uint32_t *size)
1148 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1150 if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE2)) {
1153 *size = coap_pkt->size2;
1157 coap_set_header_size2(
void *packet, uint32_t size)
1159 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1161 coap_pkt->size2 = size;
1162 SET_OPTION(coap_pkt, COAP_OPTION_SIZE2);
1167 coap_get_header_size1(
void *packet, uint32_t *size)
1169 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1171 if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE1)) {
1174 *size = coap_pkt->size1;
1178 coap_set_header_size1(
void *packet, uint32_t size)
1180 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1182 coap_pkt->size1 = size;
1183 SET_OPTION(coap_pkt, COAP_OPTION_SIZE1);
1188 coap_get_payload(
void *packet,
const uint8_t **payload)
1190 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1192 if(coap_pkt->payload) {
1193 *payload = coap_pkt->payload;
1194 return coap_pkt->payload_len;
1201 coap_set_payload(
void *packet,
const void *payload,
size_t length)
1203 coap_packet_t *
const coap_pkt = (coap_packet_t *)packet;
1205 coap_pkt->payload = (uint8_t *)payload;
1206 coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
1208 return coap_pkt->payload_len;
uip_ipaddr_t ripaddr
The IP address of the remote peer.
static void start(void)
Start measurement.
static uip_ds6_addr_t * addr
Pointer to a router list entry.
Default definitions of C compiler quirk work-arounds.
Representation of a uIP UDP connection.
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.
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.
unsigned short random_rand(void)
Generates a new random number using the cc2538 RNG.
uint16_t rport
The remote port number in network byte order.
An implementation of the Constrained Application Protocol (RFC).
uint16_t lport
The local port number in network byte order.
static uint8_t output(const uip_lladdr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
static uint8_t accept(uint8_t in)
Processes an incoming or outgoing multicast message and determines whether it should be dropped or ac...