From c47f5a459e658d050db171ef7dae00eddd6e4ca8 Mon Sep 17 00:00:00 2001
From: Oleg Hahm <oleg@hobbykeller.org>
Date: Sat, 27 Jul 2013 15:04:51 +0200
Subject: [PATCH] added callback registration for sixlowip

---
 sys/net/sixlowpan/ip.c     | 30 ++++++++++++++++++++++++++++++
 sys/net/sixlowpan/ip.h     |  4 ++++
 sys/net/sixlowpan/lowpan.c |  7 +++++++
 3 files changed, 41 insertions(+)

diff --git a/sys/net/sixlowpan/ip.c b/sys/net/sixlowpan/ip.c
index 2fc1f2d8e1..85d1dcf5c5 100644
--- a/sys/net/sixlowpan/ip.c
+++ b/sys/net/sixlowpan/ip.c
@@ -20,6 +20,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <errno.h>
 
 #include "vtimer.h"
 #include "mutex.h"
@@ -46,6 +47,9 @@ int udp_packet_handler_pid = 0;
 int tcp_packet_handler_pid = 0;
 int rpl_process_pid = 0;
 
+/* registered upper layer threads */
+int sixlowip_reg[SIXLOWIP_MAX_REGISTERED];
+
 ipv6_hdr_t *get_ipv6_buf_send(void)
 {
     return ((ipv6_hdr_t *) & (ip_send_buffer[LL_HDR_LEN]));
@@ -111,6 +115,23 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len,
                 (uint8_t *)ipv6_buf);
 }
 
+/* Register an upper layer thread */
+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++);
+
+    if (i >= SIXLOWIP_MAX_REGISTERED) {
+        return ENOMEM;
+    }
+    else {
+        sixlowip_reg[i] = pid;
+        return 1;
+    }
+}
+
 int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr)
 {
     switch (hdr->type) {
@@ -183,6 +204,8 @@ void ipv6_process(void)
     msg_t m_recv_lowpan, m_send_lowpan;
     msg_t m_recv, m_send;
     ipv6_addr_t myaddr;
+    uint8_t i;
+
     ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00,
                       get_radio_address());
 
@@ -202,6 +225,13 @@ void ipv6_process(void)
                         (uint8_t *)get_ipv6_buf_send());
         }
         else {
+            for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) {
+                if (sixlowip_reg[i]) {
+                    msg_t m_send;
+                    m_send.content.ptr = (char *) &ipv6_buf;
+                    msg_send(&m_send, sixlowip_reg[i], 1);
+                }
+            }
             switch (*nextheader) {
                 case (PROTO_NUM_ICMPV6): {
                     /* checksum test*/
diff --git a/sys/net/sixlowpan/ip.h b/sys/net/sixlowpan/ip.h
index db948544cd..1dd90c4a67 100644
--- a/sys/net/sixlowpan/ip.h
+++ b/sys/net/sixlowpan/ip.h
@@ -42,6 +42,9 @@
 #define MULTIHOP_HOPLIMIT           64
 
 #define IP_PKT_RECV_BUF_SIZE        64
+
+#define SIXLOWIP_MAX_REGISTERED     (4)
+
 #define DEBUGLINE printf("%s:%d\n",__FILE__,__LINE__)
 
 /* extern variables */
@@ -90,6 +93,7 @@ extern double start;
 /* buffer */
 extern uint8_t buffer[BUFFER_SIZE];
 
+extern int sixlowip_reg[SIXLOWIP_MAX_REGISTERED];
 
 /* ipv6 extension header length */
 
diff --git a/sys/net/sixlowpan/lowpan.c b/sys/net/sixlowpan/lowpan.c
index fa8558c056..8f3699fe35 100644
--- a/sys/net/sixlowpan/lowpan.c
+++ b/sys/net/sixlowpan/lowpan.c
@@ -1518,6 +1518,8 @@ void init_reas_bufs(lowpan_reas_buf_t *buf)
 void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border)
 {
     ipv6_addr_t tmp;
+    short i;
+
     /* init mac-layer and radio transceiver */
     sixlowmac_init(trans);
 
@@ -1574,6 +1576,11 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border)
     transfer_pid = thread_create(lowpan_transfer_buf, LOWPAN_TRANSFER_BUF_STACKSIZE,
                                  PRIORITY_MAIN - 1, CREATE_STACKTEST,
                                  lowpan_transfer, "lowpan_transfer");
+
+    for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) {
+        sixlowip_reg[i] = 0;
+    }
+
 }
 
 void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix,
-- 
GitLab