Merge pull request #288 from simonduq/neighbor-table

New neighbor tables
This commit is contained in:
Adam Dunkels 2013-08-19 12:01:55 -07:00
commit a07d332339
90 changed files with 5456 additions and 1771 deletions

View file

@ -51,7 +51,7 @@ do{\
uip_ipaddr_t ipaddr_local, ipaddr_global;\ uip_ipaddr_t ipaddr_local, ipaddr_global;\
NODE_IP(node_global, GLOBAL, &ipaddr_global);\ NODE_IP(node_global, GLOBAL, &ipaddr_global);\
NODE_IP(node_local, LOCAL, &ipaddr_local);\ NODE_IP(node_local, LOCAL, &ipaddr_local);\
uip_ds6_route_add(&ipaddr_global, 128, &ipaddr_local, 0);\ uip_ds6_route_add(&ipaddr_global, 128, &ipaddr_local);\
}while(0) }while(0)
void set_global_address(void); void set_global_address(void);

View file

@ -50,6 +50,7 @@
#include "httpd-fs.h" #include "httpd-fs.h"
#include "httpd-fsdata.h" #include "httpd-fsdata.h"
#include "lib/petsciiconv.h" #include "lib/petsciiconv.h"
#include "net/nbr-table.h"
#include "sensors.h" #include "sensors.h"
@ -479,7 +480,6 @@ PT_THREAD(addresses(struct httpd_state *s, char *ptr))
#endif /* WEBSERVER_CONF_ADDRESSES */ #endif /* WEBSERVER_CONF_ADDRESSES */
#if WEBSERVER_CONF_NEIGHBORS #if WEBSERVER_CONF_NEIGHBORS
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static unsigned short static unsigned short
make_neighbors(void *p) make_neighbors(void *p)
@ -487,11 +487,13 @@ make_neighbors(void *p)
uint8_t i,j; uint8_t i,j;
uint16_t numprinted=0; uint16_t numprinted=0;
struct httpd_state *s=p; struct httpd_state *s=p;
static uip_ds6_nbr_t *nbr;
/* Span generator calls over tcp segments */ /* Span generator calls over tcp segments */
/* Note retransmissions will execute thise code multiple times for a segment */ /* Note retransmissions will execute thise code multiple times for a segment */
i=s->starti;j=s->startj; i=s->starti;j=s->startj;
for (;i<UIP_DS6_NBR_NB;i++) { for(nbr = nbr_table_head(ds6_neighbors);
if (uip_ds6_nbr_cache[i].isused) { nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr), i++) {
j++; j++;
#if WEBSERVER_CONF_NEIGHBOR_STATUS #if WEBSERVER_CONF_NEIGHBOR_STATUS
@ -501,32 +503,31 @@ static const char httpd_cgi_nbrs3[] HTTPD_STRING_ATTR = " STALE";
static const char httpd_cgi_nbrs4[] HTTPD_STRING_ATTR = " DELAY"; static const char httpd_cgi_nbrs4[] HTTPD_STRING_ATTR = " DELAY";
static const char httpd_cgi_nbrs5[] HTTPD_STRING_ATTR = " NBR_PROBE"; static const char httpd_cgi_nbrs5[] HTTPD_STRING_ATTR = " NBR_PROBE";
{uint16_t k=numprinted+25; {uint16_t k=numprinted+25;
numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(nbr->ipaddr, uip_appdata + numprinted);
while (numprinted < k) {*((char *)uip_appdata+numprinted++) = ' ';} while (numprinted < k) {*((char *)uip_appdata+numprinted++) = ' ';}
switch (uip_ds6_nbr_cache[i].state) { switch (nbr->state) {
case NBR_INCOMPLETE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs1);break; case NBR_INCOMPLETE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs1);break;
case NBR_REACHABLE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs2);break; case NBR_REACHABLE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs2);break;
case NBR_STALE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs3);break; case NBR_STALE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs3);break;
case NBR_DELAY: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs4);break; case NBR_DELAY: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs4);break;
case NBR_PROBE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs5);break; case NBR_PROBE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs5);break;
} }
} }
#else #else
numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(nbr->ipaddr, uip_appdata + numprinted);
#endif #endif
*((char *)uip_appdata+numprinted++) = '\n'; *((char *)uip_appdata+numprinted++) = '\n';
/* If buffer near full, send it and wait for the next call. Could be a retransmission, or the next segment */ /* If buffer near full, send it and wait for the next call. Could be a retransmission, or the next segment */
if(numprinted > (uip_mss() - 50)) { if(numprinted > (uip_mss() - 50)) {
s->savei=i;s->savej=j; s->savei=i;s->savej=j;
return numprinted; return numprinted;
} }
}
} }
#if WEBSERVER_CONF_SHOW_ROOM #if WEBSERVER_CONF_SHOW_ROOM
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,NBR_TABLE_MAX_NEIGHBORS-j);
#else #else
if(UIP_DS6_NBR_NB == j) { if(NBR_TABLE_MAX_NEIGHBORS == j) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf);
} }
#endif #endif
@ -554,7 +555,6 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr))
#endif #endif
#if WEBSERVER_CONF_ROUTES #if WEBSERVER_CONF_ROUTES
extern uip_ds6_route_t uip_ds6_routing_table[];
#if WEBSERVER_CONF_ROUTE_LINKS #if WEBSERVER_CONF_ROUTE_LINKS
static const char httpd_cgi_rtesl1[] HTTPD_STRING_ATTR = "<a href=http://["; static const char httpd_cgi_rtesl1[] HTTPD_STRING_ATTR = "<a href=http://[";
static const char httpd_cgi_rtesl2[] HTTPD_STRING_ATTR = "]/status.shtml>"; static const char httpd_cgi_rtesl2[] HTTPD_STRING_ATTR = "]/status.shtml>";
@ -570,27 +570,29 @@ static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")\n";
uint8_t i,j; uint8_t i,j;
uint16_t numprinted=0; uint16_t numprinted=0;
struct httpd_state *s=p; struct httpd_state *s=p;
uip_ds6_route_t *r;
/* Span generator calls over tcp segments */ /* Span generator calls over tcp segments */
/* Note retransmissions will execute thise code multiple times for a segment */ /* Note retransmissions will execute thise code multiple times for a segment */
i=s->starti;j=s->startj; i=s->starti;j=s->startj;
for (;i<UIP_DS6_ROUTE_NB;i++) { for(r = uip_ds6_route_head();
if (uip_ds6_routing_table[i].isused) { r != NULL;
r = uip_ds6_route_next(r)) {
j++; j++;
#if WEBSERVER_CONF_ROUTE_LINKS #if WEBSERVER_CONF_ROUTE_LINKS
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl1); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl1);
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl2); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl2);
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl3); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl3);
#else #else
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
#endif #endif
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r), uip_appdata + numprinted);
if(1 || uip_ds6_routing_table[i].state.lifetime < 3600) { if(1 || r->state.lifetime < 3600) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, (long unsigned int)uip_ds6_routing_table[i].state.lifetime); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, (long unsigned int)r->state.lifetime);
} else { } else {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
} }

View file

@ -244,8 +244,6 @@ static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR = "<code>";
static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]"; static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]";
static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>"; static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>";
static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>"; static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>";
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
static unsigned short static unsigned short
@ -282,15 +280,16 @@ make_neighbors(void *p)
uint8_t i,j=0; uint8_t i,j=0;
uint16_t numprinted; uint16_t numprinted;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for (i=0; i<UIP_DS6_NBR_NB;i++) { uip_ds6_nbr_t *nbr;
if (uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
j++; nbr != NULL;
numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted); nbr = nbr_table_next(ds6_neighbors, nbr)) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb); j++;
} numprinted += httpd_cgi_sprint_ip6(nbr->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb);
} }
//if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); //if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,NBR_TABLE_MAX_NEIGHBORS-j);
return numprinted; return numprinted;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -315,13 +314,13 @@ make_routes(void *p)
uip_ds6_route_t *r; uip_ds6_route_t *r;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for(r = uip_ds6_route_list_head(); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
j++; j++;
numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r), uip_appdata + numprinted);
if(r->state.lifetime < 3600) { if(r->state.lifetime < 3600) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
} else { } else {

View file

@ -174,6 +174,11 @@
#define UIP_CONF_TCP_SPLIT 0 #define UIP_CONF_TCP_SPLIT 0
#endif /* UIP_CONF_TCP_SPLIT */ #endif /* UIP_CONF_TCP_SPLIT */
/* NBR_TABLE_CONF_MAX_NEIGHBORS specifies the maximum number of neighbors
that each node will be able to handle. */
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* 6lowpan configuration options. /* 6lowpan configuration options.

View file

@ -1,8 +1,7 @@
NET = \ NET = \
dhcpc.c \ dhcpc.c \
hc.c \ hc.c \
neighbor-attr.c \ nbr-table.c \
neighbor-info.c \
netstack.c \ netstack.c \
packetbuf.c \ packetbuf.c \
packetqueue.c \ packetqueue.c \
@ -17,6 +16,7 @@ uaodv-rt.c \
uaodv.c \ uaodv.c \
uip-debug.c \ uip-debug.c \
uip-ds6-route.c \ uip-ds6-route.c \
uip-ds6-nbr.c \
uip-ds6.c \ uip-ds6.c \
uip-fw-drv.c \ uip-fw-drv.c \
uip-fw.c \ uip-fw.c \

View file

@ -255,16 +255,6 @@ static struct compower_activity current_packet;
#include "net/mac/phase.h" #include "net/mac/phase.h"
#ifdef CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
#define MAX_PHASE_NEIGHBORS CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
#endif
#ifndef MAX_PHASE_NEIGHBORS
#define MAX_PHASE_NEIGHBORS 30
#endif
PHASE_LIST(phase_list, MAX_PHASE_NEIGHBORS);
#endif /* WITH_PHASE_OPTIMIZATION */ #endif /* WITH_PHASE_OPTIMIZATION */
#define DEFAULT_STREAM_TIME (4 * CYCLE_TIME) #define DEFAULT_STREAM_TIME (4 * CYCLE_TIME)
@ -665,7 +655,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
if(!is_broadcast && !is_receiver_awake) { if(!is_broadcast && !is_receiver_awake) {
#if WITH_PHASE_OPTIMIZATION #if WITH_PHASE_OPTIMIZATION
ret = phase_wait(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
CYCLE_TIME, GUARD_TIME, CYCLE_TIME, GUARD_TIME,
mac_callback, mac_callback_ptr, buf_list); mac_callback, mac_callback_ptr, buf_list);
if(ret == PHASE_DEFERRED) { if(ret == PHASE_DEFERRED) {
@ -865,7 +855,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
if(!is_broadcast) { if(!is_broadcast) {
if(collisions == 0 && is_receiver_awake == 0) { if(collisions == 0 && is_receiver_awake == 0) {
phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), phase_update(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
encounter_time, ret); encounter_time, ret);
} }
} }
@ -1049,7 +1039,7 @@ init(void)
contikimac_is_on = 1; contikimac_is_on = 1;
#if WITH_PHASE_OPTIMIZATION #if WITH_PHASE_OPTIMIZATION
phase_init(&phase_list); phase_init();
#endif /* WITH_PHASE_OPTIMIZATION */ #endif /* WITH_PHASE_OPTIMIZATION */
} }

View file

