From 202d651a0dc99f43f8a5d359c9254e3714809b59 Mon Sep 17 00:00:00 2001
From: authmillenon <authmill@datalove.me>
Date: Fri, 9 Aug 2013 03:13:37 +0200
Subject: [PATCH] Refactor lowpan.h

---
 sys/net/destiny/socket.c                     |   1 +
 sys/net/destiny/socket.h                     |   1 +
 sys/net/rpl/rpl.c                            |  13 +-
 sys/net/rpl/rpl_dodag.h                      |   1 +
 sys/net/sixlowpan/border.c                   |   6 +-
 sys/net/sixlowpan/icmp.c                     |  54 +++--
 sys/net/sixlowpan/icmp.h                     |   1 +
 sys/net/sixlowpan/include/sixlowpan.h        |   1 -
 sys/net/sixlowpan/include/sixlowpan/icmp.h   |  12 +
 sys/net/sixlowpan/include/sixlowpan/lowpan.h | 225 ++++++++++++++++++-
 sys/net/sixlowpan/ip.c                       |  25 ++-
 sys/net/sixlowpan/ip.h                       |   3 +-
 sys/net/sixlowpan/lowpan.c                   | 195 ++++++++++------
 sys/net/sixlowpan/lowpan.h                   | 136 ++---------
 14 files changed, 446 insertions(+), 228 deletions(-)

diff --git a/sys/net/destiny/socket.c b/sys/net/destiny/socket.c
index 7bc674706b..35500eb0b0 100644
--- a/sys/net/destiny/socket.c
+++ b/sys/net/destiny/socket.c
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <inttypes.h>
 #include <math.h>
+#include "ipv6.h"
 #include "udp.h"
 #include "tcp.h"
 #include "socket.h"
diff --git a/sys/net/destiny/socket.h b/sys/net/destiny/socket.h
index 21a8595da4..8fee5a3b0d 100644
--- a/sys/net/destiny/socket.h
+++ b/sys/net/destiny/socket.h
@@ -20,6 +20,7 @@
 #define SOCKET_H_
 
 #include <stdint.h>
+#include "ipv6.h"
 #include "tcp.h"
 #include "udp.h"
 #include "in.h"
diff --git a/sys/net/rpl/rpl.c b/sys/net/rpl/rpl.c
index 1f05effd3b..c38d2617dd 100644
--- a/sys/net/rpl/rpl.c
+++ b/sys/net/rpl/rpl.c
@@ -19,6 +19,7 @@
 #include <vtimer.h>
 #include <thread.h>
 #include <mutex.h>
+
 #include "msg.h"
 #include "rpl.h"
 #include "etx_beaconing.h"
@@ -193,7 +194,7 @@ uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address)
     objective_functions[0] = rpl_get_of0();
     /* objective_functions[1] = rpl_get_of_ETX() */
 
-    sixlowpan_init(trans, rpl_address, 0);
+    sixlowpan_lowpan_init(trans, rpl_address, 0);
     /* need link local prefix to query _our_ corresponding address  */
     ipv6_addr_t ll_address;
     ipv6_set_ll_prefix(&ll_address);
@@ -887,7 +888,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
     uint8_t *p_ptr;
     ipv6_send_buf = get_rpl_send_ipv6_buf();
     p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len);
-    packet_length = 0;
+    uint16_t packet_length = 0;
 
     ipv6_send_buf->version_trafficclass = IPV6_VER;
     ipv6_send_buf->trafficclass_flowlabel = 0;
@@ -910,7 +911,9 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
     packet_length = IPV6_HDR_LEN + p_len;
 
     if (ipv6_prefix_mcast_match(&ipv6_send_buf->destaddr)) {
-        lowpan_init((ieee_802154_long_t *) & (ipv6_send_buf->destaddr.uint16[4]), (uint8_t *)ipv6_send_buf);
+        sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_send_buf->destaddr.uint16[4]), 
+                                (uint8_t *)ipv6_send_buf,
+                                packet_length);
     }
     else {
         /* find appropriate next hop before sending */
@@ -931,7 +934,9 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
             }
         }
 
-        lowpan_init((ieee_802154_long_t *) & (next_hop->uint16[4]), (uint8_t *)ipv6_send_buf);
+        sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(next_hop->uint16[4]), 
+                                (uint8_t *)ipv6_send_buf,
+                                packet_length);
     }
 
 }
diff --git a/sys/net/rpl/rpl_dodag.h b/sys/net/rpl/rpl_dodag.h
index a21b004fb4..014a0b51a2 100644
--- a/sys/net/rpl/rpl_dodag.h
+++ b/sys/net/rpl/rpl_dodag.h
@@ -16,6 +16,7 @@
  */
 
 #include <string.h>
+#include "ipv6.h"
 #include "rpl_structs.h"
 
 rpl_instance_t *rpl_new_instance(uint8_t instanceid);
diff --git a/sys/net/sixlowpan/border.c b/sys/net/sixlowpan/border.c
index 8d2737ddf3..2de368cb38 100644
--- a/sys/net/sixlowpan/border.c
+++ b/sys/net/sixlowpan/border.c
@@ -153,7 +153,7 @@ uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_a
 
     memcpy(&(abr_addr.uint8[0]), &(border_router_addr->uint8[0]), 16);
 
-    sixlowpan_init(trans, border_router_addr->uint8[15], 1);
+    sixlowpan_lowpan_init(trans, border_router_addr->uint8[15], 1);
 
     ipv6_init_iface_as_router();
 
@@ -170,7 +170,9 @@ void border_send_ipv6_over_lowpan(ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t
     memset(buffer, 0, BUFFER_SIZE);
     memcpy(buffer + LL_HDR_LEN, packet, offset);
 
-    lowpan_init((ieee_802154_long_t *) & (packet->destaddr.uint16[4]), (uint8_t *)packet);
+    sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (packet->destaddr.uint16[4]),
+                            (uint8_t *)packet,
+                            offset);
 }
 
 void border_process_lowpan(void)
