Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / resource / csdk / connectivity / lib / libcoap-4.1.1 / net.c
index 7138f4a..d3ea2ec 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2010--2014 Olaf Bergmann <bergmann@tzi.org>
  *
  * This file is part of the CoAP library libcoap. Please see
- * README for terms of use. 
+ * README for terms of use.
  */
 
 #include "config.h"
@@ -18,7 +18,9 @@
 #elif HAVE_SYS_UNISTD_H
 #include <sys/unistd.h>
 #endif
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
@@ -45,9 +47,9 @@
 #include "block.h"
 #include "net.h"
 
-#if defined(WITH_POSIX)
+#if defined(WITH_POSIX) || defined(WITH_ARDUINO)
 
-time_t clock_offset;
+time_t clock_offset=0;
 
 static inline coap_queue_t *
 coap_malloc_node()
@@ -60,7 +62,7 @@ coap_free_node(coap_queue_t *node)
 {
     coap_free(node);
 }
-#endif /* WITH_POSIX */
+#endif /* WITH_POSIX || WITH_ARDUINO */
 #ifdef WITH_LWIP
 
 #include <lwip/memp.h>
@@ -135,8 +137,7 @@ static void received_package(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip
     context->pending_address.addr = addr->addr; /* FIXME: this has to become address-type independent, probably there'll be an lwip function for that */
     context->pending_port = port;
 
-    char* data;
-    coap_read(context, data);
+    coap_read(context);
 }
 
 #endif /* WITH_LWIP */
@@ -296,7 +297,7 @@ coap_pop_next(coap_context_t *context)
 
 #ifdef COAP_DEFAULT_WKC_HASHKEY
 /** Checks if @p Key is equal to the pre-defined hash key for.well-known/core. */
-#define is_wkc(Key)                                                    \
+#define is_wkc(Key)                         \
   (memcmp((Key), COAP_DEFAULT_WKC_HASHKEY, sizeof(coap_key_t)) == 0)
 #else
 /* Implements a singleton to store a hash key for the .wellknown/core
@@ -315,10 +316,12 @@ is_wkc(coap_key_t k)
 }
 #endif
 
+
+#ifndef WITH_ARDUINO
 coap_context_t *
 coap_new_context(const coap_address_t *listen_addr)
 {
-#ifdef WITH_POSIX
+#if defined(WITH_POSIX)
     coap_context_t *c = coap_malloc( sizeof( coap_context_t ) );
     int reuse = 1;
 #endif /* WITH_POSIX */
@@ -380,7 +383,7 @@ coap_new_context(const coap_address_t *listen_addr)
     coap_register_option(c, COAP_OPTION_BLOCK2);
     coap_register_option(c, COAP_OPTION_BLOCK1);
 
-#ifdef WITH_POSIX
+#if defined(WITH_POSIX) || defined(WITH_ARDUINO)
     c->sockfd = socket(listen_addr->addr.sa.sa_family, SOCK_DGRAM, 0);
     if ( c->sockfd < 0 )
     {
@@ -413,7 +416,7 @@ coap_new_context(const coap_address_t *listen_addr)
     coap_free( c );
     return NULL;
 
-#endif /* WITH_POSIX */
+#endif /* WITH_POSIX || WITH_ARDUINO */
 #ifdef WITH_CONTIKI
     c->conn = udp_new(NULL, 0, NULL);
     udp_bind(c->conn, listen_addr->port);
@@ -462,7 +465,7 @@ void coap_free_context(coap_context_t *context)
     coap_retransmittimer_restart(context);
 #endif
 
-#if defined(WITH_POSIX) || defined(WITH_LWIP)
+#if defined(WITH_POSIX) || defined(WITH_LWIP) || defined(WITH_ARDUINO)
 #ifdef COAP_RESOURCES_NOHASH
     LL_FOREACH(context->resources, res)
     {
@@ -488,14 +491,14 @@ void coap_free_context(coap_context_t *context)
     initialized = 0;
 #endif /* WITH_CONTIKI */
 }
-
+#endif //ifndef WITH_ARDUINO
 int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu, coap_opt_filter_t unknown)
 {
 
     coap_opt_iterator_t opt_iter;
     int ok = 1;
 
-    coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL);
+    coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL, coap_udp);
 
     while (coap_option_next(&opt_iter))
     {
@@ -548,13 +551,18 @@ void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu, coap
         return;
     }
 #endif