@ -40,11 +40,24 @@
#include "net/mac/phase.h" #include "net/mac/phase.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include "sys/clock.h" #include "sys/clock.h"
#include "lib/memb.h"
#include "sys/ctimer.h" #include "sys/ctimer.h"
#include "net/queuebuf.h" #include "net/queuebuf.h"
#include "dev/watchdog.h" #include "net/nbr-table.h"
#include "dev/leds.h"
#if PHASE_CONF_DRIFT_CORRECT
#define PHASE_DRIFT_CORRECT PHASE_CONF_DRIFT_CORRECT
#else
#define PHASE_DRIFT_CORRECT 0
#endif
struct phase {
rtimer_clock_t time;
#if PHASE_DRIFT_CORRECT
rtimer_clock_t drift;
#endif
uint8_t noacks;
struct timer noacks_timer;
};
struct phase_queueitem { struct phase_queueitem {
struct ctimer timer; struct ctimer timer;
@ -62,6 +75,7 @@ struct phase_queueitem {
#define MAX_NOACKS_TIME CLOCK_SECOND * 30 #define MAX_NOACKS_TIME CLOCK_SECOND * 30
MEMB(queued_packets_memb, struct phase_queueitem, PHASE_QUEUESIZE); MEMB(queued_packets_memb, struct phase_queueitem, PHASE_QUEUESIZE);
NBR_TABLE(struct phase, nbr_phase);
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
@ -73,38 +87,14 @@ MEMB(queued_packets_memb, struct phase_queueitem, PHASE_QUEUESIZE);
#define PRINTDEBUG(...) #define PRINTDEBUG(...)
#endif #endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
struct phase *
find_neighbor(const struct phase_list *list, const rimeaddr_t *addr)
{
struct phase *e;
for(e = list_head(*list->list); e != NULL; e = list_item_next(e)) {
if(rimeaddr_cmp(addr, &e->neighbor)) {
return e;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void void
phase_remove(const struct phase_list *list, const rimeaddr_t *neighbor) phase_update(const rimeaddr_t *neighbor, rtimer_clock_t time,
{
struct phase *e;
e = find_neighbor(list, neighbor);
if(e != NULL) {
list_remove(*list->list, e);
memb_free(list->memb, e);
}
}
/*---------------------------------------------------------------------------*/
void
phase_update(const struct phase_list *list,
const rimeaddr_t *neighbor, rtimer_clock_t time,
int mac_status) int mac_status)
{ {
struct phase *e; struct phase *e;
/* If we have an entry for this neighbor already, we renew it. */ /* If we have an entry for this neighbor already, we renew it. */
e = find_neighbor(list, neighbor); e = nbr_table_get_from_lladdr(nbr_phase, neighbor);
if(e != NULL) { if(e != NULL) {
if(mac_status == MAC_TX_OK) { if(mac_status == MAC_TX_OK) {
#if PHASE_DRIFT_CORRECT #if PHASE_DRIFT_CORRECT
@ -123,8 +113,7 @@ phase_update(const struct phase_list *list,
} }
if(e->noacks >= MAX_NOACKS || timer_expired(&e->noacks_timer)) { if(e->noacks >= MAX_NOACKS || timer_expired(&e->noacks_timer)) {
PRINTF("drop %d\n", neighbor->u8[0]); PRINTF("drop %d\n", neighbor->u8[0]);
list_remove(*list->list, e); nbr_table_remove(nbr_phase, e);
memb_free(list->memb, e);
return; return;
} }
} else if(mac_status == MAC_TX_OK) { } else if(mac_status == MAC_TX_OK) {
@ -133,20 +122,14 @@ phase_update(const struct phase_list *list,
} else { } else {
/* No matching phase was found, so we allocate a new one. */ /* No matching phase was found, so we allocate a new one. */
if(mac_status == MAC_TX_OK && e == NULL) { if(mac_status == MAC_TX_OK && e == NULL) {
e = memb_alloc(list->memb); e = nbr_table_add_lladdr(nbr_phase, neighbor);
if(e == NULL) { if(e) {
PRINTF("phase alloc NULL\n"); e->time = time;
/* We could not allocate memory for this phase, so we drop
the last item on the list and reuse it for our phase. */
e = list_chop(*list->list);
}
rimeaddr_copy(&e->neighbor, neighbor);
e->time = time;
#if PHASE_DRIFT_CORRECT #if PHASE_DRIFT_CORRECT
e->drift = 0; e->drift = 0;
#endif #endif
e->noacks = 0; e->noacks = 0;
list_push(*list->list, e); }
} }
} }
} }
@ -168,8 +151,7 @@ send_packet(void *ptr)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
phase_status_t phase_status_t
phase_wait(struct phase_list *list, phase_wait(const rimeaddr_t *neighbor, rtimer_clock_t cycle_time,
const rimeaddr_t *neighbor, rtimer_clock_t cycle_time,
rtimer_clock_t guard_time, rtimer_clock_t guard_time,
mac_callback_t mac_callback, void *mac_callback_ptr, mac_callback_t mac_callback, void *mac_callback_ptr,
struct rdc_buf_list *buf_list) struct rdc_buf_list *buf_list)
@ -180,7 +162,7 @@ phase_wait(struct phase_list *list,
phase for this particular neighbor. If so, we can compute the phase for this particular neighbor. If so, we can compute the
time for the next expected phase and setup a ctimer to switch on time for the next expected phase and setup a ctimer to switch on
the radio just before the phase. */ the radio just before the phase. */
e = find_neighbor(list, neighbor); e = nbr_table_get_from_lladdr(nbr_phase, neighbor);
if(e != NULL) { if(e != NULL) {
rtimer_clock_t wait, now, expected, sync; rtimer_clock_t wait, now, expected, sync;
clock_time_t ctimewait; clock_time_t ctimewait;
@ -242,15 +224,12 @@ phase_wait(struct phase_list *list,
p->buf_list = buf_list; p->buf_list = buf_list;
ctimer_set(&p->timer, ctimewait, send_packet, p); ctimer_set(&p->timer, ctimewait, send_packet, p);
return PHASE_DEFERRED; return PHASE_DEFERRED;
} else {
memb_free(&queued_packets_memb, p);
} }
} }
expected = now + wait - guard_time; expected = now + wait - guard_time;
if(!RTIMER_CLOCK_LT(expected, now)) { if(!RTIMER_CLOCK_LT(expected, now)) {
/* Wait until the receiver is expected to be awake */ /* Wait until the receiver is expected to be awake */
// printf("%d ",expected%cycle_time); //for spreadsheet export
while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected)); while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected));
} }
return PHASE_SEND_NOW; return PHASE_SEND_NOW;
@ -259,10 +238,9 @@ phase_wait(struct phase_list *list,
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
phase_init(struct phase_list *list) phase_init(void)
{ {
list_init(*list->list);
memb_init(list->memb);
memb_init(&queued_packets_memb); memb_init(&queued_packets_memb);
nbr_table_register(nbr_phase, NULL);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -47,28 +47,6 @@
#include "lib/memb.h" #include "lib/memb.h"
#include "net/netstack.h" #include "net/netstack.h"
#if PHASE_CONF_DRIFT_CORRECT
#define PHASE_DRIFT_CORRECT PHASE_CONF_DRIFT_CORRECT
#else
#define PHASE_DRIFT_CORRECT 0
#endif
struct phase {
struct phase *next;
rimeaddr_t neighbor;
rtimer_clock_t time;
#if PHASE_DRIFT_CORRECT
rtimer_clock_t drift;
#endif
uint8_t noacks;
struct timer noacks_timer;
};
struct phase_list {
list_t *list;
struct memb *memb;
};
typedef enum { typedef enum {
PHASE_UNKNOWN, PHASE_UNKNOWN,
PHASE_SEND_NOW, PHASE_SEND_NOW,
@ -76,18 +54,13 @@ typedef enum {
} phase_status_t; } phase_status_t;
#define PHASE_LIST(name, num) LIST(phase_list_list); \ void phase_init(void);
MEMB(phase_list_memb, struct phase, num); \ phase_status_t phase_wait(const rimeaddr_t *neighbor,
struct phase_list name = { &phase_list_list, &phase_list_memb }
void phase_init(struct phase_list *list);
phase_status_t phase_wait(struct phase_list *list, const rimeaddr_t *neighbor,
rtimer_clock_t cycle_time, rtimer_clock_t wait_before, rtimer_clock_t cycle_time, rtimer_clock_t wait_before,
mac_callback_t mac_callback, void *mac_callback_ptr, mac_callback_t mac_callback, void *mac_callback_ptr,
struct rdc_buf_list *buf_list); struct rdc_buf_list *buf_list);
void phase_update(const struct phase_list *list, const rimeaddr_t *neighbor, void phase_update(const rimeaddr_t *neighbor,
rtimer_clock_t time, int mac_status); rtimer_clock_t time, int mac_status);
void phase_remove(const rimeaddr_t *neighbor);
void phase_remove(const struct phase_list *list, const rimeaddr_t *neighbor);
#endif /* PHASE_H */ #endif /* PHASE_H */

350
core/net/nbr-table.c Normal file
View file

@ -0,0 +1,350 @@
/*
* Copyright (c) 2013, Swedish Institute of Computer Science
* Copyright (c) 2010, Vrije Universiteit Brussel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Authors: Simon Duquennoy <simonduq@sics.se>
* Joris Borms <joris.borms@vub.ac.be>
*/
#include "contiki.h"
#include <stddef.h>
#include <string.h>
#include "lib/memb.h"
#include "lib/list.h"
#include "net/nbr-table.h"
/* List of link-layer addresses of the neighbors, used as key in the tables */
typedef struct nbr_table_key {
struct nbr_table_key *next;
rimeaddr_t lladdr;
} nbr_table_key_t;
/* For each neighbor, a map of the tables that use the neighbor.
* As we are using uint8_t, we have a maximum of 8 tables in the system */
static uint8_t used_map[NBR_TABLE_MAX_NEIGHBORS];
/* For each neighbor, a map of the tables that lock the neighbor */
static uint8_t locked_map[NBR_TABLE_MAX_NEIGHBORS];
/* The maximum number of tables */
#define MAX_NUM_TABLES 8
/* A list of pointers to tables in use */
static struct nbr_table *all_tables[MAX_NUM_TABLES];
/* The current number of tables */
static unsigned num_tables;
/* The neighbor address table */
MEMB(neighbor_addr_mem, nbr_table_key_t, NBR_TABLE_MAX_NEIGHBORS);
LIST(nbr_table_keys);
/*---------------------------------------------------------------------------*/
/* Get a key from a neighbor index */
static nbr_table_key_t *
key_from_index(int index)
{
return index != -1 ? &((nbr_table_key_t *)neighbor_addr_mem.mem)[index] : NULL;
}
/*---------------------------------------------------------------------------*/
/* Get an item from its neighbor index */
static nbr_table_item_t *
item_from_index(nbr_table_t *table, int index)
{
return table != NULL && index != -1 ? (char *)table->data + index * table->item_size : NULL;
}
/*---------------------------------------------------------------------------*/
/* Get the neighbor index of an item */
static int
index_from_key(nbr_table_key_t *key)
{
return key != NULL ? key - (nbr_table_key_t *)neighbor_addr_mem.mem : -1;
}
/*---------------------------------------------------------------------------*/
/* Get the neighbor index of an item */
static int
index_from_item(nbr_table_t *table, nbr_table_item_t *item)
{
return table != NULL && item != NULL ? ((int)((char *)item - (char *)table->data)) / table->item_size : -1;
}
/*---------------------------------------------------------------------------*/
/* Get an item from its key */
static nbr_table_item_t *
item_from_key(nbr_table_t *table, nbr_table_key_t *key)
{
return item_from_index(table, index_from_key(key));
}
/*---------------------------------------------------------------------------*/
/* Get the key af an item */
static nbr_table_key_t *
key_from_item(nbr_table_t *table, nbr_table_item_t *item)
{
return key_from_index(index_from_item(table, item));
}
/*---------------------------------------------------------------------------*/
/* Get the index of a neighbor from its link-layer address */
static int
index_from_lladdr(const rimeaddr_t *lladdr)
{
nbr_table_key_t *key;
/* Allow lladdr-free insertion, useful e.g. for IPv6 ND.
* Only one such entry is possible at a time, indexed by rimeaddr_null. */
if(lladdr == NULL) {
lladdr = &rimeaddr_null;
}
key = list_head(nbr_table_keys);
while(key != NULL) {
if(lladdr && rimeaddr_cmp(lladdr, &key->lladdr)) {
return index_from_key(key);
}
key = list_item_next(key);
}
return -1;
}
/*---------------------------------------------------------------------------*/
/* Get bit from "used" or "locked" bitmap */
static int
nbr_get_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item)
{
int item_index = index_from_item(table, item);
if(table != NULL && item_index != -1) {
return (bitmap[item_index] & (1 << table->index)) != 0;
} else {
return 0;
}
return 0;
}
/*---------------------------------------------------------------------------*/
/* Set bit in "used" or "locked" bitmap */
static int
nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int value)
{
int item_index = index_from_item(table, item);
if(table != NULL && item_index != -1) {
if(value) {
bitmap[item_index] |= 1 << table->index;
} else {
bitmap[item_index] &= ~(1 << table->index);
}
return 1;
} else {
return 0;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static nbr_table_key_t *
nbr_table_allocate(void)
{
nbr_table_key_t *key;
int least_used_count = 0;
nbr_table_key_t *least_used_key = NULL;
key = memb_alloc(&neighbor_addr_mem);
if(key != NULL) {
return key;
} else { /* No more space, try to free a neighbor.
* The replacement policy is the following: remove neighbor that is:
* (1) not locked
* (2) used by fewest tables
* (3) oldest (the list is ordered by insertion time)
* */
/* Get item from first key */
key = list_head(nbr_table_keys);
while(key != NULL) {
int item_index = index_from_key(key);
int locked = locked_map[item_index];
/* Never delete a locked item */
if(!locked) {
int used = used_map[item_index];
int used_count = 0;
/* Count how many tables are using this item */
while(used != 0) {
if((used & 1) == 1) {
used_count++;
}
used >>= 1;
}
/* Find least used item */
if(least_used_key == NULL || used_count < least_used_count) {
least_used_key = key;
least_used_count = used_count;
if(used_count == 0) { /* We won't find any least used item */
break;
}
}
}
key = list_item_next(key);
}
if(least_used_key == NULL) {
/* We haven't found any unlocked item, allocation fails */
return NULL;
} else {
/* Reuse least used item */
int i;
for(i = 0; i<MAX_NUM_TABLES; i++) {
if(all_tables[i] != NULL && all_tables[i]->callback != NULL) {
/* Call table callback for each table that uses this item */
nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key);
if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) {
all_tables[i]->callback(removed_item);
}
}
}
/* Empty used map */
used_map[index_from_key(least_used_key)] = 0;
/* Remove neighbor from list */
list_remove(nbr_table_keys, least_used_key);
/* Return associated key */
return least_used_key;
}
}
}
/*---------------------------------------------------------------------------*/
/* Register a new neighbor table. To be used at initialization by modules
* using a neighbor table */
int
nbr_table_register(nbr_table_t *table, nbr_table_callback *callback)
{
if(num_tables < MAX_NUM_TABLES) {
table->index = num_tables++;
table->callback = callback;
all_tables[table->index] = table;
return 1;
} else {
/* Maximum number of tables exceeded */
return 0;
}
}
/*---------------------------------------------------------------------------*/
/* Returns the first item of the current table */
nbr_table_item_t *
nbr_table_head(nbr_table_t *table)
{
/* Get item from first key */
nbr_table_item_t *item = item_from_key(table, list_head(nbr_table_keys));
/* Item is the first neighbor, now check is it is in the current table */
if(nbr_get_bit(used_map, table, item)) {
return item;
} else {
return nbr_table_next(table, item);
}
}
/*---------------------------------------------------------------------------*/
/* Iterates over the current table */
nbr_table_item_t *
nbr_table_next(nbr_table_t *table, nbr_table_item_t *item)
{
do {
void *key = key_from_item(table, item);
key = list_item_next(key);
/* Loop until the next item is in the current table */
item = item_from_key(table, key);
} while(item && !nbr_get_bit(used_map, table, item));
return item;
}
/*---------------------------------------------------------------------------*/
/* Add a neighbor indexed with its link-layer address */
nbr_table_item_t *
nbr_table_add_lladdr(nbr_table_t *table, const rimeaddr_t *lladdr)
{
int index;
nbr_table_item_t *item;
nbr_table_key_t *key;
/* Allow lladdr-free insertion, useful e.g. for IPv6 ND.
* Only one such entry is possible at a time, indexed by rimeaddr_null. */
if(lladdr == NULL) {
lladdr = &rimeaddr_null;
}
if((index = index_from_lladdr(lladdr)) == -1) {
/* Neighbor not yet in table, let's try to allocate one */
key = nbr_table_allocate();
/* No space available for new entry */
if(key == NULL) {
return NULL;
}
/* Add neighbor to list */
list_add(nbr_table_keys, key);
/* Get index from newly allocated neighbor */
index = index_from_key(key);
/* Set link-layer address */
rimeaddr_copy(&key->lladdr, lladdr);
}
/* Get item in the current table */
item = item_from_index(table, index);
/* Initialize item data and set "used" bit */
memset(item, 0, table->item_size);
nbr_set_bit(used_map, table, item, 1);
return item;
}
/*---------------------------------------------------------------------------*/
/* Get an item from its link-layer address */
void *
nbr_table_get_from_lladdr(nbr_table_t *table, const rimeaddr_t *lladdr)
{
void *item = item_from_index(table, index_from_lladdr(lladdr));
return nbr_get_bit(used_map, table, item) ? item : NULL;
}
/*---------------------------------------------------------------------------*/
/* Removes a neighbor from the current table (unset "used" bit) */
int
nbr_table_remove(nbr_table_t *table, void *item)
{
int ret = nbr_set_bit(used_map, table, item, 0);
nbr_set_bit(locked_map, table, item, 0);
return ret;
}
/*---------------------------------------------------------------------------*/
/* Lock a neighbor for the current table (set "locked" bit) */
int
nbr_table_lock(nbr_table_t *table, void *item)
{
return nbr_set_bit(locked_map, table, item, 1);
}
/*---------------------------------------------------------------------------*/
/* Release the lock on a neighbor for the current table (unset "locked" bit) */
int
nbr_table_unlock(nbr_table_t *table, void *item)
{
return nbr_set_bit(locked_map, table, item, 0);
}
/*---------------------------------------------------------------------------*/
/* Get link-layer address of an item */
rimeaddr_t *
nbr_table_get_lladdr(nbr_table_t *table, void *item)
{
nbr_table_key_t *key = key_from_item(table, item);
return key != NULL ? &key->lladdr : NULL;
}

103
core/net/nbr-table.h Normal file
View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2013, Swedish Institute of Computer Science
* Copyright (c) 2010, Vrije Universiteit Brussel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Authors: Simon Duquennoy <simonduq@sics.se>
* Joris Borms <joris.borms@vub.ac.be>
*/
#ifndef _NBR_TABLE_H_
#define _NBR_TABLE_H_
#include "contiki.h"
#include "net/rime/rimeaddr.h"
#include "net/netstack.h"
/* Neighbor table size */
#ifdef NBR_TABLE_CONF_MAX_NEIGHBORS
#define NBR_TABLE_MAX_NEIGHBORS NBR_TABLE_CONF_MAX_NEIGHBORS
#else /* NBR_TABLE_CONF_MAX_NEIGHBORS */
#define NBR_TABLE_MAX_NEIGHBORS 8
#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
/* An item in a neighbor table */
typedef void nbr_table_item_t;
/* Callback function, called when removing an item from a table */
typedef void(nbr_table_callback)(nbr_table_item_t *item);
/* A neighbor table */
typedef struct nbr_table {
int index;
int item_size;
nbr_table_callback *callback;
nbr_table_item_t *data;
} nbr_table_t;
/** \brief A static neighbor table. To be initialized through nbr_table_register(name) */
#define NBR_TABLE(type, name) \
static type _##name##_mem[NBR_TABLE_MAX_NEIGHBORS]; \
static nbr_table_t name##_struct = { 0, sizeof(type), NULL, (nbr_table_item_t *)_##name##_mem }; \
static nbr_table_t *name = &name##_struct \
/** \brief A non-static neighbor table. To be initialized through nbr_table_register(name) */
#define NBR_TABLE_GLOBAL(type, name) \
static type _##name##_mem[NBR_TABLE_MAX_NEIGHBORS]; \
static nbr_table_t name##_struct = { 0, sizeof(type), NULL, (nbr_table_item_t *)_##name##_mem }; \
nbr_table_t *name = &name##_struct \
/** \brief Declaration of non-static neighbor tables */
#define NBR_TABLE_DECLARE(name) extern nbr_table_t *name
/** \name Neighbor tables: register and loop through table elements */
/** @{ */
int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback);
nbr_table_item_t *nbr_table_head(nbr_table_t *table);
nbr_table_item_t *nbr_table_next(nbr_table_t *table, nbr_table_item_t *item);
/** @} */
/** \name Neighbor tables: add and get data */
/** @{ */
nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const rimeaddr_t *lladdr);
nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const rimeaddr_t *lladdr);
/** @} */
/** \name Neighbor tables: set flags (unused, locked, unlocked) */
/** @{ */
int nbr_table_remove(nbr_table_t *table, nbr_table_item_t *item);
int nbr_table_lock(nbr_table_t *table, nbr_table_item_t *item);
int nbr_table_unlock(nbr_table_t *table, nbr_table_item_t *item);
/** @} */
/** \name Neighbor tables: address manipulation */
/** @{ */
rimeaddr_t *nbr_table_get_lladdr(nbr_table_t *table, nbr_table_item_t *item);
/** @} */
#endif /* _NBR_TABLE_H_ */

View file

@ -1,250 +0,0 @@
/*
* Copyright (c) 2010, Vrije Universiteit Brussel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Author: Joris Borms <joris.borms@vub.ac.be>
*
*/
#include "contiki.h"
#include "lib/memb.h"
#include "lib/list.h"
#include <stddef.h>
#include <string.h>
#include "net/neighbor-attr.h"
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
static uint16_t timeout = 0;
MEMB(neighbor_addr_mem, struct neighbor_addr, NEIGHBOR_ATTR_MAX_NEIGHBORS);
LIST(neighbor_addrs);
LIST(neighbor_attrs);
/*---------------------------------------------------------------------------*/
static struct neighbor_addr *
neighbor_addr_get(const rimeaddr_t *addr)
{
struct neighbor_addr *item;
/* check if addr is derived from table, inside memb */
if(memb_inmemb(&neighbor_addr_mem, (char *)addr)) {
return (struct neighbor_addr *)
(((char *)addr) - offsetof(struct neighbor_addr, addr));
}
item = list_head(neighbor_addrs);
while(item != NULL) {
if(rimeaddr_cmp(addr, &item->addr)) {
return item;
}
item = item->next;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
struct neighbor_addr *
neighbor_attr_list_neighbors(void)
{
return list_head(neighbor_addrs);
}
/*---------------------------------------------------------------------------*/
static void
set_attr(struct neighbor_attr *attr, uint16_t index)
{
if(attr->default_value != NULL) {
memcpy((char *)attr->data + index * attr->size,
attr->default_value, attr->size);
} else {
/* fill with zeroes */
memset((char *)attr->data + index * attr->size, 0, attr->size);
}
}
/*---------------------------------------------------------------------------*/
int
neighbor_attr_register(struct neighbor_attr *def)
{
struct neighbor_addr *addr;
list_push(neighbor_attrs, def);
/* set default values for already existing neighbors */
for(addr = list_head(neighbor_addrs); addr != NULL; addr = addr->next) {
set_attr(def, addr->index);
}
return 1;
}
/*---------------------------------------------------------------------------*/
int
neighbor_attr_has_neighbor(const rimeaddr_t *addr)
{
return neighbor_addr_get(addr) != NULL;
}
/*---------------------------------------------------------------------------*/
int
neighbor_attr_add_neighbor(const rimeaddr_t *addr)
{
struct neighbor_attr *def;
struct neighbor_addr *item;
struct neighbor_addr *ptr;
uint16_t i;
if(neighbor_attr_has_neighbor(addr)) {
return 0;
}
item = memb_alloc(&neighbor_addr_mem);
if(item == NULL) {
return -1;
}
list_push(neighbor_addrs, item);
item->time = 0;
rimeaddr_copy(&item->addr, addr);
/* look up index and set default values */
ptr = neighbor_addr_mem.mem;
for(i = 0; i < neighbor_addr_mem.num; ++i) {
if(&ptr[i] == item) {
break;
}
}
item->index = i;
for(def = list_head(neighbor_attrs); def != NULL; def = def->next) {
set_attr(def, i);
}
return 1;
}
/*---------------------------------------------------------------------------*/
int
neighbor_attr_remove_neighbor(const rimeaddr_t *addr)
{
struct neighbor_addr *item = neighbor_addr_get(addr);
if(item != NULL) {
list_remove(neighbor_addrs, item);
memb_free(&neighbor_addr_mem, item);
return 0;
}
return -1;
}
/*---------------------------------------------------------------------------*/
void *
neighbor_attr_get_data(struct neighbor_attr *def, const rimeaddr_t *addr)
{
struct neighbor_addr *attr = neighbor_addr_get(addr);
if(attr != NULL) {
return (char *)def->data + attr->index * def->size;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
int
neighbor_attr_set_data(struct neighbor_attr *def, const rimeaddr_t *addr,
void *data)
{
struct neighbor_addr *attr = neighbor_addr_get(addr);
if(attr == NULL) {
if(neighbor_attr_add_neighbor(addr)) {
attr = neighbor_addr_get(addr);
}
}
if(attr != NULL) {
attr->time = 0;
memcpy((char *)def->data + attr->index * def->size, data, def->size);
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
void
neighbor_attr_tick(const rimeaddr_t * addr)
{
struct neighbor_addr *attr = neighbor_addr_get(addr);
if(attr != NULL) {
attr->time = 0;
}
}
/*---------------------------------------------------------------------------*/
uint16_t
neighbor_attr_get_timeout(void)
{
return timeout;
}
/*---------------------------------------------------------------------------*/
static struct ctimer ct;
#define TIMEOUT_SECONDS 5
static void
timeout_check(void *ptr)
{
if(timeout > 0) {
struct neighbor_addr *item = neighbor_attr_list_neighbors();
while(item != NULL) {
item->time += TIMEOUT_SECONDS;
if(item->time >= timeout) {
struct neighbor_addr *next_item = item->next;
list_remove(neighbor_addrs, item);
memb_free(&neighbor_addr_mem, item);
item = next_item;
} else {
item = item->next;
}
}
ctimer_set(&ct, TIMEOUT_SECONDS * CLOCK_SECOND, timeout_check, ptr);
}
}
/*---------------------------------------------------------------------------*/
void
neighbor_attr_set_timeout(uint16_t time)
{
if(timeout == 0 && time > 0) {
ctimer_set(&ct, TIMEOUT_SECONDS * CLOCK_SECOND, timeout_check, NULL);
} else if(timeout > 0 && time == 0) {
ctimer_stop(&ct);
}
timeout = time;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,163 +0,0 @@
/*
* Copyright (c) 2010, Vrije Universiteit Brussel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Author: Joris Borms <joris.borms@vub.ac.be>
*
*/
#ifndef NEIGHBORATTR_H_
#define NEIGHBORATTR_H_
#include "net/rime.h"
/**
* define how many neighbors you can store
*/
#ifdef NEIGHBOR_CONF_MAX_NEIGHBORS
#define NEIGHBOR_ATTR_MAX_NEIGHBORS NEIGHBOR_CONF_MAX_NEIGHBORS
#else /* NEIGHBOR_CONF_MAX_NEIGHBORS */
#define NEIGHBOR_ATTR_MAX_NEIGHBORS 12
#endif /* NEIGHBOR_CONF_MAX_NEIGHBORS */
/**
* \brief properties of a single neighbor
*/
struct neighbor_addr {
struct neighbor_addr *next;
rimeaddr_t addr;
uint16_t time;
uint16_t index;
};
/**
* \brief properties that define a neighbor attribute
*/
struct neighbor_attr {
struct neighbor_attr *next;
uint16_t size;
void *default_value;
void *data;
};
/**
* \brief Define space for additional parameters in neighbor table entries.
* \param type The type of the attribute.
* \param name The name of the attribute.
* \param def A ptr to the default value for this attribute. If NULL, attribute will
* be filled with zeroes by default.
*
* The attribute 'name' should be registered with 'neighbor_attr_register'
* during initialization.
*/
#define NEIGHBOR_ATTRIBUTE(type, name, default_value_ptr) \
static type _##name##_mem[NEIGHBOR_ATTR_MAX_NEIGHBORS]; \
static struct neighbor_attr name = \
{NULL, sizeof(type), default_value_ptr, (void *)_##name##_mem}
/** Same as NEIGHBOR_ATTRIBUTE, only the attr is not declared static
* this way you can say <tt>extern struct neighbor_attr name</tt> in header to declare
* a global neighbor attribute
*/
#define NEIGHBOR_ATTRIBUTE_GLOBAL(type, name, default_value_ptr) \
static type _##name##_mem[NEIGHBOR_ATTR_MAX_NEIGHBORS]; \
struct neighbor_attr name = \
{NULL, sizeof(type), default_value_ptr, (void *)_##name##_mem}
#define NEIGHBOR_ATTRIBUTE_DECLARE(name) extern struct neighbor_attr name
/**
* \brief register a neighbor attribute
* \retval non-zero if successful, zero if not
*/
int neighbor_attr_register(struct neighbor_attr *);
/**
* \retval head of neighbor list, useful for iterating over all neighbors
*/
struct neighbor_addr *neighbor_attr_list_neighbors(void);
/**
* \brief Check if a neighbor is already added to the neighbor table
* \retval non-zero if present, zero if not
*/
int neighbor_attr_has_neighbor(const rimeaddr_t *addr);
/**
* \brief Add a neighbor entry to neighbor table
* \retval -1 if unsuccessful, 0 if the neighbor was already
* in the table, and 1 if successful
*/
int neighbor_attr_add_neighbor(const rimeaddr_t *addr);
/**
* \brief Remove a neighbor entry to neighbor table
* \retval -1 if unsuccessful, 0 if the neighbor was removed
*/
int neighbor_attr_remove_neighbor(const rimeaddr_t *addr);
/**
* \brief Get pointer to neighbor table data specified by id
* \param requested attribute
* \param addr requested neighbor
* \retval pointer to data, NULL if neighbor was not found
*
* Searches neighbor table for addr and returns pointer to data section
* specified by attribute type and addr.
* This pointer should not be saved, as it may point to data from another
* neighbor in the future if neighbors get removed/added over time.
*/
void *neighbor_attr_get_data(struct neighbor_attr *, const rimeaddr_t *addr);
/**
* \brief Copy data to neighbor table
* \retval non-zero if successful, zero if not
*
* Copies data to specific part of the neighbor table, specified by
* neighbor and attribute type, and resets timeout for that neighbor.
* If neighbor was not found, this will add a new neighbor to the table.
*/
int neighbor_attr_set_data(struct neighbor_attr *, const rimeaddr_t *addr,
void *data);
/**
* \brief Set global lifetime of neighbor entries.
* \param Lifetime in seconds. If 0, entries will not time out
*/
void neighbor_attr_set_timeout(uint16_t);
/**
* \brief get global lifetime of neighbor entries. If 0, entries will not time out
*/
uint16_t neighbor_attr_get_timeout(void);
/**
* \brief reset timeout of a neighbor to prevent it from being removed
*/
void neighbor_attr_tick(const rimeaddr_t *);
#endif /* NEIGHBORATTR_H_ */

View file

@ -1,193 +0,0 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* A generic module for management of neighbor information.
*
* \author Nicolas Tsiftes <nvt@sics.se>
*/
#include "net/neighbor-info.h"
#include "net/neighbor-attr.h"
#include "net/uip-ds6.h"
#include "net/uip-nd6.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#define ETX_LIMIT 15
#define ETX_SCALE 100
#define ETX_ALPHA 90
#define ETX_NOACK_PENALTY ETX_LIMIT
/*---------------------------------------------------------------------------*/
NEIGHBOR_ATTRIBUTE_GLOBAL(link_metric_t, attr_etx, NULL);
NEIGHBOR_ATTRIBUTE_GLOBAL(unsigned long, attr_timestamp, NULL);
static neighbor_info_subscriber_t subscriber_callback;
/*---------------------------------------------------------------------------*/
static void
update_metric(const rimeaddr_t *dest, int packet_metric)
{
link_metric_t *metricp;
link_metric_t recorded_metric, new_metric;
unsigned long time;
int first_update = 0;
metricp = (link_metric_t *)neighbor_attr_get_data(&attr_etx, dest);
packet_metric = NEIGHBOR_INFO_ETX2FIX(packet_metric);
if(metricp == NULL || *metricp == 0) {
recorded_metric = NEIGHBOR_INFO_ETX2FIX(ETX_LIMIT);
new_metric = packet_metric;
first_update = 1;
} else {
recorded_metric = *metricp;
/* Update the EWMA of the ETX for the neighbor. */
new_metric = ((uint16_t)recorded_metric * ETX_ALPHA +
(uint16_t)packet_metric * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
}
PRINTF("neighbor-info: ETX changed from %d to %d (packet ETX = %d) %d\n",
NEIGHBOR_INFO_FIX2ETX(recorded_metric),
NEIGHBOR_INFO_FIX2ETX(new_metric),
NEIGHBOR_INFO_FIX2ETX(packet_metric),
dest->u8[7]);
if(neighbor_attr_has_neighbor(dest)) {
time = clock_seconds();
neighbor_attr_set_data(&attr_etx, dest, &new_metric);
neighbor_attr_set_data(&attr_timestamp, dest, &time);
if((first_update || new_metric != recorded_metric) && subscriber_callback != NULL) {
subscriber_callback(dest, 1, new_metric);
}
}
}
/*---------------------------------------------------------------------------*/
static void
add_neighbor(const rimeaddr_t *addr)
{
switch(neighbor_attr_add_neighbor(addr)) {
case -1:
PRINTF("neighbor-info: failed to add a node.\n");
break;
case 0:
PRINTF("neighbor-info: The neighbor is already known\n");
break;
default:
break;
}
}
/*---------------------------------------------------------------------------*/
void
neighbor_info_packet_sent(int status, int numtx)
{
const rimeaddr_t *dest;
link_metric_t packet_metric;
#if UIP_DS6_LL_NUD
uip_ds6_nbr_t *nbr;
#endif /* UIP_DS6_LL_NUD */
dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
return;
}
packet_metric = numtx;
PRINTF("neighbor-info: packet sent to %d.%d, status=%d, metric=%u\n",
dest->u8[sizeof(*dest) - 2], dest->u8[sizeof(*dest) - 1],
status, (unsigned)packet_metric);
switch(status) {
case MAC_TX_OK:
add_neighbor(dest);
#if UIP_DS6_LL_NUD
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
if(nbr != NULL &&
(nbr->state == STALE || nbr->state == DELAY || nbr->state == PROBE)) {
nbr->state = REACHABLE;
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
PRINTF("neighbor-info : received a link layer ACK : ");
PRINTLLADDR((uip_lladdr_t *)dest);
PRINTF(" is reachable.\n");
}
#endif /* UIP_DS6_LL_NUD */
break;
case MAC_TX_NOACK:
packet_metric = ETX_NOACK_PENALTY;
break;
default:
/* Do not penalize the ETX when collisions or transmission
errors occur. */
return;
}
update_metric(dest, packet_metric);
}
/*---------------------------------------------------------------------------*/
void
neighbor_info_packet_received(void)
{
const rimeaddr_t *src;
src = packetbuf_addr(PACKETBUF_ADDR_SENDER);
if(rimeaddr_cmp(src, &rimeaddr_null)) {
return;
}
PRINTF("neighbor-info: packet received from %d.%d\n",
src->u8[sizeof(*src) - 2], src->u8[sizeof(*src) - 1]);
add_neighbor(src);
}
/*---------------------------------------------------------------------------*/
int
neighbor_info_subscribe(neighbor_info_subscriber_t s)
{
if(subscriber_callback == NULL) {
neighbor_attr_register(&attr_etx);
neighbor_attr_register(&attr_timestamp);
subscriber_callback = s;
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
link_metric_t
neighbor_info_get_metric(const rimeaddr_t *addr)
{
link_metric_t *metricp;
metricp = (link_metric_t *)neighbor_attr_get_data(&attr_etx, addr);
return metricp == NULL ? ETX_LIMIT : *metricp;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,94 +0,0 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Declarations for the neighbor information module.
*
* \author Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef NEIGHBOR_INFO_H
#define NEIGHBOR_INFO_H
#include "net/neighbor-attr.h"
#include "net/rime.h"
/* ETX_DIVISOR is the value that a fix-point representation of the ETX
should be divided by in order to obtain the integer representation. */
#define NEIGHBOR_INFO_ETX_DIVISOR 16
/* Macros for converting between a fix-point representation of the ETX
and a integer representation. */
#define NEIGHBOR_INFO_ETX2FIX(etx) ((etx) * NEIGHBOR_INFO_ETX_DIVISOR)
#define NEIGHBOR_INFO_FIX2ETX(fix) ((fix) / NEIGHBOR_INFO_ETX_DIVISOR)
typedef void (*neighbor_info_subscriber_t)(const rimeaddr_t *, int known, int etx);
typedef uint8_t link_metric_t;
NEIGHBOR_ATTRIBUTE_DECLARE(attr_etx);
NEIGHBOR_ATTRIBUTE_DECLARE(attr_timestamp);
/**
* Notify the neighbor information module about the status of
* a packet transmission.
*
* \param status The MAC status code for this packet.
*
* \param numtx The amount of transmissions made for this packet.
*/
void neighbor_info_packet_sent(int status, int numtx);
/**
* Notify the neighbor information module that a packet was received.
*
* \param status The MAC status code for this packet.
*
* \param numtx The amount of transmissions made for this packet.
*/
void neighbor_info_packet_received(void);
/**
* Subscribe to notifications of changed neighbor information.
*
* \return Returns 1 if the subscription was successful, and 0 if not.
*/
int neighbor_info_subscribe(neighbor_info_subscriber_t);
/**
* Get link metric value for a specific neighbor.
*
* \return Returns link metric if the neighbor exists, and 0 if not.
*/
link_metric_t neighbor_info_get_metric(const rimeaddr_t *addr);
#endif /* NEIGHBOR_INFO_H */

View file

@ -162,9 +162,9 @@
* Initial metric attributed to a link when the ETX is unknown * Initial metric attributed to a link when the ETX is unknown
*/ */
#ifndef RPL_CONF_INIT_LINK_METRIC #ifndef RPL_CONF_INIT_LINK_METRIC
#define RPL_INIT_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(5) #define RPL_INIT_LINK_METRIC 5 * RPL_MIN_HOPRANKINC
#else #else
#define RPL_INIT_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(RPL_CONF_INIT_LINK_METRIC) #define RPL_INIT_LINK_METRIC RPL_CONF_INIT_LINK_METRIC
#endif #endif
/* /*

View file

@ -45,6 +45,7 @@
#include "net/rpl/rpl-private.h" #include "net/rpl/rpl-private.h"
#include "net/uip.h" #include "net/uip.h"
#include "net/uip-nd6.h" #include "net/uip-nd6.h"
#include "net/nbr-table.h"
#include "lib/list.h" #include "lib/list.h"
#include "lib/memb.h" #include "lib/memb.h"
#include "sys/ctimer.h" #include "sys/ctimer.h"
@ -55,20 +56,11 @@
#define DEBUG DEBUG_NONE #define DEBUG DEBUG_NONE
#include "net/uip-debug.h" #include "net/uip-debug.h"
#include "net/neighbor-info.h"
#if UIP_CONF_IPV6 #if UIP_CONF_IPV6
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
extern rpl_of_t RPL_OF; extern rpl_of_t RPL_OF;
static rpl_of_t * const objective_functions[] = {&RPL_OF}; static rpl_of_t * const objective_functions[] = {&RPL_OF};
/*---------------------------------------------------------------------------*/
#ifndef RPL_CONF_MAX_PARENTS_PER_DAG
#define RPL_MAX_PARENTS_PER_DAG 8
#else
#define RPL_MAX_PARENTS_PER_DAG RPL_CONF_MAX_PARENTS_PER_DAG
#endif /* !RPL_CONF_MAX_PARENTS_PER_DAG */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* RPL definitions. */ /* RPL definitions. */
@ -79,14 +71,74 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF};
#endif /* !RPL_CONF_GROUNDED */ #endif /* !RPL_CONF_GROUNDED */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */ /* Per-parent RPL information */
MEMB(parent_memb, struct rpl_parent, NBR_TABLE(rpl_parent_t, rpl_parents);
RPL_MAX_PARENTS_PER_DAG * RPL_MAX_INSTANCES * RPL_MAX_DAG_PER_INSTANCE);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Allocate instance table. */ /* Allocate instance table. */
rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t instance_table[RPL_MAX_INSTANCES];
rpl_instance_t *default_instance; rpl_instance_t *default_instance;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void
rpl_dag_init(void)
{
nbr_table_register(rpl_parents, (nbr_table_callback *)rpl_remove_parent);
}
/*---------------------------------------------------------------------------*/
rpl_rank_t
rpl_get_parent_rank(uip_lladdr_t *addr)
{
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (rimeaddr_t *)addr);
if(p != NULL) {
return p->rank;
} else {
return 0;
}
}
/*---------------------------------------------------------------------------*/
uint16_t
rpl_get_parent_link_metric(uip_lladdr_t *addr)
{
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (rimeaddr_t *)addr);
if(p != NULL) {
return p->link_metric;
} else {
return 0;
}
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
rpl_get_parent_ipaddr(rpl_parent_t *p)
{
rimeaddr_t *lladdr = nbr_table_get_lladdr(rpl_parents, p);
return uip_ds6_nbr_ipaddr_from_lladdr((uip_lladdr_t *)lladdr);
}
/*---------------------------------------------------------------------------*/
static void
rpl_set_preferred_parent(rpl_dag_t *dag, rpl_parent_t *p)
{
if(dag != NULL && dag->preferred_parent != p) {
PRINTF("RPL: rpl_set_preferred_parent ");
if(p != NULL) {
PRINT6ADDR(rpl_get_parent_ipaddr(p));
} else {
PRINTF("NULL");
}
PRINTF(" used to be ");
if(dag->preferred_parent != NULL) {
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
} else {
PRINTF("NULL");
}
PRINTF("\n");
/* Always keep the preferred parent locked, so it remains in the
* neighbor table. */
nbr_table_unlock(rpl_parents, dag->preferred_parent);
nbr_table_lock(rpl_parents, p);
dag->preferred_parent = p;
}
}
/*---------------------------------------------------------------------------*/
/* Greater-than function for the lollipop counter. */ /* Greater-than function for the lollipop counter. */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int static int
@ -107,53 +159,34 @@ lollipop_greater_than(int a, int b)
static void static void
remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
{ {
rpl_parent_t *p, *p2; rpl_parent_t *p;
PRINTF("RPL: Removing parents (minimum rank %u)\n", PRINTF("RPL: Removing parents (minimum rank %u)\n",
minimum_rank); minimum_rank);
for(p = list_head(dag->parents); p != NULL; p = p2) { p = nbr_table_head(rpl_parents);
p2 = p->next; while(p != NULL) {
if(p->rank >= minimum_rank) { if(dag == p->dag && p->rank >= minimum_rank) {
rpl_remove_parent(dag, p); rpl_remove_parent(p);
} }
p = nbr_table_next(rpl_parents, p);
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
{ {
rpl_parent_t *p, *p2; rpl_parent_t *p;
PRINTF("RPL: Removing parents (minimum rank %u)\n", PRINTF("RPL: Removing parents (minimum rank %u)\n",
minimum_rank); minimum_rank);
for(p = list_head(dag->parents); p != NULL; p = p2) { p = nbr_table_head(rpl_parents);
p2 = p->next; while(p != NULL) {
if(p->rank >= minimum_rank) { if(dag == p->dag && p->rank >= minimum_rank) {
rpl_nullify_parent(dag, p); rpl_nullify_parent(p);
} }
} p = nbr_table_next(rpl_parents, p);
}
/*---------------------------------------------------------------------------*/
static void
remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
{
rpl_parent_t *p, *worst;
PRINTF("RPL: Removing the worst parent\n");
/* Find the parent with the highest rank. */
worst = NULL;
for(p = list_head(dag->parents); p != NULL; p = list_item_next(p)) {
if(p != dag->preferred_parent &&
(worst == NULL || p->rank > worst->rank)) {
worst = p;
}
}
/* Remove the neighbor if its rank is worse than the minimum worst rank. */
if(worst != NULL && worst->rank > min_worst_rank) {
rpl_remove_parent(dag, worst);
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -231,7 +264,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
dag->grounded = RPL_GROUNDED; dag->grounded = RPL_GROUNDED;
instance->mop = RPL_MOP_DEFAULT; instance->mop = RPL_MOP_DEFAULT;
instance->of = &RPL_OF; instance->of = &RPL_OF;
dag->preferred_parent = NULL; rpl_set_preferred_parent(dag, NULL);
memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id)); memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id));
@ -280,11 +313,13 @@ rpl_repair_root(uint8_t instance_id)
instance = rpl_get_instance(instance_id); instance = rpl_get_instance(instance_id);
if(instance == NULL || if(instance == NULL ||
instance->current_dag->rank != ROOT_RANK(instance)) { instance->current_dag->rank != ROOT_RANK(instance)) {
PRINTF("RPL: rpl_repair_root triggered but not root\n");
return 0; return 0;
} }
RPL_LOLLIPOP_INCREMENT(instance->current_dag->version); RPL_LOLLIPOP_INCREMENT(instance->current_dag->version);
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
PRINTF("RPL: rpl_repair_root initiating global repair with version %d\n", instance->current_dag->version);
rpl_reset_dio_timer(instance); rpl_reset_dio_timer(instance);
return 1; return 1;
} }
@ -378,8 +413,8 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
PRINT6ADDR(from); PRINT6ADDR(from);
PRINTF("\n"); PRINTF("\n");
instance->def_route = uip_ds6_defrt_add(from, instance->def_route = uip_ds6_defrt_add(from,
RPL_LIFETIME(instance, RPL_LIFETIME(instance,
instance->default_lifetime)); instance->default_lifetime));
if(instance->def_route == NULL) { if(instance->def_route == NULL) {
return 0; return 0;
} }
@ -430,7 +465,6 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
if(!dag->used) { if(!dag->used) {
memset(dag, 0, sizeof(*dag)); memset(dag, 0, sizeof(*dag));
LIST_STRUCT_INIT(dag, parents);
dag->used = 1; dag->used = 1;
dag->rank = INFINITE_RANK; dag->rank = INFINITE_RANK;
dag->min_rank = INFINITE_RANK; dag->min_rank = INFINITE_RANK;
@ -502,77 +536,66 @@ rpl_free_dag(rpl_dag_t *dag)
rpl_parent_t * rpl_parent_t *
rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
{ {
rpl_parent_t *p; rpl_parent_t *p = NULL;
/* Is the parent known by ds6? Drop this request if not.
* Typically, the parent is added upon receiving a DIO. */
uip_lladdr_t *lladdr = uip_ds6_nbr_lladdr_from_ipaddr(addr);
if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) { PRINTF("RPL: rpl_add_parent lladdr %p\n", lladdr);
return NULL; if(lladdr != NULL) {
} /* Add parent in rpl_parents */
p = nbr_table_add_lladdr(rpl_parents, (rimeaddr_t *)lladdr);
p = memb_alloc(&parent_memb); p->dag = dag;
if(p == NULL) { p->rank = dio->rank;
RPL_STAT(rpl_stats.mem_overflows++); p->dtsn = dio->dtsn;
return NULL; p->link_metric = RPL_INIT_LINK_METRIC;
}
memcpy(&p->addr, addr, sizeof(p->addr));
p->dag = dag;
p->rank = dio->rank;
p->dtsn = dio->dtsn;
p->link_metric = RPL_INIT_LINK_METRIC;
#if RPL_DAG_MC != RPL_DAG_MC_NONE #if RPL_DAG_MC != RPL_DAG_MC_NONE
memcpy(&p->mc, &dio->mc, sizeof(p->mc)); memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
list_add(dag->parents, p); }
return p; return p;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static rpl_parent_t *
find_parent_any_dag_any_instance(uip_ipaddr_t *addr)
{
uip_ds6_nbr_t *ds6_nbr = uip_ds6_nbr_lookup(addr);
uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(ds6_nbr);
return nbr_table_get_from_lladdr(rpl_parents, (rimeaddr_t *)lladdr);
}
/*---------------------------------------------------------------------------*/
rpl_parent_t * rpl_parent_t *
rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr) rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
{ {
rpl_parent_t *p; rpl_parent_t *p = find_parent_any_dag_any_instance(addr);
if(p != NULL && p->dag == dag) {
for(p = list_head(dag->parents); p != NULL; p = p->next) { return p;
if(uip_ipaddr_cmp(&p->addr, addr)) { } else {
return p; return NULL;
}
} }
return NULL;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static rpl_dag_t * static rpl_dag_t *
find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
{ {
rpl_parent_t *p; rpl_parent_t *p = find_parent_any_dag_any_instance(addr);
rpl_dag_t *dag, *end; if(p != NULL) {
return p->dag;
for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { } else {
if(dag->used) { return NULL;
for(p = list_head(dag->parents); p != NULL; p = p->next) {
if(uip_ipaddr_cmp(&p->addr, addr)) {
return dag;
}
}
}
} }
return NULL;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
rpl_parent_t * rpl_parent_t *
rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
{ {
rpl_parent_t *p; rpl_parent_t *p = find_parent_any_dag_any_instance(addr);
rpl_dag_t *dag, *end; if(p && p->dag && p->dag->instance == instance) {
return p;
for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { } else {
if(dag->used) { return NULL;
for(p = list_head(dag->parents); p != NULL; p = p->next) {
if(uip_ipaddr_cmp(&p->addr, addr)) {
return p;
}
}
}
} }
return NULL;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
rpl_dag_t * rpl_dag_t *
@ -636,7 +659,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
best_dag->min_rank = best_dag->rank; best_dag->min_rank = best_dag->rank;
} else if(!acceptable_rank(best_dag, best_dag->rank)) { } else if(!acceptable_rank(best_dag, best_dag->rank)) {
PRINTF("RPL: New rank unacceptable!\n"); PRINTF("RPL: New rank unacceptable!\n");
instance->current_dag->preferred_parent = NULL; rpl_set_preferred_parent(instance->current_dag, NULL);
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) { if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) {
/* Send a No-Path DAO to the removed preferred parent. */ /* Send a No-Path DAO to the removed preferred parent. */
dao_output(last_parent, RPL_ZERO_LIFETIME); dao_output(last_parent, RPL_ZERO_LIFETIME);
@ -645,7 +668,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
} }
if(best_dag->preferred_parent != last_parent) { if(best_dag->preferred_parent != last_parent) {
rpl_set_default_route(instance, &best_dag->preferred_parent->addr); rpl_set_default_route(instance, rpl_get_parent_ipaddr(best_dag->preferred_parent));
PRINTF("RPL: Changed preferred parent, rank changed from %u to %u\n", PRINTF("RPL: Changed preferred parent, rank changed from %u to %u\n",
(unsigned)old_rank, best_dag->rank); (unsigned)old_rank, best_dag->rank);
RPL_STAT(rpl_stats.parent_switch++); RPL_STAT(rpl_stats.parent_switch++);
@ -672,7 +695,9 @@ rpl_select_parent(rpl_dag_t *dag)
rpl_parent_t *p, *best; rpl_parent_t *p, *best;
best = NULL; best = NULL;
for(p = list_head(dag->parents); p != NULL; p = p->next) {
p = nbr_table_head(rpl_parents);
while(p != NULL) {
if(p->rank == INFINITE_RANK) { if(p->rank == INFINITE_RANK) {
/* ignore this neighbor */ /* ignore this neighbor */
} else if(best == NULL) { } else if(best == NULL) {
@ -680,42 +705,43 @@ rpl_select_parent(rpl_dag_t *dag)
} else { } else {
best = dag->instance->of->best_parent(best, p); best = dag->instance->of->best_parent(best, p);
} }
p = nbr_table_next(rpl_parents, p);
} }
if(best != NULL) { if(best != NULL) {
dag->preferred_parent = best; rpl_set_preferred_parent(dag, best);
} }
return best; return best;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent) rpl_remove_parent(rpl_parent_t *parent)
{ {
rpl_nullify_parent(dag, parent);
PRINTF("RPL: Removing parent "); PRINTF("RPL: Removing parent ");
PRINT6ADDR(&parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n"); PRINTF("\n");
list_remove(dag->parents, parent); rpl_nullify_parent(parent);
memb_free(&parent_memb, parent);
nbr_table_remove(rpl_parents, parent);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent) rpl_nullify_parent(rpl_parent_t *parent)
{ {
rpl_dag_t *dag = parent->dag;
/* This function can be called when the preferred parent is NULL, so we /* This function can be called when the preferred parent is NULL, so we
need to handle this condition in order to trigger uip_ds6_defrt_rm. */ need to handle this condition in order to trigger uip_ds6_defrt_rm. */
if(parent == dag->preferred_parent || dag->preferred_parent == NULL) { if(parent == dag->preferred_parent || dag->preferred_parent == NULL) {
dag->preferred_parent = NULL; rpl_set_preferred_parent(dag, NULL);
dag->rank = INFINITE_RANK; dag->rank = INFINITE_RANK;
if(dag->joined) { if(dag->joined) {
if(dag->instance->def_route != NULL) { if(dag->instance->def_route != NULL) {
PRINTF("RPL: Removing default route "); PRINTF("RPL: Removing default route ");
PRINT6ADDR(&parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n"); PRINTF("\n");
uip_ds6_defrt_rm(dag->instance->def_route); uip_ds6_defrt_rm(dag->instance->def_route);
dag->instance->def_route = NULL; dag->instance->def_route = NULL;
} }
dao_output(parent, RPL_ZERO_LIFETIME); dao_output(parent, RPL_ZERO_LIFETIME);
@ -723,7 +749,7 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
} }
PRINTF("RPL: Nullifying parent "); PRINTF("RPL: Nullifying parent ");
PRINT6ADDR(&parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n"); PRINTF("\n");
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -731,11 +757,11 @@ void
rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
{ {
if(parent == dag_src->preferred_parent) { if(parent == dag_src->preferred_parent) {
dag_src->preferred_parent = NULL; rpl_set_preferred_parent(dag_src, NULL);
dag_src->rank = INFINITE_RANK; dag_src->rank = INFINITE_RANK;
if(dag_src->joined && dag_src->instance->def_route != NULL) { if(dag_src->joined && dag_src->instance->def_route != NULL) {
PRINTF("RPL: Removing default route "); PRINTF("RPL: Removing default route ");
PRINT6ADDR(&parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n"); PRINTF("\n");
PRINTF("rpl_move_parent\n"); PRINTF("rpl_move_parent\n");
uip_ds6_defrt_rm(dag_src->instance->def_route); uip_ds6_defrt_rm(dag_src->instance->def_route);
@ -743,11 +769,11 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
} }
} else if(dag_src->joined) { } else if(dag_src->joined) {
/* Remove uIPv6 routes that have this parent as the next hop. */ /* Remove uIPv6 routes that have this parent as the next hop. */
rpl_remove_routes_by_nexthop(&parent->addr, dag_src); rpl_remove_routes_by_nexthop(rpl_get_parent_ipaddr(parent), dag_src);
} }
PRINTF("RPL: Moving parent "); PRINTF("RPL: Moving parent ");
PRINT6ADDR(&parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n"); PRINTF("\n");
list_remove(dag_src->parents, parent); list_remove(dag_src->parents, parent);
@ -831,7 +857,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
if(of == NULL) { if(of == NULL) {
PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n", PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",
dio->instance_id); dio->instance_id);
rpl_remove_parent(dag, p); rpl_remove_parent(p);
instance->used = 0; instance->used = 0;
return; return;
} }
@ -866,7 +892,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
/* Copy prefix information from the DIO into the DAG object. */ /* Copy prefix information from the DIO into the DAG object. */
memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t));
dag->preferred_parent = p; rpl_set_preferred_parent(dag, p);
instance->of->update_metric_container(instance); instance->of->update_metric_container(instance);
dag->rank = instance->of->calculate_rank(p, 0); dag->rank = instance->of->calculate_rank(p, 0);
/* So far this is the lowest rank we are aware of. */ /* So far this is the lowest rank we are aware of. */
@ -943,7 +969,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
instance->lifetime_unit != dio->lifetime_unit) { instance->lifetime_unit != dio->lifetime_unit) {
PRINTF("RPL: DIO for DAG instance %u uncompatible with previos DIO\n", PRINTF("RPL: DIO for DAG instance %u uncompatible with previos DIO\n",
dio->instance_id); dio->instance_id);
rpl_remove_parent(dag, p); rpl_remove_parent(p);
dag->used = 0; dag->used = 0;
return; return;
} }
@ -958,7 +984,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
/* copy prefix information into the dag */ /* copy prefix information into the dag */
memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t));
dag->preferred_parent = p; rpl_set_preferred_parent(dag, p);
dag->rank = instance->of->calculate_rank(p, 0); dag->rank = instance->of->calculate_rank(p, 0);
dag->min_rank = dag->rank; /* So far this is the lowest rank we know of. */ dag->min_rank = dag->rank; /* So far this is the lowest rank we know of. */
@ -992,6 +1018,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
} else { } else {
dag->rank = dag->instance->of->calculate_rank(p, 0); dag->rank = dag->instance->of->calculate_rank(p, 0);
dag->min_rank = dag->rank; dag->min_rank = dag->rank;
PRINTF("RPL: rpl_process_parent_event global repair\n");
rpl_process_parent_event(dag->instance, p); rpl_process_parent_event(dag->instance, p);
} }
@ -1006,6 +1033,10 @@ rpl_local_repair(rpl_instance_t *instance)
{ {
int i; int i;
if(instance == NULL) {
PRINTF("RPL: local repair requested for instance NULL\n");
return;
}
PRINTF("RPL: Starting a local instance repair\n"); PRINTF("RPL: Starting a local instance repair\n");
for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) { for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
if(instance->dag_table[i].used) { if(instance->dag_table[i].used) {
@ -1022,59 +1053,46 @@ rpl_local_repair(rpl_instance_t *instance)
void void
rpl_recalculate_ranks(void) rpl_recalculate_ranks(void)
{ {
rpl_instance_t *instance, *end;
rpl_parent_t *p; rpl_parent_t *p;
int i;
/* /*
* We recalculate ranks when we receive feedback from the system rather * We recalculate ranks when we receive feedback from the system rather
* than RPL protocol messages. This periodical recalculation is called * than RPL protocol messages. This periodical recalculation is called
* from a timer in order to keep the stack depth reasonably low. * from a timer in order to keep the stack depth reasonably low.
*/ */
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; p = nbr_table_head(rpl_parents);
instance < end; ++instance) { while(p != NULL) {
if(instance->used) { if(p->dag != NULL && p->dag->instance && p->updated) {
for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) { p->updated = 0;
if(instance->dag_table[i].used) { PRINTF("RPL: rpl_process_parent_event recalculate_ranks\n");
for(p = list_head(instance->dag_table[i].parents); if(!rpl_process_parent_event(p->dag->instance, p)) {
p != NULL; p = p->next) { PRINTF("RPL: A parent was dropped\n");
if(p->updated) {
p->updated = 0;
if(!rpl_process_parent_event(instance, p)) {
PRINTF("RPL: A parent was dropped\n");
}
/*
* Stop calculating here because the parent list may have changed.
* If more ranks need to be recalculated, it will be taken care of
* in subsequent calls to this functions.
*/
break;
}
}
}
} }
} }
p = nbr_table_next(rpl_parents, p);
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
{ {
rpl_rank_t old_rank;
int return_value; int return_value;
#if DEBUG
rpl_rank_t old_rank;
old_rank = instance->current_dag->rank; old_rank = instance->current_dag->rank;
#endif /* DEBUG */
return_value = 1; return_value = 1;
if(!acceptable_rank(p->dag, p->rank)) { if(!acceptable_rank(p->dag, p->rank)) {
/* The candidate parent is no longer valid: the rank increase resulting /* The candidate parent is no longer valid: the rank increase resulting
from the choice of it as a parent would be too high. */ from the choice of it as a parent would be too high. */
PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank); PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank);
rpl_nullify_parent(p);
if(p != instance->current_dag->preferred_parent) { if(p != instance->current_dag->preferred_parent) {
rpl_nullify_parent(p->dag, p);
return 0; return 0;
} else { } else {
rpl_nullify_parent(p->dag, p);
return_value = 0; return_value = 0;
} }
} }
@ -1092,7 +1110,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
DAG_RANK(old_rank, instance), DAG_RANK(instance->current_dag->rank, instance)); DAG_RANK(old_rank, instance), DAG_RANK(instance->current_dag->rank, instance));
if(instance->current_dag->rank != INFINITE_RANK) { if(instance->current_dag->rank != INFINITE_RANK) {
PRINTF("RPL: The preferred parent is "); PRINTF("RPL: The preferred parent is ");
PRINT6ADDR(&instance->current_dag->preferred_parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(instance->current_dag->preferred_parent));
PRINTF(" (rank %u)\n", PRINTF(" (rank %u)\n",
(unsigned)DAG_RANK(instance->current_dag->preferred_parent->rank, instance)); (unsigned)DAG_RANK(instance->current_dag->preferred_parent->rank, instance));
} else { } else {
@ -1143,8 +1161,8 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
/* The DIO sender is on an older version of the DAG. */ /* The DIO sender is on an older version of the DAG. */
PRINTF("RPL: old version received => inconsistency detected\n"); PRINTF("RPL: old version received => inconsistency detected\n");
if(dag->joined) { if(dag->joined) {
rpl_reset_dio_timer(instance); rpl_reset_dio_timer(instance);
return; return;
} }
} }
} }
@ -1196,10 +1214,6 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(p == NULL) { if(p == NULL) {
previous_dag = find_parent_dag(instance, from); previous_dag = find_parent_dag(instance, from);
if(previous_dag == NULL) { if(previous_dag == NULL) {
if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) {
/* Make room for a new parent. */
remove_worst_parent(dag, dio->rank);
}
/* Add the DIO sender as a candidate parent. */ /* Add the DIO sender as a candidate parent. */
p = rpl_add_parent(dag, dio, from); p = rpl_add_parent(dag, dio, from);
if(p == NULL) { if(p == NULL) {
@ -1233,7 +1247,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
PRINTF(", rank %u, min_rank %u, ", PRINTF(", rank %u, min_rank %u, ",
instance->current_dag->rank, instance->current_dag->min_rank); instance->current_dag->rank, instance->current_dag->min_rank);
PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n", PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n",
p->rank, p->mc.obj.etx, p->link_metric, instance->mc.obj.etx); p->rank, -1/*p->mc.obj.etx*/, p->link_metric, instance->mc.obj.etx);
/* We have allocated a candidate parent; process the DIO further. */ /* We have allocated a candidate parent; process the DIO further. */

View file

@ -75,12 +75,6 @@ rpl_verify_header(int uip_ext_opt_offset)
return 1; return 1;
} }
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
PRINTF("RPL: Forward error!\n");
/* We should try to repair it, not implemented for the moment */
return 2;
}
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance); instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
if(instance == NULL) { if(instance == NULL) {
PRINTF("RPL: Unknown instance: %u\n", PRINTF("RPL: Unknown instance: %u\n",
@ -88,6 +82,30 @@ rpl_verify_header(int uip_ext_opt_offset)
return 1; return 1;
} }
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
/* We should try to repair it by removing the neighbor that caused
the packet to be forwareded in the first place. We drop any
routes that go through the neighbor that sent the packet to
us. */
uip_ds6_route_t *route;
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
if(route != NULL) {
uip_ds6_route_rm(route);
/* If we are the root and just needed to remove a DAO route,
chances are that the network needs to be repaired. The
rpl_repair_root() function will cause a global repair if we
happen to be the root node of the dag. */
PRINTF("RPL: initiate global repair\n");
rpl_repair_root(instance->instance_id);
}
/* Remove the forwarding error flag and return 0 to let the packet
be forwarded again. */
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_FWD_ERR;
return 0;
}
if(!instance->current_dag->joined) { if(!instance->current_dag->joined) {
PRINTF("RPL: No DAG in the instance\n"); PRINTF("RPL: No DAG in the instance\n");
return 1; return 1;
@ -113,7 +131,9 @@ rpl_verify_header(int uip_ext_opt_offset)
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) { if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
PRINTF("RPL: Rank error signalled in RPL option!\n"); PRINTF("RPL: Rank error signalled in RPL option!\n");
/* We should try to repair it, not implemented for the moment */ /* We should try to repair it, not implemented for the moment */
return 3; rpl_reset_dio_timer(instance);
/* Forward the packet anyway. */
return 0;
} }
PRINTF("RPL: Single error tolerated\n"); PRINTF("RPL: Single error tolerated\n");
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR; UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
@ -191,18 +211,29 @@ rpl_update_header_empty(void)
PRINTF("RPL: Updating RPL option\n"); PRINTF("RPL: Updating RPL option\n");
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank; UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank;
/* Check the direction of the down flag, as per Section 11.2.2.3,
/* Set the down extension flag correctly as described in Section which states that if a packet is going down it should in
11.2 of RFC6550. If the packet progresses along a DAO route, general not go back up again. If this happens, a
the down flag should be set. */ RPL_HDR_OPT_FWD_ERR should be flagged. */
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
/* No route was found, so this packet will go towards the RPL UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
root. If so, we should not set the down flag. */ PRINTF("RPL forwarding error\n");
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN; }
} else { } else {
/* A DAO route was found so we set the down flag. */ /* Set the down extension flag correctly as described in Section
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN; 11.2 of RFC6550. If the packet progresses along a DAO route,
the down flag should be set. */
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
/* No route was found, so this packet will go towards the RPL
root. If so, we should not set the down flag. */
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
PRINTF("RPL option going up\n");
} else {
/* A DAO route was found so we set the down flag. */
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
PRINTF("RPL option going down\n");
}
} }
uip_ext_len = last_uip_ext_len; uip_ext_len = last_uip_ext_len;
@ -255,10 +286,8 @@ rpl_update_header_final(uip_ipaddr_t *addr)
void void
rpl_remove_header(void) rpl_remove_header(void)
{ {
int last_uip_ext_len;
uint8_t temp_len; uint8_t temp_len;
last_uip_ext_len = uip_ext_len;
uip_ext_len = 0; uip_ext_len = 0;
PRINTF("RPL: Verifying the presence of the RPL header option\n"); PRINTF("RPL: Verifying the presence of the RPL header option\n");

View file

@ -243,6 +243,13 @@ dio_input(void)
PRINTF(", "); PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n"); PRINTF("\n");
} else {
PRINTF("RPL: Out of Memory, dropping DIO from ");
PRINT6ADDR(&from);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n");
return;
} }
} else { } else {
PRINTF("RPL: Neighbor already in neighbor cache\n"); PRINTF("RPL: Neighbor already in neighbor cache\n");
@ -568,8 +575,10 @@ dao_input(void)
uint8_t prefixlen; uint8_t prefixlen;
uint8_t flags; uint8_t flags;
uint8_t subopt_type; uint8_t subopt_type;
/*
uint8_t pathcontrol; uint8_t pathcontrol;
uint8_t pathsequence; uint8_t pathsequence;
*/
uip_ipaddr_t prefix; uip_ipaddr_t prefix;
uip_ds6_route_t *rep; uip_ds6_route_t *rep;
uint8_t buffer_length; uint8_t buffer_length;
@ -621,8 +630,7 @@ dao_input(void)
} }
/* Check if there are any RPL options present. */ /* Check if there are any RPL options present. */
i = pos; for(i = pos; i < buffer_length; i += len) {
for(; i < buffer_length; i += len) {
subopt_type = buffer[i]; subopt_type = buffer[i];
if(subopt_type == RPL_OPTION_PAD1) { if(subopt_type == RPL_OPTION_PAD1) {
len = 1; len = 1;
@ -640,8 +648,8 @@ dao_input(void)
break; break;
case RPL_OPTION_TRANSIT: case RPL_OPTION_TRANSIT:
/* The path sequence and control are ignored. */ /* The path sequence and control are ignored. */
pathcontrol = buffer[i + 3]; /* pathcontrol = buffer[i + 3];
pathsequence = buffer[i + 4]; pathsequence = buffer[i + 4];*/
lifetime = buffer[i + 5]; lifetime = buffer[i + 5];
/* The parent address is also ignored. */ /* The parent address is also ignored. */
break; break;
@ -656,12 +664,17 @@ dao_input(void)
rep = uip_ds6_route_lookup(&prefix); rep = uip_ds6_route_lookup(&prefix);
if(lifetime == RPL_ZERO_LIFETIME) { if(lifetime == RPL_ZERO_LIFETIME) {
PRINTF("RPL: No-Path DAO received\n");
/* No-Path DAO received; invoke the route purging routine. */ /* No-Path DAO received; invoke the route purging routine. */
if(rep != NULL && rep->state.saved_lifetime == 0 && rep->length == prefixlen && uip_ipaddr_cmp(&rep->nexthop, &dao_sender_addr)) { if(rep != NULL &&
rep->state.nopath_received == 0 &&
rep->length == prefixlen &&
uip_ds6_route_nexthop(rep) != NULL &&
uip_ipaddr_cmp(uip_ds6_route_nexthop(rep), &dao_sender_addr)) {
PRINTF("RPL: Setting expiration timer for prefix "); PRINTF("RPL: Setting expiration timer for prefix ");
PRINT6ADDR(&prefix); PRINT6ADDR(&prefix);
PRINTF("\n"); PRINTF("\n");
rep->state.saved_lifetime = rep->state.lifetime; rep->state.nopath_received = 1;
rep->state.lifetime = DAO_EXPIRATION_TIMEOUT; rep->state.lifetime = DAO_EXPIRATION_TIMEOUT;
} }
return; return;
@ -670,20 +683,32 @@ dao_input(void)
learned_from = uip_is_addr_mcast(&dao_sender_addr) ? learned_from = uip_is_addr_mcast(&dao_sender_addr) ?
RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO; RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO;
PRINTF("RPL: DAO from %s\n",
learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast");
if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) {
/* Check whether this is a DAO forwarding loop. */ /* Check whether this is a DAO forwarding loop. */
p = rpl_find_parent(dag, &dao_sender_addr); p = rpl_find_parent(dag, &dao_sender_addr);
/* check if this is a new DAO registration with an "illegal" rank */ /* check if this is a new DAO registration with an "illegal" rank */
/* if we already route to this node it is likely */ /* if we already route to this node it is likely */
if(p != NULL && DAG_RANK(p->rank, instance) < DAG_RANK(dag->rank, instance)) { if(p != NULL &&
DAG_RANK(p->rank, instance) < DAG_RANK(dag->rank, instance)) {
PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n", PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n",
DAG_RANK(p->rank, instance), DAG_RANK(dag->rank, instance)); DAG_RANK(p->rank, instance), DAG_RANK(dag->rank, instance));
p->rank = INFINITE_RANK; p->rank = INFINITE_RANK;
p->updated = 1; p->updated = 1;
return; return;
} }
/* If we get the DAO from our parent, we also have a loop. */
if(p != NULL && p == dag->preferred_parent) {
PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n");
p->rank = INFINITE_RANK;
p->updated = 1;
return;
}
} }
PRINTF("RPL: adding DAO route\n");
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr); rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
if(rep == NULL) { if(rep == NULL) {
RPL_STAT(rpl_stats.mem_overflows++); RPL_STAT(rpl_stats.mem_overflows++);
@ -695,11 +720,12 @@ dao_input(void)
rep->state.learned_from = learned_from; rep->state.learned_from = learned_from;
if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) {
if(dag->preferred_parent) { if(dag->preferred_parent != NULL &&
rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) {
PRINTF("RPL: Forwarding DAO to parent "); PRINTF("RPL: Forwarding DAO to parent ");
PRINT6ADDR(&dag->preferred_parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
PRINTF("\n"); PRINTF("\n");
uip_icmp6_send(&dag->preferred_parent->addr, uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent),
ICMP6_RPL, RPL_CODE_DAO, buffer_length); ICMP6_RPL, RPL_CODE_DAO, buffer_length);
} }
if(flags & RPL_DAO_K_FLAG) { if(flags & RPL_DAO_K_FLAG) {
@ -734,9 +760,27 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
/* Destination Advertisement Object */ /* Destination Advertisement Object */
if(parent == NULL) {
PRINTF("RPL dao_output_target error parent NULL\n");
return;
}
dag = parent->dag; dag = parent->dag;
if(dag == NULL) {
PRINTF("RPL dao_output_target error dag NULL\n");
return;
}
instance = dag->instance; instance = dag->instance;
if(instance == NULL) {
PRINTF("RPL dao_output_target error instance NULL\n");
return;
}
if(prefix == NULL) {
PRINTF("RPL dao_output_target error prefix NULL\n");
return;
}
#ifdef RPL_DEBUG_DAO_OUTPUT #ifdef RPL_DEBUG_DAO_OUTPUT
RPL_DEBUG_DAO_OUTPUT(parent); RPL_DEBUG_DAO_OUTPUT(parent);
#endif #endif
@ -782,15 +826,18 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
PRINTF("RPL: Sending DAO with prefix "); PRINTF("RPL: Sending DAO with prefix ");
PRINT6ADDR(prefix); PRINT6ADDR(prefix);
PRINTF(" to "); PRINTF(" to ");
PRINT6ADDR(&parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
PRINTF("\n"); PRINTF("\n");
uip_icmp6_send(&parent->addr, ICMP6_RPL, RPL_CODE_DAO, pos); if(rpl_get_parent_ipaddr(parent) != NULL) {
uip_icmp6_send(rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos);
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
dao_ack_input(void) dao_ack_input(void)
{ {
#if DEBUG
unsigned char *buffer; unsigned char *buffer;
uint8_t buffer_length; uint8_t buffer_length;
uint8_t instance_id; uint8_t instance_id;
@ -808,6 +855,7 @@ dao_ack_input(void)
sequence, status); sequence, status);
PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("\n"); PRINTF("\n");
#endif /* DEBUG */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void

View file

@ -45,13 +45,13 @@
*/ */
#include "net/rpl/rpl-private.h" #include "net/rpl/rpl-private.h"
#include "net/neighbor-info.h" #include "net/nbr-table.h"
#define DEBUG DEBUG_NONE #define DEBUG DEBUG_NONE
#include "net/uip-debug.h" #include "net/uip-debug.h"
static void reset(rpl_dag_t *); static void reset(rpl_dag_t *);
static void parent_state_callback(rpl_parent_t *, int, int); static void neighbor_link_callback(rpl_parent_t *, int, int);
static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t); static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
@ -59,7 +59,7 @@ static void update_metric_container(rpl_instance_t *);
rpl_of_t rpl_mrhof = { rpl_of_t rpl_mrhof = {
reset, reset,
parent_state_callback, neighbor_link_callback,
best_parent, best_parent,
best_dag, best_dag,
calculate_rank, calculate_rank,
@ -67,6 +67,10 @@ rpl_of_t rpl_mrhof = {
1 1
}; };
/* Constants for the ETX moving average */
#define ETX_SCALE 100
#define ETX_ALPHA 90
/* Reject parents that have a higher link metric than the following. */ /* Reject parents that have a higher link metric than the following. */
#define MAX_LINK_METRIC 10 #define MAX_LINK_METRIC 10
@ -88,7 +92,6 @@ calculate_path_metric(rpl_parent_t *p)
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
} else { } else {
long link_metric = p->link_metric; long link_metric = p->link_metric;
link_metric = (link_metric * RPL_DAG_MC_ETX_DIVISOR) / NEIGHBOR_INFO_ETX_DIVISOR;
#if RPL_DAG_MC == RPL_DAG_MC_NONE #if RPL_DAG_MC == RPL_DAG_MC_NONE
return p->rank + (uint16_t)link_metric; return p->rank + (uint16_t)link_metric;
#elif RPL_DAG_MC == RPL_DAG_MC_ETX #elif RPL_DAG_MC == RPL_DAG_MC_ETX
@ -105,8 +108,29 @@ reset(rpl_dag_t *sag)
} }
static void static void
parent_state_callback(rpl_parent_t *parent, int known, int etx) neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
{ {
/* Do not penalize the ETX when collisions or transmission errors occur. */
if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
int recorded_etx = p->link_metric;
int packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
int new_etx;
if(status == MAC_TX_NOACK) {
packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
}
new_etx = ((uint16_t)recorded_etx * ETX_ALPHA +
(uint16_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
PRINTF("RPL: ETX changed from %d to %d (packet ETX = %d) %d\n",
recorded_etx / p->dag->instance->min_hoprankinc,
new_etx / p->dag->instance->min_hoprankinc,
packet_etx / p->dag->instance->min_hoprankinc,
dest->u8[7]);
p->link_metric = new_etx;
}
} }
static rpl_rank_t static rpl_rank_t
@ -119,10 +143,10 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
if(base_rank == 0) { if(base_rank == 0) {
return INFINITE_RANK; return INFINITE_RANK;
} }
rank_increase = NEIGHBOR_INFO_FIX2ETX(RPL_INIT_LINK_METRIC) * RPL_MIN_HOPRANKINC; rank_increase = RPL_INIT_LINK_METRIC;
} else { } else {
/* multiply first, then scale down to avoid truncation effects */ /* multiply first, then scale down to avoid truncation effects */
rank_increase = NEIGHBOR_INFO_FIX2ETX(p->link_metric * p->dag->instance->min_hoprankinc); rank_increase = p->link_metric;
if(base_rank == 0) { if(base_rank == 0) {
base_rank = p->rank; base_rank = p->rank;
} }

View file

@ -44,8 +44,6 @@
#define DEBUG DEBUG_NONE #define DEBUG DEBUG_NONE
#include "net/uip-debug.h" #include "net/uip-debug.h"
#include "net/neighbor-info.h"
static void reset(rpl_dag_t *); static void reset(rpl_dag_t *);
static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *); static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *); static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
@ -64,7 +62,7 @@ rpl_of_t rpl_of0 = {
#define DEFAULT_RANK_INCREMENT RPL_MIN_HOPRANKINC #define DEFAULT_RANK_INCREMENT RPL_MIN_HOPRANKINC
#define MIN_DIFFERENCE (NEIGHBOR_INFO_ETX_DIVISOR + NEIGHBOR_INFO_ETX_DIVISOR / 2) #define MIN_DIFFERENCE (RPL_MIN_HOPRANKINC + RPL_MIN_HOPRANKINC / 2)
static void static void
reset(rpl_dag_t *dag) reset(rpl_dag_t *dag)
@ -137,9 +135,9 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
p2->link_metric, p2->rank); p2->link_metric, p2->rank);
r1 = DAG_RANK(p1->rank, p1->dag->instance) * NEIGHBOR_INFO_ETX_DIVISOR + r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
p1->link_metric; p1->link_metric;
r2 = DAG_RANK(p2->rank, p1->dag->instance) * NEIGHBOR_INFO_ETX_DIVISOR + r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
p2->link_metric; p2->link_metric;
/* Compare two parents by looking both and their rank and at the ETX /* Compare two parents by looking both and their rank and at the ETX
for that parent. We choose the parent that has the most for that parent. We choose the parent that has the most

View file

@ -290,8 +290,8 @@ void rpl_free_instance(rpl_instance_t *);
rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *); rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *);
rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *); rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *);
rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr); rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr);
void rpl_nullify_parent(rpl_dag_t *, rpl_parent_t *); void rpl_nullify_parent(rpl_parent_t *);
void rpl_remove_parent(rpl_dag_t *, rpl_parent_t *); void rpl_remove_parent(rpl_parent_t *);
void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent); void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent);
rpl_parent_t *rpl_select_parent(rpl_dag_t *dag); rpl_parent_t *rpl_select_parent(rpl_dag_t *dag);
rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent); rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent);

View file

@ -44,7 +44,6 @@
#include "net/tcpip.h" #include "net/tcpip.h"
#include "net/uip-ds6.h" #include "net/uip-ds6.h"
#include "net/rpl/rpl-private.h" #include "net/rpl/rpl-private.h"
#include "net/neighbor-info.h"
#define DEBUG DEBUG_NONE #define DEBUG DEBUG_NONE
#include "net/uip-debug.h" #include "net/uip-debug.h"
@ -67,7 +66,7 @@ rpl_purge_routes(void)
rpl_dag_t *dag; rpl_dag_t *dag;
/* First pass, decrement lifetime */ /* First pass, decrement lifetime */
r = uip_ds6_route_list_head(); r = uip_ds6_route_head();
while(r != NULL) { while(r != NULL) {
if(r->state.lifetime >= 1) { if(r->state.lifetime >= 1) {
@ -78,11 +77,11 @@ rpl_purge_routes(void)
*/ */
r->state.lifetime--; r->state.lifetime--;
} }
r = list_item_next(r); r = uip_ds6_route_next(r);
} }
/* Second pass, remove dead routes */ /* Second pass, remove dead routes */
r = uip_ds6_route_list_head(); r = uip_ds6_route_head();
while(r != NULL) { while(r != NULL) {
if(r->state.lifetime < 1) { if(r->state.lifetime < 1) {
@ -90,7 +89,7 @@ rpl_purge_routes(void)
* thus we want to keep them. Hence < and not <= */ * thus we want to keep them. Hence < and not <= */
uip_ipaddr_copy(&prefix, &r->ipaddr); uip_ipaddr_copy(&prefix, &r->ipaddr);
uip_ds6_route_rm(r); uip_ds6_route_rm(r);
r = uip_ds6_route_list_head(); r = uip_ds6_route_head();
PRINTF("No more routes to "); PRINTF("No more routes to ");
PRINT6ADDR(&prefix); PRINT6ADDR(&prefix);
dag = default_instance->current_dag; dag = default_instance->current_dag;
@ -103,7 +102,7 @@ rpl_purge_routes(void)
} }
PRINTF("\n"); PRINTF("\n");
} else { } else {
r = list_item_next(r); r = uip_ds6_route_next(r);
} }
} }
} }
@ -113,14 +112,14 @@ rpl_remove_routes(rpl_dag_t *dag)
{ {
uip_ds6_route_t *r; uip_ds6_route_t *r;
r = uip_ds6_route_list_head(); r = uip_ds6_route_head();
while(r != NULL) { while(r != NULL) {
if(r->state.dag == dag) { if(r->state.dag == dag) {
uip_ds6_route_rm(r); uip_ds6_route_rm(r);
r = uip_ds6_route_list_head(); r = uip_ds6_route_head();
} else { } else {
r = list_item_next(r); r = uip_ds6_route_next(r);
} }
} }
} }
@ -130,33 +129,18 @@ rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
{ {
uip_ds6_route_t *r; uip_ds6_route_t *r;
r = uip_ds6_route_list_head(); r = uip_ds6_route_head();
while(r != NULL) { while(r != NULL) {
if(uip_ipaddr_cmp(&r->nexthop, nexthop) && if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), nexthop) &&
r->state.dag == dag) { r->state.dag == dag) {
uip_ds6_route_rm(r); uip_ds6_route_rm(r);
r = uip_ds6_route_list_head(); r = uip_ds6_route_head();
} else { } else {
r = list_item_next(r); r = uip_ds6_route_next(r);
} }
} }
ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
#if 0
uip_ds6_route_t *locroute;
for(locroute = uip_ds6_routing_table;
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
locroute++) {
if(locroute->isused
&& uip_ipaddr_cmp(&locroute->nexthop, nexthop)
&& locroute->state.dag == dag) {
locroute->isused = 0;
}
}
ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
#endif /* 0 */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_route_t * uip_ds6_route_t *
@ -165,20 +149,11 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
{ {
uip_ds6_route_t *rep; uip_ds6_route_t *rep;
rep = uip_ds6_route_lookup(prefix); if((rep = uip_ds6_route_add(prefix, prefix_len, next_hop)) == NULL) {
if(rep == NULL) { PRINTF("RPL: No space for more route entries\n");
if((rep = uip_ds6_route_add(prefix, prefix_len, next_hop, 0)) == NULL) { return NULL;
PRINTF("RPL: No space for more route entries\n");
return NULL;
}
} else {
PRINTF("RPL: Updated the next hop for prefix ");
PRINT6ADDR(prefix);
PRINTF(" to ");
PRINT6ADDR(next_hop);
PRINTF("\n");
uip_ipaddr_copy(&rep->nexthop, next_hop);
} }
rep->state.dag = dag; rep->state.dag = dag;
rep->state.lifetime = RPL_LIFETIME(dag->instance, dag->instance->default_lifetime); rep->state.lifetime = RPL_LIFETIME(dag->instance, dag->instance->default_lifetime);
rep->state.learned_from = RPL_ROUTE_FROM_INTERNAL; rep->state.learned_from = RPL_ROUTE_FROM_INTERNAL;
@ -192,8 +167,8 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
return rep; return rep;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void void
rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx) rpl_link_neighbor_callback(const rimeaddr_t *addr, int status, int numtx)
{ {
uip_ipaddr_t ipaddr; uip_ipaddr_t ipaddr;
rpl_parent_t *parent; rpl_parent_t *parent;
@ -202,37 +177,20 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, (uip_lladdr_t *)addr); uip_ds6_set_addr_iid(&ipaddr, (uip_lladdr_t *)addr);
PRINTF("RPL: Neighbor ");
PRINT6ADDR(&ipaddr);
PRINTF(" is %sknown. ETX = %u\n", known ? "" : "no longer ", NEIGHBOR_INFO_FIX2ETX(etx));
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
if(instance->used == 1 ) { if(instance->used == 1 ) {
parent = rpl_find_parent_any_dag(instance, &ipaddr); parent = rpl_find_parent_any_dag(instance, &ipaddr);
if(parent != NULL) { if(parent != NULL) {
/* Trigger DAG rank recalculation. */ /* Trigger DAG rank recalculation. */
PRINTF("RPL: rpl_link_neighbor_callback triggering update\n");
parent->updated = 1; parent->updated = 1;
parent->link_metric = etx; if(instance->of->neighbor_link_callback != NULL) {
instance->of->neighbor_link_callback(parent, status, numtx);
if(instance->of->parent_state_callback != NULL) {
instance->of->parent_state_callback(parent, known, etx);
}
if(!known) {
PRINTF("RPL: Removing parent ");
PRINT6ADDR(&parent->addr);
PRINTF(" in instance %u because of bad connectivity (ETX %d)\n", instance->instance_id, etx);
parent->rank = INFINITE_RANK;
} }
} }
} }
} }
if(!known) {
PRINTF("RPL: Deleting routes installed by DAOs received from ");
PRINT6ADDR(&ipaddr);
PRINTF("\n");
uip_ds6_route_rm_by_nexthop(&ipaddr);
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
@ -242,18 +200,17 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
rpl_instance_t *instance; rpl_instance_t *instance;
rpl_instance_t *end; rpl_instance_t *end;
if(!nbr->isused) { PRINTF("RPL: Removing neighbor ");
PRINTF("RPL: Removing neighbor "); PRINT6ADDR(&nbr->ipaddr);
PRINT6ADDR(&nbr->ipaddr); PRINTF("\n");
PRINTF("\n"); for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { if(instance->used == 1 ) {
if(instance->used == 1 ) { p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
p = rpl_find_parent_any_dag(instance, &nbr->ipaddr); if(p != NULL) {
if(p != NULL) { p->rank = INFINITE_RANK;
p->rank = INFINITE_RANK; /* Trigger DAG rank recalculation. */
/* Trigger DAG rank recalculation. */ PRINTF("RPL: rpl_ipv6_neighbor_callback infinite rank\n");
p->updated = 1; p->updated = 1;
}
} }
} }
} }
@ -266,8 +223,8 @@ rpl_init(void)
PRINTF("RPL started\n"); PRINTF("RPL started\n");
default_instance = NULL; default_instance = NULL;
rpl_dag_init();
rpl_reset_periodic_timer(); rpl_reset_periodic_timer();
neighbor_info_subscribe(rpl_link_neighbor_callback);
/* add rpl multicast address */ /* add rpl multicast address */
uip_create_linklocal_rplnodes_mcast(&rplmaddr); uip_create_linklocal_rplnodes_mcast(&rplmaddr);

View file

@ -113,9 +113,8 @@ struct rpl_parent {
#if RPL_DAG_MC != RPL_DAG_MC_NONE #if RPL_DAG_MC != RPL_DAG_MC_NONE
rpl_metric_container_t mc; rpl_metric_container_t mc;
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
uip_ipaddr_t addr;
rpl_rank_t rank; rpl_rank_t rank;
uint8_t link_metric; uint16_t link_metric;
uint8_t dtsn; uint8_t dtsn;
uint8_t updated; uint8_t updated;
}; };
@ -157,7 +156,7 @@ typedef struct rpl_instance rpl_instance_t;
* Resets the objective function state for a specific DAG. This function is * Resets the objective function state for a specific DAG. This function is
* called when doing a global repair on the DAG. * called when doing a global repair on the DAG.
* *
* parent_state_callback(parent, known, etx) * neighbor_link_callback(parent, known, etx)
* *
* Receives link-layer neighbor information. The parameter "known" is set * Receives link-layer neighbor information. The parameter "known" is set
* either to 0 or 1. The "etx" parameter specifies the current * either to 0 or 1. The "etx" parameter specifies the current
@ -186,7 +185,7 @@ typedef struct rpl_instance rpl_instance_t;
*/ */
struct rpl_of { struct rpl_of {
void (*reset)(struct rpl_dag *); void (*reset)(struct rpl_dag *);
void (*parent_state_callback)(rpl_parent_t *, int, int); void (*neighbor_link_callback)(rpl_parent_t *, int, int);
rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *); rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *);
rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *); rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *);
rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t); rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t);
@ -243,5 +242,9 @@ int rpl_update_header_final(uip_ipaddr_t *addr);
int rpl_verify_header(int); int rpl_verify_header(int);
void rpl_remove_header(void); void rpl_remove_header(void);
uint8_t rpl_invert_header(void); uint8_t rpl_invert_header(void);
uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
uint16_t rpl_get_parent_link_metric(uip_lladdr_t *addr);
void rpl_dag_init(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* RPL_H */ #endif /* RPL_H */

View file

@ -65,7 +65,6 @@
#include "net/uip-ds6.h" #include "net/uip-ds6.h"
#include "net/rime.h" #include "net/rime.h"
#include "net/sicslowpan.h" #include "net/sicslowpan.h"
#include "net/neighbor-info.h"
#include "net/netstack.h" #include "net/netstack.h"
#if UIP_CONF_IPV6 #if UIP_CONF_IPV6
@ -113,11 +112,6 @@ void uip_log(char *msg);
#endif /* SICSLOWPAN_CONF_COMPRESSION */ #endif /* SICSLOWPAN_CONF_COMPRESSION */
#endif /* SICSLOWPAN_COMPRESSION */ #endif /* SICSLOWPAN_COMPRESSION */
#ifndef SICSLOWPAN_CONF_NEIGHBOR_INFO
/* Default is to use neighbor info updates if using RPL */
#define SICSLOWPAN_CONF_NEIGHBOR_INFO UIP_CONF_IPV6_RPL
#endif /* SICSLOWPAN_CONF_NEIGHBOR_INFO */
#define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1])) #define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1]))
#define SET16(ptr,index,value) do { \ #define SET16(ptr,index,value) do { \
(ptr)[index] = ((value) >> 8) & 0xff; \ (ptr)[index] = ((value) >> 8) & 0xff; \
@ -1309,9 +1303,8 @@ compress_hdr_ipv6(rimeaddr_t *rime_destaddr)
static void static void
packet_sent(void *ptr, int status, int transmissions) packet_sent(void *ptr, int status, int transmissions)
{ {
#if SICSLOWPAN_CONF_NEIGHBOR_INFO uip_ds6_link_neighbor_callback(status, transmissions);
neighbor_info_packet_sent(status, transmissions);
#endif /* SICSLOWPAN_CONF_NEIGHBOR_INFO */
if(callback != NULL) { if(callback != NULL) {
callback->output_callback(status); callback->output_callback(status);
} }
@ -1834,10 +1827,6 @@ input(void)
} }
#endif #endif
#if SICSLOWPAN_CONF_NEIGHBOR_INFO
neighbor_info_packet_received();
#endif /* SICSLOWPAN_CONF_NEIGHBOR_INFO */
/* if callback is set then set attributes and call */ /* if callback is set then set attributes and call */
if(callback) { if(callback) {
set_packet_attrs(); set_packet_attrs();

View file

@ -561,13 +561,22 @@ tcpip_ipv6_output(void)
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
/* Next hop determination */ /* Next hop determination */
nbr = NULL; nbr = NULL;
/* We first check if the destination address is on our immediate
link. If so, we simply use the destination address as our
nexthop address. */
if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){ if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){
nexthop = &UIP_IP_BUF->destipaddr; nexthop = &UIP_IP_BUF->destipaddr;
} else { } else {
uip_ds6_route_t* locrt; uip_ds6_route_t *route;
locrt = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr); /* Check if we have a route to the destination address. */
if(locrt == NULL) { route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
if((nexthop = uip_ds6_defrt_choose()) == NULL) {
/* No route was found - we send to the default route instead. */
if(route == NULL) {
PRINTF("tcpip_ipv6_output: no route found, using default route\n");
nexthop = uip_ds6_defrt_choose();
if(nexthop == NULL) {
#ifdef UIP_FALLBACK_INTERFACE #ifdef UIP_FALLBACK_INTERFACE
PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n",
uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40));
@ -585,23 +594,61 @@ tcpip_ipv6_output(void)
uip_len = 0; uip_len = 0;
return; return;
} }
} else { } else {
nexthop = &locrt->nexthop; /* A route was found, so we look up the nexthop neighbor for
the route. */
nexthop = uip_ds6_route_nexthop(route);
/* If the nexthop is dead, for example because the neighbor
never responded to link-layer acks, we drop its route. */
if(nexthop == NULL) {
#if UIP_CONF_IPV6_RPL
/* If we are running RPL, and if we are the root of the
network, we'll trigger a global repair berfore we remove
the route. */
rpl_dag_t *dag;
rpl_instance_t *instance;
dag = (rpl_dag_t *)route->state.dag;
if(dag != NULL) {
instance = dag->instance;
rpl_repair_root(instance->instance_id);
}
#endif /* UIP_CONF_RPL */
uip_ds6_route_rm(route);
/* We don't have a nexthop to send the packet to, so we drop
it. */
return;
}
} }
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS #if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
if(nexthop != NULL) { if(nexthop != NULL) {
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); static uint8_t annotate_last;
static uint8_t annotate_has_last = 0;
if(annotate_has_last) {
printf("#L %u 0; red\n", annotate_last);
}
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
annotate_last = nexthop->u8[sizeof(uip_ipaddr_t) - 1];
annotate_has_last = 1;
} }
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */ #endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
} }
/* End of next hop determination */ /* End of next hop determination */
#if UIP_CONF_IPV6_RPL #if UIP_CONF_IPV6_RPL
if(rpl_update_header_final(nexthop)) { if(rpl_update_header_final(nexthop)) {
uip_len = 0; uip_len = 0;
return; return;
} }
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
if((nbr = uip_ds6_nbr_lookup(nexthop)) == NULL) { nbr = uip_ds6_nbr_lookup(nexthop);
if(nbr == NULL) {
#if UIP_ND6_SEND_NA #if UIP_ND6_SEND_NA
if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
uip_len = 0; uip_len = 0;
@ -655,7 +702,7 @@ tcpip_ipv6_output(void)
} }
#endif /* UIP_ND6_SEND_NA */ #endif /* UIP_ND6_SEND_NA */
tcpip_output(&nbr->lladdr); tcpip_output(uip_ds6_nbr_get_ll(nbr));
#if UIP_CONF_IPV6_QUEUE_PKT #if UIP_CONF_IPV6_QUEUE_PKT
/* /*
@ -668,15 +715,15 @@ tcpip_ipv6_output(void)
uip_len = uip_packetqueue_buflen(&nbr->packethandle); uip_len = uip_packetqueue_buflen(&nbr->packethandle);
memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len); memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len);
uip_packetqueue_free(&nbr->packethandle); uip_packetqueue_free(&nbr->packethandle);
tcpip_output(&nbr->lladdr); tcpip_output(uip_ds6_nbr_get_ll(nbr));
} }
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/ #endif /*UIP_CONF_IPV6_QUEUE_PKT*/
uip_len = 0; uip_len = 0;
return; return;
} }
return;
} }
/* Multicast IP destination address. */ /* Multicast IP destination address. */
tcpip_output(NULL); tcpip_output(NULL);
uip_len = 0; uip_len = 0;

View file

@ -43,6 +43,10 @@
void void
uip_debug_ipaddr_print(const uip_ipaddr_t *addr) uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
{ {
if(addr == NULL || addr->u8 == NULL) {
printf("(NULL IP addr)");
return;
}
#if UIP_CONF_IPV6 #if UIP_CONF_IPV6
uint16_t a; uint16_t a;
unsigned int i; unsigned int i;

297
core/net/uip-ds6-nbr.c Normal file
View file

@ -0,0 +1,297 @@
/**
* \addtogroup uip6
* @{
*/
/*
* Copyright (c) 2013, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
*/
/**
* \file
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
* \author Mathilde Durvy <mdurvy@cisco.com>
* \author Julien Abeille <jabeille@cisco.com>
* \author Simon Duquennoy <simonduq@sics.se>
*
*/
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "lib/list.h"
#include "net/rime/rimeaddr.h"
#include "net/packetbuf.h"
#include "net/uip-ds6-nbr.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
#define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n)
void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n);
#else
#define NEIGHBOR_STATE_CHANGED(n)
#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */
#ifdef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK
#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx) UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK(addr, status, numtx)
void LINK_NEIGHBOR_CALLBACK(const rimeaddr_t *addr, int status, int numtx);
#else
#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx)
#endif /* UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK */
NBR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors);
/*---------------------------------------------------------------------------*/
void
uip_ds6_neighbors_init(void)
{
nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm);
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
uint8_t isrouter, uint8_t state)
{
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (rimeaddr_t*)lladdr);
if(nbr) {
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
nbr->isrouter = isrouter;
nbr->state = state;
#if UIP_CONF_IPV6_QUEUE_PKT
uip_packetqueue_new(&nbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
/* timers are set separately, for now we put them in expired state */
stimer_set(&nbr->reachable, 0);
stimer_set(&nbr->sendns, 0);
nbr->nscount = 0;
PRINTF("Adding neighbor with ip addr ");
PRINT6ADDR(ipaddr);
PRINTF(" link addr ");
PRINTLLADDR(lladdr);
PRINTF(" state %u\n", state);
NEIGHBOR_STATE_CHANGED(nbr);
return nbr;
} else {
PRINTF("uip_ds6_nbr_add drop ip addr ");
PRINT6ADDR(ipaddr);
PRINTF(" link addr (%p) ", lladdr);
PRINTLLADDR(lladdr);
PRINTF(" state %u\n", state);
return NULL;
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
{
if(nbr != NULL) {
#if UIP_CONF_IPV6_QUEUE_PKT
uip_packetqueue_free(&nbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
NEIGHBOR_STATE_CHANGED(nbr);
nbr_table_remove(ds6_neighbors, nbr);
}
return;
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_nbr_get_ipaddr(uip_ds6_nbr_t *nbr)
{
return (nbr != NULL) ? &nbr->ipaddr : NULL;
}
/*---------------------------------------------------------------------------*/
uip_lladdr_t *
uip_ds6_nbr_get_ll(uip_ds6_nbr_t *nbr)
{
return (uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
}
/*---------------------------------------------------------------------------*/
int
uip_ds6_nbr_num(void)
{
uip_ds6_nbr_t *nbr;
int num;
num = 0;
for(nbr = nbr_table_head(ds6_neighbors);
nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr)) {
num++;
}
return num;
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
{
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
if(ipaddr != NULL) {
while(nbr != NULL) {
if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
return nbr;
}
nbr = nbr_table_next(ds6_neighbors, nbr);
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr)
{
return nbr_table_get_from_lladdr(ds6_neighbors, (rimeaddr_t*)lladdr);
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_nbr_ipaddr_from_lladdr(uip_lladdr_t *lladdr)
{
uip_ds6_nbr_t *nbr = uip_ds6_nbr_ll_lookup(lladdr);
return nbr ? &nbr->ipaddr : NULL;
}
/*---------------------------------------------------------------------------*/
uip_lladdr_t *
uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr)
{
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
const rimeaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
return;
}
LINK_NEIGHBOR_CALLBACK(dest, status, numtx);
#if UIP_DS6_LL_NUD
if(status == MAC_TX_OK) {
uip_ds6_nbr_t *nbr;
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
if(nbr != NULL &&
(nbr->state == STALE || nbr->state == DELAY || nbr->state == PROBE)) {
nbr->state = REACHABLE;
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
PRINTF("uip-ds6-neighbor : received a link layer ACK : ");
PRINTLLADDR((uip_lladdr_t *)dest);
PRINTF(" is reachable.\n");
}
}
#endif /* UIP_DS6_LL_NUD */
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_neighbor_periodic(void)
{
/* Periodic processing on neighbors */
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
while(nbr != NULL) {
switch(nbr->state) {
case NBR_REACHABLE:
if(stimer_expired(&nbr->reachable)) {
PRINTF("REACHABLE: moving to STALE (");
PRINT6ADDR(&nbr->ipaddr);
PRINTF(")\n");
nbr->state = NBR_STALE;
}
break;
#if UIP_ND6_SEND_NA
case NBR_INCOMPLETE:
if(nbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
uip_ds6_nbr_rm(nbr);
} else if(stimer_expired(&nbr->sendns) && (uip_len == 0)) {
nbr->nscount++;
PRINTF("NBR_INCOMPLETE: NS %u\n", nbr->nscount);
uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr);
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
case NBR_DELAY:
if(stimer_expired(&nbr->reachable)) {
nbr->state = NBR_PROBE;
nbr->nscount = 0;
PRINTF("DELAY: moving to PROBE\n");
stimer_set(&nbr->sendns, 0);
}
break;
case NBR_PROBE:
if(nbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
uip_ds6_defrt_t *locdefrt;
PRINTF("PROBE END\n");
if((locdefrt = uip_ds6_defrt_lookup(&nbr->ipaddr)) != NULL) {
if (!locdefrt->isinfinite) {
uip_ds6_defrt_rm(locdefrt);
}
}
uip_ds6_nbr_rm(nbr);
} else if(stimer_expired(&nbr->sendns) && (uip_len == 0)) {
nbr->nscount++;
PRINTF("PROBE: NS %u\n", nbr->nscount);
uip_nd6_ns_output(NULL, &nbr->ipaddr, &nbr->ipaddr);
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
#endif /* UIP_ND6_SEND_NA */
default:
break;
}
nbr = nbr_table_next(ds6_neighbors, nbr);
}
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_get_least_lifetime_neighbor(void)
{
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
uip_ds6_nbr_t *nbr_expiring = NULL;
while(nbr != NULL) {
if(nbr_expiring != NULL) {
clock_time_t curr = stimer_remaining(&nbr->reachable);
if(curr < stimer_remaining(&nbr->reachable)) {
nbr_expiring = nbr;
}
} else {
nbr_expiring = nbr;
}
nbr = nbr_table_next(ds6_neighbors, nbr);
}
return nbr_expiring;
}

110
core/net/uip-ds6-nbr.h Normal file
View file

@ -0,0 +1,110 @@
/**
* \addtogroup uip6
* @{
*/
/*
* Copyright (c) 2013, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
*/
/**
* \file
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
* \author Mathilde Durvy <mdurvy@cisco.com>
* \author Julien Abeille <jabeille@cisco.com>
* \author Simon Duquennoy <simonduq@sics.se>
*
*/
#ifndef __UIP_DS6_NEIGHBOR_H__
#define __UIP_DS6_NEIGHBOR_H__
#include "net/uip.h"
#include "net/nbr-table.h"
#include "sys/stimer.h"
#include "net/uip-ds6.h"
#include "net/nbr-table.h"
#if UIP_CONF_IPV6_QUEUE_PKT
#include "net/uip-packetqueue.h"
#endif /*UIP_CONF_QUEUE_PKT */
/*--------------------------------------------------*/
/** \brief Possible states for the nbr cache entries */
#define NBR_INCOMPLETE 0
#define NBR_REACHABLE 1
#define NBR_STALE 2
#define NBR_DELAY 3
#define NBR_PROBE 4
NBR_TABLE_DECLARE(ds6_neighbors);
/** \brief An entry in the nbr cache */
typedef struct uip_ds6_nbr {
uip_ipaddr_t ipaddr;
struct stimer reachable;
struct stimer sendns;
uint8_t nscount;
uint8_t isrouter;
uint8_t state;
#if UIP_CONF_IPV6_QUEUE_PKT
struct uip_packetqueue_handle packethandle;
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
#endif /*UIP_CONF_QUEUE_PKT */
} uip_ds6_nbr_t;
void uip_ds6_neighbors_init(void);
/** \brief Neighbor Cache basic routines */
uip_ds6_nbr_t *uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
uint8_t isrouter, uint8_t state);
void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
uip_lladdr_t *uip_ds6_nbr_get_ll(uip_ds6_nbr_t *nbr);
uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(uip_ds6_nbr_t *nbr);
uip_ds6_nbr_t *uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr);
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
uip_ipaddr_t *uip_ds6_nbr_ipaddr_from_lladdr(uip_lladdr_t *lladdr);
uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr);
void uip_ds6_link_neighbor_callback(int status, int numtx);
void uip_ds6_neighbor_periodic(void);
int uip_ds6_nbr_num(void);
/**
* \brief
* This searches inside the neighbor table for the neighbor that is about to
* expire the next.
*
* \return
* A reference to the neighbor about to expire the next or NULL if
* table is empty.
*/
uip_ds6_nbr_t *uip_ds6_get_least_lifetime_neighbor(void);
#endif /* __UIP_DS6_NEIGHBOR_H__ */

View file

@ -34,14 +34,28 @@
#include "lib/list.h" #include "lib/list.h"
#include "lib/memb.h" #include "lib/memb.h"
#include "net/nbr-table.h"
#if UIP_CONF_IPV6 #if UIP_CONF_IPV6
#include <string.h> #include <string.h>
LIST(routelist); /* The nbr_routes holds a neighbor table to be able to maintain
information about what routes go through what neighbor. This
neighbor table is registered with the central nbr-table repository
so that it will be maintained along with the rest of the neighbor
tables in the system. */
NBR_TABLE(struct uip_ds6_route_neighbor_routes, nbr_routes);
/* Each route is repressented by a uip_ds6_route_t structure and
memory for each route is allocated from the routememb memory
block. These routes are maintained on lists of route entries that
are attached to each neighbor, via the nbr_routes neighbor
table. */
MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB); MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB);
/* Default routes are held on the defaultrouterlist and their
structures are allocated from the defaultroutermemb memory block.*/
LIST(defaultrouterlist); LIST(defaultrouterlist);
MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB); MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB);
@ -49,10 +63,41 @@ MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB);
LIST(notificationlist); LIST(notificationlist);
#endif #endif
static int num_routes = 0;
#undef DEBUG #undef DEBUG
#define DEBUG DEBUG_NONE #define DEBUG DEBUG_NONE
#include "net/uip-debug.h" #include "net/uip-debug.h"
static void rm_routelist_callback(nbr_table_item_t *ptr);
/*---------------------------------------------------------------------------*/
#if DEBUG != DEBUG_NONE
static void
assert_nbr_routes_list_sane(void)
{
uip_ds6_route_t *r;
int count;
/* Check if the route list has an infinite loop. */
for(r = uip_ds6_route_head(),
count = 0;
r != NULL &&
count < UIP_DS6_ROUTE_NB;
r = uip_ds6_route_next(r),
count++);
if(count >= UIP_DS6_ROUTE_NB) {
printf("uip-ds6-route.c: assert_nbr_routes_list_sane route list is in infinite loop\n");
}
/* Make sure that the route list has as many entries as the
num_routes vairable. */
if(count < num_routes) {
printf("uip-ds6-route.c: assert_nbr_routes_list_sane too few entries on route list: should be %d, is %d, max %d\n",
num_routes, count, UIP_CONF_MAX_ROUTES);
}
}
#endif /* DEBUG != DEBUG_NONE */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if UIP_DS6_NOTIFICATIONS #if UIP_DS6_NOTIFICATIONS
static void static void
@ -68,7 +113,7 @@ call_route_callback(int event, uip_ipaddr_t *route,
event == UIP_DS6_NOTIFICATION_DEFRT_RM) { event == UIP_DS6_NOTIFICATION_DEFRT_RM) {
num = list_length(defaultrouterlist); num = list_length(defaultrouterlist);
} else { } else {
num = list_length(routelist); num = num_routes;
} }
n->callback(event, route, nexthop, num); n->callback(event, route, nexthop, num);
} }
@ -95,7 +140,8 @@ void
uip_ds6_route_init(void) uip_ds6_route_init(void)
{ {
memb_init(&routememb); memb_init(&routememb);
list_init(routelist); nbr_table_register(nbr_routes,
(nbr_table_callback *)rm_routelist_callback);
memb_init(&defaultroutermemb); memb_init(&defaultroutermemb);
list_init(defaultrouterlist); list_init(defaultrouterlist);
@ -105,16 +151,66 @@ uip_ds6_route_init(void)
#endif #endif
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_route_t * static uip_lladdr_t *
uip_ds6_route_list_head(void) uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route)
{ {
return list_head(routelist); if(route != NULL) {
return (uip_lladdr_t *)nbr_table_get_lladdr(nbr_routes, route->routes);
} else {
return NULL;
}
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_route_nexthop(uip_ds6_route_t *route)
{
if(route != NULL) {
return uip_ds6_nbr_ipaddr_from_lladdr(uip_ds6_route_nexthop_lladdr(route));
} else {
return NULL;
}
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_head(void)
{
struct uip_ds6_route_neighbor_routes *routes;
routes = (struct uip_ds6_route_neighbor_routes *)nbr_table_head(nbr_routes);
if(routes != NULL) {
if(list_head(routes->route_list) == NULL) {
PRINTF("uip_ds6_route_head lead_head(nbr_route_list) is NULL\n");
}
return list_head(routes->route_list);
} else {
return NULL;
}
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_next(uip_ds6_route_t *r)
{
if(r != NULL) {
uip_ds6_route_t *n = list_item_next(r);
if(n != NULL) {
return n;
} else {
struct uip_ds6_route_neighbor_routes *routes;
routes = (struct uip_ds6_route_neighbor_routes *)
nbr_table_next(nbr_routes, r->routes);
if(routes != NULL) {
return list_head(routes->route_list);
}
}
}
return NULL;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
uip_ds6_route_num_routes(void) uip_ds6_route_num_routes(void)
{ {
return list_length(routelist); return num_routes;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_route_t * uip_ds6_route_t *
@ -131,22 +227,21 @@ uip_ds6_route_lookup(uip_ipaddr_t *addr)
found_route = NULL; found_route = NULL;
longestmatch = 0; longestmatch = 0;
for(r = list_head(routelist); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
if(r->length >= longestmatch && if(r->length >= longestmatch &&
uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
longestmatch = r->length; longestmatch = r->length;
found_route = r; found_route = r;
} }
} }
if(found_route != NULL) { if(found_route != NULL) {
PRINTF("uip-ds6-route: Found route:"); PRINTF("uip-ds6-route: Found route: ");
PRINT6ADDR(addr); PRINT6ADDR(addr);
PRINTF(" via "); PRINTF(" via ");
PRINT6ADDR(&found_route->nexthop); PRINT6ADDR(uip_ds6_route_nexthop(found_route));
PRINTF("\n"); PRINTF("\n");
} else { } else {
PRINTF("uip-ds6-route: No route found\n"); PRINTF("uip-ds6-route: No route found\n");
@ -157,10 +252,23 @@ uip_ds6_route_lookup(uip_ipaddr_t *addr)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_route_t * uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *nexthop, uint8_t metric) uip_ipaddr_t *nexthop)
{ {
uip_ds6_route_t *r; uip_ds6_route_t *r;
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
/* Get link-layer address of next hop, make sure it is in neighbor table */
uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
if(nexthop_lladdr == NULL) {
PRINTF("uip_ds6_route_add: neighbor link-local address unknown ");
PRINT6ADDR(ipaddr);
PRINTF("\n");
return NULL;
}
/* First make sure that we don't add a route twice. If we find an /* First make sure that we don't add a route twice. If we find an
existing route for our destination, we'll just update the old existing route for our destination, we'll just update the old
one. */ one. */
@ -170,23 +278,58 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
PRINT6ADDR(ipaddr); PRINT6ADDR(ipaddr);
PRINTF("\n"); PRINTF("\n");
} else { } else {
/* Allocate a routing entry and add the route to the list */ struct uip_ds6_route_neighbor_routes *routes;
/* If there is no routing entry, create one */
/* Every neighbor on our neighbor table holds a struct
uip_ds6_route_neighbor_routes which holds a list of routes that
go through the neighbor. We add our route entry to this list.
We first check to see if we already have this neighbor in our
nbr_route table. If so, the neighbor already has a route entry
list.
*/
routes = nbr_table_get_from_lladdr(nbr_routes,
(rimeaddr_t *)nexthop_lladdr);
if(routes == NULL) {
/* If the neighbor did not have an entry in our neighbor table,
we create one. The nbr_table_add_lladdr() function returns a
pointer to a pointer that we may use for our own purposes. We
initialize this pointer with the list of routing entries that
are attached to this neighbor. */
routes = nbr_table_add_lladdr(nbr_routes,
(rimeaddr_t *)nexthop_lladdr);
if(routes == NULL) {
PRINTF("uip_ds6_route_add: could not allocate a neighbor table entri for new route to ");
PRINT6ADDR(ipaddr);
PRINTF(", dropping it\n");
return NULL;
}
LIST_STRUCT_INIT(routes, route_list);
}
/* Allocate a routing entry and populate it. */
r = memb_alloc(&routememb); r = memb_alloc(&routememb);
if(r == NULL) { if(r == NULL) {
PRINTF("uip_ds6_route_add: could not allocate memory for new route to "); PRINTF("uip_ds6_route_add: could not allocate memory for new route to ");
PRINT6ADDR(ipaddr); PRINT6ADDR(ipaddr);
PRINTF(", dropping it\n"); PRINTF(", dropping it\n");
return NULL; return NULL;
} }
list_add(routelist, r);
PRINTF("uip_ds6_route_add num %d\n", list_length(routelist));
/* Add the route to this neighbor */
list_add(routes->route_list, r);
num_routes++;
PRINTF("uip_ds6_route_add num %d\n", num_routes);
r->routes = routes;
} }
uip_ipaddr_copy(&(r->ipaddr), ipaddr); uip_ipaddr_copy(&(r->ipaddr), ipaddr);
r->length = length; r->length = length;
uip_ipaddr_copy(&(r->nexthop), nexthop);
r->metric = metric;
#ifdef UIP_DS6_ROUTE_STATE_TYPE #ifdef UIP_DS6_ROUTE_STATE_TYPE
memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE)); memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
@ -203,6 +346,9 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop); call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
#endif #endif
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
return r; return r;
} }
@ -210,57 +356,97 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
void void
uip_ds6_route_rm(uip_ds6_route_t *route) uip_ds6_route_rm(uip_ds6_route_t *route)
{ {
uip_ds6_route_t *r; #if DEBUG != DEBUG_NONE
/* Make sure that the route is in the list before removing it. */ assert_nbr_routes_list_sane();
for(r = list_head(routelist); #endif /* DEBUG != DEBUG_NONE */
r != NULL; if(route != NULL && route->routes != NULL) {
r = list_item_next(r)) {
if(r == route) {
list_remove(routelist, route);
memb_free(&routememb, route);
PRINTF("uip_ds6_route_rm num %d\n", list_length(routelist)); PRINTF("uip_ds6_route_rm: removing route: ");
PRINT6ADDR(&route->ipaddr);
PRINTF("\n");
list_remove(route->routes->route_list, route);
if(list_head(route->routes->route_list) == NULL) {
/* If this was the only route using this neighbor, remove the
neibhor from the table */
PRINTF("uip_ds6_route_rm: removing neighbor too\n");
nbr_table_remove(nbr_routes, route->routes->route_list);
}
memb_free(&routememb, route);
num_routes--;
PRINTF("uip_ds6_route_rm num %d\n", num_routes);
#if UIP_DS6_NOTIFICATIONS #if UIP_DS6_NOTIFICATIONS
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
&route->ipaddr, &route->nexthop); &route->ipaddr, uip_ds6_route_nexthop(route));
#endif #endif
#if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE #if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
/* we need to check if this was the last route towards "nexthop" */ /* we need to check if this was the last route towards "nexthop" */
/* if so - remove that link (annotation) */ /* if so - remove that link (annotation) */
for(r = list_head(routelist); uip_ds6_route_t *r;
r != NULL; for(r = uip_ds6_route_head();
r = list_item_next(r)) { r != NULL;
if(uip_ipaddr_cmp(&r->nexthop, &route->nexthop)) { r = uip_ds6_route_next(r)) {
/* we found another link using the specific nexthop, so keep the #L */ uip_ipaddr_t *nextr, *nextroute;
return; nextr = uip_ds6_route_nexthop(r);
} nextroute = uip_ds6_route_nexthop(route);
if(nextr != NULL &&
nextroute != NULL &&
uip_ipaddr_cmp(nextr, nextroute)) {
/* we found another link using the specific nexthop, so keep the #L */
return;
} }
ANNOTATE("#L %u 0\n", route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]);
#endif
return;
} }
ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]);
#endif
} }
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
return;
}
/*---------------------------------------------------------------------------*/
static void
rm_routelist(struct uip_ds6_route_neighbor_routes *routes)
{
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
PRINTF("uip_ds6_route_rm_routelist\n");
if(routes != NULL && routes->route_list != NULL) {
uip_ds6_route_t *r;
r = list_head(routes->route_list);
while(r != NULL) {
uip_ds6_route_rm(r);
r = list_head(routes->route_list);
}
nbr_table_remove(nbr_routes, routes);
}
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
}
/*---------------------------------------------------------------------------*/
static void
rm_routelist_callback(nbr_table_item_t *ptr)
{
rm_routelist((struct uip_ds6_route_neighbor_routes *)ptr);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop) uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
{ {
uip_ds6_route_t *r; /* Get routing entry list of this neighbor */
uip_lladdr_t *nexthop_lladdr;
struct uip_ds6_route_neighbor_routes *routes;
r = list_head(routelist); nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
while(r != NULL) { routes = nbr_table_get_from_lladdr(nbr_routes,
if(uip_ipaddr_cmp(&r->nexthop, nexthop)) { (rimeaddr_t *)nexthop_lladdr);
list_remove(routelist, r); rm_routelist(routes);
#if UIP_DS6_NOTIFICATIONS
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
&r->ipaddr, &r->nexthop);
#endif
r = list_head(routelist);
} else {
r = list_item_next(r);
}
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_defrt_t * uip_ds6_defrt_t *
@ -268,6 +454,11 @@ uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{ {
uip_ds6_defrt_t *d; uip_ds6_defrt_t *d;
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
PRINTF("uip_ds6_defrt_add\n");
d = uip_ds6_defrt_lookup(ipaddr); d = uip_ds6_defrt_lookup(ipaddr);
if(d == NULL) { if(d == NULL) {
d = memb_alloc(&defaultroutermemb); d = memb_alloc(&defaultroutermemb);
@ -299,6 +490,10 @@ uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr); call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
#endif #endif
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
return d; return d;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -306,6 +501,11 @@ void
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt) uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
{ {
uip_ds6_defrt_t *d; uip_ds6_defrt_t *d;
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
/* Make sure that the defrt is in the list before we remove it. */ /* Make sure that the defrt is in the list before we remove it. */
for(d = list_head(defaultrouterlist); for(d = list_head(defaultrouterlist);
d != NULL; d != NULL;
@ -322,6 +522,10 @@ uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
return; return;
} }
} }
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_defrt_t * uip_ds6_defrt_t *

View file

@ -32,6 +32,8 @@
#ifndef UIP_DS6_ROUTE_H #ifndef UIP_DS6_ROUTE_H
#define UIP_DS6_ROUTE_H #define UIP_DS6_ROUTE_H
#include "lib/list.h"
void uip_ds6_route_init(void); void uip_ds6_route_init(void);
#ifndef UIP_CONF_UIP_DS6_NOTIFICATIONS #ifndef UIP_CONF_UIP_DS6_NOTIFICATIONS
@ -84,24 +86,32 @@ void uip_ds6_notification_rm(struct uip_ds6_notification *n);
/* Needed for the extended route entry state when using ContikiRPL */ /* Needed for the extended route entry state when using ContikiRPL */
typedef struct rpl_route_entry { typedef struct rpl_route_entry {
uint32_t lifetime; uint32_t lifetime;
uint32_t saved_lifetime;
void *dag; void *dag;
uint8_t learned_from; uint8_t learned_from;
uint8_t nopath_received;
} rpl_route_entry_t; } rpl_route_entry_t;
#endif /* UIP_DS6_ROUTE_STATE_TYPE */ #endif /* UIP_DS6_ROUTE_STATE_TYPE */
/** \brief The neighbor routes hold a list of routing table entries
that are attached to a specific neihbor. */
struct uip_ds6_route_neighbor_routes {
LIST_STRUCT(route_list);
};
/** \brief An entry in the routing table */ /** \brief An entry in the routing table */
typedef struct uip_ds6_route { typedef struct uip_ds6_route {
struct uip_ds6_route *next; struct uip_ds6_route *next;
/* Each route entry belongs to a specific neighbor. That neighbor
holds a list of all routing entries that go through it. The
routes field point to the uip_ds6_route_neighbor_routes that
belong to the neighbor table entry that this routing table entry
uses. */
struct uip_ds6_route_neighbor_routes *routes;
uip_ipaddr_t ipaddr; uip_ipaddr_t ipaddr;
uip_ipaddr_t nexthop;
uint8_t length;
uint8_t metric;
#ifdef UIP_DS6_ROUTE_STATE_TYPE #ifdef UIP_DS6_ROUTE_STATE_TYPE
UIP_DS6_ROUTE_STATE_TYPE state; UIP_DS6_ROUTE_STATE_TYPE state;
#endif #endif
uint8_t length;
} uip_ds6_route_t; } uip_ds6_route_t;
@ -130,12 +140,14 @@ void uip_ds6_defrt_periodic(void);
/** @{ */ /** @{ */
uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr); uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr);
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *next_hop, uint8_t metric); uip_ipaddr_t *next_hop);
void uip_ds6_route_rm(uip_ds6_route_t *route); void uip_ds6_route_rm(uip_ds6_route_t *route);
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop); void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
uip_ipaddr_t *uip_ds6_route_nexthop(uip_ds6_route_t *);
int uip_ds6_route_num_routes(void); int uip_ds6_route_num_routes(void);
uip_ds6_route_t *uip_ds6_route_list_head(void); uip_ds6_route_t *uip_ds6_route_head(void);
uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *);
/** @} */ /** @} */