diff --git a/sys/net/sixlowpan/icmp.c b/sys/net/sixlowpan/icmp.c
index 44487f2d0a..369cb308a7 100644
--- a/sys/net/sixlowpan/icmp.c
+++ b/sys/net/sixlowpan/icmp.c
@@ -167,13 +167,13 @@ static opt_aro_t *get_opt_aro_buf(uint8_t ext_len, uint8_t opt_len)
 
 void init_echo_req(ipv6_addr_t *destaddr, uint16_t id, uint16_t seq, char *data, size_t data_len)
 {
+    uint16_t packet_length;
+
     ipv6_buf = get_ipv6_buf();
     icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
     struct echo_req_t *echo_buf = get_echo_req_buf(ipv6_ext_hdr_len);
     char *echo_data_buf = ((char *)echo_buf) + sizeof(struct echo_req_t);
 
-    packet_length = 0;
-
     icmp_buf->type = ICMP_ECHO_REQ;
     icmp_buf->code = 0;
     ipv6_buf->version_trafficclass = IPV6_VER;
@@ -200,19 +200,20 @@ void init_echo_req(ipv6_addr_t *destaddr, uint16_t id, uint16_t seq, char *data,
     printf("INFO: send echo request to: ");
     ipv6_print_addr(&ipv6_buf->destaddr);
 #endif
-    lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
-                (uint8_t *)ipv6_buf);
+    sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                            (uint8_t *)ipv6_buf,
+                            packet_length);
 }
 
 void init_echo_repl(ipv6_addr_t *destaddr, uint16_t id, uint16_t seq, char *data, size_t data_len)
 {
+    uint16_t packet_length;
+
     ipv6_buf = get_ipv6_buf();
     icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
     struct echo_repl_t *echo_buf = get_echo_repl_buf(ipv6_ext_hdr_len);
     char *echo_data_buf = ((char *)echo_buf) + sizeof(struct echo_repl_t);
 
-    packet_length = 0;
-
     icmp_buf->type = ICMP_ECHO_REPL;
     icmp_buf->code = 0;
     ipv6_buf->version_trafficclass = IPV6_VER;
@@ -239,18 +240,19 @@ void init_echo_repl(ipv6_addr_t *destaddr, uint16_t id, uint16_t seq, char *data
     printf("INFO: send echo request to: ");
     ipv6_print_addr(&ipv6_buf->destaddr);
 #endif
-    lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
-                (uint8_t *)ipv6_buf);
+    sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                            (uint8_t *)ipv6_buf,
+                            packet_length);
 }
 
 /* send router solicitation message - RFC4861 section 4.1 */
 void init_rtr_sol(uint8_t sllao)
 {
+    uint16_t packet_length;
+
     ipv6_buf = get_ipv6_buf();
     icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
 
-    packet_length = 0;
-
     icmp_buf->type = ICMP_RTR_SOL;
     icmp_buf->code = 0;
     ipv6_buf->version_trafficclass = IPV6_VER;
@@ -286,8 +288,9 @@ void init_rtr_sol(uint8_t sllao)
     printf("INFO: send router solicitation to: ");
     ipv6_print_addr(&ipv6_buf->destaddr);
 #endif
-    lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
-                (uint8_t *)ipv6_buf);
+    sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                            (uint8_t *)ipv6_buf,
+                            packet_length);
 }
 
 void recv_echo_req(void)
@@ -387,8 +390,9 @@ void recv_rtr_sol(void)
     printf("INFO: send router advertisment to: ");
     ipv6_print_addr(&ipv6_buf->destaddr);
 #endif
-    lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
-                (uint8_t *)ipv6_buf);
+    sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                            (uint8_t *)ipv6_buf,
+                            IPV6_HDR_LEN + NTOHS(ipv6_buf->length));
 
 }
 
@@ -419,6 +423,7 @@ lowpan_context_t *abr_get_context(abr_cache_t *abr, uint8_t cid);
 void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi,
                   uint8_t sixco, uint8_t abro)
 {
+    uint16_t packet_length;
     lowpan_context_t *contexts = NULL;
 
     abr_cache_t *msg_abr = NULL;
@@ -591,9 +596,11 @@ void recv_rtr_adv(void)
     int8_t trigger_ns = -1;
     int8_t abro_found = 0;
     int16_t abro_version = 0;    /* later replaced, just to supress warnings */
+    uint16_t packet_length;
     ipv6_addr_t abro_addr;
 
     ipv6_buf = get_ipv6_buf();
+    packet_length = IPV6_HDR_LEN + ipv6_buf->length;
     opt_hdr_len = RTR_ADV_LEN;
     rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len);
     ipv6_addr_t newaddr;
@@ -767,13 +774,17 @@ void recv_rtr_adv(void)
         printf("INFO: send neighbor solicitation to: ");
         ipv6_print_addr(&(ipv6_buf->destaddr));
 #endif
