Initial merge-commit of the OIC code. Should successfully do discovery for single...
[platform/upstream/iotivity.git] / csdk / libcoap-4.1.1 / net.c
1 /* net.c -- CoAP network interface
2  *
3  * Copyright (C) 2010--2014 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use.
7  */
8
9 #include "config.h"
10
11 #include <ctype.h>
12 #include <stdio.h>
13 #ifdef HAVE_LIMITS_H
14 #include <limits.h>
15 #endif
16 #ifdef HAVE_UNISTD_H
17 #include <unistd.h>
18 #elif HAVE_SYS_UNISTD_H
19 #include <sys/unistd.h>
20 #endif
21 #include <sys/types.h>
22 #ifdef HAVE_SYS_SOCKET_H
23 #include <sys/socket.h>
24 #endif
25 #ifdef HAVE_NETINET_IN_H
26 #include <netinet/in.h>
27 #endif
28 #ifdef HAVE_ARPA_INET_H
29 #include <arpa/inet.h>
30 #endif
31
32 #ifdef WITH_LWIP
33 #include <lwip/pbuf.h>
34 #include <lwip/udp.h>
35 #include <lwip/timers.h>
36 #endif
37
38 #include "debug.h"
39 #include "mem.h"
40 #include "str.h"
41 #include "async.h"
42 #include "resource.h"
43 #include "option.h"
44 #include "encode.h"
45 #include "block.h"
46 #include "net.h"
47
48 #if defined(WITH_POSIX)
49
50 #include <ocsocket.h>
51 #include <logger.h>
52
53 #define MOD_NAME ("net.c")
54
55 time_t clock_offset;
56
57 static inline coap_queue_t *
58 coap_malloc_node() {
59     return (coap_queue_t *)coap_malloc(sizeof(coap_queue_t));
60 }
61
62 static inline void
63 coap_free_node(coap_queue_t *node) {
64     coap_free(node);
65 }
66 #endif /* WITH_POSIX */
67 #ifdef WITH_LWIP
68
69 #include <lwip/memp.h>
70
71 static void coap_retransmittimer_execute(void *arg);
72 static void coap_retransmittimer_restart(coap_context_t *ctx);
73
74 static inline coap_queue_t *
75 coap_malloc_node() {
76     return (coap_queue_t *)memp_malloc(MEMP_COAP_NODE);
77 }
78
79 static inline void
80 coap_free_node(coap_queue_t *node) {
81     memp_free(MEMP_COAP_NODE, node);
82 }
83
84 #endif /* WITH_LWIP */
85 #ifdef WITH_CONTIKI
86 # ifndef DEBUG
87 #  define DEBUG DEBUG_PRINT
88 # endif /* DEBUG */
89
90 #include "memb.h"
91 #include "net/uip-debug.h"
92
93 clock_time_t clock_offset;
94
95 #define UIP_IP_BUF   ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
96 #define UIP_UDP_BUF  ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
97
98 void coap_resources_init();
99 void coap_pdu_resources_init();
100
101 unsigned char initialized = 0;
102 coap_context_t the_coap_context;
103
104 MEMB(node_storage, coap_queue_t, COAP_PDU_MAXCNT);
105
106 PROCESS(coap_retransmit_process, "message retransmit process");
107
108 static inline coap_queue_t *
109 coap_malloc_node() {
110     return (coap_queue_t *)memb_alloc(&node_storage);
111 }
112
113 static inline void
114 coap_free_node(coap_queue_t *node) {
115     memb_free(&node_storage, node);
116 }
117 #endif /* WITH_CONTIKI */
118 #ifdef WITH_LWIP
119
120 /** Callback to udp_recv when using lwIP. Gets called by lwIP on arriving
121  * packages, places a reference in context->pending_package, and calls
122  * coap_read to process the package. Thus, coap_read needs not be called in
123  * lwIP main loops. (When modifying this for thread-like operation, ie. if you
124  * remove the coap_read call from this, make sure that coap_read gets a chance
125  * to run before this callback is entered the next time.)
126  */
127 static void received_package(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
128 {
129     struct coap_context_t *context = (coap_context_t *)arg;
130
131     LWIP_ASSERT("pending_package was not cleared.", context->pending_package == NULL);
132
133     context->pending_package = p; /* we don't free it, coap_read has to do that */
134     context->pending_address.addr = addr->addr; /* FIXME: this has to become address-type independent, probably there'll be an lwip function for that */
135     context->pending_port = port;
136
137     coap_read(context, -1); /* we want to read from unicast socket */
138 }
139
140 #endif /* WITH_LWIP */
141
142 int print_wellknown(coap_context_t *, unsigned char *, size_t *, size_t,
143         coap_opt_t *);
144
145 void coap_handle_failed_notify(coap_context_t *, const coap_address_t *,
146         const str *);
147
148 unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now) {
149     unsigned int result = 0;
150     coap_tick_diff_t delta = now - ctx->sendqueue_basetime;
151
152     if (ctx->sendqueue) {
153         /* delta < 0 means that the new time stamp is before the old. */
154         if (delta <= 0) {
155             ctx->sendqueue->t -= delta;
156         } else {
157             /* This case is more complex: The time must be advanced forward,
158              * thus possibly leading to timed out elements at the queue's
159              * start. For every element that has timed out, its relative
160              * time is set to zero and the result counter is increased. */
161
162             coap_queue_t *q = ctx->sendqueue;
163             coap_tick_t t = 0;
164             while (q && (t + q->t < (coap_tick_t) delta)) {
165                 t += q->t;
166                 q->t = 0;
167                 result++;
168                 q = q->next;
169             }
170
171             /* finally adjust the first element that has not expired */
172             if (q) {
173                 q->t = (coap_tick_t) delta - t;
174             }
175         }
176     }
177
178     /* adjust basetime */
179     ctx->sendqueue_basetime += delta;
180
181     return result;
182 }
183
184 int coap_insert_node(coap_queue_t **queue, coap_queue_t *node) {
185     coap_queue_t *p, *q;
186     if (!queue || !node)
187         return 0;
188
189     /* set queue head if empty */
190     if (!*queue) {
191         *queue = node;
192         return 1;
193     }
194
195     /* replace queue head if PDU's time is less than head's time */
196     q = *queue;
197     if (node->t < q->t) {
198         node->next = q;
199         *queue = node;
200         q->t -= node->t; /* make q->t relative to node->t */
201         return 1;
202     }
203
204     /* search for right place to insert */
205     do {
206         node->t -= q->t; /* make node-> relative to q->t */
207         p = q;
208         q = q->next;
209     } while (q && q->t <= node->t);
210
211     /* insert new item */
212     if (q) {
213         q->t -= node->t; /* make q->t relative to node->t */
214     }
215     node->next = q;
216     p->next = node;
217     return 1;
218 }
219
220 int coap_delete_node(coap_queue_t *node) {
221     if (!node)
222         return 0;
223
224     coap_delete_pdu(node->pdu);
225     coap_free_node(node);
226
227     return 1;
228 }
229
230 void coap_delete_all(coap_queue_t *queue) {
231     if (!queue)
232         return;
233
234     coap_delete_all(queue->next);
235     coap_delete_node(queue);
236 }
237
238 coap_queue_t *
239 coap_new_node() {
240     coap_queue_t *node;
241     node = coap_malloc_node();
242
243     if (!node) {
244 #ifndef NDEBUG
245         coap_log(LOG_WARNING, "coap_new_node: malloc\n");
246 #endif
247         return NULL;
248     }
249
250     memset(node, 0, sizeof *node);
251     return node;
252 }
253
254 coap_queue_t *
255 coap_peek_next(coap_context_t *context) {
256     if (!context || !context->sendqueue)
257         return NULL;
258
259     return context->sendqueue;
260 }
261
262 coap_queue_t *
263 coap_pop_next(coap_context_t *context) {
264     coap_queue_t *next;
265
266     if (!context || !context->sendqueue)
267         return NULL;
268
269     next = context->sendqueue;
270     context->sendqueue = context->sendqueue->next;
271     if (context->sendqueue) {
272         context->sendqueue->t += next->t;
273     }
274     next->next = NULL;
275     return next;
276 }
277
278 #ifdef COAP_DEFAULT_WKC_HASHKEY
279 /** Checks if @p Key is equal to the pre-defined hash key for.well-known/core. */
280 #define is_wkc(Key)                                                     \
281   (memcmp((Key), COAP_DEFAULT_WKC_HASHKEY, sizeof(coap_key_t)) == 0)
282 #else
283 /* Implements a singleton to store a hash key for the .wellknown/core
284  * resources. */
285 int
286 is_wkc(coap_key_t k) {
287     static coap_key_t wkc;
288     static unsigned char _initialized = 0;
289     if (!_initialized) {
290         _initialized = coap_hash_path((unsigned char *)COAP_DEFAULT_URI_WELLKNOWN,
291                 sizeof(COAP_DEFAULT_URI_WELLKNOWN) - 1, wkc);
292     }
293     return memcmp(k, wkc, sizeof(coap_key_t)) == 0;
294 }
295 #endif
296
297 coap_context_t *
298 coap_new_context(const coap_address_t *listen_addr) {
299 #ifdef WITH_POSIX
300     coap_context_t *c = (coap_context_t*)coap_malloc( sizeof( coap_context_t ) );
301     //int reuse = 1;
302 #endif /* WITH_POSIX */
303 #ifdef WITH_LWIP
304     coap_context_t *c = memp_malloc(MEMP_COAP_CONTEXT);
305 #endif /* WITH_LWIP */
306 #ifdef WITH_CONTIKI
307     coap_context_t *c;
308
309     if (initialized)
310     return NULL;
311 #endif /* WITH_CONTIKI */
312
313     if (!listen_addr) {
314         coap_log(LOG_EMERG, "no listen address specified\n");
315         return NULL;
316     }
317
318     coap_clock_init();
319 #ifdef WITH_LWIP
320     prng_init(LWIP_RAND());
321 #else /* WITH_LWIP */
322     prng_init((unsigned long)listen_addr ^ clock_offset);
323 #endif /* WITH_LWIP */
324
325 #ifndef WITH_CONTIKI
326     if (!c) {
327 #ifndef NDEBUG
328         coap_log(LOG_EMERG, "coap_init: malloc:\n");
329 #endif
330         return NULL;
331     }
332 #endif /* not WITH_CONTIKI */
333 #ifdef WITH_CONTIKI
334     coap_resources_init();
335     coap_pdu_resources_init();
336
337     c = &the_coap_context;
338     initialized = 1;
339 #endif /* WITH_CONTIKI */
340
341     memset(c, 0, sizeof(coap_context_t));
342
343     /* set well-known sockfd to uninitialize value  */
344     c->sockfd_wellknown = -1;
345
346     /* initialize message id */
347     prng((unsigned char * )&c->message_id, sizeof(unsigned short));
348
349     /* register the critical options that we know */
350     coap_register_option(c, COAP_OPTION_IF_MATCH);
351     coap_register_option(c, COAP_OPTION_URI_HOST);
352     coap_register_option(c, COAP_OPTION_IF_NONE_MATCH);
353     coap_register_option(c, COAP_OPTION_URI_PORT);
354     coap_register_option(c, COAP_OPTION_URI_PATH);
355     coap_register_option(c, COAP_OPTION_URI_QUERY);
356     coap_register_option(c, COAP_OPTION_ACCEPT);
357     coap_register_option(c, COAP_OPTION_PROXY_URI);
358     coap_register_option(c, COAP_OPTION_PROXY_SCHEME);
359     coap_register_option(c, COAP_OPTION_BLOCK2);
360     coap_register_option(c, COAP_OPTION_BLOCK1);
361
362 #ifdef WITH_POSIX
363 #if 0
364     c->sockfd = socket(listen_addr->addr.sa.sa_family, SOCK_DGRAM, 0);
365     if ( c->sockfd < 0 ) {
366 #ifndef NDEBUG
367         coap_log(LOG_EMERG, "coap_new_context: socket\n");
368 #endif /* WITH_NDEBUG */
369         goto onerror;
370     }
371
372     if ( setsockopt( c->sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse) ) < 0 ) {
373 #ifndef NDEBUG
374         coap_log(LOG_WARNING, "setsockopt SO_REUSEADDR\n");
375 #endif
376     }
377
378     if (bind(c->sockfd, &listen_addr->addr.sa, listen_addr->size) < 0) {
379 #ifndef NDEBUG
380         coap_log(LOG_EMERG, "coap_new_context: bind\n");
381 #endif
382         goto onerror;
383     }
384
385     return c;
386
387     onerror:
388     if ( c->sockfd >= 0 )
389     close ( c->sockfd );
390     coap_free( c );
391     return NULL;
392 #endif //0
393     if (OCInitUDP((OCDevAddr *)listen_addr, (int32_t *)&(c->sockfd)) != ERR_SUCCESS) {
394         coap_free( c);
395         return NULL;
396     }
397     else {
398         return c;
399     }
400
401 #endif /* WITH_POSIX */
402 #ifdef WITH_CONTIKI
403     c->conn = udp_new(NULL, 0, NULL);
404     udp_bind(c->conn, listen_addr->port);
405
406     process_start(&coap_retransmit_process, (char *)c);
407
408     PROCESS_CONTEXT_BEGIN(&coap_retransmit_process);
409 #ifndef WITHOUT_OBSERVE
410     etimer_set(&c->notify_timer, COAP_RESOURCE_CHECK_TIME * COAP_TICKS_PER_SECOND);
411 #endif /* WITHOUT_OBSERVE */
412     /* the retransmit timer must be initialized to some large value */
413     etimer_set(&the_coap_context.retransmit_timer, 0xFFFF);
414     PROCESS_CONTEXT_END(&coap_retransmit_process);
415     return c;
416 #endif /* WITH_CONTIKI */
417 #ifdef WITH_LWIP
418     c->pcb = udp_new();
419     /* hard assert: this is not expected to fail dynamically */
420     LWIP_ASSERT("Failed to allocate PCB for CoAP", c->pcb != NULL);
421
422     udp_recv(c->pcb, received_package, (void*)c);
423     udp_bind(c->pcb, &listen_addr->addr, listen_addr->port);
424
425     c->timer_configured = 0;
426
427     return c;
428 #endif
429 }
430
431 void coap_free_context(coap_context_t *context) {
432 #if defined(WITH_POSIX) || defined(WITH_LWIP)
433     coap_resource_t *res;
434 #ifndef COAP_RESOURCES_NOHASH
435     coap_resource_t *rtmp;
436 #endif
437 #endif /* WITH_POSIX || WITH_LWIP */
438     if (!context)
439         return;
440
441     coap_delete_all(context->recvqueue);
442     coap_delete_all(context->sendqueue);
443
444 #ifdef WITH_LWIP
445     context->sendqueue = NULL;
446     coap_retransmittimer_restart(context);
447 #endif
448
449 #if defined(WITH_POSIX) || defined(WITH_LWIP)
450 #ifdef COAP_RESOURCES_NOHASH
451     LL_FOREACH(context->resources, res) {
452 #else
453         HASH_ITER(hh, context->resources, res, rtmp) {
454 #endif
455             coap_delete_resource(context, res->key);
456         }
457 #endif /* WITH_POSIX || WITH_LWIP */
458
459 #ifdef WITH_POSIX
460     /* coap_delete_list(context->subscriptions); */
461     OCClose( context->sockfd );
462     if (context->sockfd_wellknown != -1) {
463         OCClose( context->sockfd_wellknown );
464     }
465     coap_free( context );
466 #endif
467 #ifdef WITH_LWIP
468     udp_remove(context->pcb);
469     memp_free(MEMP_COAP_CONTEXT, context);
470 #endif
471 #ifdef WITH_CONTIKI
472     memset(&the_coap_context, 0, sizeof(coap_context_t));
473     initialized = 0;
474 #endif /* WITH_CONTIKI */
475 }
476
477 int coap_join_wellknown_group(coap_context_t *ctx,
478         const coap_address_t *multicast_addr) {
479 #ifdef WITH_POSIX
480     if (OCInitUDPMulticast((OCDevAddr *)multicast_addr,
481                     (int32_t *)&(ctx->sockfd_wellknown)) != ERR_SUCCESS) {
482         return 1;
483     }
484     return 0;
485 #endif
486 }
487
488 int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu,
489         coap_opt_filter_t unknown) {
490
491     coap_opt_iterator_t opt_iter;
492     int ok = 1;
493
494     coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL);
495
496     while (coap_option_next(&opt_iter)) {
497
498         /* The following condition makes use of the fact that
499          * coap_option_getb() returns -1 if type exceeds the bit-vector
500          * filter. As the vector is supposed to be large enough to hold
501          * the largest known option, we know that everything beyond is
502          * bad.
503          */
504         if (opt_iter.type & 0x01
505                 && coap_option_getb(ctx->known_options, opt_iter.type) < 1) {
506             debug("unknown critical option %d\n", opt_iter.type);
507
508             ok = 0;
509
510             /* When opt_iter.type is beyond our known option range,
511              * coap_option_setb() will return -1 and we are safe to leave
512              * this loop. */
513             if (coap_option_setb(unknown, opt_iter.type) == -1)
514                 break;
515         }
516     }
517
518     return ok;
519 }
520
521 void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu,
522         coap_tid_t *id) {
523     coap_key_t h;
524
525     memset(h, 0, sizeof(coap_key_t));
526
527     /* Compare the complete address structure in case of IPv4. For IPv6,
528      * we need to look at the transport address only. */
529
530 #ifdef WITH_POSIX
531     switch (peer->addr.sa.sa_family) {
532         case AF_INET:
533         coap_hash((const unsigned char *)&peer->addr.sa, peer->size, h);
534         break;
535         case AF_INET6:
536         coap_hash((const unsigned char *)&peer->addr.sin6.sin6_port,
537                 sizeof(peer->addr.sin6.sin6_port), h);
538         coap_hash((const unsigned char *)&peer->addr.sin6.sin6_addr,
539                 sizeof(peer->addr.sin6.sin6_addr), h);
540         break;
541         default:
542         return;
543     }
544 #endif
545 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
546     /* FIXME: with lwip, we can do better */
547     coap_hash((const unsigned char *)&peer->port, sizeof(peer->port), h);
548     coap_hash((const unsigned char *)&peer->addr, sizeof(peer->addr), h);
549 #endif /* WITH_LWIP || WITH_CONTIKI */
550
551     coap_hash((const unsigned char * )&pdu->hdr->id, sizeof(unsigned short), h);
552
553     *id = ((h[0] << 8) | h[1]) ^ ((h[2] << 8) | h[3]);
554 }
555
556 coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst,
557         coap_pdu_t *request) {
558     coap_pdu_t *response;
559     coap_tid_t result = COAP_INVALID_TID;
560
561     if (request && request->hdr->type == COAP_MESSAGE_CON) {
562         response = coap_pdu_init(COAP_MESSAGE_ACK, 0, request->hdr->id,
563                 sizeof(coap_pdu_t));
564         if (response) {
565             result = coap_send(context, dst, response);
566             coap_delete_pdu(response);
567         }
568     }
569     return result;
570 }
571
572 #ifdef WITH_POSIX
573 /* releases space allocated by PDU if free_pdu is set */
574 coap_tid_t
575 coap_send_impl(coap_context_t *context,
576         const coap_address_t *dst,
577         coap_pdu_t *pdu) {
578     ssize_t bytes_written;
579     coap_tid_t id = COAP_INVALID_TID;
580
581     if ( !context || !dst || !pdu )
582     return id;
583
584     //bytes_written = sendto( context->sockfd, pdu->hdr, pdu->length, 0,
585     //                    &dst->addr.sa, dst->size);
586     bytes_written = OCSendTo( context->sockfd, (uint8_t*)(pdu->hdr), pdu->length, 0,
587             (OCDevAddr*)dst);
588     printf("bytes_written %d\n", (int)bytes_written);
589
590     if (bytes_written >= 0) {
591         coap_transaction_id(dst, pdu, &id);
592     } else {
593         coap_log(LOG_CRIT, "coap_send: sendto\n");
594     }
595
596     return id;
597 }
598 #endif /* WITH_POSIX */
599 #ifdef WITH_CONTIKI
600 /* releases space allocated by PDU if free_pdu is set */
601 coap_tid_t
602 coap_send_impl(coap_context_t *context,
603         const coap_address_t *dst,
604         coap_pdu_t *pdu) {
605     coap_tid_t id = COAP_INVALID_TID;
606
607     if ( !context || !dst || !pdu )
608     return id;
609
610     /* FIXME: is there a way to check if send was successful? */
611     uip_udp_packet_sendto(context->conn, pdu->hdr, pdu->length,
612             &dst->addr, dst->port);
613
614     coap_transaction_id(dst, pdu, &id);
615
616     return id;
617 }
618 #endif /* WITH_CONTIKI */
619 #ifdef WITH_LWIP
620 coap_tid_t
621 coap_send_impl(coap_context_t *context,
622         const coap_address_t *dst,
623         coap_pdu_t *pdu) {
624     coap_tid_t id = COAP_INVALID_TID;
625     struct pbuf *p;
626     uint8_t err;
627     char *data_backup;
628
629     if ( !context || !dst || !pdu )
630     {
631         return id;
632     }
633
634     data_backup = pdu->data;
635
636     /* FIXME: we can't check this here with the existing infrastructure, but we
637      * should actually check that the pdu is not held by anyone but us. the
638      * respective pbuf is already exclusively owned by the pdu. */
639
640     p = pdu->pbuf;
641     LWIP_ASSERT("The PDU header is not where it is expected", pdu->hdr == p->payload + sizeof(coap_pdu_t));
642
643     err = pbuf_header(p, -sizeof(coap_pdu_t));
644     if (err)
645     {
646         debug("coap_send_impl: pbuf_header failed\n");
647         pbuf_free(p);
648         return id;
649     }
650
651     coap_transaction_id(dst, pdu, &id);
652
653     pbuf_realloc(p, pdu->length);
654
655     udp_sendto(context->pcb, p,
656             &dst->addr, dst->port);
657
658     pbuf_header(p, -(ptrdiff_t)((uint8_t*)pdu - (uint8_t*)p->payload) - sizeof(coap_pdu_t)); /* FIXME hack around udp_sendto not restoring; see http://lists.gnu.org/archive/html/lwip-users/2013-06/msg00008.html. for udp over ip over ethernet, this was -42; as we're doing ppp too, this has to be calculated generically */
659
660     err = pbuf_header(p, sizeof(coap_pdu_t));
661     LWIP_ASSERT("Cannot undo pbuf_header", err == 0);
662
663     /* restore destroyed pdu data */
664     LWIP_ASSERT("PDU not restored", p->payload == pdu);
665     pdu->max_size = p->tot_len - sizeof(coap_pdu_t); /* reduced after pbuf_realloc */
666     pdu->hdr = p->payload + sizeof(coap_pdu_t);
667     pdu->max_delta = 0; /* won't be used any more */
668     pdu->length = pdu->max_size;
669     pdu->data = data_backup;
670     pdu->pbuf = p;
671
672     return id;
673 }
674 #endif /* WITH_LWIP */
675
676 coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst,
677         coap_pdu_t *pdu) {
678     return coap_send_impl(context, dst, pdu);
679 }
680
681 coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request,
682         const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts) {
683     coap_pdu_t *response;
684     coap_tid_t result = COAP_INVALID_TID;
685
686     assert(request);
687     assert(dst);
688
689     response = coap_new_error_response(request, code, opts);
690     if (response) {
691         result = coap_send(context, dst, response);
692         coap_delete_pdu(response);
693     }
694
695     return result;
696 }
697
698 coap_tid_t coap_send_message_type(coap_context_t *context,
699         const coap_address_t *dst, coap_pdu_t *request, unsigned char type) {
700     coap_pdu_t *response;
701     coap_tid_t result = COAP_INVALID_TID;
702
703     if (request) {
704         response = coap_pdu_init(type, 0, request->hdr->id, sizeof(coap_pdu_t));
705         if (response) {
706             result = coap_send(context, dst, response);
707             coap_delete_pdu(response);
708         }
709     }
710     return result;
711 }
712
713 coap_tid_t coap_send_confirmed(coap_context_t *context,
714         const coap_address_t *dst, coap_pdu_t *pdu) {
715     coap_queue_t *node;
716     coap_tick_t now;
717     int r;
718
719     node = coap_new_node();
720     if (!node) {
721         debug("coap_send_confirmed: insufficient memory\n");
722         return COAP_INVALID_TID;
723     }
724
725     node->id = coap_send_impl(context, dst, pdu);
726     if (COAP_INVALID_TID == node->id) {
727         debug("coap_send_confirmed: error sending pdu\n");
728         coap_free_node(node);
729         return COAP_INVALID_TID;
730     }
731
732     prng((unsigned char * )&r, sizeof(r));
733
734     /* add randomized RESPONSE_TIMEOUT to determine retransmission timeout */
735     node->timeout = COAP_DEFAULT_RESPONSE_TIMEOUT * COAP_TICKS_PER_SECOND
736             + (COAP_DEFAULT_RESPONSE_TIMEOUT >> 1)
737                     * ((COAP_TICKS_PER_SECOND * (r & 0xFF)) >> 8);
738
739     memcpy(&node->remote, dst, sizeof(coap_address_t));
740     node->pdu = pdu;
741
742     /* Set timer for pdu retransmission. If this is the first element in
743      * the retransmission queue, the base time is set to the current
744      * time and the retransmission time is node->timeout. If there is
745      * already an entry in the sendqueue, we must check if this node is
746      * to be retransmitted earlier. Therefore, node->timeout is first
747      * normalized to the base time and then inserted into the queue with
748      * an adjusted relative time.
749      */coap_ticks(&now);
750     if (context->sendqueue == NULL) {
751         node->t = node->timeout;
752         context->sendqueue_basetime = now;
753     } else {
754         /* make node->t relative to context->sendqueue_basetime */
755         node->t = (now - context->sendqueue_basetime) + node->timeout;
756     }
757
758     coap_insert_node(&context->sendqueue, node);
759
760 #ifdef WITH_LWIP
761     if (node == context->sendqueue) /* don't bother with timer stuff if there are earlier retransmits */
762     coap_retransmittimer_restart(context);
763 #endif
764
765 #ifdef WITH_CONTIKI
766     { /* (re-)initialize retransmission timer */
767         coap_queue_t *nextpdu;
768
769         nextpdu = coap_peek_next(context);
770         assert(nextpdu); /* we have just inserted a node */
771
772         /* must set timer within the context of the retransmit process */
773         PROCESS_CONTEXT_BEGIN(&coap_retransmit_process);
774         etimer_set(&context->retransmit_timer, nextpdu->t);
775         PROCESS_CONTEXT_END(&coap_retransmit_process);
776     }
777 #endif /* WITH_CONTIKI */
778
779     return node->id;
780 }
781
782 coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node) {
783     if (!context || !node)
784         return COAP_INVALID_TID;
785
786     /* re-initialize timeout when maximum number of retransmissions are not reached yet */
787     if (node->retransmit_cnt < COAP_DEFAULT_MAX_RETRANSMIT) {
788         node->retransmit_cnt++;
789         node->t = node->timeout << node->retransmit_cnt;
790         coap_insert_node(&context->sendqueue, node);
791 #ifdef WITH_LWIP
792         if (node == context->sendqueue) /* don't bother with timer stuff if there are earlier retransmits */
793         coap_retransmittimer_restart(context);
794 #endif
795
796         debug("** retransmission #%d of transaction %d\n", node->retransmit_cnt,
797                 ntohs(node->pdu->hdr->id));
798
799         node->id = coap_send_impl(context, &node->remote, node->pdu);
800         return node->id;
801     }
802
803     /* no more retransmissions, remove node from system */
804
805 #ifndef WITH_CONTIKI
806     debug("** removed transaction %d\n", ntohs(node->id));
807 #endif
808
809 #ifndef WITHOUT_OBSERVE
810     /* Check if subscriptions exist that should be canceled after
811      COAP_MAX_NOTIFY_FAILURES */
812     if (node->pdu->hdr->code >= 64) {
813         str token = { 0, NULL };
814
815         token.length = node->pdu->hdr->token_length;
816         token.s = node->pdu->hdr->token;
817
818         coap_handle_failed_notify(context, &node->remote, &token);
819     }
820 #endif /* WITHOUT_OBSERVE */
821
822     /* And finally delete the node */
823     coap_delete_node(node);
824     return COAP_INVALID_TID;
825 }
826
827 /**
828  * Checks if @p opt fits into the message that ends with @p maxpos.
829  * This function returns @c 1 on success, or @c 0 if the option @p opt
830  * would exceed @p maxpos.
831  */
832 static inline int check_opt_size(coap_opt_t *opt, unsigned char *maxpos) {
833     if (opt && opt < maxpos) {
834         if (((*opt & 0x0f) < 0x0f) || (opt + 1 < maxpos))
835             return opt + COAP_OPT_SIZE(opt) < maxpos;
836     }
837     return 0;
838 }
839
840 int coap_read(coap_context_t *ctx, int sockfd) {
841 #ifdef WITH_POSIX
842     static char buf[COAP_MAX_PDU_SIZE];
843 #endif
844 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
845     char *buf;
846 #endif
847     coap_hdr_t *pdu;
848     ssize_t bytes_read = -1;
849     coap_address_t src, dst;
850     coap_queue_t *node;
851
852 #ifdef WITH_CONTIKI
853     buf = uip_appdata;
854 #endif /* WITH_CONTIKI */
855 #ifdef WITH_LWIP
856     LWIP_ASSERT("No package pending", ctx->pending_package != NULL);
857     LWIP_ASSERT("Can only deal with contiguous PBUFs to read the initial details", ctx->pending_package->tot_len == ctx->pending_package->len);
858     buf = ctx->pending_package->payload;
859 #endif /* WITH_LWIP */
860
861     pdu = (coap_hdr_t *) buf;
862
863     coap_address_init(&src);
864
865 #ifdef WITH_POSIX
866     //bytes_read = recvfrom(ctx->sockfd, buf, sizeof(buf), 0,
867     //                  &src.addr.sa, &src.size);
868
869     bytes_read = OCRecvFrom( sockfd, (uint8_t*)buf, sizeof(buf), 0,
870             (OCDevAddr*)&src);
871 #endif /* WITH_POSIX */
872 #ifdef WITH_CONTIKI
873     if(uip_newdata()) {
874         uip_ipaddr_copy(&src.addr, &UIP_IP_BUF->srcipaddr);
875         src.port = UIP_UDP_BUF->srcport;
876         uip_ipaddr_copy(&dst.addr, &UIP_IP_BUF->destipaddr);
877         dst.port = UIP_UDP_BUF->destport;
878
879         bytes_read = uip_datalen();
880         ((char *)uip_appdata)[bytes_read] = 0;
881         PRINTF("Server received %d bytes from [", (int)bytes_read);
882         PRINT6ADDR(&src.addr);
883         PRINTF("]:%d\n", uip_ntohs(src.port));
884     }
885 #endif /* WITH_CONTIKI */
886 #ifdef WITH_LWIP
887     /* FIXME: use lwip address operation functions */
888     src.addr.addr = ctx->pending_address.addr;
889     src.port = ctx->pending_port;
890     bytes_read = ctx->pending_package->tot_len;
891 #endif /* WITH_LWIP */
892
893     if (bytes_read < 0) {
894         warn("coap_read: recvfrom");
895         goto error_early;
896     }
897
898     if ((size_t) bytes_read < sizeof(coap_hdr_t)) {
899         debug("coap_read: discarded invalid frame\n");
900         goto error_early;
901     }
902
903     if (pdu->version != COAP_DEFAULT_VERSION) {
904         debug("coap_read: unknown protocol version\n");
905         goto error_early;
906     }
907
908     node = coap_new_node();
909     if (!node)
910         goto error_early;
911
912 #ifdef WITH_LWIP
913     node->pdu = coap_pdu_from_pbuf(ctx->pending_package);
914     ctx->pending_package = NULL;
915 #else
916     node->pdu = coap_pdu_init(0, 0, 0, bytes_read);
917 #endif
918     if (!node->pdu)
919         goto error;
920
921     coap_ticks(&node->t);
922     memcpy(&node->local, &dst, sizeof(coap_address_t));
923     memcpy(&node->remote, &src, sizeof(coap_address_t));
924
925     if (!coap_pdu_parse((unsigned char *) buf, bytes_read, node->pdu)) {
926         warn("discard malformed PDU");
927         goto error;
928     }
929
930     /* and add new node to receive queue */
931     coap_transaction_id(&node->remote, node->pdu, &node->id);
932     coap_insert_node(&ctx->recvqueue, node);
933
934 #ifndef NDEBUG
935     if (LOG_DEBUG <= coap_get_log_level()) {
936 #ifndef INET6_ADDRSTRLEN
937 #define INET6_ADDRSTRLEN 40
938 #endif
939         unsigned char addr[INET6_ADDRSTRLEN + 8];
940
941         if (coap_print_addr(&src, addr, INET6_ADDRSTRLEN + 8))
942             debug("** received %d bytes from %s:\n", (int )bytes_read, addr);
943
944         coap_show_pdu(node->pdu);
945     }
946 #endif
947
948     return 0;
949
950     error:
951     /* FIXME: send back RST? */
952     coap_delete_node(node);
953     return -1;
954     error_early:
955 #ifdef WITH_LWIP
956     /* even if there was an error, clean up */
957     pbuf_free(ctx->pending_package);
958     ctx->pending_package = NULL;
959 #endif
960     return -1;
961 }
962
963 int coap_remove_from_queue(coap_queue_t **queue, coap_tid_t id,
964         coap_queue_t **node) {
965     coap_queue_t *p, *q;
966
967     if (!queue || !*queue)
968         return 0;
969
970     /* replace queue head if PDU's time is less than head's time */
971
972     if (id == (*queue)->id) { /* found transaction */
973         *node = *queue;
974         *queue = (*queue)->next;
975         if (*queue) { /* adjust relative time of new queue head */
976             (*queue)->t += (*node)->t;
977         }
978         (*node)->next = NULL;
979         /* coap_delete_node( q ); */
980         debug("*** removed transaction %u\n", id);
981         return 1;
982     }
983
984     /* search transaction to remove (only first occurence will be removed) */
985     q = *queue;
986     do {
987         p = q;
988         q = q->next;
989     } while (q && id != q->id);
990
991     if (q) { /* found transaction */
992         p->next = q->next;
993         if (p->next) { /* must update relative time of p->next */
994             p->next->t += q->t;
995         }
996         q->next = NULL;
997         *node = q;
998         /* coap_delete_node( q ); */
999         debug("*** removed transaction %u\n", id);
1000         return 1;
1001     }
1002
1003     return 0;
1004
1005 }
1006
1007 static inline int token_match(const unsigned char *a, size_t alen,
1008         const unsigned char *b, size_t blen) {
1009     return alen == blen && (alen == 0 || memcmp(a, b, alen) == 0);
1010 }
1011
1012 void coap_cancel_all_messages(coap_context_t *context,
1013         const coap_address_t *dst, const unsigned char *token,
1014         size_t token_length) {
1015     /* cancel all messages in sendqueue that are for dst
1016      * and use the specified token */
1017     coap_queue_t *p, *q;
1018
1019     debug("cancel_all_messages\n");
1020     while (context->sendqueue
1021             && coap_address_equals(dst, &context->sendqueue->remote)
1022             && token_match(token, token_length,
1023                     context->sendqueue->pdu->hdr->token,
1024                     context->sendqueue->pdu->hdr->token_length)) {
1025         q = context->sendqueue;
1026         context->sendqueue = q->next;
1027         debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->id));
1028         coap_delete_node(q);
1029     }
1030
1031     if (!context->sendqueue)
1032         return;
1033
1034     p = context->sendqueue;
1035     q = p->next;
1036
1037     /* when q is not NULL, it does not match (dst, token), so we can skip it */
1038     while (q) {
1039         if (coap_address_equals(dst, &q->remote)
1040                 && token_match(token, token_length, q->pdu->hdr->token,
1041                         q->pdu->hdr->token_length)) {
1042             p->next = q->next;
1043             debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->id));
1044             coap_delete_node(q);
1045             q = p->next;
1046         } else {
1047             p = q;
1048             q = q->next;
1049         }
1050     }
1051 }
1052
1053 coap_queue_t *
1054 coap_find_transaction(coap_queue_t *queue, coap_tid_t id) {
1055     while (queue && queue->id != id)
1056         queue = queue->next;
1057
1058     return queue;
1059 }
1060
1061 coap_pdu_t *
1062 coap_new_error_response(coap_pdu_t *request, unsigned char code,
1063         coap_opt_filter_t opts) {
1064     coap_opt_iterator_t opt_iter;
1065     coap_pdu_t *response;
1066     size_t size = sizeof(coap_hdr_t) + request->hdr->token_length;
1067     int type;
1068     coap_opt_t *option;
1069     unsigned short opt_type = 0; /* used for calculating delta-storage */
1070
1071 #if COAP_ERROR_PHRASE_LENGTH > 0
1072     char *phrase = coap_response_phrase(code);
1073
1074     /* Need some more space for the error phrase and payload start marker */
1075     if (phrase)
1076         size += strlen(phrase) + 1;
1077 #endif
1078
1079     assert(request);
1080
1081     /* cannot send ACK if original request was not confirmable */
1082     type = request->hdr->type == COAP_MESSAGE_CON ?
1083             COAP_MESSAGE_ACK : COAP_MESSAGE_NON;
1084
1085     /* Estimate how much space we need for options to copy from
1086      * request. We always need the Token, for 4.02 the unknown critical
1087      * options must be included as well. */
1088     coap_option_clrb(opts, COAP_OPTION_CONTENT_TYPE); /* we do not want this */
1089
1090     coap_option_iterator_init(request, &opt_iter, opts);
1091
1092     /* Add size of each unknown critical option. As known critical
1093      options as well as elective options are not copied, the delta
1094      value might grow.
1095      */
1096     while ((option = coap_option_next(&opt_iter))) {
1097         unsigned short delta = opt_iter.type - opt_type;
1098         /* calculate space required to encode (opt_iter.type - opt_type) */
1099         if (delta < 13) {
1100             size++;
1101         } else if (delta < 269) {
1102             size += 2;
1103         } else {
1104             size += 3;
1105         }
1106
1107         /* add coap_opt_length(option) and the number of additional bytes
1108          * required to encode the option length */
1109
1110         size += coap_opt_length(option);
1111         switch (*option & 0x0f) {
1112         case 0x0e:
1113             size++;
1114             /* fall through */
1115         case 0x0d:
1116             size++;
1117             break;
1118         default:
1119             ;
1120         }
1121
1122         opt_type = opt_iter.type;
1123     }
1124
1125     /* Now create the response and fill with options and payload data. */
1126     response = coap_pdu_init(type, code, request->hdr->id, size);
1127     if (response) {
1128         /* copy token */
1129         if (!coap_add_token(response, request->hdr->token_length,
1130                 request->hdr->token)) {
1131             debug("cannot add token to error response\n");
1132             coap_delete_pdu(response);
1133             return NULL;
1134         }
1135
1136         /* copy all options */
1137         coap_option_iterator_init(request, &opt_iter, opts);
1138         while ((option = coap_option_next(&opt_iter)))
1139             coap_add_option(response, opt_iter.type, COAP_OPT_LENGTH(option),
1140                     COAP_OPT_VALUE(option));
1141
1142 #if COAP_ERROR_PHRASE_LENGTH > 0
1143         /* note that diagnostic messages do not need a Content-Format option. */
1144         if (phrase)
1145             coap_add_data(response, strlen(phrase), (unsigned char *) phrase);
1146 #endif
1147     }
1148
1149     return response;
1150 }
1151
1152 /**
1153  * Quick hack to determine the size of the resource description for
1154  * .well-known/core.
1155  */
1156 static inline size_t get_wkc_len(coap_context_t *context,
1157         coap_opt_t *query_filter) {
1158     unsigned char buf[1];
1159     size_t len = 0;
1160
1161     if (print_wellknown(context, buf, &len, UINT_MAX,
1162             query_filter) & COAP_PRINT_STATUS_ERROR) {
1163         warn("cannot determine length of /.well-known/core\n");
1164         return 0;
1165     }
1166
1167     debug("get_wkc_len: print_wellknown() returned %zu\n", len);
1168
1169     return len;
1170 }
1171
1172 #define SZX_TO_BYTES(SZX) ((size_t)(1 << ((SZX) + 4)))
1173
1174 coap_pdu_t *
1175 wellknown_response(coap_context_t *context, coap_pdu_t *request) {
1176     coap_pdu_t *resp;
1177     coap_opt_iterator_t opt_iter;
1178     size_t len, wkc_len;
1179     unsigned char buf[2];
1180     int result = 0;
1181     int need_block2 = 0; /* set to 1 if Block2 option is required */
1182     coap_block_t block;
1183     coap_opt_t *query_filter;
1184     size_t offset = 0;
1185
1186     resp = coap_pdu_init(
1187             request->hdr->type == COAP_MESSAGE_CON ?
1188                     COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
1189             COAP_RESPONSE_CODE(205), request->hdr->id, COAP_MAX_PDU_SIZE);
1190     if (!resp) {
1191         debug("wellknown_response: cannot create PDU\n");
1192         return NULL;
1193     }
1194
1195     if (!coap_add_token(resp, request->hdr->token_length,
1196             request->hdr->token)) {
1197         debug("wellknown_response: cannot add token\n");
1198         goto error;
1199     }
1200
1201     query_filter = coap_check_option(request, COAP_OPTION_URI_QUERY, &opt_iter);
1202     wkc_len = get_wkc_len(context, query_filter);
1203
1204     /* check whether the request contains the Block2 option */
1205     if (coap_get_block(request, COAP_OPTION_BLOCK2, &block)) {
1206         offset = block.num << (block.szx + 4);
1207         if (block.szx > 6) { /* invalid, MUST lead to 4.00 Bad Request */
1208             resp->hdr->code = COAP_RESPONSE_CODE(400);
1209             return resp;
1210         } else if (block.szx > COAP_MAX_BLOCK_SZX) {
1211             block.szx = COAP_MAX_BLOCK_SZX;
1212             block.num = offset >> (block.szx + 4);
1213         }
1214
1215         need_block2 = 1;
1216     }
1217
1218     /* Check if there is sufficient space to add Content-Format option
1219      * and data. We do this before adding the Content-Format option to
1220      * avoid sending error responses with that option but no actual
1221      * content. */
1222     if (resp->max_size <= (size_t) resp->length + 3) {
1223         debug("wellknown_response: insufficient storage space\n");
1224         goto error;
1225     }
1226
1227     /* Add Content-Format. As we have checked for available storage,
1228      * nothing should go wrong here. */
1229     assert(
1230             coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT)
1231                     == 1);
1232     coap_add_option(resp, COAP_OPTION_CONTENT_FORMAT,
1233             coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT),
1234             buf);
1235
1236     /* check if Block2 option is required even if not requested */
1237     if (!need_block2 && (resp->max_size - (size_t) resp->length < wkc_len)) {
1238         assert(resp->length <= resp->max_size);
1239         const size_t payloadlen = resp->max_size - resp->length;
1240         /* yes, need block-wise transfer */
1241         block.num = 0;
1242         block.m = 0; /* the M bit is set by coap_write_block_opt() */
1243         block.szx = COAP_MAX_BLOCK_SZX;
1244         while (payloadlen < SZX_TO_BYTES(block.szx)) {
1245             if (block.szx == 0) {
1246                 debug(
1247                         "wellknown_response: message to small even for szx == 0\n");
1248                 goto error;
1249             } else {
1250                 block.szx--;
1251             }
1252         }
1253
1254         need_block2 = 1;
1255     }
1256
1257     /* write Block2 option if necessary */
1258     if (need_block2) {
1259         if (coap_write_block_opt(&block, COAP_OPTION_BLOCK2, resp, wkc_len)
1260                 < 0) {
1261             debug("wellknown_response: cannot add Block2 option\n");
1262             goto error;
1263         }
1264     }
1265
1266     /* Manually set payload of response to let print_wellknown() write,
1267      * into our buffer without copying data. */
1268
1269     resp->data = (unsigned char *) resp->hdr + resp->length;
1270     *resp->data = COAP_PAYLOAD_START;
1271     resp->data++;
1272     resp->length++;
1273     len = need_block2 ? SZX_TO_BYTES(block.szx) : resp->max_size - resp->length;
1274
1275     result = print_wellknown(context, resp->data, &len, offset, query_filter);
1276     if ((result & COAP_PRINT_STATUS_ERROR) != 0) {
1277         debug("print_wellknown failed\n");
1278         goto error;
1279     }
1280
1281     resp->length += COAP_PRINT_OUTPUT_LENGTH(result);
1282     return resp;
1283
1284     error:
1285     /* set error code 5.03 and remove all options and data from response */
1286     resp->hdr->code = COAP_RESPONSE_CODE(503);
1287     resp->length = sizeof(coap_hdr_t) + resp->hdr->token_length;
1288     return resp;
1289 }
1290
1291 #define WANT_WKC(Pdu,Key)                                       \
1292   (((Pdu)->hdr->code == COAP_REQUEST_GET) && is_wkc(Key))
1293
1294 #if 0
1295 void
1296 handle_request(coap_context_t *context, coap_queue_t *node) {
1297     coap_method_handler_t h = NULL;
1298     coap_pdu_t *response = NULL;
1299     coap_opt_filter_t opt_filter;
1300     coap_resource_t *resource;
1301     coap_key_t key;
1302
1303     coap_option_filter_clear(opt_filter);
1304
1305     /* try to find the resource from the request URI */
1306     coap_hash_request_uri(node->pdu, key);
1307     resource = coap_get_resource_from_key(context, key);
1308
1309     if (!resource) {
1310         /* The resource was not found. Check if the request URI happens to
1311          * be the well-known URI. In that case, we generate a default
1312          * response, otherwise, we return 4.04 */
1313
1314         switch(node->pdu->hdr->code) {
1315
1316             case COAP_REQUEST_GET:
1317             if (is_wkc(key)) { /* GET request for .well-known/core */
1318                 info("create default response for %s\n", COAP_DEFAULT_URI_WELLKNOWN);
1319                 response = wellknown_response(context, node->pdu);
1320
1321             } else { /* GET request for any another resource, return 4.04 */
1322
1323                 debug("GET for unknown resource 0x%02x%02x%02x%02x, return 4.04\n",
1324                         key[0], key[1], key[2], key[3]);
1325                 response =
1326                 coap_new_error_response(node->pdu, COAP_RESPONSE_CODE(404),
1327                         opt_filter);
1328             }
1329             break;
1330
1331             default: /* any other request type */
1332
1333             debug("unhandled request for unknown resource 0x%02x%02x%02x%02x\r\n",
1334                     key[0], key[1], key[2], key[3]);
1335             if (!coap_is_mcast(&node->local))
1336             response = coap_new_error_response(node->pdu, COAP_RESPONSE_CODE(405),
1337                     opt_filter);
1338         }
1339
1340         if (response && coap_send(context, &node->remote, response) == COAP_INVALID_TID) {
1341             warn("cannot send response for transaction %u\n", node->id);
1342         }
1343         coap_delete_pdu(response);
1344
1345         return;
1346     }
1347
1348     /* the resource was found, check if there is a registered handler */
1349     if ((size_t)node->pdu->hdr->code - 1 <
1350             sizeof(resource->handler)/sizeof(coap_method_handler_t))
1351     h = resource->handler[node->pdu->hdr->code - 1];
1352
1353     if (h) {
1354         debug("call custom handler for resource 0x%02x%02x%02x%02x\n",
1355                 key[0], key[1], key[2], key[3]);
1356         response = coap_pdu_init(node->pdu->hdr->type == COAP_MESSAGE_CON
1357                 ? COAP_MESSAGE_ACK
1358                 : COAP_MESSAGE_NON,
1359                 0, node->pdu->hdr->id, COAP_MAX_PDU_SIZE);
1360
1361         /* Implementation detail: coap_add_token() immediately returns 0
1362          if response == NULL */
1363         if (coap_add_token(response, node->pdu->hdr->token_length,
1364                         node->pdu->hdr->token)) {
1365             str token = {node->pdu->hdr->token_length, node->pdu->hdr->token};
1366
1367             h(context, resource, &node->remote,
1368                     node->pdu, &token, response);
1369             if (response->hdr->type != COAP_MESSAGE_NON ||
1370                     (response->hdr->code >= 64
1371                             && !coap_is_mcast(&node->local))) {
1372                 if (coap_send(context, &node->remote, response) == COAP_INVALID_TID) {
1373                     debug("cannot send response for message %d\n", node->pdu->hdr->id);
1374                 }
1375             }
1376
1377             coap_delete_pdu(response);
1378         } else {
1379             warn("cannot generate response\r\n");
1380         }
1381     } else {
1382         if (WANT_WKC(node->pdu, key)) {
1383             debug("create default response for %s\n", COAP_DEFAULT_URI_WELLKNOWN);
1384             response = wellknown_response(context, node->pdu);
1385         } else
1386         response = coap_new_error_response(node->pdu, COAP_RESPONSE_CODE(405),
1387                 opt_filter);
1388
1389         if (!response || (coap_send(context, &node->remote, response)
1390                         == COAP_INVALID_TID)) {
1391             debug("cannot send response for transaction %u\n", node->id);
1392         }
1393         coap_delete_pdu(response);
1394     }
1395 }
1396 #endif
1397 static inline void handle_request(coap_context_t *context, coap_queue_t *rcvd) {
1398
1399     /* Call application-specific reponse handler when available.  If
1400      * not, we must acknowledge confirmable messages. */
1401     if (context->request_handler) {
1402         context->request_handler(context, rcvd);
1403     } else {
1404         /* send ACK if rcvd is confirmable (i.e. a separate response) */
1405         coap_send_ack(context, &rcvd->remote, rcvd->pdu);
1406     }
1407 }
1408
1409 static inline void handle_response(coap_context_t *context, coap_queue_t *rcvd) {
1410
1411     /* Call application-specific reponse handler when available.  If
1412      * not, we must acknowledge confirmable messages. */
1413     if (context->response_handler) {
1414         context->response_handler(context, rcvd);
1415     } else {
1416         /* send ACK if rcvd is confirmable (i.e. a separate response) */
1417         coap_send_ack(context, &rcvd->remote, rcvd->pdu);
1418     }
1419 }
1420
1421 static inline int
1422 #ifdef __GNUC__
1423 handle_locally(coap_context_t *context __attribute__ ((unused)),
1424         coap_queue_t *node __attribute__ ((unused))) {
1425 #else /* not a GCC */
1426     handle_locally(coap_context_t *context, coap_queue_t *node) {
1427 #endif /* GCC */
1428         /* this function can be used to check if node->pdu is really for us */
1429         return 1;
1430     }
1431
1432     /**
1433      * This function handles RST messages received for the message passed
1434      * in @p sent.
1435      */
1436     static void coap_handle_rst(coap_context_t *context,
1437             const coap_queue_t *sent) {
1438 #ifndef WITHOUT_OBSERVE
1439         coap_resource_t *r;
1440 #ifndef COAP_RESOURCES_NOHASH
1441         coap_resource_t *tmp;
1442 #endif
1443         str token = { 0, NULL };
1444
1445         /* remove observer for this resource, if any
1446          * get token from sent and try to find a matching resource. Uh!
1447          */
1448
1449         COAP_SET_STR(&token, sent->pdu->hdr->token_length,
1450                 sent->pdu->hdr->token);
1451
1452 #ifndef WITH_CONTIKI
1453 #ifdef COAP_RESOURCES_NOHASH
1454         LL_FOREACH(context->resources, r) {
1455 #else
1456         HASH_ITER(hh, context->resources, r, tmp)
1457         {
1458 #endif
1459             coap_delete_observer(r, &sent->remote, &token);
1460             coap_cancel_all_messages(context, &sent->remote, token.s,
1461                     token.length);
1462         }
1463 #else /* WITH_CONTIKI */
1464         r = (coap_resource_t *)resource_storage.mem;
1465         for (i = 0; i < resource_storage.num; ++i, ++r) {
1466             if (resource_storage.count[i]) {
1467                 coap_delete_observer(r, &sent->remote, &token);
1468                 coap_cancel_all_messages(context, &sent->remote, token.s, token.length);
1469             }
1470         }
1471 #endif /* WITH_CONTIKI */
1472 #endif /* WITOUT_OBSERVE */
1473     }
1474
1475     void coap_dispatch(coap_context_t *context) {
1476         coap_queue_t *rcvd = NULL, *sent = NULL;
1477         coap_pdu_t *response;
1478         coap_opt_filter_t opt_filter;
1479
1480         if (!context)
1481             return;
1482
1483         memset(opt_filter, 0, sizeof(coap_opt_filter_t));
1484
1485         while (context->recvqueue) {
1486             rcvd = context->recvqueue;
1487
1488             /* remove node from recvqueue */
1489             context->recvqueue = context->recvqueue->next;
1490             rcvd->next = NULL;
1491
1492             if (rcvd->pdu->hdr->version != COAP_DEFAULT_VERSION) {
1493                 debug("dropped packet with unknown version %u\n",
1494                         rcvd->pdu->hdr->version);
1495                 goto cleanup;
1496             }
1497
1498             switch (rcvd->pdu->hdr->type) {
1499             case COAP_MESSAGE_NON: /* check for unknown critical options */
1500                 if (coap_option_check_critical(context, rcvd->pdu, opt_filter)
1501                         == 0)
1502                     goto cleanup;
1503                 break;
1504             default:
1505                 // TODO : need to handle other message types in  coap_dispatch;;;;;;;;;;;;;;;;
1506                 debug("Need to handle other message types in  coap_dispatch;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
1507             }
1508 #if 0
1509             switch (rcvd->pdu->hdr->type) {
1510                 case COAP_MESSAGE_ACK:
1511                 /* find transaction in sendqueue to stop retransmission */
1512                 coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent);
1513
1514                 if (rcvd->pdu->hdr->code == 0)
1515                 goto cleanup;
1516
1517                 /* FIXME: if sent code was >= 64 the message might have been a
1518                  * notification. Then, we must flag the observer to be alive
1519                  * by setting obs->fail_cnt = 0. */
1520                 if (sent && COAP_RESPONSE_CLASS(sent->pdu->hdr->code) == 2) {
1521                     const str token = {sent->pdu->hdr->token_length,
1522                         sent->pdu->hdr->token};
1523                     coap_touch_observer(context, &sent->remote, &token);
1524                 }
1525                 break;
1526
1527                 case COAP_MESSAGE_RST:
1528                 /* We have sent something the receiver disliked, so we remove
1529                  * not only the transaction but also the subscriptions we might
1530                  * have. */
1531
1532                 coap_log(LOG_ALERT, "got RST for message %u\n",
1533                         ntohs(rcvd->pdu->hdr->id));
1534
1535                 /* find transaction in sendqueue to stop retransmission */
1536                 coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent);
1537
1538                 if (sent)
1539                 coap_handle_rst(context, sent);
1540                 goto cleanup;
1541
1542                 case COAP_MESSAGE_NON: /* check for unknown critical options */
1543                 if (coap_option_check_critical(context, rcvd->pdu, opt_filter)
1544                         == 0)
1545                 goto cleanup;
1546                 break;
1547
1548                 case COAP_MESSAGE_CON: /* check for unknown critical options */
1549                 if (coap_option_check_critical(context, rcvd->pdu, opt_filter)
1550                         == 0) {
1551
1552                     /* FIXME: send response only if we have received a request. Otherwise,
1553                      * send RST. */
1554                     response = coap_new_error_response(rcvd->pdu,
1555                             COAP_RESPONSE_CODE(402), opt_filter);
1556
1557                     if (!response)
1558                     warn("coap_dispatch: cannot create error reponse\n");
1559                     else {
1560                         if (coap_send(context, &rcvd->remote,
1561                                         response) == COAP_INVALID_TID) {
1562                             warn("coap_dispatch: error sending reponse\n");
1563                         }
1564                         coap_delete_pdu(response);
1565                     }
1566
1567                     goto cleanup;
1568                 }
1569                 break;
1570             }
1571 #endif
1572
1573             /* Pass message to upper layer if a specific handler was
1574              * registered for a request that should be handled locally. */
1575             if (handle_locally(context, rcvd)) {
1576                 if (COAP_MESSAGE_IS_REQUEST(rcvd->pdu->hdr))
1577                     handle_request(context, rcvd);
1578                 else if (COAP_MESSAGE_IS_RESPONSE(rcvd->pdu->hdr))
1579                     handle_response(context, rcvd);
1580                 else {
1581                     debug("dropped message with invalid code\n");
1582                     coap_send_message_type(context, &rcvd->remote, rcvd->pdu,
1583                             COAP_MESSAGE_RST);
1584                 }
1585             }
1586
1587             // we should not retrying responses.....
1588             cleanup: coap_delete_node(sent);
1589             coap_delete_node(rcvd);
1590         }
1591     }
1592
1593     int coap_can_exit(coap_context_t *context) {
1594         return !context
1595                 || (context->recvqueue == NULL && context->sendqueue == NULL);
1596     }
1597
1598 #ifdef WITH_CONTIKI
1599
1600     /*---------------------------------------------------------------------------*/
1601     /* CoAP message retransmission */
1602     /*---------------------------------------------------------------------------*/
1603     PROCESS_THREAD(coap_retransmit_process, ev, data)
1604     {
1605         coap_tick_t now;
1606         coap_queue_t *nextpdu;
1607
1608         PROCESS_BEGIN();
1609
1610         debug("Started retransmit process\r\n");
1611
1612         while(1) {
1613             PROCESS_YIELD();
1614             if (ev == PROCESS_EVENT_TIMER) {
1615                 if (etimer_expired(&the_coap_context.retransmit_timer)) {
1616
1617                     nextpdu = coap_peek_next(&the_coap_context);
1618
1619                     coap_ticks(&now);
1620                     while (nextpdu && nextpdu->t <= now) {
1621                         coap_retransmit(&the_coap_context, coap_pop_next(&the_coap_context));
1622                         nextpdu = coap_peek_next(&the_coap_context);
1623                     }
1624
1625                     /* need to set timer to some value even if no nextpdu is available */
1626                     etimer_set(&the_coap_context.retransmit_timer,
1627                             nextpdu ? nextpdu->t - now : 0xFFFF);
1628                 }
1629 #ifndef WITHOUT_OBSERVE
1630                 if (etimer_expired(&the_coap_context.notify_timer)) {
1631                     coap_check_notify(&the_coap_context);
1632                     etimer_reset(&the_coap_context.notify_timer);
1633                 }
1634 #endif /* WITHOUT_OBSERVE */
1635             }
1636         }
1637
1638         PROCESS_END();
1639     }
1640     /*---------------------------------------------------------------------------*/
1641
1642 #endif /* WITH_CONTIKI */
1643
1644 #ifdef WITH_LWIP
1645     /* FIXME: retransmits that are not required any more due to incoming packages
1646      * do *not* get cleared at the moment, the wakeup when the transmission is due
1647      * is silently accepted. this is mainly due to the fact that the required
1648      * checks are similar in two places in the code (when receiving ACK and RST)
1649      * and that they cause more than one patch chunk, as it must be first checked
1650      * whether the sendqueue item to be dropped is the next one pending, and later
1651      * the restart function has to be called. nothing insurmountable, but it can
1652      * also be implemented when things have stabilized, and the performance
1653      * penality is minimal
1654      *
1655      * also, this completely ignores COAP_RESOURCE_CHECK_TIME.
1656      * */
1657
1658     static void coap_retransmittimer_execute(void *arg)
1659     {
1660         coap_context_t *ctx = (coap_context_t*)arg;
1661         coap_tick_t now;
1662         coap_tick_t elapsed;
1663         coap_queue_t *nextinqueue;
1664
1665         ctx->timer_configured = 0;
1666
1667         coap_ticks(&now);
1668
1669         elapsed = now - ctx->sendqueue_basetime; /* that's positive for sure, and unless we haven't been called for a complete wrapping cycle, did not wrap */
1670
1671         nextinqueue = coap_peek_next(ctx);
1672         while (nextinqueue != NULL)
1673         {
1674             if (nextinqueue->t > elapsed) {
1675                 nextinqueue->t -= elapsed;
1676                 break;
1677             } else {
1678                 elapsed -= nextinqueue->t;
1679                 coap_retransmit(ctx, coap_pop_next(ctx));
1680                 nextinqueue = coap_peek_next(ctx);
1681             }
1682         }
1683
1684         ctx->sendqueue_basetime = now;
1685
1686         coap_retransmittimer_restart(ctx);
1687     }
1688
1689     static void coap_retransmittimer_restart(coap_context_t *ctx)
1690     {
1691         coap_tick_t now, elapsed, delay;
1692
1693         if (ctx->timer_configured)
1694         {
1695             printf("clearing\n");
1696             sys_untimeout(coap_retransmittimer_execute, (void*)ctx);
1697             ctx->timer_configured = 0;
1698         }
1699         if (ctx->sendqueue != NULL)
1700         {
1701             coap_ticks(&now);
1702             elapsed = now - ctx->sendqueue_basetime;
1703             if (ctx->sendqueue->t >= elapsed) {
1704                 delay = ctx->sendqueue->t - elapsed;
1705             } else {
1706                 /* a strange situation, but not completely impossible.
1707                  *
1708                  * this happens, for example, right after
1709                  * coap_retransmittimer_execute, when a retransmission
1710                  * was *just not yet* due, and the clock ticked before
1711                  * our coap_ticks was called.
1712                  *
1713                  * not trying to retransmit anything now, as it might
1714                  * cause uncontrollable recursion; let's just try again
1715                  * with the next main loop run.
1716                  * */
1717                 delay = 0;
1718             }
1719
1720             printf("scheduling for %d ticks\n", delay);
1721             sys_timeout(delay, coap_retransmittimer_execute, (void*)ctx);
1722             ctx->timer_configured = 1;
1723         }
1724     }
1725 #endif