View file

@ -53,13 +53,6 @@
#define DEBUG DEBUG_NONE #define DEBUG DEBUG_NONE
#include "net/uip-debug.h" #include "net/uip-debug.h"
#ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
#define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n)
void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n);
#else
#define NEIGHBOR_STATE_CHANGED(n)
#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */
struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */ struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */
#if UIP_CONF_ROUTER #if UIP_CONF_ROUTER
@ -76,10 +69,7 @@ static uint8_t rscount; /** \brief numbe
/** \name "DS6" Data structures */ /** \name "DS6" Data structures */
/** @{ */ /** @{ */
uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */ uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */
uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; /** \brief Neighor cache */
//uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */
uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */ uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */
//uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */
/* Used by Cooja to enable extraction of addresses from memory.*/ /* Used by Cooja to enable extraction of addresses from memory.*/
uint8_t uip_ds6_addr_size; uint8_t uip_ds6_addr_size;
@ -95,25 +85,21 @@ static uip_ds6_addr_t *locaddr;
static uip_ds6_maddr_t *locmaddr; static uip_ds6_maddr_t *locmaddr;
static uip_ds6_aaddr_t *locaaddr; static uip_ds6_aaddr_t *locaaddr;
static uip_ds6_prefix_t *locprefix; static uip_ds6_prefix_t *locprefix;
static uip_ds6_nbr_t *locnbr;
static uip_ds6_defrt_t *locdefrt;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uip_ds6_init(void) uip_ds6_init(void)
{ {
uip_ds6_neighbors_init();
uip_ds6_route_init(); uip_ds6_route_init();
PRINTF("Init of IPv6 data structures\n"); PRINTF("Init of IPv6 data structures\n");
PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n", PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n",
UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB, NBR_TABLE_MAX_NEIGHBORS, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB); UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
memset(uip_ds6_nbr_cache, 0, sizeof(uip_ds6_nbr_cache));
// memset(uip_ds6_defrt_list, 0, sizeof(uip_ds6_defrt_list));
memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list)); memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list));
memset(&uip_ds6_if, 0, sizeof(uip_ds6_if)); memset(&uip_ds6_if, 0, sizeof(uip_ds6_if));
// memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table));
uip_ds6_addr_size = sizeof(struct uip_ds6_addr); uip_ds6_addr_size = sizeof(struct uip_ds6_addr);
uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list); uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list);
@ -198,61 +184,7 @@ uip_ds6_periodic(void)
} }
#endif /* !UIP_CONF_ROUTER */ #endif /* !UIP_CONF_ROUTER */
/* Periodic processing on neighbors */ uip_ds6_neighbor_periodic();
for(locnbr = uip_ds6_nbr_cache;
locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB;
locnbr++) {
if(locnbr->isused) {
switch(locnbr->state) {
case NBR_REACHABLE:
if(stimer_expired(&locnbr->reachable)) {
PRINTF("REACHABLE: moving to STALE (");
PRINT6ADDR(&locnbr->ipaddr);
PRINTF(")\n");
locnbr->state = NBR_STALE;
}
break;
#if UIP_ND6_SEND_NA
case NBR_INCOMPLETE:
if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
uip_ds6_nbr_rm(locnbr);
} else if(stimer_expired(&locnbr->sendns) && (uip_len == 0)) {
locnbr->nscount++;
PRINTF("NBR_INCOMPLETE: NS %u\n", locnbr->nscount);
uip_nd6_ns_output(NULL, NULL, &locnbr->ipaddr);
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
case NBR_DELAY:
if(stimer_expired(&locnbr->reachable)) {
locnbr->state = NBR_PROBE;
locnbr->nscount = 0;
PRINTF("DELAY: moving to PROBE\n");
stimer_set(&locnbr->sendns, 0);
}
break;
case NBR_PROBE:
if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
PRINTF("PROBE END\n");
if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) != NULL) {
if (!locdefrt->isinfinite) {
uip_ds6_defrt_rm(locdefrt);
}
}
uip_ds6_nbr_rm(locnbr);
} else if(stimer_expired(&locnbr->sendns) && (uip_len == 0)) {
locnbr->nscount++;
PRINTF("PROBE: NS %u\n", locnbr->nscount);
uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr);
stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
#endif /* UIP_ND6_SEND_NA */
default:
break;
}
}
}
#if UIP_CONF_ROUTER & UIP_ND6_SEND_RA #if UIP_CONF_ROUTER & UIP_ND6_SEND_RA
/* Periodic RA sending */ /* Periodic RA sending */
@ -291,118 +223,6 @@ uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
return *out_element != NULL ? FREESPACE : NOSPACE; return *out_element != NULL ? FREESPACE : NOSPACE;
} }
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
uint8_t isrouter, uint8_t state)
{
int r;
r = uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
sizeof(uip_ds6_nbr_t), ipaddr, 128,
(uip_ds6_element_t **)&locnbr);
if(r == FREESPACE) {
locnbr->isused = 1;
uip_ipaddr_copy(&locnbr->ipaddr, ipaddr);
if(lladdr != NULL) {
memcpy(&locnbr->lladdr, lladdr, UIP_LLADDR_LEN);
} else {
memset(&locnbr->lladdr, 0, UIP_LLADDR_LEN);
}
locnbr->isrouter = isrouter;
locnbr->state = state;
#if UIP_CONF_IPV6_QUEUE_PKT
uip_packetqueue_new(&locnbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
/* timers are set separately, for now we put them in expired state */
stimer_set(&locnbr->reachable, 0);
stimer_set(&locnbr->sendns, 0);
locnbr->nscount = 0;
PRINTF("Adding neighbor with ip addr ");
PRINT6ADDR(ipaddr);
PRINTF("link addr ");
PRINTLLADDR((&(locnbr->lladdr)));
PRINTF("state %u\n", state);
NEIGHBOR_STATE_CHANGED(locnbr);
locnbr->last_lookup = clock_time();
return locnbr;
} else if(r == NOSPACE) {
/* We did not find any empty slot on the neighbor list, so we need
to remove one old entry to make room. */
uip_ds6_nbr_t *n, *oldest;
clock_time_t oldest_time;
oldest = NULL;
oldest_time = clock_time();
for(n = uip_ds6_nbr_cache;
n < &uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
n++) {
if(n->isused && !uip_ds6_defrt_lookup(&n->ipaddr)) {
if(n->last_lookup < oldest_time) {
oldest = n;
oldest_time = n->last_lookup;
}
}
}
if(oldest != NULL) {
uip_ds6_nbr_rm(oldest);
return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
}
}
PRINTF("uip_ds6_nbr_add drop\n");
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
{
if(nbr != NULL) {
nbr->isused = 0;
#if UIP_CONF_IPV6_QUEUE_PKT
uip_packetqueue_free(&nbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
NEIGHBOR_STATE_CHANGED(nbr);
}
return;
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_nbr_cache, UIP_DS6_NBR_NB,
sizeof(uip_ds6_nbr_t), ipaddr, 128,
(uip_ds6_element_t **)&locnbr) == FOUND) {
locnbr->last_lookup = clock_time();
return locnbr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr)
{
uip_ds6_nbr_t *fin;
for(locnbr = uip_ds6_nbr_cache, fin = locnbr + UIP_DS6_NBR_NB;
locnbr < fin;
++locnbr) {
if(locnbr->isused) {
if(!memcmp(lladdr, &locnbr->lladdr, UIP_LLADDR_LEN)) {
return locnbr;
}
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if UIP_CONF_ROUTER #if UIP_CONF_ROUTER
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -878,25 +698,5 @@ uip_ds6_compute_reachable_time(void)
UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time)); UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time));
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_get_least_lifetime_neighbor(void)
{
uip_ds6_nbr_t *nbr_expiring = NULL;
uint8_t i;
for(i = 0; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) {
if(nbr_expiring != NULL) {
clock_time_t curr = stimer_remaining(&uip_ds6_nbr_cache[i].reachable);
if(curr < stimer_remaining(&nbr_expiring->reachable)) {
nbr_expiring = &uip_ds6_nbr_cache[i];
}
} else {
nbr_expiring = &uip_ds6_nbr_cache[i];
}
}
}
return nbr_expiring;
}
/*---------------------------------------------------------------------------*/
/** @} */ /** @} */
#endif /* UIP_CONF_IPV6 */ #endif /* UIP_CONF_IPV6 */