-        lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf);
+        sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                                (uint8_t *)ipv6_buf,
+                                packet_length);
     }
 }
 
 void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ,
                   uint8_t sllao, uint8_t aro)
 {
+    uint16_t packet_length;
+
     ipv6_buf = get_ipv6_buf();
     ipv6_buf->version_trafficclass = IPV6_VER;
     ipv6_buf->trafficclass_flowlabel = 0;
@@ -847,6 +858,7 @@ void recv_nbr_sol(void)
     uint8_t send_na = 0;
     uint8_t sllao_set = 0;
     uint8_t aro_state = OPT_ARO_STATE_SUCCESS;
+    uint16_t packet_length = IPV6_HDR_LEN + ipv6_buf->length;
 
     /* check whick options are set, we need that because an aro
      * option condition is that a sllao option is set. thus that we don't
@@ -1022,13 +1034,17 @@ void recv_nbr_sol(void)
         printf("INFO: send neighbor advertisment to: ");
         ipv6_print_addr(&ipv6_buf->destaddr);
 #endif
-        lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf);
+        sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                                (uint8_t *)ipv6_buf,
+                                packet_length);
     }
 }
 
 void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt,
                   uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state)
 {
+    uint16_t packet_length;
+
     ipv6_buf = get_ipv6_buf();
     ipv6_buf->version_trafficclass = IPV6_VER;
     ipv6_buf->trafficclass_flowlabel = 0;
@@ -1083,6 +1099,8 @@ void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt,
 
 void recv_nbr_adv(void)
 {
+    ipv6_buf = get_ipv6_buf();
+    uint16_t packet_length = IPV6_HDR_LEN + ipv6_buf->length;
     opt_hdr_len = NBR_ADV_LEN;
     llao = NULL;
     nbr_entry = NULL;
@@ -1215,11 +1233,9 @@ uint16_t icmpv6_csum(uint8_t proto)
 
 void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code, uint32_t pointer, uint8_t *packet, uint8_t packet_len)
 {
+    uint16_t packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + PARA_PROB_LEN;
     struct para_prob_t *para_prob_buf;
 
-
-    packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + PARA_PROB_LEN;
-
     memcpy(&(ipv6_buf[packet_length]), packet, min(MTU - packet_length, packet_len));
 
     ipv6_buf = get_ipv6_buf();
diff --git a/sys/net/sixlowpan/icmp.h b/sys/net/sixlowpan/icmp.h
index e635dcfc68..ed4eff401a 100644
--- a/sys/net/sixlowpan/icmp.h
+++ b/sys/net/sixlowpan/icmp.h
@@ -22,6 +22,7 @@
 
 #include <stdint.h>
 #include "vtimer.h"
+#include "sixlowpan/icmp.h"
 #include "lowpan.h"
 #include "ip.h"
 
diff --git a/sys/net/sixlowpan/include/sixlowpan.h b/sys/net/sixlowpan/include/sixlowpan.h
index ce8db15586..eeb1634a70 100644
--- a/sys/net/sixlowpan/include/sixlowpan.h
+++ b/sys/net/sixlowpan/include/sixlowpan.h
@@ -48,7 +48,6 @@
 #include "sixlowpan/mac.h"
 
 #include "../border.h"      /* TODO: remove if not needed anymore */
-#include "../lowpan.h"      /* TODO: remove if not needed anymore */
 
 /**
  * @}
diff --git a/sys/net/sixlowpan/include/sixlowpan/icmp.h b/sys/net/sixlowpan/include/sixlowpan/icmp.h
index 270091a058..a064df3a5c 100644
--- a/sys/net/sixlowpan/include/sixlowpan/icmp.h
+++ b/sys/net/sixlowpan/include/sixlowpan/icmp.h
@@ -21,4 +21,16 @@
 #ifndef SIXLOWPAN_ICMP_H
 #define SIXLOWPAN_ICMP_H
 
+/* icmp message types rfc4443 */
+#define ICMP_PARA_PROB                 	(4)
+#define ICMP_ECHO_REQ                   (128)
+#define ICMP_ECHO_REPL                  (129)
+/* icmp message types rfc4861 4.*/
+#define ICMP_RTR_ADV                   	(134)
+#define ICMP_RTR_SOL                   	(133)
+#define ICMP_NBR_ADV                   	(136)
+#define ICMP_NBR_SOL                   	(135)
+#define ICMP_REDIRECT                  	(137)	/* will be filtered out by the border router */
+#define ICMP_RPL_CONTROL                (155)
+
 #endif /* SIXLOWPAN_ICMP_H */
diff --git a/sys/net/sixlowpan/include/sixlowpan/lowpan.h b/sys/net/sixlowpan/include/sixlowpan/lowpan.h
index 4b2d70e66d..a2c7122d0d 100644
--- a/sys/net/sixlowpan/include/sixlowpan/lowpan.h
+++ b/sys/net/sixlowpan/include/sixlowpan/lowpan.h
@@ -1,5 +1,6 @@
 /**
- * 6LoWPAN constants, data structs, and prototypes for 6LoWPAN layer
+ * sixlowpan/lowpan.h   - 6LoWPAN constants, data structs, and
+ *                        prototypes for 6LoWPAN layer
  *
  * Copyright (C) 2013  INRIA.
  *
@@ -9,16 +10,234 @@
  *
  * @ingroup sixlowpan
  * @{
- * @file    sixlowpan/lowpan.h
+ * @file
  * @brief   6LoWPAN LoWPAN layer header
  * @author  Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
  * @author  Martin Lenders <mlenders@inf.fu-berlin.de>
  * @author  Eric Engel <eric.engel@fu-berlin.de>
  * @author  Oliver Gesch <oliver.gesch@googlemail.com>
- * @}
  */
 
 #ifndef SIXLOWPAN_LOWPAN_H
 #define SIXLOWPAN_LOWPAN_H
 
+#include <stdint.h>
+
+#include "transceiver.h"
+#include "sixlowpan/types.h"
+
+/**
+ * @brief   6LoWPAN dispatch value for uncompressed IPv6 packets.
+ * @see <a href="http://tools.ietf.org/html/rfc4944#section-5.1">
+ *          RFC 4944, section 5.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPV6_DISPATCH   	(0x41)
+
+/**
+ * @brief   6LoWPAN dispatch value for IPv6 header compression (part of
+ *          first byte of LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 4944, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC1_DISPATCH   	(0x60)
+
+/**
+ * @brief   Flag for Flow Label elision (part of first byte of
+ *          LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC1_FL_C       	(0x10)
+
+/**
+ * @brief   Flag for Traffic Class elision (part of first byte of
+ *          LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC1_TC_C       	(0x08)
+
+/**
+ * @brief   Flag for Next Header Compression (part of first byte of
+ *          LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC1_NH         	(0x04)
+
+/**
+ * @brief   Flag for Context Identifier Extention (part of second byte
+ *          of LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC2_CID        	(0x80)
+
+/**
+ * @brief   Flag for Source Address Compression (part of second byte
+ *          of LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC2_SAC        	(0x40)
+
+/**
+ * @brief   Bits for Source Address Mode (part of second byte of
+ *          LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC2_SAM        	(0x30)
+
+/**
+ * @brief   Flag for Destination Address Compression (part of second
+ *          byte of LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC2_DAC        	(0x04)
+
+/**
+ * @brief   Bits for Destination Address Mode (part of second byte of
+ *          LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC2_DAM        	(0x03)
+
+/**
+ * @brief   Flag for Multicast Compression (part of second byte of
+ *          LOWPAN_IPHC).
+ * @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
+ *          RFC 6282, section 3.1.1
+ *      </a>
+ */
+#define SIXLOWPAN_IPHC2_M          	(0x08)
+
+
+/**
+ * 6LoWPAN dispatch value for fragmentation header (first fragment)
+ * @see <a href="http://tools.ietf.org/html/rfc4944#section-5.1">
+ *          RFC 4944, section 5.1
+ *      </a>
+ */
+#define SIXLOWPAN_FRAG1_DISPATCH    (0xc0)
+
+/**
+ * 6LoWPAN dispatch value for fragmentation header (subsequent fragment)
+ * @see <a href="http://tools.ietf.org/html/rfc4944#section-5.1">
+ *          RFC 4944, section 5.1
+ *      </a>
+ */
+#define SIXLOWPAN_FRAGN_DISPATCH    (0xe0)
+
+
+/**
+ * 6LoWPAN fragmentation header length (first fragment)
+ */
+#define SIXLOWPAN_FRAG1_HDR_LEN  	(4)
+
+/**
+ * 6LoWPAN fragmentation header length (subsequent fragment)
+ */
+#define SIXLOWPAN_FRAGN_HDR_LEN    	(5)
+
+
+/**
+ * @brief   Data type to configure 6LoWPAN IPv6 header compression.
+ */
+typedef enum __attribute__((packed))
+{
+    LOWPAN_IPHC_DISABLE = 0,    ///< header compression disabled
+    LOWPAN_IPHC_ENABLE = 1      ///< header compression enabled
+} sixlowpan_lowpan_iphc_status_t;
+
+/**
+ * @brief   Data type to represent an 6LoWPAN frame as byte stream.
+ */
+typedef struct __attribute__((packed)) {
+    uint8_t length;             ///< length of the byte stream.
+    uint8_t *data;              ///< the byte stream representing the 6LoWPAN frame.
+} sixlowpan_lowpan_frame_t;
+
+
+/**
+ * @brief   Initializes 6LoWPAN.
+ *
+ * @param[in] trans     Transceiver to use with 6LoWPAN.
+ * @param[in] r_addr    PHY layer address.
+ * @param[in] as_border 1 if node should act as border router,
+ *                      0 otherwise.
+ */
+void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr,
+                           int as_border);
+
+/**
+ * @brief   Initializes a 6LoWPAN router with address prefix
+ *
+ * @param[in] trans     transceiver to use with 6LoWPAN.
+ * @param[in] prefix    the address prefix to advertise.
+ * @param[in] r_addr    PHY layer address.
+ */
+void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans,
+                                 const ipv6_addr_t *prefix, 
+                                 uint8_t r_addr);
+
+/**
+ * @brief   Send data via 6LoWPAN to destination node dest.
+ *
+ * @param[in] dest      EUI-64 of destination node.
+ * @param[in] data      Data to send to destination node (may be 
+ *                      manipulated).
+ * @param[in] data_len  Length of data.
+ */
+void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, 
+                             uint8_t *data, uint16_t data_len);
+
+/**
+ * @brief   Set header compression status for 6LoWPAN.
+ *
+ * @param[in] status    Header compression status to set to.
+ */
+void sixlowpan_lowpan_set_iphc_status(
+    sixlowpan_lowpan_iphc_status_t status);
+
+/**
+ * @brief   Registers a thread to read received 6LoWPAN frames. The
+ *          6LoWPAN frames are delivered as sixlowpan_lowpan_frame_t
+ *          structs.
+ *
+ * @param[in] pid   The PID of the receiver thread.
+ *
+ * @return  1 on success, ENOMEM if maximum number of registrable
+ *          threads is exceeded.
+ */
+uint8_t sixlowpan_lowpan_register(int pid);
+
+#if ENABLE_DEBUG
+/**
+ * @brief   Print current buffer of assembled (i. e. not fragmented)
+ *          6LoWPAN packages.
+ */
+void sixlowpan_lowpan_print_fifo_buffers(void);
+
+/**
+ * @brief   Print current buffer for 6LoWPAN fragmentation reassembly.
+ */
+void sixlowpan_lowpan_print_reassembly_buffers(void);
+#endif
+
+/**
+ * @}
+ */
 #endif /* SIXLOWPAN_LOWPAN_H */