+
+#ifdef WITH_ARDUINO
+    coap_hash((const unsigned char *)peer->addr, peer->size, h);
+#endif /* WITH_ARDUINO */
+
 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
     /* FIXME: with lwip, we can do better */
     coap_hash((const unsigned char *)&peer->port, sizeof(peer->port), h);
     coap_hash((const unsigned char *)&peer->addr, sizeof(peer->addr), h);
 #endif /* WITH_LWIP || WITH_CONTIKI */
 
-    coap_hash((const unsigned char *)&pdu->hdr->id, sizeof(unsigned short), h);
+    coap_hash((const unsigned char *)&pdu->hdr->coap_hdr_udp_t.id, sizeof(unsigned short), h);
 
     *id = ((h[0] << 8) | h[1]) ^ ((h[2] << 8) | h[3]);
 }
@@ -564,9 +572,10 @@ coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst, coa
     coap_pdu_t *response;
     coap_tid_t result = COAP_INVALID_TID;
 
-    if (request && request->hdr->type == COAP_MESSAGE_CON)
+    if (request && request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON)
     {
-        response = coap_pdu_init(COAP_MESSAGE_ACK, 0, request->hdr->id, sizeof(coap_pdu_t));
+        response = coap_pdu_init(COAP_MESSAGE_ACK, 0, request->hdr->coap_hdr_udp_t.id,
+                                 sizeof(coap_pdu_t), coap_udp);
         if (response)
         {
             result = coap_send(context, dst, response);
@@ -576,16 +585,23 @@ coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst, coa
     return result;
 }
 
-#ifdef WITH_POSIX
+#if defined(WITH_ARDUINO)
+coap_tid_t
+coap_send_impl(coap_context_t *context,
+               const coap_address_t *dst,
+               coap_pdu_t *pdu)
+{
+    return 0;
+}
+#endif
+
+#if defined(WITH_POSIX)
 /* releases space allocated by PDU if free_pdu is set */
 coap_tid_t
 coap_send_impl(coap_context_t *context,
         const coap_address_t *dst,
         coap_pdu_t *pdu)
 {
-
-    char* z = inet_ntoa(*(struct in_addr *)&(dst->addr));
-
     ssize_t bytes_written;
     coap_tid_t id = COAP_INVALID_TID;
 
@@ -606,7 +622,7 @@ coap_send_impl(coap_context_t *context,
 
     return id;
 }
-#endif /* WITH_POSIX */
+#endif /* WITH_POSIX || WITH_ARDUINO */
 #ifdef WITH_CONTIKI
 /* releases space allocated by PDU if free_pdu is set */
 coap_tid_t
@@ -688,7 +704,9 @@ coap_send_impl(coap_context_t *context,
 
 coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu)
 {
+#ifndef WITH_ARDUINO
     return coap_send_impl(context, dst, pdu);
+#endif
 }
 
 coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request, const coap_address_t *dst,
@@ -718,7 +736,8 @@ coap_tid_t coap_send_message_type(coap_context_t *context, const coap_address_t
 
     if (request)
     {
-        response = coap_pdu_init(type, 0, request->hdr->id, sizeof(coap_pdu_t));
+        response = coap_pdu_init(type, 0, request->hdr->coap_hdr_udp_t.id,
+                                 sizeof(coap_pdu_t), coap_udp);
         if (response)
         {
             result = coap_send(context, dst, response);
@@ -813,12 +832,14 @@ coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node)
         node->t = node->timeout << node->retransmit_cnt;
         coap_insert_node(&context->sendqueue, node);
 #ifdef WITH_LWIP
-        if (node == context->sendqueue) /* don't bother with timer stuff if there are earlier retransmits */
+        /* don't bother with timer stuff if there are earlier retransmits */
+        if (node == context->sendqueue)
         coap_retransmittimer_restart(context);
 #endif
 
         debug(
-                "** retransmission #%d of transaction %d\n", node->retransmit_cnt, ntohs(node->pdu->hdr->id));
+                "** retransmission #%d of transaction %d\n", node->retransmit_cnt,
+                ntohs(node->pdu->hdr->coap_hdr_udp_t.id));
 
         node->id = coap_send_impl(context, &node->remote, node->pdu);
         return node->id;
@@ -826,20 +847,20 @@ coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node)
 
     /* no more retransmissions, remove node from system */
 
-#ifndef WITH_CONTIKI
+#if !defined(WITH_CONTIKI) && !defined(WITH_ARDUINO)
     debug("** removed transaction %d\n", ntohs(node->id));
 #endif
 
 #ifndef WITHOUT_OBSERVE
     /* Check if subscriptions exist that should be canceled after
      COAP_MAX_NOTIFY_FAILURES */
-    if (node->pdu->hdr->code >= 64)
+    if (node->pdu->hdr->coap_hdr_udp_t.code >= 64)
     {
         str token =
         { 0, NULL };
 
-        token.length = node->pdu->hdr->token_length;
-        token.s = node->pdu->hdr->token;
+        token.length = node->pdu->hdr->coap_hdr_udp_t.token_length;
+        token.s = node->pdu->hdr->coap_hdr_udp_t.token;
 
         coap_handle_failed_notify(context, &node->remote, &token);
     }
@@ -850,7 +871,7 @@ coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node)
     return COAP_INVALID_TID;
 }
 