View file

@ -47,6 +47,7 @@
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */ /* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
#include "net/uip-nd6.h" #include "net/uip-nd6.h"
#include "net/uip-ds6-route.h" #include "net/uip-ds6-route.h"
#include "net/uip-ds6-nbr.h"
/*--------------------------------------------------*/ /*--------------------------------------------------*/
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table, /** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
@ -56,14 +57,6 @@
* - the number of elements assigned by the system (name suffixed by _NBS) * - the number of elements assigned by the system (name suffixed by _NBS)
* - the total number of elements is the sum (name suffixed by _NB) * - the total number of elements is the sum (name suffixed by _NB)
*/ */
/* Neighbor cache */
#define UIP_DS6_NBR_NBS 0
#ifndef UIP_CONF_DS6_NBR_NBU
#define UIP_DS6_NBR_NBU 4
#else
#define UIP_DS6_NBR_NBU UIP_CONF_DS6_NBR_NBU
#endif
#define UIP_DS6_NBR_NB UIP_DS6_NBR_NBS + UIP_DS6_NBR_NBU
/* Default router list */ /* Default router list */
#define UIP_DS6_DEFRT_NBS 0 #define UIP_DS6_DEFRT_NBS 0
@ -126,14 +119,6 @@
#define UIP_DS6_LL_NUD UIP_CONF_DS6_LL_NUD #define UIP_DS6_LL_NUD UIP_CONF_DS6_LL_NUD
#endif #endif
/*--------------------------------------------------*/
/** \brief Possible states for the nbr cache entries */
#define NBR_INCOMPLETE 0
#define NBR_REACHABLE 1
#define NBR_STALE 2
#define NBR_DELAY 3
#define NBR_PROBE 4
/** \brief Possible states for the an address (RFC 4862) */ /** \brief Possible states for the an address (RFC 4862) */
#define ADDR_TENTATIVE 0 #define ADDR_TENTATIVE 0
#define ADDR_PREFERRED 1 #define ADDR_PREFERRED 1
@ -155,22 +140,6 @@
#if UIP_CONF_IPV6_QUEUE_PKT #if UIP_CONF_IPV6_QUEUE_PKT
#include "net/uip-packetqueue.h" #include "net/uip-packetqueue.h"
#endif /*UIP_CONF_QUEUE_PKT */ #endif /*UIP_CONF_QUEUE_PKT */
/** \brief An entry in the nbr cache */
typedef struct uip_ds6_nbr {
uint8_t isused;
uip_ipaddr_t ipaddr;
uip_lladdr_t lladdr;
struct stimer reachable;
struct stimer sendns;
clock_time_t last_lookup;
uint8_t nscount;
uint8_t isrouter;
uint8_t state;
#if UIP_CONF_IPV6_QUEUE_PKT
struct uip_packetqueue_handle packethandle;
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
#endif /*UIP_CONF_QUEUE_PKT */
} uip_ds6_nbr_t;
/** \brief A prefix list entry */ /** \brief A prefix list entry */
#if UIP_CONF_ROUTER #if UIP_CONF_ROUTER
@ -226,6 +195,11 @@ typedef struct uip_ds6_maddr {
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */ #endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
#if UIP_CONF_IPV6_RPL
#ifndef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK
#define UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK rpl_link_neighbor_callback
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
#endif /* UIP_CONF_IPV6_RPL */
/** \brief Interface structure (contains all the interface variables) */ /** \brief Interface structure (contains all the interface variables) */
@ -273,14 +247,6 @@ uint8_t uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
uint8_t ipaddrlen, uint8_t ipaddrlen,
uip_ds6_element_t **out_element); uip_ds6_element_t **out_element);
/** \name Neighbor Cache basic routines */
/** @{ */
uip_ds6_nbr_t *uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr,
uint8_t isrouter, uint8_t state);
void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
uip_ds6_nbr_t *uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr);
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
/** @} */ /** @} */
@ -371,15 +337,4 @@ uint32_t uip_ds6_compute_reachable_time(void); /** \brief compute random reachab
/** @} */ /** @} */
/** @} */ /** @} */
/**
* \brief
* This searches inside the neighbor table for the neighbor that is about to
* expire the next.
*
* \return
* A reference to the neighbor about to expire the next or NULL if
* table is empty.
*/
uip_ds6_nbr_t *uip_ds6_get_least_lifetime_neighbor(void);
#endif /* __UIP_DS6_H__ */ #endif /* __UIP_DS6_H__ */