diff --git a/sys/net/sixlowpan/ip.c b/sys/net/sixlowpan/ip.c
index 5a8886388d..40d60e40cf 100644
--- a/sys/net/sixlowpan/ip.c
+++ b/sys/net/sixlowpan/ip.c
@@ -84,6 +84,7 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len,
                     uint8_t next_header)
 {
     uint8_t *p_ptr;
+    uint16_t packet_length;
 
     if (next_header == IPPROTO_TCP) {
         p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
@@ -95,7 +96,6 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len,
     }
 
     icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
-    packet_length = 0;
 
     ipv6_buf->version_trafficclass = IPV6_VER;
     ipv6_buf->trafficclass_flowlabel = 0;
@@ -111,8 +111,8 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len,
 
     packet_length = IPV6_HDR_LEN + p_len;
 
-    lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
-                (uint8_t *)ipv6_buf);
+    sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                            (uint8_t *)ipv6_buf, packet_length);
 }
 
 /* Register an upper layer thread */
@@ -120,8 +120,10 @@ uint8_t sixlowip_register(int pid)
 {
     uint8_t i;
 
-    for (i = 0; ((sixlowip_reg[i] != pid) && (i < SIXLOWIP_MAX_REGISTERED) && 
-                 (sixlowip_reg[i] != 0)); i++);
+    for (i = 0; ((sixlowip_reg[i] != pid) && (i < SIXLOWIP_MAX_REGISTERED) &&
+                 (sixlowip_reg[i] != 0)); i++) {
+        ;
+    }
 
     if (i >= SIXLOWIP_MAX_REGISTERED) {
         return ENOMEM;
@@ -205,6 +207,7 @@ void ipv6_process(void)
     msg_t m_recv, m_send;
     ipv6_addr_t myaddr;
     uint8_t i;
+    uint16_t packet_length;
 
     ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00,
                       sixlowpan_mac_get_radio_address());
@@ -219,10 +222,11 @@ void ipv6_process(void)
 
         if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) &&
             (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) {
-            memcpy(get_ipv6_buf_send(), get_ipv6_buf(),
-                   IPV6_HDR_LEN + ipv6_buf->length);
-            lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
-                        (uint8_t *)get_ipv6_buf_send());
+            packet_length = IPV6_HDR_LEN + ipv6_buf->length;
+            memcpy(get_ipv6_buf_send(), get_ipv6_buf(), packet_length);
+            sixlowpan_lowpan_sendto((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]),
+                                    (uint8_t *)get_ipv6_buf_send(),
+                                    packet_length);
         }
         else {
             for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) {
@@ -232,6 +236,7 @@ void ipv6_process(void)
                     msg_send(&m_send, sixlowip_reg[i], 1);
                 }
             }
+
             switch (*nextheader) {
                 case (PROTO_NUM_ICMPV6): {
                     /* checksum test*/
@@ -365,7 +370,7 @@ void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix)
     memcpy(&(inout->uint8[8]), &(iface.laddr.uint8[0]), 8);
 }
 
-void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix)
+void ipv6_set_prefix(ipv6_addr_t *inout, const ipv6_addr_t *prefix)
 {
     inout->uint16[0] = prefix->uint16[0];
     inout->uint16[1] = prefix->uint16[1];
diff --git a/sys/net/sixlowpan/ip.h b/sys/net/sixlowpan/ip.h
index c72116d724..7baa7a2744 100644
--- a/sys/net/sixlowpan/ip.h
+++ b/sys/net/sixlowpan/ip.h
@@ -52,7 +52,6 @@
 /* extern variables */
 extern uint8_t ipv6_ext_hdr_len;
 extern uint8_t opt_hdr_len;
-extern uint16_t packet_length;
 extern uint8_t packet_dispatch;
 extern uint8_t iface_addr_list_count;
 extern mutex_t buf_mutex;
@@ -168,7 +167,7 @@ void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1,
                        uint16_t addr5, uint16_t addr6, uint16_t addr7);
 uint32_t get_remaining_time(timex_t *t);
 void set_remaining_time(timex_t *t, uint32_t time);
-void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix);
+void ipv6_set_prefix(ipv6_addr_t *inout, const ipv6_addr_t *prefix);
 uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr);
 uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr);
 uint8_t ipv6_next_hdr_unrec(uint8_t next_hdr);
diff --git a/sys/net/sixlowpan/lowpan.c b/sys/net/sixlowpan/lowpan.c
index ce22c175c4..2fd6077890 100644
--- a/sys/net/sixlowpan/lowpan.c
+++ b/sys/net/sixlowpan/lowpan.c
@@ -43,7 +43,42 @@
 #include "sys/net/destiny/in.h"
 #include "sys/net/net_help/net_help.h"
 
-uint16_t packet_length;
+#define IP_PROCESS_STACKSIZE           	(KERNEL_CONF_STACKSIZE_IDLE * 6)
+#define NC_STACKSIZE                   	(KERNEL_CONF_STACKSIZE_IDLE)
+#define CON_STACKSIZE                  	(KERNEL_CONF_STACKSIZE_IDLE)
+#define LOWPAN_TRANSFER_BUF_STACKSIZE  	(KERNEL_CONF_STACKSIZE_IDLE)
+
+#define SIXLOWPAN_MAX_REGISTERED     (4)
+
+#define LOWPAN_REAS_BUF_TIMEOUT (15 * 1000 * 1000) /* TODO: Set back to 3 * 1000 *	(1000) */
+
+typedef struct lowpan_interval_list_t {
+    uint8_t                         start;
+    uint8_t                         end;
+    struct lowpan_interval_list_t   *next;
+} lowpan_interval_list_t;
+
+typedef struct lowpan_reas_buf_t {
+    /* Source Address */
+    ieee_802154_long_t       s_laddr;
+    /* Destination Address */
+    ieee_802154_long_t       d_laddr;
+    /* Identification Number */
+    uint16_t                 ident_no;
+    /* Timestamp of last packet fragment */
+    long                     timestamp;
+    /* Size of reassembled packet with possible IPHC header */
+    uint16_t                 packet_size;
+    /* Additive size of currently already received fragments */
+    uint16_t                 current_packet_size;
+    /* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */
+    uint8_t                  *packet;
+    /* Pointer to list of intervals of received packet fragments (if any) */
+    lowpan_interval_list_t   *interval_list_head;
+    /* Pointer to next reassembly buffer (if any) */
+    struct lowpan_reas_buf_t *next;
+} lowpan_reas_buf_t;
+
 uint8_t packet_dispatch;
 uint16_t tag;
 uint8_t header_size = 0;
