From b68ee5067146d9a69e537a33d806663e1581b98e Mon Sep 17 00:00:00 2001
From: Oleg Hahm <oleg@hobbykeller.org>
Date: Sat, 27 Jul 2013 16:13:53 +0200
Subject: [PATCH] added callback for sixlowpan

---
 sys/net/sixlowpan/lowpan.c | 32 ++++++++++++++++++++++++++++++++
 sys/net/sixlowpan/lowpan.h |  7 +++++++
 2 files changed, 39 insertions(+)

diff --git a/sys/net/sixlowpan/lowpan.c b/sys/net/sixlowpan/lowpan.c
index 8f3699fe35..3502496dc4 100644
--- a/sys/net/sixlowpan/lowpan.c
+++ b/sys/net/sixlowpan/lowpan.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <limits.h>
+#include <errno.h>
 
 #include "vtimer.h"
 #include "timex.h"
@@ -76,6 +77,9 @@ ieee_802154_long_t laddr;
 mutex_t buf_mutex;
 mutex_t lowpan_context_mutex;
 
+/* registered upper layer threads */
+int sixlowpan_reg[SIXLOWPAN_MAX_REGISTERED];
+
 char ip_process_buf[IP_PROCESS_STACKSIZE];
 char nc_buf[NC_STACKSIZE];
 char con_buf[CON_STACKSIZE];
@@ -625,6 +629,23 @@ void add_fifo_packet(lowpan_reas_buf_t *current_packet)
     current_packet->next = NULL;
 }
 
+/* Register an upper layer thread */
+uint8_t sixlowpan_register(int pid)
+{
+    uint8_t i;
+
+    for (i = 0; ((sixlowpan_reg[i] != pid) && (i < SIXLOWPAN_MAX_REGISTERED) && 
+                 (sixlowpan_reg[i] != 0)); i++);
+
+    if (i >= SIXLOWPAN_MAX_REGISTERED) {
+        return ENOMEM;
+    }
+    else {
+        sixlowpan_reg[i] = pid;
+        return 1;
+    }
+}
+
 void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
                  ieee_802154_long_t *d_laddr)
 {
@@ -633,9 +654,20 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
     uint8_t datagram_offset = 0;
     uint16_t datagram_size = 0;
     uint16_t datagram_tag = 0;
+    short i;
+    lowpan_datagram_t current_datagram;
 
     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;
+            msg_send(&m_send, sixlowpan_reg[i], 1);
+        }
+    }
     /* Fragmented Packet */
     if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) {
         /* get 11-bit from first 2 byte*/
diff --git a/sys/net/sixlowpan/lowpan.h b/sys/net/sixlowpan/lowpan.h
index 99d6e00df8..5e5283528d 100644
--- a/sys/net/sixlowpan/lowpan.h
+++ b/sys/net/sixlowpan/lowpan.h
@@ -30,6 +30,8 @@
 #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)
@@ -100,6 +102,11 @@ typedef struct lowpan_reas_buf_t {
     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 {
-- 
GitLab