View file

@ -191,9 +191,10 @@ uip_nd6_ns_input(void)
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
0, NBR_STALE); 0, NBR_STALE);
} else { } else {
uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr);
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
&nbr->lladdr, UIP_LLADDR_LEN) != 0) { lladdr, UIP_LLADDR_LEN) != 0) {
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN); UIP_LLADDR_LEN);
nbr->state = NBR_STALE; nbr->state = NBR_STALE;
} else { } else {
@ -460,20 +461,22 @@ uip_nd6_na_input(void)
PRINTF("NA received is bad\n"); PRINTF("NA received is bad\n");
goto discard; goto discard;
} else { } else {
uip_lladdr_t *lladdr;
nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr);
lladdr = uip_ds6_nbr_get_ll(nbr);
if(nbr == NULL) { if(nbr == NULL) {
goto discard; goto discard;
} }
if(nd6_opt_llao != 0) { if(nd6_opt_llao != 0) {
is_llchange = is_llchange =
memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)(&nbr->lladdr), memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)lladdr,
UIP_LLADDR_LEN); UIP_LLADDR_LEN);
} }
if(nbr->state == NBR_INCOMPLETE) { if(nbr->state == NBR_INCOMPLETE) {
if(nd6_opt_llao == NULL) { if(nd6_opt_llao == NULL) {
goto discard; goto discard;
} }
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN); UIP_LLADDR_LEN);
if(is_solicited) { if(is_solicited) {
nbr->state = NBR_REACHABLE; nbr->state = NBR_REACHABLE;
@ -496,7 +499,7 @@ uip_nd6_na_input(void)
if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange) if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange)
|| nd6_opt_llao == 0) { || nd6_opt_llao == 0) {
if(nd6_opt_llao != 0) { if(nd6_opt_llao != 0) {
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN); UIP_LLADDR_LEN);
} }
if(is_solicited) { if(is_solicited) {
@ -583,7 +586,7 @@ uip_nd6_rs_input(void)
#endif /*UIP_CONF_IPV6_CHECKS */ #endif /*UIP_CONF_IPV6_CHECKS */
switch (UIP_ND6_OPT_HDR_BUF->type) { switch (UIP_ND6_OPT_HDR_BUF->type) {
case UIP_ND6_OPT_SLLAO: case UIP_ND6_OPT_SLLAO:
nd6_opt_llao = UIP_ND6_OPT_HDR_BUF; nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
break; break;
default: default:
PRINTF("ND option not supported in RS\n"); PRINTF("ND option not supported in RS\n");
@ -602,14 +605,18 @@ uip_nd6_rs_input(void)
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
/* we need to add the neighbor */ /* we need to add the neighbor */
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
} else { } else {
/* If LL address changed, set neighbor state to stale */ /* If LL address changed, set neighbor state to stale */
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
&nbr->lladdr, UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) {
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], uip_ds6_nbr_t nbr_data = *nbr;
UIP_LLADDR_LEN); uip_ds6_nbr_rm(nbr);
nbr->state = NBR_STALE; nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
nbr->reachable = nbr_data.reachable;
nbr->sendns = nbr_data.sendns;
nbr->nscount = nbr_data.nscount;
} }
nbr->isrouter = 0; nbr->isrouter = 0;
} }

