]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/net/blip/ICMPResponderP.nc
radv generation bug
[tinyos-2.x.git] / tos / lib / net / blip / ICMPResponderP.nc
index 102d077bbedf75ed3fbac02d3149c2a89ce35eb0..2a9b98fa3d428756d833f25460337415cdb47271 100644 (file)
@@ -23,6 +23,7 @@
 #include <lib6lowpan.h>
 #include <6lowpan.h>
 #include <ip_malloc.h>
+#include <Statistics.h>
 #include "in_cksum.h"
 #include "PrintfUART.h"
 #include "ICMP.h"
@@ -52,14 +53,14 @@ module ICMPResponderP {
   icmp_statistics_t stats;
   uint32_t solicitation_period;
   uint32_t advertisement_period;
+  uint16_t nd_seqno = 0;
 
   uint16_t ping_seq, ping_n, ping_rcv, ping_ident;
   struct in6_addr ping_dest;
 
-#ifndef SIM
-#define CHECK_NODE_ID
-#else
-#define CHECK_NODE_ID if (TOS_NODE_ID == BASESTATION_ID) return
+#ifdef PRINTFUART_ENABLED
+#undef dbg
+#define dbg(X, fmt, args ...) printfUART(fmt, ## args)
 #endif
 
   command uint16_t ICMP.cksum(struct split_ip_msg *msg, uint8_t nxt_hdr) {
@@ -69,15 +70,15 @@ module ICMPResponderP {
 
   command void ICMP.sendSolicitations() {
     uint16_t jitter = (call Random.rand16()) % TRICKLE_JITTER;
-    CHECK_NODE_ID;
     if (call Solicitation.isRunning()) return;
     solicitation_period = TRICKLE_PERIOD;
     call Solicitation.startOneShot(jitter);
   }
 
   command void ICMP.sendAdvertisements() {
+
+
     uint16_t jitter = (call Random.rand16()) % TRICKLE_JITTER;
-    CHECK_NODE_ID;
     if (call Advertisement.isRunning()) return;
     advertisement_period = TRICKLE_PERIOD;
     call Advertisement.startOneShot(jitter);
@@ -137,7 +138,7 @@ module ICMPResponderP {
 
     msg->hdr.nxt_hdr = IANA_ICMP;
 
-    i_hdr->cksum = call ICMP.cksum(msg, IANA_ICMP);
+    i_hdr->cksum = htons(call ICMP.cksum(msg, IANA_ICMP));
 
     call IP.send(msg);
 
@@ -152,8 +153,7 @@ module ICMPResponderP {
 
     if (ipmsg == NULL) return;
 
-    dbg("ICMPResponder", "Solicitation\n");
-    //stats.sol_tx++;
+    BLIP_STATS_INCR(stats.sol_tx);
 
     msg->type = ICMP_TYPE_ROUTER_SOL;
     msg->code = 0;
@@ -169,7 +169,9 @@ module ICMPResponderP {
 
 
     call IPAddress.getLLAddr(&ipmsg->hdr.ip6_src);
-    inet_pton6("ff02::2", &ipmsg->hdr.ip6_dst);
+    ip_memclr((uint8_t *)&ipmsg->hdr.ip6_dst, 16);
+    ipmsg->hdr.ip6_dst.s6_addr16[0] = htons(0xff02);
+    ipmsg->hdr.ip6_dst.s6_addr16[7] = htons(2);
 
     msg->cksum = call ICMP.cksum(ipmsg, IANA_ICMP);
 
@@ -213,22 +215,38 @@ module ICMPResponderP {
     
     radv_t *r = (radv_t *)payload;
     pfx_t  *pfx = (pfx_t *)(r->options);
-    uint16_t cost = 0;
     rqual_t *beacon = (rqual_t *)(pfx + 1);
 
     if (len > sizeof(radv_t) + sizeof(pfx_t) && 
         beacon->type == ICMP_EXT_TYPE_BEACON) {
-      cost = beacon->metric;
-      dbg("ICMPResponder", " * beacon cost: 0x%x\n", cost);
-    } else 
-        dbg("ICMPResponder", " * no beacon cost\n");
 
-    call IPRouting.reportAdvertisement(meta->sender, r->hlim,
-                                       meta->lqi, cost);
+      printfUART("beacon seqno: %i my seqno: %i\n", beacon->seqno, nd_seqno);
+
+      if (beacon->seqno > nd_seqno || 
+          (nd_seqno > 0 && beacon->seqno == 0) ||
+          !call IPRouting.hasRoute()) {
+        call IPRouting.reset();
+        nd_seqno = beacon->seqno;
+      }
+
+      if (beacon->seqno == nd_seqno) {
+        call IPRouting.reportAdvertisement(meta->sender, r->hlim,
+                                           meta->lqi, beacon->metric);
+        // push out the seqno update
+        // call Advertisement.stop();
+        // call ICMP.sendAdvertisements();
+
+        if (pfx->type != ICMP_EXT_TYPE_PREFIX) return;
+
+        call IPAddress.setPrefix((uint8_t *)pfx->prefix);
+      }
+
 
-    if (pfx->type != ICMP_EXT_TYPE_PREFIX) return;
+      dbg("ICMPResponder", " * beacon cost: 0x%x\n", beacon->metric);
+    } else {
+        dbg("ICMPResponder", " * no beacon cost\n");
+    }
 
-    call IPAddress.setPrefix((uint8_t *)pfx->prefix);
 
     // TODO : get short address here...
   }
@@ -249,6 +267,7 @@ module ICMPResponderP {
       ip_free(ipmsg);
       return;
     }
+    BLIP_STATS_INCR(stats.adv_tx);
 
     r->type = ICMP_TYPE_ROUTER_ADV;
     r->code = 0;
@@ -263,17 +282,21 @@ module ICMPResponderP {
     if (globalPrefix) {
       len += sizeof(pfx_t);
       p->type = ICMP_EXT_TYPE_PREFIX;
-      p->length = 8;
+      p->length = sizeof(pfx_t) >> 3;
+      p->pfx_len = 64;
       memcpy(p->prefix, call IPAddress.getPublicAddr(), 8);
     }
 
     len += sizeof(rqual_t);
     q->type = ICMP_EXT_TYPE_BEACON;
-    q->length = 2;
+    q->length = sizeof(rqual_t) >> 3;;
     q->metric = call IPRouting.getQuality();
+    q->seqno = nd_seqno;
 
     call IPAddress.getLLAddr(&ipmsg->hdr.ip6_src);
-    inet_pton6("ff02::1", &ipmsg->hdr.ip6_dst);
+    ip_memclr((uint8_t *)&ipmsg->hdr.ip6_dst, 16);
+    ipmsg->hdr.ip6_dst.s6_addr16[0] = htons(0xff02);
+    ipmsg->hdr.ip6_dst.s6_addr16[7] = htons(1);
 
     //dbg("ICMPResponder", "My Address: [0x%x] [0x%x] [0x%x] [0x%x]\n", ipmsg->hdr.src_addr[12], ipmsg->hdr.src_addr[13], ipmsg->hdr.src_addr[14], ipmsg->hdr.src_addr[15]);
     dbg("ICMPResponder", "adv hop limit: 0x%x\n", r->hlim);
@@ -300,7 +323,7 @@ module ICMPResponderP {
                      struct ip_metadata *meta) {
     icmp_echo_hdr_t *req = (icmp_echo_hdr_t *)payload;
     uint16_t len = ntohs(iph->plen);
-    stats.rx++;
+    BLIP_STATS_INCR(stats.rx);
   
     // for checksum calculation
     printfUART ("icmp type: 0x%x code: 0x%x cksum: 0x%x ident: 0x%x seqno: 0x%x len: 0x%x\n",
@@ -308,24 +331,26 @@ module ICMPResponderP {
 
     switch (req->type) {
     case ICMP_TYPE_ROUTER_ADV:
-        handleRouterAdv(payload, len, meta);
-        //stats.adv_rx++;
-        break;
+      handleRouterAdv(payload, len, meta);
+      BLIP_STATS_INCR(stats.adv_rx);
+      break;
     case ICMP_TYPE_ROUTER_SOL:
       // only reply to solicitations if we have established a default route.
       if (call IPRouting.hasRoute()) {
           call ICMP.sendAdvertisements();
       }
+      BLIP_STATS_INCR(stats.sol_rx);
       break;
     case ICMP_TYPE_ECHO_REPLY:
       {
         nx_uint32_t *sendTime = (nx_uint32_t *)(req + 1);
         struct icmp_stats p_stat;
         p_stat.seq = req->seqno;
-        p_stat.ttl = 0;// buf->hdr.hlim;
+        p_stat.ttl = iph->hlim;
         p_stat.rtt = (call LocalTime.get()) - (*sendTime);
         signal ICMPPing.pingReply[req->ident](&iph->ip6_src, &p_stat);
         ping_rcv++;
+        BLIP_STATS_INCR(stats.echo_rx);
       }
       break;
     case ICMP_TYPE_ECHO_REQUEST:
@@ -335,8 +360,9 @@ module ICMPResponderP {
         msg.headers = NULL;
         msg.data = payload;
         msg.data_len = len;
-        call IPAddress.getIPAddr(&msg.hdr.ip6_src);
+
         memcpy(&msg.hdr.ip6_dst, &iph->ip6_src, 16);      
+        call IPAddress.setSource(&msg.hdr);
         
         req->type = ICMP_TYPE_ECHO_REPLY;
         req->code = 0;
@@ -345,15 +371,18 @@ module ICMPResponderP {
         
         // remember, this can't really fail in a way we care about
         call IP.send(&msg);
+        BLIP_STATS_INCR(stats.echo_tx);
         break;
       }
+    default:
+      BLIP_STATS_INCR(stats.unk_rx);
     }
   }
 
 
   event void Solicitation.fired() {
     sendSolicitation();
-    dbg("ICMPResponder", "solicitation period: 0x%x max: 0x%x\n", solicitation_period, TRICKLE_MAX);
+    dbg("ICMPResponder", "solicitation period: 0x%x max: 0x%x seq: %i\n", solicitation_period, TRICKLE_MAX, nd_seqno);
     solicitation_period <<= 1;
     if (solicitation_period < TRICKLE_MAX) {
       call Solicitation.startOneShot(solicitation_period);
@@ -399,7 +428,7 @@ module ICMPResponderP {
 
 
   command void Statistics.get(icmp_statistics_t *statistics) {
-    statistics = &stats;
+    memcpy(statistics, &stats, sizeof(icmp_statistics_t));
   }
   
   command void Statistics.clear() {