-/** 
+/**
  * Checks if @p opt fits into the message that ends with @p maxpos.
  * This function returns @c 1 on success, or @c 0 if the option @p opt
  * would exceed @p maxpos.
@@ -865,9 +886,10 @@ static inline int check_opt_size(coap_opt_t *opt, unsigned char *maxpos)
     return 0;
 }
 
-int coap_read(coap_context_t *ctx, char* data)
+#ifndef WITH_ARDUINO
+int coap_read(coap_context_t *ctx)
 {
-#ifdef WITH_POSIX
+#if defined(WITH_POSIX)
     static char buf[COAP_MAX_PDU_SIZE];
 #endif
 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
@@ -891,10 +913,10 @@ int coap_read(coap_context_t *ctx, char* data)
 
     coap_address_init(&src);
 
-#ifdef WITH_POSIX
+#if defined(WITH_POSIX)
     bytes_read = recvfrom(ctx->sockfd, buf, sizeof(buf), 0, &src.addr.sa, &src.size);
 
-#endif /* WITH_POSIX */
+#endif /* WITH_POSIX || WITH_ARDUINO */
 #ifdef WITH_CONTIKI
     if(uip_newdata())
     {
@@ -929,7 +951,7 @@ int coap_read(coap_context_t *ctx, char* data)
         goto error_early;
     }
 