@@ -51,9 +86,12 @@ uint8_t max_frame = 0;
 uint8_t max_frag_initial = 0;
 uint8_t position;
 uint8_t max_frag;
-lowpan_iphc_status_t iphc_status = LOWPAN_IPHC_ENABLE;
 
+static uint16_t packet_length;
+static sixlowpan_lowpan_iphc_status_t iphc_status = LOWPAN_IPHC_ENABLE;
 static ipv6_hdr_t *ipv6_buf;
+static lowpan_reas_buf_t *head = NULL;
+static lowpan_reas_buf_t *packet_fifo = NULL;
 
 /* length of compressed packet */
 uint16_t comp_len;
@@ -62,8 +100,6 @@ uint8_t reas_buf[512];
 uint8_t comp_buf[512];
 uint8_t byte_offset;
 uint8_t first_frag = 0;
-lowpan_reas_buf_t *head = NULL;
-lowpan_reas_buf_t *packet_fifo = NULL;
 mutex_t fifo_mutex;
 
 unsigned int ip_process_pid;
@@ -89,26 +125,43 @@ uint8_t context_len = 0;
 uint16_t local_address = 0;
 
 void lowpan_context_auto_remove(void);
+void lowpan_iphc_encoding(ieee_802154_long_t *dest,
+                          ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr);
+void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
+                          ieee_802154_long_t *s_laddr,
+                          ieee_802154_long_t *d_laddr);
+void add_fifo_packet(lowpan_reas_buf_t *current_packet);
+lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf);
+lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf);
+void init_reas_bufs(lowpan_reas_buf_t *buf);
+void check_timeout(void);
+
+lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr);
+
+void lowpan_ipv6_set_dispatch(uint8_t *data);
 
 /* deliver packet to mac*/