View file

@ -213,11 +213,6 @@
#define UIP_CONF_DS6_PREFIX_NBU 2 #define UIP_CONF_DS6_PREFIX_NBU 2
#endif #endif
#ifndef UIP_CONF_DS6_NBR_NBU
/** Default number of neighbors that can be stored in the %neighbor cache */
#define UIP_CONF_DS6_NBR_NBU 4
#endif
#ifndef UIP_CONF_DS6_DEFRT_NBU #ifndef UIP_CONF_DS6_DEFRT_NBU
/** Minimum number of default routers */ /** Minimum number of default routers */
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2

View file

@ -73,8 +73,8 @@
*/ */
/* Save some memory for the sky platform. */ /* Save some memory for the sky platform. */
#undef UIP_CONF_DS6_NBR_NBU #undef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 10 #define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#undef UIP_CONF_MAX_ROUTES #undef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 10 #define UIP_CONF_MAX_ROUTES 10

View file

@ -43,8 +43,6 @@
#define NETSTACK_CONF_RDC nullrdc_driver #define NETSTACK_CONF_RDC nullrdc_driver
/* #define NETSTACK_CONF_RDC contikimac_driver */ /* #define NETSTACK_CONF_RDC contikimac_driver */
#define CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS 7
#undef NULLRDC_CONF_802154_AUTOACK #undef NULLRDC_CONF_802154_AUTOACK
#define NULLRDC_CONF_802154_AUTOACK 1 #define NULLRDC_CONF_802154_AUTOACK 1
@ -56,8 +54,8 @@
#undef QUEUEBUF_CONF_NUM #undef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 4 #define QUEUEBUF_CONF_NUM 4
#undef UIP_CONF_DS6_NBR_NBU #undef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 7 #define NBR_TABLE_CONF_MAX_NEIGHBORS 7
#undef UIP_CONF_MAX_ROUTES #undef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 7 #define UIP_CONF_MAX_ROUTES 7

View file

@ -63,9 +63,6 @@
uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern long slip_sent; extern long slip_sent;
extern long slip_received; extern long slip_received;
@ -150,32 +147,34 @@ PT_THREAD(generate_routes(struct httpd_state *s))
{ {
static int i; static int i;
static uip_ds6_route_t *r; static uip_ds6_route_t *r;
static uip_ds6_nbr_t *nbr;
PSOCK_BEGIN(&s->sout); PSOCK_BEGIN(&s->sout);
SEND_STRING(&s->sout, TOP); SEND_STRING(&s->sout, TOP);
blen = 0; blen = 0;
ADD("Neighbors<pre>"); ADD("Neighbors<pre>");
for(i = 0; i < UIP_DS6_NBR_NB; i++) { for(nbr = nbr_table_head(ds6_neighbors);
if(uip_ds6_nbr_cache[i].isused) { nbr != NULL;
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); nbr = nbr_table_next(ds6_neighbors, nbr)) {
ADD("\n"); ipaddr_add(&nbr->ipaddr;);
if(blen > sizeof(buf) - 45) { ADD("\n");
SEND_STRING(&s->sout, buf); if(blen > sizeof(buf) - 45) {
blen = 0; SEND_STRING(&s->sout, buf);
} blen = 0;
} }
} }
ADD("</pre>Routes<pre>"); ADD("</pre>Routes<pre>");
SEND_STRING(&s->sout, buf); SEND_STRING(&s->sout, buf);
blen = 0; blen = 0;
for(r = uip_ds6_route_list_head(); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
ipaddr_add(&r->ipaddr); ipaddr_add(&r->ipaddr);
ADD("/%u (via ", r->length); ADD("/%u (via ", r->length);
ipaddr_add(&r->nexthop); ipaddr_add(uip_ds6_route_nexthop(r));
if(r->state.lifetime < 600) { if(r->state.lifetime < 600) {
ADD(") %lus\n", (unsigned long)r->state.lifetime); ADD(") %lus\n", (unsigned long)r->state.lifetime);
} else { } else {

View file

@ -56,8 +56,6 @@
uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
static uip_ipaddr_t prefix; static uip_ipaddr_t prefix;
static uint8_t prefix_set; static uint8_t prefix_set;
@ -149,6 +147,7 @@ PT_THREAD(generate_routes(struct httpd_state *s))
{ {
static int i; static int i;
static uip_ds6_route_t *r; static uip_ds6_route_t *r;
static uip_ds6_nbr_t *nbr;
#if BUF_USES_STACK #if BUF_USES_STACK
char buf[256]; char buf[256];
#endif #endif
@ -166,15 +165,17 @@ PT_THREAD(generate_routes(struct httpd_state *s))
blen = 0; blen = 0;
#endif #endif
ADD("Neighbors<pre>"); ADD("Neighbors<pre>");
for(i = 0; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr)) {
#if WEBSERVER_CONF_NEIGHBOR_STATUS #if WEBSERVER_CONF_NEIGHBOR_STATUS
#if BUF_USES_STACK #if BUF_USES_STACK
{char* j=bufptr+25; {char* j=bufptr+25;
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); ipaddr_add(&nbr->ipaddr);
while (bufptr < j) ADD(" "); while (bufptr < j) ADD(" ");
switch (uip_ds6_nbr_cache[i].state) { switch (nbr->state) {
case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_REACHABLE: ADD(" REACHABLE");break;
case NBR_STALE: ADD(" STALE");break; case NBR_STALE: ADD(" STALE");break;
@ -184,9 +185,9 @@ PT_THREAD(generate_routes(struct httpd_state *s))
} }
#else #else
{uint8_t j=blen+25; {uint8_t j=blen+25;
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); ipaddr_add(&nbr->ipaddr);
while (blen < j) ADD(" "); while (blen < j) ADD(" ");
switch (uip_ds6_nbr_cache[i].state) { switch (nbr->state) {
case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_REACHABLE: ADD(" REACHABLE");break;
case NBR_STALE: ADD(" STALE");break; case NBR_STALE: ADD(" STALE");break;
@ -196,7 +197,7 @@ PT_THREAD(generate_routes(struct httpd_state *s))
} }
#endif #endif
#else #else
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); ipaddr_add(&nbr->ipaddr);
#endif #endif
ADD("\n"); ADD("\n");
@ -211,7 +212,6 @@ PT_THREAD(generate_routes(struct httpd_state *s))
blen = 0; blen = 0;
} }
#endif #endif
}
} }
ADD("</pre>Routes<pre>"); ADD("</pre>Routes<pre>");
SEND_STRING(&s->sout, buf); SEND_STRING(&s->sout, buf);
@ -221,7 +221,7 @@ PT_THREAD(generate_routes(struct httpd_state *s))
blen = 0; blen = 0;
#endif #endif
for(r = uip_ds6_route_list_head(); r != NULL; r = list_item_next(r)) { for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) {
#if BUF_USES_STACK #if BUF_USES_STACK
#if WEBSERVER_CONF_ROUTE_LINKS #if WEBSERVER_CONF_ROUTE_LINKS
@ -247,7 +247,7 @@ PT_THREAD(generate_routes(struct httpd_state *s))
#endif #endif
#endif #endif
ADD("/%u (via ", r->length); ADD("/%u (via ", r->length);
ipaddr_add(&r->nexthop); ipaddr_add(uip_ds6_route_nexthop(r));
if(1 || (r->state.lifetime < 600)) { if(1 || (r->state.lifetime < 600)) {
ADD(") %lus\n", r->state.lifetime); ADD(") %lus\n", r->state.lifetime);
} else { } else {

View file

@ -31,7 +31,6 @@
#include "net/uip.h" #include "net/uip.h"
#include "net/uip-ds6.h" #include "net/uip-ds6.h"
#include "net/uip-udp-packet.h" #include "net/uip-udp-packet.h"
#include "net/neighbor-info.h"
#include "net/rpl/rpl.h" #include "net/rpl/rpl.h"
#include "dev/serial-line.h" #include "dev/serial-line.h"
#if CONTIKI_TARGET_Z1 #if CONTIKI_TARGET_Z1
@ -64,7 +63,6 @@ collect_common_set_sink(void)
/* A udp client can never become sink */ /* A udp client can never become sink */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
extern uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB];
void void
collect_common_net_print(void) collect_common_net_print(void)
@ -76,12 +74,12 @@ collect_common_net_print(void)
dag = rpl_get_any_dag(); dag = rpl_get_any_dag();
if(dag->preferred_parent != NULL) { if(dag->preferred_parent != NULL) {
PRINTF("Preferred parent: "); PRINTF("Preferred parent: ");
PRINT6ADDR(&dag->preferred_parent->addr); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
PRINTF("\n"); PRINTF("\n");
} }
for(r = uip_ds6_route_list_head(); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
PRINT6ADDR(&r->ipaddr); PRINT6ADDR(&r->ipaddr);
} }
PRINTF("---\n"); PRINTF("---\n");
@ -134,12 +132,12 @@ collect_common_send(void)
preferred_parent = dag->preferred_parent; preferred_parent = dag->preferred_parent;
if(preferred_parent != NULL) { if(preferred_parent != NULL) {
uip_ds6_nbr_t *nbr; uip_ds6_nbr_t *nbr;
nbr = uip_ds6_nbr_lookup(&preferred_parent->addr); nbr = uip_ds6_nbr_lookup(rpl_get_parent_ipaddr(preferred_parent));
if(nbr != NULL) { if(nbr != NULL) {
/* Use parts of the IPv6 address as the parent address, in reversed byte order. */ /* Use parts of the IPv6 address as the parent address, in reversed byte order. */
parent.u8[RIMEADDR_SIZE - 1] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 2]; parent.u8[RIMEADDR_SIZE - 1] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 2];
parent.u8[RIMEADDR_SIZE - 2] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]; parent.u8[RIMEADDR_SIZE - 2] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 1];
parent_etx = neighbor_info_get_metric((rimeaddr_t *) &nbr->lladdr) / 2; parent_etx = rpl_get_parent_rank((rimeaddr_t *) uip_ds6_nbr_get_ll(nbr)) / 2;
} }
} }
rtmetric = dag->rank; rtmetric = dag->rank;

View file

@ -131,3 +131,9 @@ uip_icmp6chksum(void)
{ {
return upper_layer_chksum(UIP_PROTO_ICMP6); return upper_layer_chksum(UIP_PROTO_ICMP6);
} }
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
}

View file

@ -33,8 +33,8 @@
/* Free some code and RAM space */ /* Free some code and RAM space */
#define UIP_CONF_TCP 0 #define UIP_CONF_TCP 0
#undef UIP_CONF_DS6_NBR_NBU #undef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 8 #define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#undef UIP_CONF_MAX_ROUTES #undef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 8 #define UIP_CONF_MAX_ROUTES 8

View file

@ -290,8 +290,6 @@ static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR = "<code>";
static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]"; static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]";
static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>"; static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>";
static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>"; static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>";
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
static unsigned short static unsigned short
@ -328,15 +326,16 @@ make_neighbors(void *p)
uint8_t i,j=0; uint8_t i,j=0;
uint16_t numprinted; uint16_t numprinted;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for (i=0; i<UIP_DS6_NBR_NB;i++) { uip_ds6_nbr_t *nbr;
if (uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
j++; nbr != NULL;
numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted); nbr = nbr_table_next(ds6_neighbors, nbr)) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb); j++;
} numprinted += httpd_cgi_sprint_ip6(nbr->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb);
} }
//if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); //if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,NBR_TABLE_MAX_NEIGHBORS-j);
return numprinted; return numprinted;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -358,15 +357,17 @@ static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>";
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>"; static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
uint8_t i,j=0; uint8_t i,j=0;
uint16_t numprinted; uint16_t numprinted;
uip_ds6_route_t *r;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for (i=0; i<UIP_DS6_ROUTE_NB;i++) { for(r = uip_ds6_route_head();
if (uip_ds6_routing_table[i].isused) { r != NULL;
r = uip_ds6_route_next(r)) {
j++; j++;
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r), uip_appdata + numprinted);
if(uip_ds6_routing_table[i].state.lifetime < 3600) { if(r->state.lifetime < 3600) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
} else { } else {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
} }

View file

@ -221,7 +221,7 @@ typedef unsigned short uip_stats_t;
/* 25 bytes per UDP connection */ /* 25 bytes per UDP connection */
#define UIP_CONF_UDP_CONNS 10 #define UIP_CONF_UDP_CONNS 10
/* See uip-ds6.h */ /* See uip-ds6.h */
#define UIP_CONF_DS6_NBR_NBU 20 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_PREFIX_NBU 3
#define UIP_CONF_MAX_ROUTES 20 #define UIP_CONF_MAX_ROUTES 20
@ -266,7 +266,7 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_MAX_CONNECTIONS 2 #define UIP_CONF_MAX_CONNECTIONS 2
#define UIP_CONF_MAX_LISTENPORTS 4 #define UIP_CONF_MAX_LISTENPORTS 4
#define UIP_CONF_UDP_CONNS 5 #define UIP_CONF_UDP_CONNS 5
#define UIP_CONF_DS6_NBR_NBU 20 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_PREFIX_NBU 3
#define UIP_CONF_MAX_ROUTES 4 #define UIP_CONF_MAX_ROUTES 4
@ -302,7 +302,7 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_MAX_CONNECTIONS 2 #define UIP_CONF_MAX_CONNECTIONS 2
#define UIP_CONF_MAX_LISTENPORTS 4 #define UIP_CONF_MAX_LISTENPORTS 4
#define UIP_CONF_UDP_CONNS 5 #define UIP_CONF_UDP_CONNS 5
#define UIP_CONF_DS6_NBR_NBU 4 #define NBR_TABLE_CONF_MAX_NEIGHBORS 4
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_PREFIX_NBU 3
#define UIP_CONF_MAX_ROUTES 4 #define UIP_CONF_MAX_ROUTES 4

View file

@ -419,6 +419,9 @@ ipaddr_add(const uip_ipaddr_t *addr)
int int
main(void) main(void)
{ {
#if UIP_CONF_IPV6
uip_ds6_nbr_t *nbr;
#endif /* UIP_CONF_IPV6 */
initialize(); initialize();
while(1) { while(1) {
@ -514,8 +517,6 @@ if ((clocktime%PINGS)==1) {
#if ROUTES && UIP_CONF_IPV6 #if ROUTES && UIP_CONF_IPV6
if ((clocktime%ROUTES)==2) { if ((clocktime%ROUTES)==2) {
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j; uint8_t i,j;
@ -526,13 +527,14 @@ extern uip_ds6_netif_t uip_ds6_if;
PRINTF("\n"); PRINTF("\n");
} }
} }
PRINTF("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB); PRINTF("\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); nbr != NULL;
PRINTF("\n"); nbr = nbr_table_next(ds6_neighbors, nbr)) {
j=0; ipaddr_add(&nbr->ipaddr);
} PRINTF("\n");
j=0;
} }
if (j) PRINTF(" <none>"); if (j) PRINTF(" <none>");
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
@ -540,17 +542,13 @@ extern uip_ds6_netif_t uip_ds6_if;
uip_ds6_route_t *r; uip_ds6_route_t *r;
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
j = 1; j = 1;
for(r = uip_ds6_route_list_head(); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
ipaddr_add(&r->ipaddr); ipaddr_add(&r->ipaddr);
PRINTF("/%u (via ", r->length); PRINTF("/%u (via ", r->length);
ipaddr_add(&r->nexthop); ipaddr_add(uip_ds6_route_nexthop(r));
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
PRINTF(") %lus\n", r->state.lifetime); PRINTF(") %lus\n", r->state.lifetime);
// } else {
// PRINTF(")\n");
// }
j = 0; j = 0;
} }
} }

View file