-    if (pdu->version != COAP_DEFAULT_VERSION)
+    if (pdu->coap_hdr_udp_t.version != COAP_DEFAULT_VERSION)
     {
         debug("coap_read: unknown protocol version\n");
         goto error_early;
@@ -943,7 +965,7 @@ int coap_read(coap_context_t *ctx, char* data)
     node->pdu = coap_pdu_from_pbuf(ctx->pending_package);
     ctx->pending_package = NULL;
 #else
-    node->pdu = coap_pdu_init(0, 0, 0, bytes_read);
+    node->pdu = coap_pdu_init(0, 0, 0, bytes_read, coap_udp);
 #endif
     if (!node->pdu)
         goto error;
@@ -952,7 +974,7 @@ int coap_read(coap_context_t *ctx, char* data)
     memcpy(&node->local, &dst, sizeof(coap_address_t));
     memcpy(&node->remote, &src, sizeof(coap_address_t));
 
-    if (!coap_pdu_parse((unsigned char *) buf, bytes_read, node->pdu))
+    if (!coap_pdu_parse((unsigned char *) buf, bytes_read, node->pdu, coap_udp))
     {
         warn("discard malformed PDU");
         goto error;
@@ -991,6 +1013,7 @@ int coap_read(coap_context_t *ctx, char* data)
 #endif
     return -1;
 }
+#endif //#ifndef WITH_ARDUINO
 
 int coap_remove_from_queue(coap_queue_t **queue, coap_tid_t id, coap_queue_t **node)
 {
@@ -1050,18 +1073,18 @@ static inline int token_match(const unsigned char *a, size_t alen, const unsigne
 void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst,
         const unsigned char *token, size_t token_length)
 {
-    /* cancel all messages in sendqueue that are for dst 
+    /* cancel all messages in sendqueue that are for dst
      * and use the specified token */
     coap_queue_t *p, *q;
 
     debug("cancel_all_messages\n");
     while (context->sendqueue && coap_address_equals(dst, &context->sendqueue->remote)
-            && token_match(token, token_length, context->sendqueue->pdu->hdr->token,
-                    context->sendqueue->pdu->hdr->token_length))
+            && token_match(token, token_length, context->sendqueue->pdu->hdr->coap_hdr_udp_t.token,
+                    context->sendqueue->pdu->hdr->coap_hdr_udp_t.token_length))
     {
         q = context->sendqueue;
         context->sendqueue = q->next;
-        debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->id));
+        debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->coap_hdr_udp_t.id));
         coap_delete_node(q);
     }
 
@@ -1075,10 +1098,11 @@ void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst
     while (q)
     {
         if (coap_address_equals(dst, &q->remote)
-                && token_match(token, token_length, q->pdu->hdr->token, q->pdu->hdr->token_length))
+                && token_match(token, token_length, q->pdu->hdr->coap_hdr_udp_t.token,
+                               q->pdu->hdr->coap_hdr_udp_t.token_length))
         {
             p->next = q->next;
-            debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->id));
+            debug("**** removed transaction %d\n", ntohs(q->pdu->hdr->coap_hdr_udp_t.id));
             coap_delete_node(q);
             q = p->next;
         }
@@ -1104,7 +1128,7 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter
 {
     coap_opt_iterator_t opt_iter;
     coap_pdu_t *response;
-    size_t size = sizeof(coap_hdr_t) + request->hdr->token_length;
+    size_t size = sizeof(coap_hdr_t) + request->hdr->coap_hdr_udp_t.token_length;
     int type;
     coap_opt_t *option;
     unsigned short opt_type = 0; /* used for calculating delta-storage */
@@ -1120,14 +1144,14 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter
     assert(request);
 
     /* cannot send ACK if original request was not confirmable */
-    type = request->hdr->type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON;
+    type = request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON;
 
     /* Estimate how much space we need for options to copy from
      * request. We always need the Token, for 4.02 the unknown critical
      * options must be included as well. */
     coap_option_clrb(opts, COAP_OPTION_CONTENT_TYPE); /* we do not want this */
 
-    coap_option_iterator_init(request, &opt_iter, opts);
+    coap_option_iterator_init(request, &opt_iter, opts, coap_udp);
 
     /* Add size of each unknown critical option. As known critical
      options as well as elective options are not copied, the delta
@@ -1170,11 +1194,12 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter
     }
 
     /* Now create the response and fill with options and payload data. */
-    response = coap_pdu_init(type, code, request->hdr->id, size);
+    response = coap_pdu_init(type, code, request->hdr->coap_hdr_udp_t.id, size, coap_udp);
     if (response)
     {
         /* copy token */
-        if (!coap_add_token(response, request->hdr->token_length, request->hdr->token))
+        if (!coap_add_token(response, request->hdr->coap_hdr_udp_t.token_length,
+                            request->hdr->coap_hdr_udp_t.token, coap_udp))
         {
             debug("cannot add token to error response\n");
             coap_delete_pdu(response);
@@ -1182,10 +1207,10 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code, coap_opt_filter
         }
 
         /* copy all options */
-        coap_option_iterator_init(request, &opt_iter, opts);
+        coap_option_iterator_init(request, &opt_iter, opts, coap_udp);
         while ((option = coap_option_next(&opt_iter)))
             coap_add_option(response, opt_iter.type, COAP_OPT_LENGTH(option),
-                    COAP_OPT_VALUE(option));
+                    COAP_OPT_VALUE(option), coap_udp);
 
 #if COAP_ERROR_PHRASE_LENGTH > 0
         /* note that diagnostic messages do not need a Content-Format option. */
@@ -1233,16 +1258,17 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request)
     size_t offset = 0;
 
     resp = coap_pdu_init(
-            request->hdr->type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
+            request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
             COAP_RESPONSE_CODE(205),
-            request->hdr->id, COAP_MAX_PDU_SIZE);
+            request->hdr->coap_hdr_udp_t.id, COAP_MAX_PDU_SIZE, coap_udp);
     if (!resp)
     {
         debug("wellknown_response: cannot create PDU\n");
         return NULL;
     }
 