-void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
+void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, 
+                             uint8_t *data, uint16_t data_len)
 {
     uint8_t mcast = 0;
 
     ipv6_buf = (ipv6_hdr_t *) data;
+    packet_length = data_len;
 
-    memcpy(&laddr.uint8[0], &addr->uint8[0], 8);
+    memcpy(&laddr.uint8[0], &dest->uint8[0], 8);
 
     if (ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) {
         /* send broadcast */
         mcast = 1;
     }
-    
+
     if (iphc_status == LOWPAN_IPHC_ENABLE) {
         lowpan_iphc_encoding(&laddr, ipv6_buf, data);
         data = &comp_buf[0];
         packet_length = comp_len;
-    } else {
+    }
+    else {
         lowpan_ipv6_set_dispatch(data);
     }
 
@@ -123,8 +176,8 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
 
         memcpy(fragbuf + 4, data, max_frag_initial);
 
-        fragbuf[0] = (((0xc0 << 8) | packet_length) >> 8) & 0xff;
-        fragbuf[1] = ((0xc0 << 8) | packet_length) & 0xff;
+        fragbuf[0] = (((SIXLOWPAN_FRAG1_DISPATCH << 8) | packet_length) >> 8) & 0xff;
+        fragbuf[1] = ((SIXLOWPAN_FRAG1_DISPATCH << 8) | packet_length) & 0xff;
         fragbuf[2] = (tag >> 8) & 0xff;
         fragbuf[3] = tag & 0xff;
 
@@ -142,8 +195,8 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
             memset(&fragbuf, 0, packet_length + header_size);
             memcpy(fragbuf + 5, data, max_frag);
 
-            fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
-            fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
+            fragbuf[0] = (((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) >> 8) & 0xff;
+            fragbuf[1] = ((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) & 0xff;
             fragbuf[2] = (tag >> 8) & 0xff;
             fragbuf[3] = tag & 0xff;
             fragbuf[4] = position / 8;
@@ -162,8 +215,8 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
         memset(&fragbuf, 0, packet_length + header_size);
         memcpy(fragbuf + 5, data, remaining);
 
-        fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
-        fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
+        fragbuf[0] = (((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) >> 8) & 0xff;
+        fragbuf[1] = ((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) & 0xff;
         fragbuf[2] = (tag >> 8) & 0xff;
         fragbuf[3] = tag & 0xff;
         fragbuf[4] = position / 8;
@@ -180,12 +233,14 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
     tag++;
 }
 
-void lowpan_set_iphc_status(lowpan_iphc_status_t status)
+void sixlowpan_lowpan_set_iphc_status(
+    sixlowpan_lowpan_iphc_status_t status)
 {
     iphc_status = status;
 }
 
-void printLongLocalAddr(ieee_802154_long_t *saddr)
+#if ENABLE_DEBUG
+void print_long_local_addr(ieee_802154_long_t *saddr)
 {
     printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
            ((uint8_t *)saddr)[0], ((uint8_t *)saddr)[1], ((uint8_t *)saddr)[2],
@@ -193,7 +248,7 @@ void printLongLocalAddr(ieee_802154_long_t *saddr)
            ((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]);
 }
 
-void printReasBuffers(void)
+void sixlowpan_lowpan_print_reassembly_buffers(void)
 {
     lowpan_reas_buf_t *temp_buffer;
     lowpan_interval_list_t *temp_interval;
@@ -202,7 +257,7 @@ void printReasBuffers(void)
     printf("\n\n--- Reassembly Buffers ---\n");
 
     while (temp_buffer != NULL) {
-        printLongLocalAddr(&temp_buffer->s_laddr);
+        print_long_local_addr(&temp_buffer->s_laddr);
         printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n",
                temp_buffer->ident_no, temp_buffer->current_packet_size,
                temp_buffer->packet_size, temp_buffer->timestamp);
@@ -217,7 +272,7 @@ void printReasBuffers(void)
     }
 }
 
-void printFIFOBuffers(void)
+void sixlowpan_lowpan_print_fifo_buffers(void)
 {
     lowpan_reas_buf_t *temp_buffer;
     lowpan_interval_list_t *temp_interval;
@@ -226,7 +281,7 @@ void printFIFOBuffers(void)
     printf("\n\n--- Reassembly Buffers ---\n");
 
     while (temp_buffer != NULL) {
-        printLongLocalAddr(&temp_buffer->s_laddr);
+        print_long_local_addr(&temp_buffer->s_laddr);
         printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n",
                temp_buffer->ident_no, temp_buffer->current_packet_size,
                temp_buffer->packet_size, temp_buffer->timestamp);
@@ -240,6 +295,7 @@ void printFIFOBuffers(void)
         temp_buffer = temp_buffer->next;
     }
 }
+#endif
 
 void lowpan_transfer(void)
 {
@@ -257,14 +313,14 @@ void lowpan_transfer(void)
         if (current_buf != NULL) {
             mutex_unlock(&fifo_mutex);
 
-            if ((current_buf->packet)[0] == LOWPAN_IPV6_DISPATCH) {
+            if ((current_buf->packet)[0] == SIXLOWPAN_IPV6_DISPATCH) {
                 ipv6_buf = get_ipv6_buf();
                 memcpy(ipv6_buf, (current_buf->packet) + 1, current_buf->packet_size - 1);
                 m_send.content.ptr = (char *)ipv6_buf;
                 packet_length = current_buf->packet_size - 1;
                 msg_send_receive(&m_send, &m_recv, ip_process_pid);
             }
-            else if (((current_buf->packet)[0] & 0xe0) == LOWPAN_IPHC_DISPATCH) {
+            else if (((current_buf->packet)[0] & 0xe0) == SIXLOWPAN_IPHC1_DISPATCH) {
                 lowpan_iphc_decoding(current_buf->packet,
                                      current_buf->packet_size,
                                      &(current_buf->s_laddr),
@@ -393,7 +449,7 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size,
                              current_buf, temp_buf);
 }
 
-uint8_t isInInterval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2)
+uint8_t is_in_interval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2)
 {
     /* 1: Interval 1 and 2 are the same or overlapping */
     /* 0: Interval 1 and 2 are not overlapping or the same */
@@ -417,7 +473,7 @@ uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf,
     current_interval = current_buf->interval_list_head;
 
     while (current_interval != NULL) {
-        if (isInInterval(current_interval->start, current_interval->end, datagram_offset, datagram_offset + frag_size) == 1) {
+        if (is_in_interval(current_interval->start, current_interval->end, datagram_offset, datagram_offset + frag_size) == 1) {
             /* Interval is overlapping or the same as one of a previous fragment, discard fragment */
             return 0;
         }
@@ -636,12 +692,14 @@ void add_fifo_packet(lowpan_reas_buf_t *current_packet)
 }
 
 /* Register an upper layer thread */
-uint8_t sixlowpan_register(int pid)
+uint8_t sixlowpan_lowpan_register(int pid)
 {
     uint8_t i;
 
-    for (i = 0; ((sixlowpan_reg[i] != pid) && (i < SIXLOWPAN_MAX_REGISTERED) && 
-                 (sixlowpan_reg[i] != 0)); i++);
+    for (i = 0; ((sixlowpan_reg[i] != pid) && (i < SIXLOWPAN_MAX_REGISTERED) &&
+                 (sixlowpan_reg[i] != 0)); i++) {
+        ;
+    }
 
     if (i >= SIXLOWPAN_MAX_REGISTERED) {
         return ENOMEM;
@@ -661,21 +719,22 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
     uint16_t datagram_size = 0;
     uint16_t datagram_tag = 0;
     short i;
-    lowpan_datagram_t current_datagram;
+    sixlowpan_lowpan_frame_t current_frame;
 
     check_timeout();
 
     for (i = 0; i < SIXLOWPAN_MAX_REGISTERED; i++) {
         if (sixlowpan_reg[i]) {
             msg_t m_send;
-            current_datagram.length = length;
-            current_datagram.data = data;
-            m_send.content.ptr = (char *) &current_datagram;
+            current_frame.length = length;
+            current_frame.data = data;
+            m_send.content.ptr = (char *) &current_frame;
             msg_send(&m_send, sixlowpan_reg[i], 1);
         }
     }
+
     /* Fragmented Packet */
-    if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) {
+    if (((data[0] & 0xf8) == SIXLOWPAN_FRAG1_DISPATCH) || ((data[0] & 0xf8) == SIXLOWPAN_FRAGN_DISPATCH)) {
         /* get 11-bit from first 2 byte*/
         datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff;
 
@@ -684,14 +743,14 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
 
         switch (data[0] & 0xf8) {
                 /* First Fragment */
-            case (0xc0): {
+            case (SIXLOWPAN_FRAG1_DISPATCH): {
                 datagram_offset = 0;
                 hdr_length += 4;
                 break;
             }
 
             /* Subsequent Fragment */
-            case (0xe0): {
+            case (SIXLOWPAN_FRAGN_DISPATCH): {
                 datagram_offset = data[4];
                 hdr_length += 5;
                 break;
@@ -730,7 +789,7 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
 void lowpan_ipv6_set_dispatch(uint8_t *data)
 {
     memmove(data + 1, data, packet_length);
-    data[0] = LOWPAN_IPV6_DISPATCH;
+    data[0] = SIXLOWPAN_IPV6_DISPATCH;
     packet_length++;
 }
 
@@ -750,7 +809,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
     memset(&lowpan_iphc, 0, 2);
 
     /* set iphc dispatch */
-    lowpan_iphc[0] = LOWPAN_IPHC_DISPATCH;
+    lowpan_iphc[0] = SIXLOWPAN_IPHC1_DISPATCH;
 
     /* TF: Traffic Class, Flow Label:
      * first we need to change DSCP and ECN because in 6lowpan-nd-13 these
@@ -762,12 +821,12 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
     if ((ipv6_buf->flowlabel == 0) &&
         (ipv6_buf->trafficclass_flowlabel & 0x0f) == 0) {
         /* flowlabel is elided */
-        lowpan_iphc[0] |= LOWPAN_IPHC_FL_C;
+        lowpan_iphc[0] |= SIXLOWPAN_IPHC1_FL_C;
 
         if (((ipv6_buf->version_trafficclass & 0x0f) == 0) &&
             ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) {
             /* traffic class is elided */
-            lowpan_iphc[0] |= LOWPAN_IPHC_TC_C;
+            lowpan_iphc[0] |= SIXLOWPAN_IPHC1_TC_C;
         }
         else {
             /* ECN + DSCP (1 byte), Flow Label is elided */
@@ -780,7 +839,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
         if (((ipv6_buf->version_trafficclass & 0x0f) == 0) &&
             ((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) {
             /* traffic class is elided */
-            lowpan_iphc[0] |= LOWPAN_IPHC_TC_C;
+            lowpan_iphc[0] |= SIXLOWPAN_IPHC1_TC_C;
             /* ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided */
             ipv6_hdr_fields[hdr_pos] = ((tc & 0xc0) |
                                         (ipv6_buf->trafficclass_flowlabel & 0x0f));
@@ -832,7 +891,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
     /* CID: Context Identifier Extension: */
     if ((lowpan_context_lookup(&ipv6_buf->srcaddr) != NULL) ||
         (lowpan_context_lookup(&ipv6_buf->destaddr) != NULL)) {
-        lowpan_iphc[1] |= LOWPAN_IPHC_CID;
+        lowpan_iphc[1] |= SIXLOWPAN_IPHC2_CID;
         memmove(&ipv6_hdr_fields[1], &ipv6_hdr_fields[0], hdr_pos);
         hdr_pos++;
     }
@@ -840,12 +899,12 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
     /* SAC: Source Address Compression */
     if (ipv6_addr_unspec_match(&(ipv6_buf->srcaddr))) {
         /* SAC = 1 and SAM = 00 */
-        lowpan_iphc[1] |= LOWPAN_IPHC_SAC;
+        lowpan_iphc[1] |= SIXLOWPAN_IPHC2_SAC;
     }
     else if ((con = lowpan_context_lookup(&ipv6_buf->srcaddr)) != NULL) {
         /* 1: Source address compression uses stateful, context-based
          *    compression. */
-        lowpan_iphc[1] |= LOWPAN_IPHC_SAC;
+        lowpan_iphc[1] |= SIXLOWPAN_IPHC2_SAC;
         ipv6_hdr_fields[0] |= (con->num << 4);
 
         if (memcmp(&(ipv6_buf->srcaddr.uint8[8]), &(iface.laddr.uint8[0]), 8) == 0) {
@@ -909,7 +968,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
     /* M: Multicast Compression */
     if (ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) {
         /* 1: Destination address is a multicast address. */
-        lowpan_iphc[1] |= LOWPAN_IPHC_M;
+        lowpan_iphc[1] |= SIXLOWPAN_IPHC2_M;
 
         /* just another cool if condition */
         if ((ipv6_buf->destaddr.uint8[1] == 2) &&
@@ -962,7 +1021,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
         if ((con = lowpan_context_lookup(&ipv6_buf->destaddr)) != NULL) {
             /* 1: Destination address compression uses stateful, context-based
              * compression. */
-            lowpan_iphc[1] |= LOWPAN_IPHC_DAC;
+            lowpan_iphc[1] |= SIXLOWPAN_IPHC2_DAC;
             ipv6_hdr_fields[0] = con->num;
 
             if (memcmp(&(ipv6_buf->destaddr.uint8[8]), &(dest->uint8[0]), 8) == 0) {
@@ -1064,15 +1123,15 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
     hdr_pos += 2;
 
     /* first check if CID flag is set */
-    if (lowpan_iphc[1] & LOWPAN_IPHC_CID) {
+    if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_CID) {
         hdr_pos++;
         cid = 1;
     }
 
     /* TF: Traffic Class, Flow Label: */
-    if (lowpan_iphc[0] & LOWPAN_IPHC_FL_C) {
+    if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_FL_C) {
         /* flowlabel is elided */
-        if (lowpan_iphc[0] & LOWPAN_IPHC_TC_C) {
+        if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_TC_C) {
             /* traffic class is elided */
             ipv6_buf->version_trafficclass = 0x60;
             ipv6_buf->trafficclass_flowlabel = 0;
@@ -1090,7 +1149,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
     }
     else {
         /* flowlabel carried inline */
-        if (lowpan_iphc[0] & LOWPAN_IPHC_TC_C) {
+        if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_TC_C) {
             /* traffic class is elided */
             ipv6_buf->version_trafficclass = 0x60;
             /* ecn + 4 bit flowlabel*/
@@ -1115,7 +1174,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
     }
 
     /* NH: Next Header: */
-    if (lowpan_iphc[0] & LOWPAN_IPHC_NH) {
+    if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_NH) {
         // TODO: next header decompression
     }
     else {
@@ -1151,7 +1210,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
     }
 
     /* CID: Context Identifier Extension: + SAC: Source Address Compression */
-    if (lowpan_iphc[1] & LOWPAN_IPHC_SAC) {
+    if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAC) {
         /* 1: Source address compression uses stateful, context-based
          * compression.*/
         if (cid) {
@@ -1161,7 +1220,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
         mutex_lock(&lowpan_context_mutex);
 
         /* check context number */
-        if (((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) {
+        if (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) {
             con = lowpan_context_num_lookup(sci);
         }
 
@@ -1170,7 +1229,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
             return;
         }
 
-        switch (((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) {
+        switch (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) {
             case (0x01): {
                 /* 64-bits */
                 memcpy(&(ipv6_buf->srcaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8);
@@ -1212,7 +1271,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
         mutex_unlock(&lowpan_context_mutex);
     }
     else {
-        switch (((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) {
+        switch (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) {
             case (0x01): {
                 /* 64-bits */
                 memcpy(&(ipv6_buf->srcaddr.uint8[0]), &ll_prefix[0], 2);
@@ -1250,9 +1309,9 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
     }
 
     /* M: Multicast Compression + DAC: Destination Address Compression */
-    if (lowpan_iphc[1] & LOWPAN_IPHC_M) {
+    if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_M) {
         /* 1: Destination address is a multicast address. */
-        if (lowpan_iphc[1] & LOWPAN_IPHC_DAC) {
+        if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAC) {
             /* 1: Destination address compression uses stateful, context-based
              * compression.
              * If M=1 and DAC=1: */
@@ -1262,7 +1321,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
 
             mutex_lock(&lowpan_context_mutex);
 
-            if ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
+            if ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
                 con = lowpan_context_num_lookup(dci);
             }
 
@@ -1326,7 +1385,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
         }
     }
     else {
-        if (lowpan_iphc[1] & LOWPAN_IPHC_DAC) {
+        if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAC) {
             /* 1: Destination address compression uses stateful, context-based
              * compression.
              * If M=1 and DAC=1: */
@@ -1336,7 +1395,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
 
             mutex_lock(&lowpan_context_mutex);
 
-            if ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
+            if ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
                 con = lowpan_context_num_lookup(dci);
             }
 
@@ -1345,7 +1404,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
                 return;
             }
 
-            switch ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
+            switch ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
                 case (0x01): {
                     memcpy(&(ipv6_buf->destaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8);
                     /* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */
@@ -1378,7 +1437,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
             mutex_unlock(&lowpan_context_mutex);
         }
         else {
-            switch ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
+            switch ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
                 case (0x01): {
                     memcpy(&(ipv6_buf->destaddr.uint8[0]), &ll_prefix[0], 2);
                     memset(&(ipv6_buf->destaddr.uint8[2]), 0, 6);
@@ -1553,7 +1612,8 @@ void init_reas_bufs(lowpan_reas_buf_t *buf)
     buf->next = 				NULL;
 }
 
-void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border)
+void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr,
+                           int as_border)
 {
     ipv6_addr_t tmp;
     short i;
@@ -1621,12 +1681,15 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border)
 
 }
 
-void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix,
-                          uint8_t r_addr)
+void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans, 
+                                 const ipv6_addr_t *prefix,
+                                 uint8_t r_addr)
 {
     /* init network prefix */
-    ipv6_set_prefix(prefix, prefix);
-    plist_add(prefix, 64, OPT_PI_VLIFETIME_INFINITE, 0, 1, OPT_PI_FLAG_A);
+    ipv6_addr_t save_prefix;
+    ipv6_set_prefix(&save_prefix, prefix);
+    plist_add(&save_prefix, 64, OPT_PI_VLIFETIME_INFINITE, 0, 1, 
+              OPT_PI_FLAG_A);
     ipv6_init_iface_as_router();
-    sixlowpan_init(trans, r_addr, 0);
+    sixlowpan_lowpan_init(trans, r_addr, 0);
 }
diff --git a/sys/net/sixlowpan/lowpan.h b/sys/net/sixlowpan/lowpan.h
index 5e5283528d..a1c7937447 100644
--- a/sys/net/sixlowpan/lowpan.h
+++ b/sys/net/sixlowpan/lowpan.h
@@ -1,5 +1,5 @@
 /*
- * 6lowpan constants, data structs, and prototypes
+ * 6LoWPAN constants, data structs, and prototypes
  *
  * Copyright (C) 2013  INRIA.
  *
@@ -15,57 +15,15 @@
  * @author  Martin Lenders <mlenders@inf.fu-berlin.de>
  * @author  Oliver Gesch <oliver.gesch@googlemail.com>
  * @author  Eric Engel <eric.engel@fu-berlin.de>
- * @}
  */
 
 #ifndef _SIXLOWPAN_LOWPAN_H
 #define _SIXLOWPAN_LOWPAN_H
 
-#define IP_PROCESS_STACKSIZE           	(3072)
-#define NC_STACKSIZE                   	(512)
-#define CON_STACKSIZE                  	(512)
-#define LOWPAN_TRANSFER_BUF_STACKSIZE  	(512)
-
-/* fragment size in bytes*/
-#define FRAG_PART_ONE_HDR_LEN  	(4)
-#define FRAG_PART_N_HDR_LEN    	(5)
-
-#define SIXLOWPAN_MAX_REGISTERED     (4)
-
-#define LOWPAN_IPHC_DISPATCH   	(0x60)
-#define LOWPAN_IPHC_FL_C       	(0x10)
-#define LOWPAN_IPHC_TC_C       	(0x08)
-#define LOWPAN_IPHC_CID        	(0x80)
-#define LOWPAN_IPHC_SAC        	(0x40)
-#define LOWPAN_IPHC_SAM        	(0x30)
-#define LOWPAN_IPHC_DAC        	(0x04)
-#define LOWPAN_IPHC_DAM        	(0x03)
-#define LOWPAN_IPHC_M          	(0x08)
-#define LOWPAN_IPHC_NH         	(0x04)
-#define LOWPAN_IPV6_DISPATCH   	(0x41)
-#define LOWPAN_CONTEXT_MAX     	(16)
-
-#define LOWPAN_REAS_BUF_TIMEOUT (15 * 1000 * 1000) /* TODO: Set back to 3 * 1000 *	(1000) */
-
-/* icmp message types rfc4443 */
-#define ICMP_PARA_PROB                 	(4)
-#define ICMP_ECHO_REQ                   (128)
-#define ICMP_ECHO_REPL                  (129)
-/* icmp message types rfc4861 4.*/
-#define ICMP_RTR_ADV                   	(134)
-#define ICMP_RTR_SOL                   	(133)
-#define ICMP_NBR_ADV                   	(136)
-#define ICMP_NBR_SOL                   	(135)
-#define ICMP_REDIRECT                  	(137)	/* will be filtered out by the border router */
-#define ICMP_RPL_CONTROL                (155)
-
-#include "transceiver.h"
-#include "ip.h"
 #include "vtimer.h"
-#include "mutex.h"
+#include "sixlowpan/lowpan.h"
 
-extern mutex_t lowpan_context_mutex;
-extern uint16_t local_address;
+#define LOWPAN_CONTEXT_MAX     	(16)
 
 typedef struct {
     uint8_t num;
@@ -75,85 +33,21 @@ typedef struct {
     uint16_t lifetime;
 } lowpan_context_t;
 
-typedef struct lowpan_interval_list_t {
-    uint8_t                         start;
-    uint8_t                         end;
-    struct lowpan_interval_list_t   *next;
-} lowpan_interval_list_t;
-
-typedef struct lowpan_reas_buf_t {
-    /* Source Address */
-    ieee_802154_long_t       s_laddr;
-    /* Destination Address */
-    ieee_802154_long_t       d_laddr;
-    /* Identification Number */
-    uint16_t                 ident_no;
-    /* Timestamp of last packet fragment */
-    long                     timestamp;
-    /* Size of reassembled packet with possible IPHC header */
-    uint16_t                 packet_size;
-    /* Additive size of currently already received fragments */
-    uint16_t                 current_packet_size;
-    /* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */
-    uint8_t                  *packet;
-    /* Pointer to list of intervals of received packet fragments (if any) */
-    lowpan_interval_list_t   *interval_list_head;
-    /* Pointer to next reassembly buffer (if any) */
-    struct lowpan_reas_buf_t *next;
-} lowpan_reas_buf_t;
-
-typedef struct {
-    uint8_t length;
-    uint8_t *data;
-} lowpan_datagram_t;
-
-extern lowpan_reas_buf_t *head;
-
-typedef enum {
-    LOWPAN_IPHC_DISABLE = 0,
-    LOWPAN_IPHC_ENABLE = 1
-} lowpan_iphc_status_t;
-
-/**
- * @brief   Initializes 6lowpan
- *
- * @param[in] trans     transceiver to use with 6lowpan
- * @param[in] r_addr    phy layer address
- * @param[in] as_border 1 if node shoud act as border router, 0 otherwise
- */
-void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border);
+extern uint16_t local_address;
+extern mutex_t lowpan_context_mutex;
 
-/**
- * @brief Initializes a 6lowpan router with address prefix
- *
- * @param[in] trans     transceiver to use with 6lowpan
- * @param[in] prefix    the address prefix to advertise
- * @param[in] r_addr    phy layer address
- */
-void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix,
-                          uint8_t r_addr);
-void lowpan_init(ieee_802154_long_t *addr, uint8_t *data);
-void lowpan_set_iphc_status(lowpan_iphc_status_t status);
-void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
+void lowpan_read(uint8_t *data, uint8_t length,
+                 ieee_802154_long_t *s_laddr,
                  ieee_802154_long_t *d_laddr);
-void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr);
-void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
-                          ieee_802154_long_t *s_laddr,
-                          ieee_802154_long_t *d_laddr);
 uint8_t lowpan_context_len(void);
-void add_fifo_packet(lowpan_reas_buf_t *current_packet);
-lowpan_context_t *lowpan_context_update(
-    uint8_t num, const ipv6_addr_t *prefix,
-    uint8_t length, uint8_t comp,
-    uint16_t lifetime);
+lowpan_context_t *lowpan_context_update(uint8_t num,
+                                        const ipv6_addr_t *prefix,
+                                        uint8_t length, uint8_t comp,
+                                        uint16_t lifetime);
 lowpan_context_t *lowpan_context_get(void);
-lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr);
 lowpan_context_t *lowpan_context_num_lookup(uint8_t num);
-lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf);
-lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf);
-void check_timeout(void);
-void lowpan_ipv6_set_dispatch(uint8_t *data);
-void init_reas_bufs(lowpan_reas_buf_t *buf);
-void printReasBuffers(void);
-void printFIFOBuffers(void);
+
+/**
+ * @}
+ */
 #endif  /* _SIXLOWPAN_LOWPAN_H */
-- 
GitLab