@ -291,8 +291,6 @@ static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR = "<code>";
static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]"; static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]";
static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>"; static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>";
static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>"; static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>";
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
static unsigned short static unsigned short
@ -328,16 +326,18 @@ make_neighbors(void *p)
{ {
uint8_t i,j=0; uint8_t i,j=0;
uint16_t numprinted; uint16_t numprinted;
uip_ds6_nbr_t *nbr;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for (i=0; i<UIP_DS6_NBR_NB;i++) { for(nbr = nbr_table_head(ds6_neighbors);
if (uip_ds6_nbr_cache[i].isused) { nbr != NULL;
j++; nbr = nbr_table_next(ds6_neighbors, nbr)) {
numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted); j++;
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb); numprinted += httpd_cgi_sprint_ip6(nbr->ipaddr, uip_appdata + numprinted);
} numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb);
} }
//if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); //if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,NBR_TABLE_MAX_NEIGHBORS-j);
return numprinted; return numprinted;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -362,13 +362,13 @@ make_routes(void *p)
uip_ds6_route_t *r; uip_ds6_route_t *r;
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
for(r = uip_ds6_route_list_head(); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
j++; j++;
numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted); numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r), uip_appdata + numprinted);
if(r->state.lifetime < 3600) { if(r->state.lifetime < 3600) {
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
} else { } else {

View file

@ -238,7 +238,7 @@ typedef unsigned short uip_stats_t;
/* 25 bytes per UDP connection */ /* 25 bytes per UDP connection */
#define UIP_CONF_UDP_CONNS 10 #define UIP_CONF_UDP_CONNS 10
/* See uip-ds6.h */ /* See uip-ds6.h */
#define UIP_CONF_DS6_NBR_NBU 20 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_PREFIX_NBU 3
#define UIP_CONF_MAX_ROUTES 20 #define UIP_CONF_MAX_ROUTES 20
@ -281,7 +281,7 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_MAX_CONNECTIONS 2 #define UIP_CONF_MAX_CONNECTIONS 2
#define UIP_CONF_MAX_LISTENPORTS 2 #define UIP_CONF_MAX_LISTENPORTS 2
#define UIP_CONF_UDP_CONNS 4 #define UIP_CONF_UDP_CONNS 4
#define UIP_CONF_DS6_NBR_NBU 10 #define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 2 #define UIP_CONF_DS6_PREFIX_NBU 2
#define UIP_CONF_MAX_ROUTES 4 #define UIP_CONF_MAX_ROUTES 4
@ -314,7 +314,7 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_MAX_CONNECTIONS 2 #define UIP_CONF_MAX_CONNECTIONS 2
#define UIP_CONF_MAX_LISTENPORTS 4 #define UIP_CONF_MAX_LISTENPORTS 4
#define UIP_CONF_UDP_CONNS 5 #define UIP_CONF_UDP_CONNS 5
#define UIP_CONF_DS6_NBR_NBU 4 #define NBR_TABLE_CONF_MAX_NEIGHBORS 4
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_PREFIX_NBU 3
#define UIP_CONF_MAX_ROUTES 4 #define UIP_CONF_MAX_ROUTES 4

View file

@ -429,6 +429,9 @@ ipaddr_add(const uip_ipaddr_t *addr)
int int
main(void) main(void)
{ {
#if UIP_CONF_IPV6
uip_ds6_nbr_t *nbr;
#endif /* UIP_CONF_IPV6 */
initialize(); initialize();
while(1) { while(1) {
@ -510,8 +513,6 @@ if ((clocktime%PINGS)==1) {
#if ROUTES && UIP_CONF_IPV6 #if ROUTES && UIP_CONF_IPV6
if ((clocktime%ROUTES)==2) { if ((clocktime%ROUTES)==2) {
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j; uint8_t i,j;
@ -522,30 +523,26 @@ extern uip_ds6_netif_t uip_ds6_if;
PRINTF("\n"); PRINTF("\n");
} }
} }
PRINTF("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB); PRINTF("\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) { for(nbr = nbr_table_head(ds6_neighbors);
if(uip_ds6_nbr_cache[i].isused) { nbr != NULL;
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); nbr = nbr_table_next(ds6_neighbors, nbr)) {
PRINTF("\n"); ipaddr_add(&nbr->ipaddr);
j=0; PRINTF("\n");
} j=0;
} }
if (j) PRINTF(" <none>"); if (j) PRINTF(" <none>");
{ {
uip_ds6_route_t *r; uip_ds6_route_t *r;
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
j = 1; j = 1;
for(r = uip_ds6_route_list_head(); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
ipaddr_add(&r->ipaddr); ipaddr_add(&r->ipaddr);
PRINTF("/%u (via ", r->length); PRINTF("/%u (via ", r->length);
ipaddr_add(&r->nexthop); ipaddr_add(uip_ds6_route_nexthop(r));
// if(uip_ds6_routing_table[i].state.lifetime < 600) { PRINTF(") %lus\n", r->state.lifetime);
PRINTF(") %lus\n", r->state.lifetime);
// } else {
// PRINTF(")\n");
// }
j = 0; j = 0;
} }
} }

View file

@ -579,11 +579,10 @@ void menu_process(char c)
#if UIP_CONF_IPV6_RPL #if UIP_CONF_IPV6_RPL
#include "rpl.h" #include "rpl.h"
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
case 'N': case 'N':
{ uint8_t i,j; { uint8_t i,j;
uip_ds6_nbr_t *nbr;
PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB); PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) { for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) { if (uip_ds6_if.addr_list[i].isused) {
@ -591,21 +590,24 @@ extern uip_ds6_netif_t uip_ds6_if;
PRINTF_P(PSTR("\n\r")); PRINTF_P(PSTR("\n\r"));
} }
} }
PRINTF_P(PSTR("\n\rNeighbors [%u max]\n\r"),UIP_DS6_NBR_NB); PRINTF_P(PSTR("\n\rNeighbors [%u max]\n\r"),NBR_TABLE_MAX_NEIGHBORS);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); nbr != NULL;
PRINTF_P(PSTR("\n\r")); nbr = nbr_table_next(ds6_neighbors, nbr)) {
j=0; ipaddr_add(&nbr->ipaddr);
} PRINTF_P(PSTR("\n\r"));
j=0;
} }
if (j) PRINTF_P(PSTR(" <none>")); if (j) PRINTF_P(PSTR(" <none>"));
PRINTF_P(PSTR("\n\rRoutes [%u max]\n\r"),UIP_DS6_ROUTE_NB); PRINTF_P(PSTR("\n\rRoutes [%u max]\n\r"),UIP_DS6_ROUTE_NB);
uip_ds6_route_t *route; uip_ds6_route_t *route;
for(route = uip_ds6_route_list_head(),j=1; route != NULL; route = list_item_next(route)) { for(route = uip_ds6_route_head();
route != NULL;
route = uip_ds6_route_next(r)) {
ipaddr_add(&route->ipaddr); ipaddr_add(&route->ipaddr);
PRINTF_P(PSTR("/%u (via "), route->length); PRINTF_P(PSTR("/%u (via "), route->length);
ipaddr_add(&route->nexthop); ipaddr_add(uip_ds6_route_nexthop(route));
if(route->state.lifetime < 600) { if(route->state.lifetime < 600) {
PRINTF_P(PSTR(") %lus\n\r"), route->state.lifetime); PRINTF_P(PSTR(") %lus\n\r"), route->state.lifetime);
} else { } else {

View file

@ -232,7 +232,7 @@ extern void mac_log_802_15_4_rx(const uint8_t* buffer, size_t total_len);
#endif /* UIP_CONF_IPV6 */ #endif /* UIP_CONF_IPV6 */
/* See uip-ds6.h */ /* See uip-ds6.h */
#define UIP_CONF_DS6_NBR_NBU 2 #define NBR_TABLE_CONF_MAX_NEIGHBORS 2
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_PREFIX_NBU 3
#define UIP_CONF_MAX_ROUTES 2 #define UIP_CONF_MAX_ROUTES 2
@ -360,8 +360,8 @@ typedef unsigned short uip_stats_t;
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 #define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8
#undef QUEUEBUF_CONF_NUM #undef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8 #define QUEUEBUF_CONF_NUM 8
#undef UIP_CONF_DS6_NBR_NBU #undef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 5 #define NBR_TABLE_CONF_MAX_NEIGHBORS 5
#undef UIP_CONF_MAX_ROUTES #undef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 5 #define UIP_CONF_MAX_ROUTES 5
@ -409,7 +409,7 @@ typedef unsigned short uip_stats_t;
#endif #endif
#define RPL_CONF_STATS 0 #define RPL_CONF_STATS 0
#define UIP_CONF_BUFFER_SIZE 1300 #define UIP_CONF_BUFFER_SIZE 1300
//#define UIP_CONF_DS6_NBR_NBU 12 //#define NBR_TABLE_CONF_MAX_NEIGHBORS 12
//#define UIP_CONF_MAX_ROUTES 12 //#define UIP_CONF_MAX_ROUTES 12
#ifdef RPL_BORDER_ROUTER #ifdef RPL_BORDER_ROUTER
@ -446,8 +446,8 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_TCP 1 #define UIP_CONF_TCP 1
#define UIP_CONF_TCP_MSS 48 #define UIP_CONF_TCP_MSS 48
#define UIP_CONF_RECEIVE_WINDOW 48 #define UIP_CONF_RECEIVE_WINDOW 48
#undef UIP_CONF_DS6_NBR_NBU #undef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 5 #define NBR_TABLE_CONF_MAX_NEIGHBORS 5
#undef UIP_CONF_MAX_ROUTES #undef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 5 #define UIP_CONF_MAX_ROUTES 5
#undef UIP_CONF_MAX_CONNECTIONS #undef UIP_CONF_MAX_CONNECTIONS

View file

@ -652,12 +652,12 @@ if ((rtime%PINGS)==1) {
#if ROUTES && UIP_CONF_IPV6_RPL #if ROUTES && UIP_CONF_IPV6_RPL
if ((rtime%ROUTES)==2) { if ((rtime%ROUTES)==2) {
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j; uint8_t i,j;
uip_ds6_nbr_t *nbr;
PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) { for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) { if (uip_ds6_if.addr_list[i].isused) {
@ -665,23 +665,27 @@ extern uip_ds6_netif_t uip_ds6_if;
PRINTA("\n"); PRINTA("\n");
} }
} }
PRINTA("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB); PRINTA("\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr); nbr != NULL;
PRINTA("\n"); nbr = nbr_table_next(ds6_neighbors, nbr)) {
j=0; uip_debug_ipaddr_print(&nbr->ipaddr);
} PRINTA("\n");
j=0;
} }
if (j) PRINTA(" <none>"); if (j) PRINTA(" <none>");
PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { uip_ds6_route_t *r;
if(uip_ds6_routing_table[i].isused) { for(r = uip_ds6_route_head();
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr); r != NULL;
PRINTA("/%u (via ", uip_ds6_routing_table[i].length); r = uip_ds6_route_next(r)) {
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop); if(r->isused) {
// if(uip_ds6_routing_table[i].state.lifetime < 600) { uip_debug_ipaddr_print(&r->ipaddr);
PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime); PRINTA("/%u (via ", r->length);
uip_debug_ipaddr_print(uip_ds6_route_nexthop(r));
// if(r->state.lifetime < 600) {
PRINTA(") %lus\n", r->state.lifetime);
// } else { // } else {
// PRINTA(")\n"); // PRINTA(")\n");
// } // }

View file

@ -243,10 +243,6 @@ ipaddr_add(const uip_ipaddr_t *addr)
const char TOP1[] PROGMEM = "<html><head><title>ContikiRPL(Jackdaw)"; const char TOP1[] PROGMEM = "<html><head><title>ContikiRPL(Jackdaw)";
const char TOP2[] PROGMEM = "</title></head><body>"; const char TOP2[] PROGMEM = "</title></head><body>";
const char BOTTOM[] PROGMEM = "</body></html>"; const char BOTTOM[] PROGMEM = "</body></html>";
#if UIP_CONF_IPV6
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
#endif
static static
PT_THREAD(generate_routes(struct httpd_state *s)) PT_THREAD(generate_routes(struct httpd_state *s))
@ -259,30 +255,33 @@ PT_THREAD(generate_routes(struct httpd_state *s))
#if UIP_CONF_IPV6 //allow ip4 builds #if UIP_CONF_IPV6 //allow ip4 builds
blen = 0; blen = 0;
ADD("<h2>Neighbors [%u max]</h2>",UIP_DS6_NBR_NB); ADD("<h2>Neighbors [%u max]</h2>",NBR_TABLE_CONF_MAX_NEIGHBORS);
PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf);
blen = 0; blen = 0;
for(i = 0; i < UIP_DS6_NBR_NB; i++) { uip_ds6_nbr_t *nbr;
if(uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr)) {
ipaddr_add(&nbr->ipaddr);
ADD("<br>"); ADD("<br>");
// if(blen > sizeof(buf) - 45) { // if(blen > sizeof(buf) - 45) {
PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf);
blen = 0; blen = 0;
// } // }
}
} }
ADD("<h2>Routes [%u max]</h2>",UIP_DS6_ROUTE_NB); ADD("<h2>Routes [%u max]</h2>",UIP_DS6_ROUTE_NB);
PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf);
blen = 0; blen = 0;
uip_ds6_route_t *route; uip_ds6_route_t *route;
for(route = uip_ds6_route_list_head(); route != NULL; route = list_item_next(route)) { for(route = uip_ds6_route_head();
route != NULL;
route = uip_ds6_route_next(route)) {
ipaddr_add(&route->ipaddr); ipaddr_add(&route->ipaddr);
ADD("/%u (via ", route->length); ADD("/%u (via ", route->length);
PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf);
blen=0; blen=0;
ipaddr_add(&route->nexthop); ipaddr_add(uip_ds6_route_nexthop(route));
if(route->state.lifetime < 600) { if(route->state.lifetime < 600) {
PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf); PSOCK_GENERATOR_SEND(&s->sout, generate_string, buf);
blen=0; blen=0;

View file

@ -123,7 +123,6 @@ void clock_adjust_ticks(clock_time_t howmany);
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#if UIP_CONF_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined #if UIP_CONF_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined
#define UIP_CONF_ICMP6 1 #define UIP_CONF_ICMP6 1

View file

@ -163,7 +163,6 @@ void clock_adjust_ticks(clock_time_t howmany);
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_UDP_CHECKSUMS 1 #define UIP_CONF_UDP_CHECKSUMS 1
#define UIP_CONF_TCP_SPLIT 1 #define UIP_CONF_TCP_SPLIT 1

View file

@ -232,8 +232,8 @@
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000
#define UIP_CONF_ND6_RETRANS_TIMER 10000 #define UIP_CONF_ND6_RETRANS_TIMER 10000
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 4 /* Handle n Neighbors */ #define NBR_TABLE_CONF_MAX_NEIGHBORS 4 /* Handle n Neighbors */
#endif #endif
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 4 /* Handle n Routes */ #define UIP_CONF_MAX_ROUTES 4 /* Handle n Routes */

View file

@ -69,7 +69,6 @@ static int8_t len;
#define REQUEST_TYPE_TOTALS 0xFF #define REQUEST_TYPE_TOTALS 0xFF
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
extern uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
static uip_ds6_route_t *rt; static uip_ds6_route_t *rt;
static uip_ds6_defrt_t *defrt; static uip_ds6_defrt_t *defrt;
static uip_ipaddr_t *addr; static uip_ipaddr_t *addr;
@ -82,6 +81,7 @@ process_request() CC_NON_BANKED
uint8_t i; uint8_t i;
uint8_t left; uint8_t left;
uint8_t entry_size; uint8_t entry_size;
uip_ds6_nbr_t *nbr;
left = VIZTOOL_MAX_PAYLOAD_LEN - 1; left = VIZTOOL_MAX_PAYLOAD_LEN - 1;
len = 2; /* start filling the buffer from position [2] */ len = 2; /* start filling the buffer from position [2] */
@ -89,46 +89,44 @@ process_request() CC_NON_BANKED
if(buf[0] == REQUEST_TYPE_ND) { if(buf[0] == REQUEST_TYPE_ND) {
/* Neighbors */ /* Neighbors */
PRINTF("Neighbors\n"); PRINTF("Neighbors\n");
for(i = buf[1]; i < UIP_DS6_NBR_NB; i++) { for(nbr = nbr_table_head(ds6_neighbors);
if(uip_ds6_nbr_cache[i].isused) { nbr != NULL;
entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t) nbr = nbr_table_next(ds6_neighbors, nbr)) {
+ sizeof(uip_ds6_nbr_cache[i].state); entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t)
PRINTF("%02u: ", i); + sizeof(nbr->state);
PRINT6ADDR(&uip_ds6_nbr_cache[i].ipaddr); PRINTF("%02u: ", i);
PRINTF(" - "); PRINT6ADDR(&nbr->ipaddr);
PRINTLLADDR(&uip_ds6_nbr_cache[i].lladdr); PRINTF(" - ");
PRINTF(" - %u\n", uip_ds6_nbr_cache[i].state); PRINTLLADDR(&nbr->lladdr);
PRINTF(" - %u\n", nbr->state);
memcpy(buf + len, &i, sizeof(i)); memcpy(buf + len, &i, sizeof(i));
len += sizeof(i); len += sizeof(i);
memcpy(buf + len, &uip_ds6_nbr_cache[i].ipaddr, sizeof(uip_ipaddr_t)); memcpy(buf + len, uip_ds6_nbr_get_ipaddr(nbr), sizeof(uip_ipaddr_t));
len += sizeof(uip_ipaddr_t); len += sizeof(uip_ipaddr_t);
memcpy(buf + len, &uip_ds6_nbr_cache[i].lladdr, sizeof(uip_lladdr_t)); memcpy(buf + len, uip_ds6_nbr_get_ll(nbr), sizeof(uip_lladdr_t));
len += sizeof(uip_lladdr_t); len += sizeof(uip_lladdr_t);
memcpy(buf + len, &uip_ds6_nbr_cache[i].state, memcpy(buf + len, &nbr->state,
sizeof(uip_ds6_nbr_cache[i].state)); sizeof(nbr->state));
len += sizeof(uip_ds6_nbr_cache[i].state); len += sizeof(nbr->state);
count++; count++;
left -= entry_size; left -= entry_size;
if(left < entry_size) { if(left < entry_size) {
break; break;
}
} }
} }
} else if(buf[0] == REQUEST_TYPE_RT) { } else if(buf[0] == REQUEST_TYPE_RT) {
uint32_t flip = 0; uint32_t flip = 0;
PRINTF("Routing table\n"); PRINTF("Routing table\n");
rt = uip_ds6_route_list_head(); rt = uip_ds6_route_head();
for(i = buf[1]; i < uip_ds6_route_num_routes(); i++) { for(i = buf[1]; i < uip_ds6_route_num_routes(); i++) {
if(rt != NULL) { if(rt != NULL) {
entry_size = sizeof(i) + sizeof(rt->ipaddr) entry_size = sizeof(i) + sizeof(rt->ipaddr)
+ sizeof(rt->length) + sizeof(rt->length)
+ sizeof(rt->metric)
+ sizeof(rt->nexthop)
+ sizeof(rt->state.lifetime) + sizeof(rt->state.lifetime)
+ sizeof(rt->state.learned_from); + sizeof(rt->state.learned_from);
@ -138,16 +136,11 @@ process_request() CC_NON_BANKED
len += sizeof(rt->ipaddr); len += sizeof(rt->ipaddr);
memcpy(buf + len, &rt->length, sizeof(rt->length)); memcpy(buf + len, &rt->length, sizeof(rt->length));
len += sizeof(rt->length); len += sizeof(rt->length);
memcpy(buf + len, &rt->metric, sizeof(rt->metric));
len += sizeof(rt->metric);
memcpy(buf + len, &rt->nexthop, sizeof(rt->nexthop));
len += sizeof(rt->nexthop);
PRINT6ADDR(&rt->ipaddr); PRINT6ADDR(&rt->ipaddr);
PRINTF(" - %02x", rt->length); PRINTF(" - %02x", rt->length);
PRINTF(" - %02x", rt->metric);
PRINTF(" - "); PRINTF(" - ");
PRINT6ADDR(&rt->nexthop); PRINT6ADDR(uip_ds6_route_nexthop(rt));
flip = uip_htonl(rt->state.lifetime); flip = uip_htonl(rt->state.lifetime);
memcpy(buf + len, &flip, sizeof(flip)); memcpy(buf + len, &flip, sizeof(flip));
@ -163,7 +156,7 @@ process_request() CC_NON_BANKED
count++; count++;
left -= entry_size; left -= entry_size;
rt = list_item_next(rt); rt = uip_ds6_route_next(rt);
if(left < entry_size) { if(left < entry_size) {
break; break;
@ -226,10 +219,10 @@ process_request() CC_NON_BANKED
buf[2]++; buf[2]++;
} }
} }
for(i = 0; i < UIP_DS6_NBR_NB; i++) { for(nbr = nbr_table_head(ds6_neighbors);
if(uip_ds6_nbr_cache[i].isused) { nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr)) {
buf[3]++; buf[3]++;
}
} }
buf[4] = uip_ds6_route_num_routes(); buf[4] = uip_ds6_route_num_routes();

View file

@ -341,8 +341,8 @@ typedef uint32_t rtimer_clock_t;
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000
#define UIP_CONF_ND6_RETRANS_TIMER 10000 #define UIP_CONF_ND6_RETRANS_TIMER 10000
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 20 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20
#endif #endif
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 20 #define UIP_CONF_MAX_ROUTES 20

View file

@ -129,9 +129,9 @@
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 300 #define NBR_TABLE_CONF_MAX_NEIGHBORS 300
#endif /* UIP_CONF_DS6_NBR_NBU */ #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 300 #define UIP_CONF_MAX_ROUTES 300
#endif /* UIP_CONF_MAX_ROUTES */ #endif /* UIP_CONF_MAX_ROUTES */
@ -145,7 +145,6 @@
#define RIMEADDR_CONF_SIZE 8 #define RIMEADDR_CONF_SIZE 8
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#ifndef UIP_CONF_IPV6_QUEUE_PKT #ifndef UIP_CONF_IPV6_QUEUE_PKT
@ -155,7 +154,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#ifndef UIP_CONF_BUFFER_SIZE #ifndef UIP_CONF_BUFFER_SIZE

View file

@ -239,7 +239,7 @@ radio_uip_uaodv_send(void)
} }
/* Add header and buffer packet for persistent transmission */ /* Add header and buffer packet for persistent transmission */
uip_len = radio_uip_uaodv_add_header(&uip_buf[UIP_LLH_LEN], uip_len, &route->nexthop); /* TODO Correct? */ uip_len = radio_uip_uaodv_add_header(&uip_buf[UIP_LLH_LEN], uip_len, uip_ds6_route_nexthop(route)); /* TODO Correct? */
return radio_uip_buffer_outgoing_packet( return radio_uip_buffer_outgoing_packet(
&uip_buf[UIP_LLH_LEN], &uip_buf[UIP_LLH_LEN],
uip_len, uip_len,

View file

@ -142,7 +142,7 @@
#define XMAC_CONF_COMPOWER 0 #define XMAC_CONF_COMPOWER 0
#define CXMAC_CONF_COMPOWER 0 #define CXMAC_CONF_COMPOWER 0
#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32
#endif /* WITH_UIP6 */ #endif /* WITH_UIP6 */
@ -184,7 +184,7 @@
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
#endif #endif
#define UIP_CONF_DS6_NBR_NBU 30 #define NBR_TABLE_CONF_MAX_NEIGHBORS 30
#define UIP_CONF_MAX_ROUTES 30 #define UIP_CONF_MAX_ROUTES 30
#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_SEND_RA 0
@ -197,7 +197,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 1300 #define UIP_CONF_BUFFER_SIZE 1300

View file

@ -137,9 +137,9 @@
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 30 #define NBR_TABLE_CONF_MAX_NEIGHBORS 30
#endif /* UIP_CONF_DS6_NBR_NBU */ #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 30 #define UIP_CONF_MAX_ROUTES 30
#endif /* UIP_CONF_MAX_ROUTES */ #endif /* UIP_CONF_MAX_ROUTES */
@ -156,7 +156,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#ifndef UIP_CONF_BUFFER_SIZE #ifndef UIP_CONF_BUFFER_SIZE

View file

@ -79,7 +79,7 @@
#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 #define CONTIKIMAC_CONF_ANNOUNCEMENTS 0
#define CONTIKIMAC_CONF_COMPOWER 1 #define CONTIKIMAC_CONF_COMPOWER 1
#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32
#endif /* WITH_UIP6 */ #endif /* WITH_UIP6 */
@ -113,11 +113,11 @@
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#define UIP_CONF_DS6_NBR_NBU 5 #define NBR_TABLE_CONF_MAX_NEIGHBORS 5
#define UIP_CONF_MAX_ROUTES 5 #define UIP_CONF_MAX_ROUTES 5
#define RPL_CONF_MAX_PARENTS 4 #define RPL_CONF_MAX_PARENTS 4
#define NEIGHBOR_CONF_MAX_NEIGHBORS 8 #define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000
@ -129,7 +129,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 240 #define UIP_CONF_BUFFER_SIZE 240

View file

@ -108,7 +108,7 @@
#define ENERGEST_CONF_ON 0 #define ENERGEST_CONF_ON 0
#define QUEUEBUF_CONF_NUM 2 #define QUEUEBUF_CONF_NUM 2
#define QUEUEBUF_CONF_REF_NUM 0 #define QUEUEBUF_CONF_REF_NUM 0
#define UIP_CONF_DS6_NBR_NBU 4 #define NBR_TABLE_CONF_MAX_NEIGHBORS 4
#define UIP_CONF_DS6_ROUTE_NBU 4 #define UIP_CONF_DS6_ROUTE_NBU 4
#define RPL_CONF_MAX_PARENTS_PER_DAG 4 #define RPL_CONF_MAX_PARENTS_PER_DAG 4
#define RPL_CONF_MAX_INSTANCES 1 #define RPL_CONF_MAX_INSTANCES 1
@ -144,7 +144,6 @@
#define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_CHECKS 1
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_ND6_MAX_PREFIXES 2 #define UIP_CONF_ND6_MAX_PREFIXES 2
#define UIP_CONF_ND6_MAX_NEIGHBORS 2
#define UIP_CONF_ND6_MAX_DEFROUTERS 1 #define UIP_CONF_ND6_MAX_DEFROUTERS 1
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 140 #define UIP_CONF_BUFFER_SIZE 140

View file

@ -84,7 +84,7 @@
#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 #define CONTIKIMAC_CONF_ANNOUNCEMENTS 0
#define CONTIKIMAC_CONF_COMPOWER 1 #define CONTIKIMAC_CONF_COMPOWER 1
#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32
#endif /* WITH_UIP6 */ #endif /* WITH_UIP6 */
@ -118,11 +118,11 @@
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#define UIP_CONF_DS6_NBR_NBU 5 #define NBR_TABLE_CONF_MAX_NEIGHBORS 5
#define UIP_CONF_MAX_ROUTES 5 #define UIP_CONF_MAX_ROUTES 5
#define RPL_CONF_MAX_PARENTS 4 #define RPL_CONF_MAX_PARENTS 4
#define NEIGHBOR_CONF_MAX_NEIGHBORS 8 #define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000
@ -134,7 +134,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 240 #define UIP_CONF_BUFFER_SIZE 240

View file

@ -160,9 +160,8 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_IPV6_REASSEMBLY 1 #define UIP_CONF_IPV6_REASSEMBLY 1
//#define UIP_CONF_NETIF_MAX_ADDRESSES 5 //#define UIP_CONF_NETIF_MAX_ADDRESSES 5
//#define UIP_CONF_ND6_MAX_PREFIXES 3 //#define UIP_CONF_ND6_MAX_PREFIXES 3
//#define UIP_CONF_ND6_MAX_NEIGHBORS 40
//#define UIP_CONF_ND6_MAX_DEFROUTERS 2 //#define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_DS6_NBR_NBU 100 #define NBR_TABLE_CONF_MAX_NEIGHBORS 100
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 5 #define UIP_CONF_DS6_PREFIX_NBU 5
#define UIP_CONF_MAX_ROUTES 100 #define UIP_CONF_MAX_ROUTES 100

View file

@ -125,14 +125,13 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_ICMP6 1 #define UIP_CONF_ICMP6 1
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 30 #define NBR_TABLE_CONF_MAX_NEIGHBORS 30
#endif /* UIP_CONF_DS6_NBR_NBU */ #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 30 #define UIP_CONF_MAX_ROUTES 30
#endif /* UIP_CONF_MAX_ROUTES */ #endif /* UIP_CONF_MAX_ROUTES */

View file

@ -141,7 +141,7 @@ typedef unsigned long rtimer_clock_t;
#define XMAC_CONF_COMPOWER 0 #define XMAC_CONF_COMPOWER 0
#define CXMAC_CONF_COMPOWER 0 #define CXMAC_CONF_COMPOWER 0
#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32
#endif /* WITH_UIP6 */ #endif /* WITH_UIP6 */
@ -178,7 +178,7 @@ typedef unsigned long rtimer_clock_t;
#define UIP_CONF_ROUTER 1 #define UIP_CONF_ROUTER 1
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
#define UIP_CONF_DS6_NBR_NBU 30 #define NBR_TABLE_CONF_MAX_NEIGHBORS 30
#define UIP_CONF_MAX_ROUTES 30 #define UIP_CONF_MAX_ROUTES 30
#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_SEND_RA 0
@ -191,7 +191,6 @@ typedef unsigned long rtimer_clock_t;
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 1300 #define UIP_CONF_BUFFER_SIZE 1300

View file

@ -159,7 +159,7 @@ typedef unsigned long rtimer_clock_t;
#define XMAC_CONF_COMPOWER 0 #define XMAC_CONF_COMPOWER 0
#define CXMAC_CONF_COMPOWER 0 #define CXMAC_CONF_COMPOWER 0
#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32
#endif /* WITH_UIP6 */ #endif /* WITH_UIP6 */
@ -196,7 +196,7 @@ typedef unsigned long rtimer_clock_t;
#define UIP_CONF_ROUTER 1 #define UIP_CONF_ROUTER 1
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
#define UIP_CONF_DS6_NBR_NBU 30 #define NBR_TABLE_CONF_MAX_NEIGHBORS 30
#define UIP_CONF_MAX_ROUTES 30 #define UIP_CONF_MAX_ROUTES 30
#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_SEND_RA 0
@ -209,7 +209,6 @@ typedef unsigned long rtimer_clock_t;
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 1300 #define UIP_CONF_BUFFER_SIZE 1300

View file

@ -593,8 +593,6 @@ if ((clocktime%PINGS)==1) {
#if ROUTES && UIP_CONF_IPV6 #if ROUTES && UIP_CONF_IPV6
if ((clocktime%ROUTES)==2) { if ((clocktime%ROUTES)==2) {
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j; uint8_t i,j;
@ -605,13 +603,14 @@ extern uip_ds6_netif_t uip_ds6_if;
printf("\n"); printf("\n");
} }
} }
printf("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB); printf("\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) { uip_ds6_nbr_t *nbr;
if(uip_ds6_nbr_cache[i].isused) { for(nbr = nbr_table_head(ds6_neighbors);
uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr); nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr)) {
uip_debug_ipaddr_print(&nbr->ipaddr);
printf("\n"); printf("\n");
j=0; j=0;
}
} }
if (j) printf(" <none>"); if (j) printf(" <none>");
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
@ -619,17 +618,13 @@ extern uip_ds6_netif_t uip_ds6_if;
uip_ds6_route_t *r; uip_ds6_route_t *r;
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
j = 1; j = 1;
for(r = uip_ds6_route_list_head(); for(r = uip_ds6_route_head();
r != NULL; r != NULL;
r = list_item_next(r)) { r = uip_ds6_route_next(r)) {
ipaddr_add(&r->ipaddr); ipaddr_add(&r->ipaddr);
PRINTF("/%u (via ", r->length); PRINTF("/%u (via ", r->length);
ipaddr_add(&r->nexthop); ipaddr_add(uip_ds6_route_nexthop(r));
// if(uip_ds6_routing_table[i].state.lifetime < 600) { PRINTF(") %lus\n", r->state.lifetime);
PRINTF(") %lus\n", r->state.lifetime);
// } else {
// PRINTF(")\n");
// }
j = 0; j = 0;
} }
} }

View file

@ -97,7 +97,7 @@ typedef uint32_t rtimer_clock_t;
/* IPv6 configuration options */ /* IPv6 configuration options */
#define UIP_CONF_IPV6 1 #define UIP_CONF_IPV6 1
#define UIP_CONF_DS6_NBR_NBU 20 /* number of neighbors */ #define NBR_TABLE_CONF_MAX_NEIGHBORS 20 /* number of neighbors */
#define UIP_CONF_DS6_ROUTE_NBU 20 /* number of routes */ #define UIP_CONF_DS6_ROUTE_NBU 20 /* number of routes */
#define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000

View file

@ -230,8 +230,8 @@
#define UIP_CONF_ND6_REACHABLE_TIME 600000 #define UIP_CONF_ND6_REACHABLE_TIME 600000
#define UIP_CONF_ND6_RETRANS_TIMER 10000 #define UIP_CONF_ND6_RETRANS_TIMER 10000
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 4 /* Handle n Neighbors */ #define NBR_TABLE_CONF_MAX_NEIGHBORS 4 /* Handle n Neighbors */
#endif #endif
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 4 /* Handle n Routes */ #define UIP_CONF_MAX_ROUTES 4 /* Handle n Routes */

View file