-    if (!coap_add_token(resp, request->hdr->token_length, request->hdr->token))
+    if (!coap_add_token(resp, request->hdr->coap_hdr_udp_t.token_length,
+                        request->hdr->coap_hdr_udp_t.token, coap_udp))
     {
         debug("wellknown_response: cannot add token\n");
         goto error;
@@ -1257,7 +1283,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request)
         offset = block.num << (block.szx + 4);
         if (block.szx > 6)
         { /* invalid, MUST lead to 4.00 Bad Request */
-            resp->hdr->code = COAP_RESPONSE_CODE(400);
+            resp->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(400);
             return resp;
         }
         else if (block.szx > COAP_MAX_BLOCK_SZX)
@@ -1269,7 +1295,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request)
         need_block2 = 1;
     }
 
-    /* Check if there is sufficient space to add Content-Format option 
+    /* Check if there is sufficient space to add Content-Format option
      * and data. We do this before adding the Content-Format option to
      * avoid sending error responses with that option but no actual
      * content. */
@@ -1283,7 +1309,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request)
      * nothing should go wrong here. */
     assert(coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT) == 1);
     coap_add_option(resp, COAP_OPTION_CONTENT_FORMAT,
-            coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT), buf);
+            coap_encode_var_bytes(buf, COAP_MEDIATYPE_APPLICATION_LINK_FORMAT), buf, coap_udp);
 
     /* check if Block2 option is required even if not requested */
     if (!need_block2 && (resp->max_size - (size_t) resp->length < wkc_len))
@@ -1341,13 +1367,13 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request)
 
     error:
     /* set error code 5.03 and remove all options and data from response */
-    resp->hdr->code = COAP_RESPONSE_CODE(503);
-    resp->length = sizeof(coap_hdr_t) + resp->hdr->token_length;
+    resp->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(503);
+    resp->length = sizeof(coap_hdr_t) + resp->hdr->coap_hdr_udp_t.token_length;
     return resp;
 }
 
