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