@ -69,7 +69,6 @@ static int8_t len;
#define REQUEST_TYPE_TOTALS 0xFF #define REQUEST_TYPE_TOTALS 0xFF
extern uip_ds6_netif_t uip_ds6_if; extern uip_ds6_netif_t uip_ds6_if;
extern uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
static uip_ds6_route_t *rt; static uip_ds6_route_t *rt;
static uip_ds6_defrt_t *defrt; static uip_ds6_defrt_t *defrt;
static uip_ipaddr_t *addr; static uip_ipaddr_t *addr;
@ -82,6 +81,7 @@ process_request() CC_NON_BANKED
uint8_t i; uint8_t i;
uint8_t left; uint8_t left;
uint8_t entry_size; uint8_t entry_size;
uip_ds6_nbr_t *nbr;
left = VIZTOOL_MAX_PAYLOAD_LEN - 1; left = VIZTOOL_MAX_PAYLOAD_LEN - 1;
len = 2; /* start filling the buffer from position [2] */ len = 2; /* start filling the buffer from position [2] */
@ -89,46 +89,44 @@ process_request() CC_NON_BANKED
if(buf[0] == REQUEST_TYPE_ND) { if(buf[0] == REQUEST_TYPE_ND) {
/* Neighbors */ /* Neighbors */
PRINTF("Neighbors\n"); PRINTF("Neighbors\n");
for(i = buf[1]; i < UIP_DS6_NBR_NB; i++) { for(nbr = nbr_table_head(ds6_neighbors);
if(uip_ds6_nbr_cache[i].isused) { nbr != NULL;
entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t) nbr = nbr_table_next(ds6_neighbors, nbr)) {
+ sizeof(uip_ds6_nbr_cache[i].state); entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t)
PRINTF("%02u: ", i); + sizeof(nbr->state);
PRINT6ADDR(&uip_ds6_nbr_cache[i].ipaddr); PRINTF("%02u: ", i);
PRINTF(" - "); PRINT6ADDR(&nbr->ipaddr);
PRINTLLADDR(&uip_ds6_nbr_cache[i].lladdr); PRINTF(" - ");
PRINTF(" - %u\n", uip_ds6_nbr_cache[i].state); PRINTLLADDR(&nbr->lladdr);
PRINTF(" - %u\n", nbr->state);
memcpy(buf + len, &i, sizeof(i)); memcpy(buf + len, &i, sizeof(i));
len += sizeof(i); len += sizeof(i);
memcpy(buf + len, &uip_ds6_nbr_cache[i].ipaddr, sizeof(uip_ipaddr_t)); memcpy(buf + len, uip_ds6_nbr_get_ipaddr(nbr), sizeof(uip_ipaddr_t));
len += sizeof(uip_ipaddr_t); len += sizeof(uip_ipaddr_t);
memcpy(buf + len, &uip_ds6_nbr_cache[i].lladdr, sizeof(uip_lladdr_t)); memcpy(buf + len, uip_ds6_nbr_get_ll(nbr), sizeof(uip_lladdr_t));
len += sizeof(uip_lladdr_t); len += sizeof(uip_lladdr_t);
memcpy(buf + len, &uip_ds6_nbr_cache[i].state, memcpy(buf + len, &nbr->state,
sizeof(uip_ds6_nbr_cache[i].state)); sizeof(nbr->state));
len += sizeof(uip_ds6_nbr_cache[i].state); len += sizeof(nbr->state);
count++; count++;
left -= entry_size; left -= entry_size;
if(left < entry_size) { if(left < entry_size) {
break; break;
}
} }
} }
} else if(buf[0] == REQUEST_TYPE_RT) { } else if(buf[0] == REQUEST_TYPE_RT) {
uint32_t flip = 0; uint32_t flip = 0;
PRINTF("Routing table\n"); PRINTF("Routing table\n");
rt = uip_ds6_route_list_head(); rt = uip_ds6_route_head();
for(i = buf[1]; i < uip_ds6_route_num_routes(); i++) { for(i = buf[1]; i < uip_ds6_route_num_routes(); i++) {
if(rt != NULL) { if(rt != NULL) {
entry_size = sizeof(i) + sizeof(rt->ipaddr) entry_size = sizeof(i) + sizeof(rt->ipaddr)
+ sizeof(rt->length) + sizeof(rt->length)
+ sizeof(rt->metric)
+ sizeof(rt->nexthop)
+ sizeof(rt->state.lifetime) + sizeof(rt->state.lifetime)
+ sizeof(rt->state.learned_from); + sizeof(rt->state.learned_from);
@ -138,16 +136,11 @@ process_request() CC_NON_BANKED
len += sizeof(rt->ipaddr); len += sizeof(rt->ipaddr);
memcpy(buf + len, &rt->length, sizeof(rt->length)); memcpy(buf + len, &rt->length, sizeof(rt->length));
len += sizeof(rt->length); len += sizeof(rt->length);
memcpy(buf + len, &rt->metric, sizeof(rt->metric));
len += sizeof(rt->metric);
memcpy(buf + len, &rt->nexthop, sizeof(rt->nexthop));
len += sizeof(rt->nexthop);
PRINT6ADDR(&rt->ipaddr); PRINT6ADDR(&rt->ipaddr);
PRINTF(" - %02x", rt->length); PRINTF(" - %02x", rt->length);
PRINTF(" - %02x", rt->metric);
PRINTF(" - "); PRINTF(" - ");
PRINT6ADDR(&rt->nexthop); PRINT6ADDR(uip_ds6_route_nexthop(rt));
flip = uip_htonl(rt->state.lifetime); flip = uip_htonl(rt->state.lifetime);
memcpy(buf + len, &flip, sizeof(flip)); memcpy(buf + len, &flip, sizeof(flip));
@ -163,7 +156,7 @@ process_request() CC_NON_BANKED
count++; count++;
left -= entry_size; left -= entry_size;
rt = list_item_next(rt); rt = uip_ds6_route_next(rt);
if(left < entry_size) { if(left < entry_size) {
break; break;
@ -226,10 +219,10 @@ process_request() CC_NON_BANKED
buf[2]++; buf[2]++;
} }
} }
for(i = 0; i < UIP_DS6_NBR_NB; i++) { for(nbr = nbr_table_head(ds6_neighbors);
if(uip_ds6_nbr_cache[i].isused) { nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr)) {
buf[3]++; buf[3]++;
}
} }
buf[4] = uip_ds6_route_num_routes(); buf[4] = uip_ds6_route_num_routes();

View file

@ -137,9 +137,9 @@
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 20 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20
#endif /* UIP_CONF_DS6_NBR_NBU */ #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 20 #define UIP_CONF_MAX_ROUTES 20
#endif /* UIP_CONF_MAX_ROUTES */ #endif /* UIP_CONF_MAX_ROUTES */
@ -156,7 +156,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#ifndef UIP_CONF_BUFFER_SIZE #ifndef UIP_CONF_BUFFER_SIZE

View file

@ -45,7 +45,7 @@ void clock_adjust_ticks(clock_time_t howmany);
//#define UIP_CONF_IPV6_RPL 0 //#define UIP_CONF_IPV6_RPL 0
/* See uip-ds6.h */ /* See uip-ds6.h */
#define UIP_CONF_DS6_NBR_NBU 20 #define NBR_TABLE_CONF_MAX_NEIGHBORS 20
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 3 #define UIP_CONF_DS6_PREFIX_NBU 3
#define UIP_CONF_MAX_ROUTES 20 #define UIP_CONF_MAX_ROUTES 20

View file

@ -63,7 +63,7 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_TCP_SPLIT 1 #define UIP_CONF_TCP_SPLIT 1
#if UIP_CONF_IPV6 #if UIP_CONF_IPV6
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_DS6_NBR_NBU 100 #define NBR_TABLE_CONF_MAX_NEIGHBORS 100
#define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_DEFRT_NBU 2
#define UIP_CONF_DS6_PREFIX_NBU 5 #define UIP_CONF_DS6_PREFIX_NBU 5
#define UIP_CONF_MAX_ROUTES 100 #define UIP_CONF_MAX_ROUTES 100

View file

@ -133,9 +133,9 @@
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#ifndef UIP_CONF_DS6_NBR_NBU #ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define UIP_CONF_DS6_NBR_NBU 30 #define NBR_TABLE_CONF_MAX_NEIGHBORS 30
#endif /* UIP_CONF_DS6_NBR_NBU */ #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 30 #define UIP_CONF_MAX_ROUTES 30
#endif /* UIP_CONF_MAX_ROUTES */ #endif /* UIP_CONF_MAX_ROUTES */
@ -152,7 +152,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#ifndef UIP_CONF_BUFFER_SIZE #ifndef UIP_CONF_BUFFER_SIZE

View file

@ -84,7 +84,7 @@
#define XMAC_CONF_COMPOWER 1 #define XMAC_CONF_COMPOWER 1
#define CXMAC_CONF_COMPOWER 1 #define CXMAC_CONF_COMPOWER 1
#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32
#define QUEUEBUF_CONF_NUM 8 #define QUEUEBUF_CONF_NUM 8
@ -134,7 +134,7 @@
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
/* Handle 10 neighbors */ /* Handle 10 neighbors */
#define UIP_CONF_DS6_NBR_NBU 15 #define NBR_TABLE_CONF_MAX_NEIGHBORS 15
/* Handle 10 routes */ /* Handle 10 routes */
#define UIP_CONF_MAX_ROUTES 15 #define UIP_CONF_MAX_ROUTES 15
@ -148,7 +148,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 140 #define UIP_CONF_BUFFER_SIZE 140

View file

@ -78,7 +78,7 @@
#define XMAC_CONF_COMPOWER 1 #define XMAC_CONF_COMPOWER 1
#define CXMAC_CONF_COMPOWER 1 #define CXMAC_CONF_COMPOWER 1
#define COLLECT_NEIGHBOR_CONF_MAX_NEIGHBORS 32 #define COLLECT_NBR_TABLE_CONF_MAX_NEIGHBORS 32
#define QUEUEBUF_CONF_NUM 8 #define QUEUEBUF_CONF_NUM 8
@ -133,7 +133,7 @@
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
/* Handle 10 neighbors */ /* Handle 10 neighbors */
#define UIP_CONF_DS6_NBR_NBU 15 #define NBR_TABLE_CONF_MAX_NEIGHBORS 15
/* Handle 10 routes */ /* Handle 10 routes */
#define UIP_CONF_MAX_ROUTES 15 #define UIP_CONF_MAX_ROUTES 15
@ -147,7 +147,6 @@
#define UIP_CONF_IPV6_REASSEMBLY 0 #define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3 #define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 140 #define UIP_CONF_BUFFER_SIZE 140

View file

@ -0,0 +1,344 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype743</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype452</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype782</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-22.5728586847096</x>
<y>123.9358664968653</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype782</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype743</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-1.39303771455413</x>
<y>100.21446701029119</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype782</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype782</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype782</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype782</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>10.931583432822638</x>
<y>69.848248459216</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype782</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>0.0</x>
<y>0.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype452</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>1</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757</viewport>
</plugin_config>
<width>400</width>
<z>2</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
</plugin_config>
<width>1184</width>
<z>3</z>
<height>240</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
//GENERATE_MSG(1000000, "remove-sink");&#xD;
//GENERATE_MSG(1020000, "add-sink");&#xD;
&#xD;
lostMsgs = 0;&#xD;
&#xD;
TIMEOUT(1000000, if(lostMsgs == 0) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>962</width>
<z>0</z>
<height>596</height>
<location_x>603</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,344 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype951</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype170</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype767</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-22.5728586847096</x>
<y>123.9358664968653</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype767</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype951</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-1.39303771455413</x>
<y>100.21446701029119</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype767</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype767</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype767</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype767</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>10.931583432822638</x>
<y>69.848248459216</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype767</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>0.0</x>
<y>0.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype170</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>0</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757</viewport>
</plugin_config>
<width>400</width>
<z>2</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
</plugin_config>
<width>1184</width>
<z>3</z>
<height>240</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
GENERATE_MSG(1000000, "remove-sink");&#xD;
GENERATE_MSG(2000000, "add-sink");&#xD;
&#xD;
lostMsgs = 0;&#xD;
&#xD;
TIMEOUT(2000000, if(lostMsgs == 0) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>962</width>
<z>1</z>
<height>596</height>
<location_x>603</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,647 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype419</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype484</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype718</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-0.4799968467515439</x>
<y>98.79087181374759</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>99.56423154395364</x>
<y>50.06466731257512</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype419</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-0.4799968467515439</x>
<y>0.30173505605854883</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype484</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>12.779318616702257</x>
<y>8.464865358169643</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>9.391922400291703</x>
<y>49.22878206790311</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>48.16367625505583</x>
<y>33.27520746599595</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>16.582742473429345</x>
<y>24.932911331640646</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>8.445564421140666</x>
<y>6.770205395698742</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>87.04968129458189</x>
<y>34.46536562612724</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>9</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>94.47123252519145</x>
<y>18.275940194868184</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>10</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.28044254364556</x>
<y>17.683438211793558</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>11</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>56.124622439456076</x>
<y>33.88966252832571</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>12</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>98.33149749474546</x>
<y>37.448034626592744</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>13</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>58.75337436025891</x>
<y>68.64082018992522</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>14</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.83816496627988</x>
<y>68.38008376830592</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>15</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>90.88648665466316</x>
<y>50.942053906416575</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>16</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>68.80089833632896</x>
<y>84.17294684073734</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>17</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>73.6760846183129</x>
<y>81.76699743886633</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>18</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>0.2960103456537466</x>
<y>98.5587829617092</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>19</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>8.130479493904208</x>
<y>57.642099520821645</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>20</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>30.550120982984865</x>
<y>85.58346736403402</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>21</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.65300377698182</x>
<y>63.50257213104861</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>22</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>34.92110687576687</x>
<y>70.71381297232249</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>23</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype718</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>1</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>1.92914676942954 0.0 0.0 1.92914676942954 75.9259843662471 55.41790879138101</viewport>
</plugin_config>
<width>400</width>
<z>2</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1184</width>
<z>3</z>
<height>500</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>function place(id, x, y) {&#xD;
var node = sim.getMoteWithID(id);&#xD;
node.getInterfaces().getPosition().setCoordinates(x, y, 0);&#xD;
}&#xD;
&#xD;
function getRandom(min, max) {&#xD;
return Math.random() * (max - min) + min;&#xD;
}&#xD;
&#xD;
// From: http://bost.ocks.org/mike/shuffle/&#xD;
function shuffle(array) {&#xD;
var m = array.length, t, i;&#xD;
&#xD;
// While there remain elements to shuffle…&#xD;
while (m) {&#xD;
&#xD;
// Pick a remaining element…&#xD;
i = Math.floor(Math.random() * m--);&#xD;
&#xD;
// And swap it with the current element.&#xD;
t = array[m];&#xD;
array[m] = array[i];&#xD;
array[i] = t;&#xD;
}&#xD;
&#xD;
return array;&#xD;
}&#xD;
&#xD;
GENERATE_MSG(000000, 'randomize-nodes');&#xD;
GENERATE_MSG(1200000, 'randomize-nodes');&#xD;
GENERATE_MSG(2400000, 'randomize-nodes');&#xD;
GENERATE_MSG(3600000, 'randomize-nodes');&#xD;
&#xD;
var numForwarders = 20;&#xD;
var forwardIDStart = 4;&#xD;
packetsReceived = [];&#xD;
var hops;&#xD;
&#xD;
TIMEOUT(6000000, if(packetsReceived.length &gt; 50) { log.testOK(); } );&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("randomize-nodes")) {&#xD;
log.log('Rearranging network\n');&#xD;
var allnodes = [];&#xD;
for(var i = 0; i &lt; numForwarders; i++) {&#xD;
allnodes.push(i);&#xD;
}&#xD;
shuffle(allnodes);&#xD;
/* Place 1/4 of the nodes in the first quadrant. */&#xD;
var i = 0;&#xD;
for(; i &lt; numForwarders / 4; i++) {&#xD;
place(i + forwardIDStart, &#xD;
getRandom(0, 50),&#xD;
getRandom(0, 50));&#xD;
}&#xD;
/* Place 1/4 of the nodes in the second quadrant. */&#xD;
for(; i &lt; 2 * numForwarders / 4; i++) {&#xD;
place(i + forwardIDStart, &#xD;
getRandom(50, 100),&#xD;
getRandom(0, 50));&#xD;
}&#xD;
/* Place 1/4 of the nodes in the third quadrant. */&#xD;
for(; i &lt; 3 * numForwarders / 4; i++) {&#xD;
place(i + forwardIDStart, &#xD;
getRandom(50, 100),&#xD;
getRandom(50, 100));&#xD;
} &#xD;
/* Place 1/4 of the nodes in the fourth quadrant. */&#xD;
for(; i &lt; 4 * numForwarders / 4; i++) {&#xD;
place(i + forwardIDStart, &#xD;
getRandom(0, 50),&#xD;
getRandom(50, 100));&#xD;
} &#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
var data = msg.split(" ");&#xD;
var num = parseInt(data[14]);&#xD;
packetsReceived.push(num);&#xD;
&#xD;
/* Copy packetsReceived array to the packets array. */&#xD;
var packets = packetsReceived.slice();&#xD;
var recvstr = '';&#xD;
for(var i = 0; i &lt; num; i++) {&#xD;
if(packets[0] == i) {&#xD;
recvstr += '*';&#xD;
packets.shift();&#xD;
} else {&#xD;
recvstr += '_'; &#xD;
} &#xD;
}&#xD;
log.log(packetsReceived.length + ' packets received: ' + recvstr + '\n');&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>612</width>
<z>0</z>
<height>726</height>
<location_x>953</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype921</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype873</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype812</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-7.199692787830563</x>
<y>98.21738321803603</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype812</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype921</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>12.0</x>
<y>68.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype812</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype812</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype812</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype812</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>58.0</x>
<y>108.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype812</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-40.352178879596096</x>
<y>102.66976131212861</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype873</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>3</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904</viewport>
</plugin_config>
<width>400</width>
<z>0</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1184</width>
<z>2</z>
<height>500</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
//GENERATE_MSG(1000000, "remove-sink");&#xD;
//GENERATE_MSG(1020000, "add-sink");&#xD;
GENERATE_MSG(000000, 'init-8-and-4');&#xD;
GENERATE_MSG(600000, 'move-8-and-4');&#xD;
&#xD;
&#xD;
lostMsgs = 0;&#xD;
seenMsgs = 0;&#xD;
&#xD;
TIMEOUT(2000000, if(seenMsgs &gt; 15) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.equals("init-8-and-4")) { &#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node8.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node4.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.equals("move-8-and-4")) {&#xD;
log.log('Moving nodes 8 and 4\n');&#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node4.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node8.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
seenMsgs++;&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>612</width>
<z>1</z>
<height>726</height>
<location_x>953</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype672</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype780</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype36</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-7.199692787830563</x>
<y>98.21738321803603</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype672</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>12.0</x>
<y>68.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>58.0</x>
<y>108.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-25.71843353317142</x>
<y>43.05517674255262</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype780</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>3</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757</viewport>
</plugin_config>
<width>400</width>
<z>2</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1184</width>
<z>1</z>
<height>500</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
//GENERATE_MSG(1000000, "remove-sink");&#xD;
//GENERATE_MSG(1020000, "add-sink");&#xD;
GENERATE_MSG(000000, 'init-8-and-4');&#xD;
GENERATE_MSG(600000, 'move-8-and-4');&#xD;
&#xD;
&#xD;
lostMsgs = 0;&#xD;
seenMsgs = 0;&#xD;
&#xD;
TIMEOUT(2000000, if(seenMsgs &gt; 15) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.equals("init-8-and-4")) { &#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node8.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node4.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.equals("move-8-and-4")) {&#xD;
log.log('Moving nodes 8 and 4\n');&#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node4.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node8.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
seenMsgs++;&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>612</width>
<z>0</z>
<height>726</height>
<location_x>953</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype672</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype780</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype36</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-7.199692787830563</x>
<y>98.21738321803603</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype672</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>12.0</x>
<y>68.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>58.0</x>
<y>108.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>16.0472370839803</x>
<y>6.017695251870905</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype780</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>3</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>2.5379695437350276 0.0 0.0 2.5379695437350276 75.2726010197627 15.727272727272757</viewport>
</plugin_config>
<width>400</width>
<z>0</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1184</width>
<z>2</z>
<height>500</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
//GENERATE_MSG(1000000, "remove-sink");&#xD;
//GENERATE_MSG(1020000, "add-sink");&#xD;
GENERATE_MSG(000000, 'init-8-and-4');&#xD;
GENERATE_MSG(600000, 'move-8-and-4');&#xD;
&#xD;
&#xD;
lostMsgs = 0;&#xD;
seenMsgs = 0;&#xD;
&#xD;
TIMEOUT(2000000, if(seenMsgs &gt; 15) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.equals("init-8-and-4")) { &#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node8.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node4.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.equals("move-8-and-4")) {&#xD;
log.log('Moving nodes 8 and 4\n');&#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node4.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node8.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
seenMsgs++;&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>612</width>
<z>1</z>
<height>726</height>
<location_x>953</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype672</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype780</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype36</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-7.199692787830563</x>
<y>98.21738321803603</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype672</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>12.0</x>
<y>68.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>58.0</x>
<y>108.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype36</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>79.48377453078622</x>
<y>4.835647970253402</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype780</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>3</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276</viewport>
</plugin_config>
<width>400</width>
<z>0</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1184</width>
<z>2</z>
<height>500</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
//GENERATE_MSG(1000000, "remove-sink");&#xD;
//GENERATE_MSG(1020000, "add-sink");&#xD;
GENERATE_MSG(000000, 'init-8-and-4');&#xD;
GENERATE_MSG(600000, 'move-8-and-4');&#xD;
&#xD;
&#xD;
lostMsgs = 0;&#xD;
seenMsgs = 0;&#xD;
&#xD;
TIMEOUT(2000000, if(seenMsgs &gt; 15) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.equals("init-8-and-4")) { &#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node8.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node4.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.equals("move-8-and-4")) {&#xD;
log.log('Moving nodes 8 and 4\n');&#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node4.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node8.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
seenMsgs++;&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>612</width>
<z>1</z>
<height>726</height>
<location_x>953</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype192</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype575</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype912</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-7.199692787830563</x>
<y>98.21738321803603</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype912</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype192</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>12.0</x>
<y>68.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype912</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype912</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype912</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype912</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>58.0</x>
<y>108.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype912</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>122.82550819009461</x>
<y>29.658640884220933</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype575</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>3</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>2.5379695437350276 0.0 0.0 2.5379695437350276 70.27260101976269 60.72727272727276</viewport>
</plugin_config>
<width>400</width>
<z>0</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1184</width>
<z>2</z>
<height>500</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
//GENERATE_MSG(1000000, "remove-sink");&#xD;
//GENERATE_MSG(1020000, "add-sink");&#xD;
GENERATE_MSG(000000, 'init-8-and-4');&#xD;
GENERATE_MSG(600000, 'move-8-and-4');&#xD;
&#xD;
&#xD;
lostMsgs = 0;&#xD;
seenMsgs = 0;&#xD;
&#xD;
TIMEOUT(2000000, if(seenMsgs &gt; 15) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.equals("init-8-and-4")) { &#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node8.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node4.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.equals("move-8-and-4")) {&#xD;
log.log('Moving nodes 8 and 4\n');&#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node4.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node8.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
seenMsgs++;&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>612</width>
<z>1</z>
<height>726</height>
<location_x>953</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype372</identifier>
<description>Sender</description>
<source>[CONFIG_DIR]/code/sender-node.c</source>
<commands>make clean TARGET=cooja
make sender-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype229</identifier>
<description>RPL root</description>
<source>[CONFIG_DIR]/code/root-node.c</source>
<commands>make clean TARGET=cooja
make root-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
se.sics.cooja.contikimote.ContikiMoteType
<identifier>mtype424</identifier>
<description>Receiver</description>
<source>[CONFIG_DIR]/code/receiver-node.c</source>
<commands>make clean TARGET=cooja
make receiver-node.cooja TARGET=cooja</commands>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Battery</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>se.sics.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>-7.199692787830563</x>
<y>98.21738321803603</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype424</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>116.13379149678028</x>
<y>88.36698920455684</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype372</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>12.0</x>
<y>68.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype424</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>95.25095618820441</x>
<y>63.14998053005015</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype424</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.09378990830604</x>
<y>38.32698761608261</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype424</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>29.05630841762433</x>
<y>30.840688165838436</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype424</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>58.0</x>
<y>108.0</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype424</motetype_identifier>
</mote>
<mote>
<interface_config>
se.sics.cooja.interfaces.Position
<x>145.93059238811136</x>
<y>111.16474110935306</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
se.sics.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<motetype_identifier>mtype229</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>280</width>
<z>3</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>1.6480321712565114 0.0 0.0 1.6480321712565114 98.5016889738719 55.796930342384904</viewport>
</plugin_config>
<width>400</width>
<z>0</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1184</width>
<z>2</z>
<height>500</height>
<location_x>402</location_x>
<location_y>162</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>904</width>
<z>4</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.ScriptRunner
<plugin_config>
<script>GENERATE_MSG(0000000, "add-sink");&#xD;
//GENERATE_MSG(1000000, "remove-sink");&#xD;
//GENERATE_MSG(1020000, "add-sink");&#xD;
GENERATE_MSG(000000, 'init-8-and-4');&#xD;
GENERATE_MSG(600000, 'move-8-and-4');&#xD;
&#xD;
&#xD;
lostMsgs = 0;&#xD;
seenMsgs = 0;&#xD;
&#xD;
TIMEOUT(2000000, if(seenMsgs &gt; 15) { log.testOK(); } );&#xD;
&#xD;
lastMsg = -1;&#xD;
packets = "_________";&#xD;
hops = 0;&#xD;
&#xD;
while(true) {&#xD;
YIELD();&#xD;
if(msg.equals("remove-sink")) {&#xD;
m = sim.getMoteWithID(3);&#xD;
sim.removeMote(m);&#xD;
log.log("removed sink\n");&#xD;
} else if(msg.equals("add-sink")) {&#xD;
if(!sim.getMoteWithID(3)) {&#xD;
m = sim.getMoteTypes()[1].generateMote(sim);&#xD;
m.getInterfaces().getMoteID().setMoteID(3);&#xD;
sim.addMote(m);&#xD;
log.log("added sink\n");&#xD;
} else {&#xD;
log.log("did not add sink as it was already there\n"); &#xD;
}&#xD;
} else if(msg.equals("init-8-and-4")) { &#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node8.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node4.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.equals("move-8-and-4")) {&#xD;
log.log('Moving nodes 8 and 4\n');&#xD;
var node4 = sim.getMoteWithID(4);&#xD;
var node8 = sim.getMoteWithID(8);&#xD;
node4.getInterfaces().getPosition().setCoordinates(12, 68, 0);&#xD;
node8.getInterfaces().getPosition().setCoordinates(58, 108, 0);&#xD;
} else if(msg.startsWith("Sending")) {&#xD;
hops = 0;&#xD;
} else if(msg.startsWith("#L")) {&#xD;
hops++;&#xD;
} else if(msg.startsWith("Data")) {&#xD;
// log.log("" + msg + "\n"); &#xD;
data = msg.split(" ");&#xD;
num = parseInt(data[14]);&#xD;
packets = packets.substr(0, num) + "*";&#xD;
log.log("" + hops + " " + packets + "\n");&#xD;
seenMsgs++;&#xD;
// log.log("Num " + num + "\n");&#xD;
if(lastMsg != -1) {&#xD;
if(num != lastMsg + 1) {&#xD;
numMissed = num - lastMsg;&#xD;
lostMsgs += numMissed;&#xD;
log.log("Missed messages " + numMissed + " before " + num + "\n"); &#xD;
for(i = 0; i &lt; numMissed; i++) {&#xD;
packets = packets.substr(0, lastMsg + i) + "_"; &#xD;
}&#xD;
} &#xD;
}&#xD;
lastMsg = num;&#xD;
}&#xD;
}</script>
<active>true</active>
</plugin_config>
<width>612</width>
<z>1</z>
<height>726</height>
<location_x>953</location_x>
<location_y>43</location_y>
</plugin>
</simconf>

View file

@ -127,3 +127,10 @@ uip_icmp6chksum(void)
{ {
return upper_layer_chksum(UIP_PROTO_ICMP6); return upper_layer_chksum(UIP_PROTO_ICMP6);
} }
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
}

View file

@ -127,3 +127,9 @@ uip_icmp6chksum(void)
{ {
return upper_layer_chksum(UIP_PROTO_ICMP6); return upper_layer_chksum(UIP_PROTO_ICMP6);
} }
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
}

View file

@ -73,3 +73,9 @@ uip_icmp6chksum(void)
{ {
return upper_layer_chksum(UIP_PROTO_ICMP6); return upper_layer_chksum(UIP_PROTO_ICMP6);
} }
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
}