15 #elif HAVE_SYS_UNISTD_H
16 #include <sys/unistd.h>
18 #include <sys/types.h>
19 #ifdef HAVE_SYS_SOCKET_H
20 #include <sys/socket.h>
22 #ifdef HAVE_NETINET_IN_H
23 #include <netinet/in.h>
25 #ifdef HAVE_ARPA_INET_H
26 #include <arpa/inet.h>
53 # define DEBUG DEBUG_PRINT
57 #include "net/uip-debug.h"
61 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
62 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
64 void coap_resources_init();
65 void coap_pdu_resources_init();
67 unsigned char initialized = 0;
72 PROCESS(coap_retransmit_process,
"message retransmit process");
81 memb_free(&node_storage, node);
94 if ( !queue || !node )
105 if ( order( node, q ) < 0) {
115 }
while ( q && order( node, q ) >= 0 );
155 memset(node, 0,
sizeof *node );
180 #ifdef COAP_DEFAULT_WKC_HASHKEY
182 #define is_wkc(Key) \
183 (memcmp((Key), COAP_DEFAULT_WKC_HASHKEY, sizeof(coap_key_t)) == 0)
190 static unsigned char _initialized = 0;
195 return memcmp(k, wkc,
sizeof(
coap_key_t)) == 0;
227 coap_resources_init();
228 coap_pdu_resources_init();
230 c = &the_coap_context;
251 c->
sockfd = socket(listen_addr->addr.sa.sa_family, SOCK_DGRAM, 0);
259 if ( setsockopt( c->
sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse) ) < 0 ) {
265 if (bind(c->
sockfd, &listen_addr->addr.sa, listen_addr->size) < 0) {
281 c->conn = udp_new(NULL, 0, NULL);
282 udp_bind(c->conn, listen_addr->port);
284 process_start(&coap_retransmit_process, (
char *)c);
286 PROCESS_CONTEXT_BEGIN(&coap_retransmit_process);
287 #ifndef WITHOUT_OBSERVE
291 etimer_set(&the_coap_context.retransmit_timer, 0xFFFF);
292 PROCESS_CONTEXT_END(&coap_retransmit_process);
340 if (opt_iter.
type & 0x01 &&
342 debug(
"unknown critical option %d\n", opt_iter.
type);
368 switch (peer->addr.sa.sa_family) {
370 coap_hash((
const unsigned char *)&peer->addr.sa, peer->size, h);
373 coap_hash((
const unsigned char *)&peer->addr.sin6.sin6_port,
374 sizeof(peer->addr.sin6.sin6_port), h);
375 coap_hash((
const unsigned char *)&peer->addr.sin6.sin6_addr,
376 sizeof(peer->addr.sin6.sin6_addr), h);
382 coap_hash((
const unsigned char *)&peer->port,
sizeof(peer->port), h);
383 coap_hash((
const unsigned char *)&peer->addr,
sizeof(peer->addr), h);
386 coap_hash((
const unsigned char *)&pdu->
hdr->
id,
sizeof(
unsigned short), h);
388 *
id = ((h[0] << 8) | h[1]) ^ ((h[2] << 8) | h[3]);
402 result =
coap_send(context, dst, response);
415 ssize_t bytes_written;
418 if ( !context || !dst || !pdu )
422 &dst->addr.sa, dst->size);
424 if (bytes_written >= 0) {
440 if ( !context || !dst || !pdu )
444 uip_udp_packet_sendto(context->conn, pdu->
hdr, pdu->
length,
445 &dst->addr, dst->port);
474 result =
coap_send(context, dst, response);
485 unsigned char type) {
492 result =
coap_send(context, dst, response);
501 return lhs && rhs && ( lhs->
t < rhs->
t ) ? -1 : 1;
514 debug(
"coap_send_confirmed: insufficient memory\n");
520 debug(
"coap_send_confirmed: error sending pdu\n");
525 prng((
unsigned char *)&r,
sizeof(r));
549 PROCESS_CONTEXT_BEGIN(&coap_retransmit_process);
550 etimer_set(&context->retransmit_timer,
551 now < nextpdu->t ? nextpdu->
t - now : 0);
552 PROCESS_CONTEXT_END(&coap_retransmit_process);
561 if ( !context || !node )
571 debug(
"** retransmission #%d of transaction %d\n",
574 debug(
"** retransmission #%u of transaction %u\n",
585 debug(
"** removed transaction %d\n", ntohs(node->
id));
588 #ifndef WITHOUT_OBSERVE
592 str token = { 0, NULL };
608 return ( lhs && rhs && lhs->
pdu && rhs->
pdu &&
609 ( lhs->
id < rhs->
id ) )
621 if (opt && opt < maxpos) {
622 if (((*opt & 0x0f) < 0x0f) || (opt + 1 < maxpos))
637 ssize_t bytes_read = -1;
649 bytes_read = recvfrom(ctx->
sockfd, buf,
sizeof(buf), 0,
650 &src.addr.sa, &src.size);
653 uip_ipaddr_copy(&src.addr, &UIP_IP_BUF->srcipaddr);
654 src.port = UIP_UDP_BUF->srcport;
655 uip_ipaddr_copy(&dst.addr, &UIP_IP_BUF->destipaddr);
656 dst.port = UIP_UDP_BUF->destport;
658 bytes_read = uip_datalen();
659 ((
char *)uip_appdata)[bytes_read] = 0;
660 PRINTF(
"Server received %d bytes from [", (
int)bytes_read);
661 PRINT6ADDR(&src.addr);
662 PRINTF(
"]:%d\n", uip_ntohs(src.port));
666 if ( bytes_read < 0 ) {
667 warn(
"coap_read: recvfrom");
671 if ( (
size_t)bytes_read <
sizeof(
coap_hdr_t) ) {
672 debug(
"coap_read: discarded invalid frame\n" );
677 debug(
"coap_read: unknown protocol version\n" );
694 warn(
"discard malformed PDU");
704 #ifndef INET6_ADDRSTRLEN
705 #define INET6_ADDRSTRLEN 40
710 debug(
"** received %d bytes from %s:\n", (
int)bytes_read, addr);
727 if ( !queue || !*queue)
732 if (
id == (*queue)->id ) {
734 *queue = (*queue)->
next;
735 (*node)->
next = NULL;
737 debug(
"*** removed transaction %u\n",
id);
746 }
while ( q &&
id != q->
id );
753 debug(
"*** removed transaction %u\n",
id);
763 const unsigned char *b,
size_t blen) {
764 return alen == blen && (alen == 0 || memcmp(a, b, alen) == 0);
769 const unsigned char *token,
size_t token_length) {
774 debug(
"cancel_all_messages\n");
782 debug(
"**** removed transaction %d\n", ntohs(q->
pdu->
hdr->
id));
798 debug(
"**** removed transaction %d\n", ntohs(q->
pdu->
hdr->
id));
810 while (queue && queue->
id !=
id)
824 unsigned short opt_type = 0;
831 size += strlen(phrase) + 1;
853 unsigned short delta = opt_iter.
type - opt_type;
857 }
else if (delta < 269) {
867 switch (*option & 0x0f) {
878 opt_type = opt_iter.
type;
887 debug(
"cannot add token to error response\n");
899 #if COAP_ERROR_PHRASE_LENGTH > 0
902 coap_add_data(response, strlen(phrase), (
unsigned char *)phrase);
914 unsigned char buf[2];
922 debug(
"wellknown_response: cannot create PDU\n");
927 debug(
"wellknown_response: cannot add token\n");
936 debug(
"wellknown_response: insufficient storage space\n");
959 debug(
"print_wellknown failed\n");
973 #define WANT_WKC(Pdu,Key) \
974 (((Pdu)->hdr->code == COAP_REQUEST_GET) && is_wkc(Key))
1004 debug(
"GET for unknown resource 0x%02x%02x%02x%02x, return 4.04\n",
1005 key[0], key[1], key[2], key[3]);
1014 debug(
"unhandled request for unknown resource 0x%02x%02x%02x%02x\r\n",
1015 key[0], key[1], key[2], key[3]);
1022 warn(
"cannot send response for transaction %u\n", node->
id);
1035 debug(
"call custom handler for resource 0x%02x%02x%02x%02x\n",
1036 key[0], key[1], key[2], key[3]);
1048 h(context, resource, &node->
remote,
1049 node->
pdu, &token, response);
1050 if (response->
hdr->
type != COAP_MESSAGE_NON ||
1054 debug(
"cannot send response for message %d\n", node->
pdu->
hdr->
id);
1060 warn(
"cannot generate response\r\n");
1072 debug(
"cannot send response for transaction %u\n", node->
id);
1087 rcvd->
pdu, rcvd->
id);
1111 #ifndef WITHOUT_OBSERVE
1113 str token = { 0, NULL };
1121 #ifndef WITH_CONTIKI
1128 for (i = 0; i < resource_storage.num; ++i, ++r) {
1129 if (resource_storage.count[i]) {
1174 { sent->pdu->hdr->token_length, sent->pdu->hdr->token };
1184 #ifndef WITH_CONTIKI
1209 warn(
"coap_dispatch: cannot create error reponse\n");
1213 warn(
"coap_dispatch: error sending reponse\n");
1231 debug(
"dropped message with invalid code\n");
1260 debug(
"Started retransmit process\r\n");
1264 if (ev == PROCESS_EVENT_TIMER) {
1265 if (etimer_expired(&the_coap_context.retransmit_timer)) {
1270 while (nextpdu && nextpdu->
t <= now) {
1276 etimer_set(&the_coap_context.retransmit_timer,
1277 nextpdu ? nextpdu->
t - now : 0xFFFF);
1279 #ifndef WITHOUT_OBSERVE
1280 if (etimer_expired(&the_coap_context.notify_timer)) {
1282 etimer_reset(&the_coap_context.notify_timer);