-#define WANT_WKC(Pdu,Key)                                      \
-  (((Pdu)->hdr->code == COAP_REQUEST_GET) && is_wkc(Key))
+#define WANT_WKC(Pdu,Key)                   \
+  (((Pdu)->hdr->coap_hdr_udp_t.code == COAP_REQUEST_GET) && is_wkc(Key))
 
 void handle_request(coap_context_t *context, coap_queue_t *node, const char* responseData)
 {
@@ -1370,7 +1396,7 @@ void handle_request(coap_context_t *context, coap_queue_t *node, const char* res
          * be the well-known URI. In that case, we generate a default
          * response, otherwise, we return 4.04 */
 
-        switch (node->pdu->hdr->code)
+        switch (node->pdu->hdr->coap_hdr_udp_t.code)
         {
 
             case COAP_REQUEST_GET:
@@ -1410,42 +1436,43 @@ void handle_request(coap_context_t *context, coap_queue_t *node, const char* res
     }
 
     /* the resource was found, check if there is a registered handler */
-    if ((size_t) node->pdu->hdr->code - 1
+    if ((size_t) node->pdu->hdr->coap_hdr_udp_t.code - 1
             < sizeof(resource->handler) / sizeof(coap_method_handler_t))
-        h = resource->handler[node->pdu->hdr->code - 1];
+        h = resource->handler[node->pdu->hdr->coap_hdr_udp_t.code - 1];
 
     if (h)
     {
         debug(
                 "call custom handler for resource 0x%02x%02x%02x%02x\n", key[0], key[1], key[2], key[3]);
         response = coap_pdu_init(
-                node->pdu->hdr->type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
-                0, node->pdu->hdr->id, COAP_MAX_PDU_SIZE);
+                node->pdu->hdr->coap_hdr_udp_t.type ==
+                        COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
+                0, node->pdu->hdr->coap_hdr_udp_t.id, COAP_MAX_PDU_SIZE, coap_udp);
 
         /* Implementation detail: coap_add_token() immediately returns 0
          if response == NULL */
-        if (coap_add_token(response, node->pdu->hdr->token_length, node->pdu->hdr->token))
+        if (coap_add_token(response, node->pdu->hdr->coap_hdr_udp_t.token_length,
+                           node->pdu->hdr->coap_hdr_udp_t.token, coap_udp))
         {
             str token =
-            { node->pdu->hdr->token_length, node->pdu->hdr->token };
+            { node->pdu->hdr->coap_hdr_udp_t.token_length, node->pdu->hdr->coap_hdr_udp_t.token };
 
-            //h(context, resource, &node->remote, 
-            //node->pdu, &token, response);
+            h(context, resource, &node->remote, node->pdu, &token, response);
 
             unsigned char buf[3];
-            response->hdr->code = COAP_RESPONSE_CODE(205);
+            response->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(205);
             coap_add_option(response, COAP_OPTION_CONTENT_TYPE,
-                    coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);
-            coap_add_option(response, COAP_OPTION_MAXAGE, coap_encode_var_bytes(buf, 0x2ffff), buf);
+                    coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf, coap_udp);
+            coap_add_option(response, COAP_OPTION_MAXAGE, coap_encode_var_bytes(buf, 0x2ffff), buf, coap_udp);
             coap_add_data(response, strlen(responseData), (unsigned char *) responseData);
 
-            if (response->hdr->type != COAP_MESSAGE_NON
-                    || (response->hdr->code >= 64 && !coap_is_mcast(&node->local)))
+            if (response->hdr->coap_hdr_udp_t.type != COAP_MESSAGE_NON
+                    || (response->hdr->coap_hdr_udp_t.code >= 64 && !coap_is_mcast(&node->local)))
             {
 
                 if (coap_send(context, &node->remote, response) == COAP_INVALID_TID)
                 {
-                    debug("cannot send response for message %d\n", node->pdu->hdr->id);
+                    debug("cannot send response for message %d\n", node->pdu->hdr->coap_hdr_udp_t.id);
                 }
             }
 
@@ -1519,11 +1546,12 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
         str token =
         { 0, NULL };
 
-        /* remove observer for this resource, if any 
+        /* remove observer for this resource, if any
          * get token from sent and try to find a matching resource. Uh!
          */
 
-        COAP_SET_STR(&token, sent->pdu->hdr->token_length, sent->pdu->hdr->token);
+        COAP_SET_STR(&token, sent->pdu->hdr->coap_hdr_udp_t.token_length,
+                     sent->pdu->hdr->coap_hdr_udp_t.token);
 
 #ifndef WITH_CONTIKI
 #ifdef COAP_RESOURCES_NOHASH
@@ -1547,7 +1575,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
             }
         }
 #endif /* WITH_CONTIKI */
-#endif /* WITOUT_OBSERVE */  
+#endif /* WITOUT_OBSERVE */
     }
 
     void coap_dispatch(coap_context_t *context, const char* responseData)
@@ -1569,28 +1597,30 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
             context->recvqueue = context->recvqueue->next;
             rcvd->next = NULL;
 
-            if (rcvd->pdu->hdr->version != COAP_DEFAULT_VERSION)
+            if (rcvd->pdu->hdr->coap_hdr_udp_t.version != COAP_DEFAULT_VERSION)
             {
-                debug("dropped packet with unknown version %u\n", rcvd->pdu->hdr->version);
+                debug("dropped packet with unknown version %u\n", rcvd->pdu->hdr->coap_hdr_udp_t.version);
                 goto cleanup;
             }
 
-            switch (rcvd->pdu->hdr->type)
+            switch (rcvd->pdu->hdr->coap_hdr_udp_t.type)
             {
                 case COAP_MESSAGE_ACK:
                     /* find transaction in sendqueue to stop retransmission */
                     coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent);
 
-                    if (rcvd->pdu->hdr->code == 0)
+                    if (rcvd->pdu->hdr->coap_hdr_udp_t.code == 0)
                         goto cleanup;
 
-                    /* FIXME: if sent code was >= 64 the message might have been a 
+                    /* FIXME: if sent code was >= 64 the message might have been a
                      * notification. Then, we must flag the observer to be alive
                      * by setting obs->fail_cnt = 0. */
-                    if (sent && COAP_RESPONSE_CLASS(sent->pdu->hdr->code) == 2)
+                    if (sent && COAP_RESPONSE_CLASS(sent->pdu->hdr->coap_hdr_udp_t.code) == 2)
                     {
                         const str token =
-                        { sent->pdu->hdr->token_length, sent->pdu->hdr->token };
+                        { sent->pdu->hdr->coap_hdr_udp_t.token_length,
+                          sent->pdu->hdr->coap_hdr_udp_t.token };
+
                         coap_touch_observer(context, &sent->remote, &token);
                     }
                     break;
@@ -1600,7 +1630,8 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
                      * not only the transaction but also the subscriptions we might
                      * have. */
 
-                    coap_log(LOG_ALERT, "got RST for message %u\n", ntohs(rcvd->pdu->hdr->id));
+                    coap_log(LOG_ALERT, "got RST for message %u\n",
+                             ntohs(rcvd->pdu->hdr->coap_hdr_udp_t.id));
 
                     /* find transaction in sendqueue to stop retransmission */
                     coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent);
@@ -1618,7 +1649,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
                     if (coap_option_check_critical(context, rcvd->pdu, opt_filter) == 0)
                     {
 
-                        /* FIXME: send response only if we have received a request. Otherwise, 
+                        /* FIXME: send response only if we have received a request. Otherwise,
                          * send RST. */
                         response = coap_new_error_response(rcvd->pdu, COAP_RESPONSE_CODE(402),
                                 opt_filter);
@@ -1643,9 +1674,9 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
              * registered for a request that should be handled locally. */
             if (handle_locally(context, rcvd))
             {
-                if (COAP_MESSAGE_IS_REQUEST(rcvd->pdu->hdr))
+                if (COAP_MESSAGE_IS_REQUEST(rcvd->pdu->hdr->coap_hdr_udp_t))
                     handle_request(context, rcvd, responseData);
-                else if (COAP_MESSAGE_IS_RESPONSE(rcvd->pdu->hdr))
+                else if (COAP_MESSAGE_IS_RESPONSE(rcvd->pdu->hdr->coap_hdr_udp_t))
                     handle_response(context, sent, rcvd);
                 else
                 {