Merge pull request #1213 from joakimeriksson/dao_ack_handling

End-to-End DAO and DAO ACK handling for Contiki RPL.
This commit is contained in:
Antonio Lignan 2016-04-11 18:53:43 +02:00
commit 8f064511d3
37 changed files with 2825 additions and 204 deletions

View file

@ -148,6 +148,13 @@
#define UIP_CONF_IPV6_RPL 1 #define UIP_CONF_IPV6_RPL 1
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
/* If RPL is enabled also enable the RPL NBR Policy */
#if UIP_CONF_IPV6_RPL
#ifndef NBR_TABLE_FIND_REMOVABLE
#define NBR_TABLE_FIND_REMOVABLE rpl_nbr_policy_find_removable
#endif /* NBR_TABLE_FIND_REMOVABLE */
#endif /* UIP_CONF_IPV6_RPL */
/* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each /* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each
node will be able to handle. */ node will be able to handle. */
#ifndef UIP_CONF_MAX_ROUTES #ifndef UIP_CONF_MAX_ROUTES

View file

@ -644,7 +644,7 @@ tcpip_ipv6_output(void)
nbr = uip_ds6_nbr_lookup(nexthop); nbr = uip_ds6_nbr_lookup(nexthop);
if(nbr == NULL) { 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, NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) {
uip_clear_buf(); uip_clear_buf();
return; return;
} else { } else {

View file

@ -79,9 +79,11 @@ uip_ds6_neighbors_init(void)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_nbr_t * uip_ds6_nbr_t *
uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
uint8_t isrouter, uint8_t state) uint8_t isrouter, uint8_t state, nbr_table_reason_t reason,
void *data)
{ {
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr); uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr
, reason, data);
if(nbr) { if(nbr) {
uip_ipaddr_copy(&nbr->ipaddr, ipaddr); uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER #if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
@ -115,7 +117,7 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void int
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr) uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
{ {
if(nbr != NULL) { if(nbr != NULL) {
@ -123,9 +125,9 @@ uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
uip_packetqueue_free(&nbr->packethandle); uip_packetqueue_free(&nbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */ #endif /* UIP_CONF_IPV6_QUEUE_PKT */
NEIGHBOR_STATE_CHANGED(nbr); NEIGHBOR_STATE_CHANGED(nbr);
nbr_table_remove(ds6_neighbors, nbr); return nbr_table_remove(ds6_neighbors, nbr);
} }
return; return 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -86,9 +86,11 @@ typedef struct uip_ds6_nbr {
void uip_ds6_neighbors_init(void); void uip_ds6_neighbors_init(void);
/** \brief Neighbor Cache basic routines */ /** \brief Neighbor Cache basic routines */
uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr, uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr,
uint8_t isrouter, uint8_t state); const uip_lladdr_t *lladdr,
void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr); uint8_t isrouter, uint8_t state,
nbr_table_reason_t reason, void *data);
int uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr); const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr);
const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr); const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr);
uip_ds6_nbr_t *uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr); uip_ds6_nbr_t *uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr);

View file

@ -207,6 +207,19 @@ uip_ds6_route_next(uip_ds6_route_t *r)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
uip_ds6_route_is_nexthop(const uip_ipaddr_t *ipaddr)
{
const uip_lladdr_t *lladdr;
lladdr = uip_ds6_nbr_lladdr_from_ipaddr(ipaddr);
if(lladdr == NULL) {
return 0;
}
return nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)lladdr) != NULL;
}
/*---------------------------------------------------------------------------*/
int
uip_ds6_route_num_routes(void) uip_ds6_route_num_routes(void)
{ {
return num_routes; return num_routes;
@ -307,11 +320,16 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
least recently used one we have. */ least recently used one we have. */
if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) { if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) {
uip_ds6_route_t *oldest;
oldest = NULL;
#if UIP_DS6_ROUTE_REMOVE_LEAST_RECENTLY_USED
/* Removing the oldest route entry from the route table. The /* Removing the oldest route entry from the route table. The
least recently used route is the first route on the list. */ least recently used route is the first route on the list. */
uip_ds6_route_t *oldest; oldest = list_tail(routelist);
#endif
oldest = list_tail(routelist); /* uip_ds6_route_head(); */ if(oldest == NULL) {
return NULL;
}
PRINTF("uip_ds6_route_add: dropping route to "); PRINTF("uip_ds6_route_add: dropping route to ");
PRINT6ADDR(&oldest->ipaddr); PRINT6ADDR(&oldest->ipaddr);
PRINTF("\n"); PRINTF("\n");
@ -337,7 +355,8 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
initialize this pointer with the list of routing entries that initialize this pointer with the list of routing entries that
are attached to this neighbor. */ are attached to this neighbor. */
routes = nbr_table_add_lladdr(nbr_routes, routes = nbr_table_add_lladdr(nbr_routes,
(linkaddr_t *)nexthop_lladdr); (linkaddr_t *)nexthop_lladdr,
NBR_TABLE_REASON_ROUTE, NULL);
if(routes == NULL) { if(routes == NULL) {
/* This should not happen, as we explicitly deallocated one /* This should not happen, as we explicitly deallocated one
route table entry above. */ route table entry above. */

View file

@ -97,11 +97,48 @@ void uip_ds6_notification_rm(struct uip_ds6_notification *n);
#ifndef UIP_DS6_ROUTE_STATE_TYPE #ifndef UIP_DS6_ROUTE_STATE_TYPE
#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t #define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t
/* Needed for the extended route entry state when using ContikiRPL */ /* Needed for the extended route entry state when using ContikiRPL */
#define RPL_ROUTE_ENTRY_NOPATH_RECEIVED 0x01
#define RPL_ROUTE_ENTRY_DAO_PENDING 0x02
#define RPL_ROUTE_ENTRY_DAO_NACK 0x04
#define RPL_ROUTE_IS_NOPATH_RECEIVED(route) \
(((route)->state.state_flags & RPL_ROUTE_ENTRY_NOPATH_RECEIVED) != 0)
#define RPL_ROUTE_SET_NOPATH_RECEIVED(route) do { \
(route)->state.state_flags |= RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \
} while(0)
#define RPL_ROUTE_CLEAR_NOPATH_RECEIVED(route) do { \
(route)->state.state_flags &= ~RPL_ROUTE_ENTRY_NOPATH_RECEIVED; \
} while(0)
#define RPL_ROUTE_IS_DAO_PENDING(route) \
((route->state.state_flags & RPL_ROUTE_ENTRY_DAO_PENDING) != 0)
#define RPL_ROUTE_SET_DAO_PENDING(route) do { \
(route)->state.state_flags |= RPL_ROUTE_ENTRY_DAO_PENDING; \
} while(0)
#define RPL_ROUTE_CLEAR_DAO_PENDING(route) do { \
(route)->state.state_flags &= ~RPL_ROUTE_ENTRY_DAO_PENDING; \
} while(0)
#define RPL_ROUTE_IS_DAO_NACKED(route) \
((route->state.state_flags & RPL_ROUTE_ENTRY_DAO_NACK) != 0)
#define RPL_ROUTE_SET_DAO_NACKED(route) do { \
(route)->state.state_flags |= RPL_ROUTE_ENTRY_DAO_NACK; \
} while(0)
#define RPL_ROUTE_CLEAR_DAO_NACKED(route) do { \
(route)->state.state_flags &= ~RPL_ROUTE_ENTRY_DAO_NACK; \
} while(0)
#define RPL_ROUTE_CLEAR_DAO(route) do { \
(route)->state.state_flags &= ~(RPL_ROUTE_ENTRY_DAO_NACK|RPL_ROUTE_ENTRY_DAO_PENDING); \
} while(0)
struct rpl_dag;
typedef struct rpl_route_entry { typedef struct rpl_route_entry {
uint32_t lifetime; uint32_t lifetime;
void *dag; struct rpl_dag *dag;
uint8_t learned_from; uint8_t dao_seqno_out;
uint8_t nopath_received; uint8_t dao_seqno_in;
uint8_t state_flags;
} rpl_route_entry_t; } rpl_route_entry_t;
#endif /* UIP_DS6_ROUTE_STATE_TYPE */ #endif /* UIP_DS6_ROUTE_STATE_TYPE */
@ -166,7 +203,7 @@ 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_head(void); uip_ds6_route_t *uip_ds6_route_head(void);
uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *); uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *);
int uip_ds6_route_is_nexthop(const uip_ipaddr_t *ipaddr);
/** @} */ /** @} */
#endif /* UIP_DS6_ROUTE_H */ #endif /* UIP_DS6_ROUTE_H */

View file

@ -203,7 +203,8 @@ ns_input(void)
if(nbr == NULL) { if(nbr == NULL) {
uip_lladdr_t lladdr_aligned; uip_lladdr_t lladdr_aligned;
extract_lladdr_aligned(&lladdr_aligned); extract_lladdr_aligned(&lladdr_aligned);
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
} else { } else {
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); uip_lladdr_t *lladdr = (uip_lladdr_t *)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],
@ -634,14 +635,16 @@ rs_input(void)
extract_lladdr_aligned(&lladdr_aligned); extract_lladdr_aligned(&lladdr_aligned);
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, &lladdr_aligned, 0, NBR_STALE); uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
} 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],
uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) {
uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_t nbr_data = *nbr;
uip_ds6_nbr_rm(nbr); uip_ds6_nbr_rm(nbr);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
nbr->reachable = nbr_data.reachable; nbr->reachable = nbr_data.reachable;
nbr->sendns = nbr_data.sendns; nbr->sendns = nbr_data.sendns;
nbr->nscount = nbr_data.nscount; nbr->nscount = nbr_data.nscount;
@ -870,7 +873,8 @@ ra_input(void)
if(nbr == NULL) { if(nbr == NULL) {
uip_lladdr_t lladdr_aligned; uip_lladdr_t lladdr_aligned;
extract_lladdr_aligned(&lladdr_aligned); extract_lladdr_aligned(&lladdr_aligned);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE); nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
1, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
} else { } else {
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr);
if(nbr->state == NBR_INCOMPLETE) { if(nbr->state == NBR_INCOMPLETE) {

View file

@ -188,7 +188,7 @@ parse(void)
info = nbr_table_get_from_lladdr(anti_replay_table, sender); info = nbr_table_get_from_lladdr(anti_replay_table, sender);
if(!info) { if(!info) {
info = nbr_table_add_lladdr(anti_replay_table, sender); info = nbr_table_add_lladdr(anti_replay_table, sender, NBR_TABLE_REASON_LLSEC, NULL);
if(!info) { if(!info) {
PRINTF("noncoresec: could not get nbr_table_item\n"); PRINTF("noncoresec: could not get nbr_table_item\n");
return FRAMER_FAILED; return FRAMER_FAILED;

View file

@ -122,7 +122,7 @@ phase_update(const linkaddr_t *neighbor, rtimer_clock_t time,
} 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 = nbr_table_add_lladdr(nbr_phase, neighbor); e = nbr_table_add_lladdr(nbr_phase, neighbor, NBR_TABLE_REASON_MAC, NULL);
if(e) { if(e) {
e->time = time; e->time = time;
#if PHASE_DRIFT_CORRECT #if PHASE_DRIFT_CORRECT

View file

@ -47,11 +47,20 @@
static void handle_periodic_timer(void *ptr); static void handle_periodic_timer(void *ptr);
static struct ctimer periodic_timer; static struct ctimer periodic_timer;
static uint8_t initialized = 0; static uint8_t initialized = 0;
static void print_table();
#define PRINTF(...) printf(__VA_ARGS__) #define PRINTF(...) printf(__VA_ARGS__)
#else #else
#define PRINTF(...) #define PRINTF(...)
#endif #endif
/* This is the callback function that will be called when there is a
* nbr-policy active
**/
#ifdef NBR_TABLE_FIND_REMOVABLE
const linkaddr_t *NBR_TABLE_FIND_REMOVABLE(nbr_table_reason_t reason, void *data);
#endif /* NBR_TABLE_FIND_REMOVABLE */
/* List of link-layer addresses of the neighbors, used as key in the tables */ /* List of link-layer addresses of the neighbors, used as key in the tables */
typedef struct nbr_table_key { typedef struct nbr_table_key {
struct nbr_table_key *next; struct nbr_table_key *next;
@ -170,7 +179,7 @@ nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int val
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static nbr_table_key_t * static nbr_table_key_t *
nbr_table_allocate(void) nbr_table_allocate(nbr_table_reason_t reason, void *data)
{ {
nbr_table_key_t *key; nbr_table_key_t *key;
int least_used_count = 0; int least_used_count = 0;
@ -179,39 +188,66 @@ nbr_table_allocate(void)
key = memb_alloc(&neighbor_addr_mem); key = memb_alloc(&neighbor_addr_mem);
if(key != NULL) { if(key != NULL) {
return key; return key;
} else { /* No more space, try to free a neighbor. } else {
* The replacement policy is the following: remove neighbor that is: #ifdef NBR_TABLE_FIND_REMOVABLE
* (1) not locked const linkaddr_t *lladdr;
* (2) used by fewest tables lladdr = NBR_TABLE_FIND_REMOVABLE(reason, data);
* (3) oldest (the list is ordered by insertion time) if(lladdr == NULL) {
* */ /* Nothing found that can be deleted - return NULL to indicate failure */
/* Get item from first key */ PRINTF("*** Not removing entry to allocate new\n");
key = list_head(nbr_table_keys); return NULL;
while(key != NULL) { } else {
int item_index = index_from_key(key); /* used least_used_key to indicate what is the least useful entry */
int locked = locked_map[item_index]; int index;
/* Never delete a locked item */ int locked = 0;
if(!locked) { if((index = index_from_lladdr(lladdr)) != -1) {
int used = used_map[item_index]; least_used_key = key_from_index(index);
int used_count = 0; locked = locked_map[index];
/* Count how many tables are using this item */ }
while(used != 0) { /* Allow delete of locked item? */
if((used & 1) == 1) { if(least_used_key != NULL && locked) {
used_count++; PRINTF("Deleting locked item!\n");
} locked_map[index] = 0;
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);
} }
#endif /* NBR_TABLE_FIND_REMOVABLE */
if(least_used_key == NULL) {
/* 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) { if(least_used_key == NULL) {
/* We haven't found any unlocked item, allocation fails */ /* We haven't found any unlocked item, allocation fails */
return NULL; return NULL;
@ -289,7 +325,7 @@ nbr_table_next(nbr_table_t *table, nbr_table_item_t *item)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Add a neighbor indexed with its link-layer address */ /* Add a neighbor indexed with its link-layer address */
nbr_table_item_t * nbr_table_item_t *
nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr) nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data)
{ {
int index; int index;
nbr_table_item_t *item; nbr_table_item_t *item;
@ -303,7 +339,7 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr)
if((index = index_from_lladdr(lladdr)) == -1) { if((index = index_from_lladdr(lladdr)) == -1) {
/* Neighbor not yet in table, let's try to allocate one */ /* Neighbor not yet in table, let's try to allocate one */
key = nbr_table_allocate(); key = nbr_table_allocate(reason, data);
/* No space available for new entry */ /* No space available for new entry */
if(key == NULL) { if(key == NULL) {
@ -327,6 +363,9 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr)
memset(item, 0, table->item_size); memset(item, 0, table->item_size);
nbr_set_bit(used_map, table, item, 1); nbr_set_bit(used_map, table, item, 1);
#if DEBUG
print_table();
#endif
return item; return item;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -379,7 +418,7 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if DEBUG #if DEBUG
static void static void
handle_periodic_timer(void *ptr) print_table()
{ {
int i, j; int i, j;
/* Printout all neighbors and which tables they are used in */ /* Printout all neighbors and which tables they are used in */
@ -394,6 +433,12 @@ handle_periodic_timer(void *ptr)
PRINTF("\n"); PRINTF("\n");
} }
} }
}
/*---------------------------------------------------------------------------*/
static void
handle_periodic_timer(void *ptr)
{
print_table();
ctimer_reset(&periodic_timer); ctimer_reset(&periodic_timer);
} }
#endif #endif

View file

@ -75,6 +75,17 @@ typedef struct nbr_table {
/** \brief Declaration of non-static neighbor tables */ /** \brief Declaration of non-static neighbor tables */
#define NBR_TABLE_DECLARE(name) extern nbr_table_t *name #define NBR_TABLE_DECLARE(name) extern nbr_table_t *name
typedef enum {
NBR_TABLE_REASON_UNDEFINED,
NBR_TABLE_REASON_RPL_DIO,
NBR_TABLE_REASON_RPL_DAO,
NBR_TABLE_REASON_RPL_DIS,
NBR_TABLE_REASON_ROUTE,
NBR_TABLE_REASON_IPV6_ND,
NBR_TABLE_REASON_MAC,
NBR_TABLE_REASON_LLSEC
} nbr_table_reason_t;
/** \name Neighbor tables: register and loop through table elements */ /** \name Neighbor tables: register and loop through table elements */
/** @{ */ /** @{ */
int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback); int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback);
@ -84,7 +95,7 @@ nbr_table_item_t *nbr_table_next(nbr_table_t *table, nbr_table_item_t *item);
/** \name Neighbor tables: add and get data */ /** \name Neighbor tables: add and get data */
/** @{ */ /** @{ */
nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data);
nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr); nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr);
/** @} */ /** @} */

View file

@ -118,7 +118,7 @@
#ifdef RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME #ifdef RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME
#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME #define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME
#else #else
#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 0 #define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 1
#endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */ #endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */
/* /*
@ -200,7 +200,7 @@
* used in RPL lifetime values, in seconds. * used in RPL lifetime values, in seconds.
*/ */
#ifndef RPL_CONF_DEFAULT_LIFETIME_UNIT #ifndef RPL_CONF_DEFAULT_LIFETIME_UNIT
#define RPL_DEFAULT_LIFETIME_UNIT 0xffff #define RPL_DEFAULT_LIFETIME_UNIT 0x60
#else #else
#define RPL_DEFAULT_LIFETIME_UNIT RPL_CONF_DEFAULT_LIFETIME_UNIT #define RPL_DEFAULT_LIFETIME_UNIT RPL_CONF_DEFAULT_LIFETIME_UNIT
#endif #endif
@ -209,7 +209,7 @@
* Default route lifetime as a multiple of the lifetime unit. * Default route lifetime as a multiple of the lifetime unit.
*/ */
#ifndef RPL_CONF_DEFAULT_LIFETIME #ifndef RPL_CONF_DEFAULT_LIFETIME
#define RPL_DEFAULT_LIFETIME 0xff #define RPL_DEFAULT_LIFETIME 0x30
#else #else
#define RPL_DEFAULT_LIFETIME RPL_CONF_DEFAULT_LIFETIME #define RPL_DEFAULT_LIFETIME RPL_CONF_DEFAULT_LIFETIME
#endif #endif
@ -235,6 +235,39 @@
#define RPL_INSERT_HBH_OPTION 1 #define RPL_INSERT_HBH_OPTION 1
#endif #endif
/*
* RPL DAO ACK support. When enabled, DAO ACK will be sent and requested.
* This will also enable retransmission of DAO when no ack is received.
* */
#ifdef RPL_CONF_WITH_DAO_ACK
#define RPL_WITH_DAO_ACK RPL_CONF_WITH_DAO_ACK
#else
#define RPL_WITH_DAO_ACK 1
#endif /* RPL_CONF_WITH_DAO_ACK */
/*
* RPL REPAIR ON DAO NACK. When enabled, DAO NACK will trigger a local
* repair in order to quickly find a new parent to send DAO's to.
* NOTE: this is too agressive in some cases so use with care.
* */
#ifdef RPL_CONF_RPL_REPAIR_ON_DAO_NACK
#define RPL_REPAIR_ON_DAO_NACK RPL_CONF_RPL_REPAIR_ON_DAO_NACK
#else
#define RPL_REPAIR_ON_DAO_NACK 0
#endif /* RPL_CONF_RPL_REPAIR_ON_DAO_NACK */
/*
* Setting the DIO_REFRESH_DAO_ROUTES will make RPL always increase
* the DTSN (Destination Advertisement Trigger Sequence Number) when
* sending broadcast DIO. This is to get all children to re-register
* their DAO route.
* */
#ifdef RPL_CONF_DIO_REFRESH_DAO_ROUTES
#define RPL_DIO_REFRESH_DAO_ROUTES RPL_CONF_DIO_REFRESH_DAO_ROUTES
#else
#define RPL_DIO_REFRESH_DAO_ROUTES 0
#endif /* RPL_CONF_DIO_REFRESH_DAO_ROUTES */
/* /*
* RPL probing. When enabled, probes will be sent periodically to keep * RPL probing. When enabled, probes will be sent periodically to keep
* parent link estimates up to date. * parent link estimates up to date.

View file

@ -634,8 +634,9 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
PRINT6ADDR(addr); PRINT6ADDR(addr);
PRINTF("\n"); PRINTF("\n");
if(lladdr != NULL) { if(lladdr != NULL) {
/* Add parent in rpl_parents */ /* Add parent in rpl_parents - again this is due to DIO */
p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr); p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr,
NBR_TABLE_REASON_RPL_DIO, dio);
if(p == NULL) { if(p == NULL) {
PRINTF("RPL: rpl_add_parent p NULL\n"); PRINTF("RPL: rpl_add_parent p NULL\n");
} else { } else {
@ -898,6 +899,18 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
parent->dag = dag_dst; parent->dag = dag_dst;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int
rpl_has_downward_route(void)
{
int i;
for(i = 0; i < RPL_MAX_INSTANCES; ++i) {
if(instance_table[i].used && instance_table[i].has_downward_route) {
return 1;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
rpl_dag_t * rpl_dag_t *
rpl_get_any_dag(void) rpl_get_any_dag(void)
{ {
@ -1155,6 +1168,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
RPL_STAT(rpl_stats.global_repairs++); RPL_STAT(rpl_stats.global_repairs++);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_local_repair(rpl_instance_t *instance) rpl_local_repair(rpl_instance_t *instance)
@ -1173,7 +1187,12 @@ rpl_local_repair(rpl_instance_t *instance)
} }
} }
/* no downward route anymore */
instance->has_downward_route = 0;
rpl_reset_dio_timer(instance); rpl_reset_dio_timer(instance);
/* Request refresh of DAO registrations next DIO */
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
RPL_STAT(rpl_stats.local_repairs++); RPL_STAT(rpl_stats.local_repairs++);
} }
@ -1250,6 +1269,19 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
return return_value; return return_value;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int
add_nbr_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
{
/* add this to the neighbor cache if not already there */
if(rpl_icmp6_update_nbr_table(from, NBR_TABLE_REASON_RPL_DIO, dio) == NULL) {
PRINTF("RPL: Out of memory, dropping DIO from ");
PRINT6ADDR(from);
PRINTF("\n");
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
void void
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
{ {
@ -1303,7 +1335,11 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(instance == NULL) { if(instance == NULL) {
PRINTF("RPL: New instance detected (ID=%u): Joining...\n", dio->instance_id); PRINTF("RPL: New instance detected (ID=%u): Joining...\n", dio->instance_id);
rpl_join_instance(from, dio); if(add_nbr_from_dio(from, dio)) {
rpl_join_instance(from, dio);
} else {
PRINTF("RPL: Not joining since could not add parent\n");
}
return; return;
} }
@ -1315,6 +1351,10 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dag == NULL) { if(dag == NULL) {
#if RPL_MAX_DAG_PER_INSTANCE > 1 #if RPL_MAX_DAG_PER_INSTANCE > 1
PRINTF("RPL: Adding new DAG to known instance.\n"); PRINTF("RPL: Adding new DAG to known instance.\n");
if(!add_nbr_from_dio(from, dio)) {
PRINTF("RPL: Could not add new DAG, could not add parent\n");
return;
}
dag = rpl_add_dag(from, dio); dag = rpl_add_dag(from, dio);
if(dag == NULL) { if(dag == NULL) {
PRINTF("RPL: Failed to add DAG.\n"); PRINTF("RPL: Failed to add DAG.\n");
@ -1363,6 +1403,11 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
* whether to keep it in the set. * whether to keep it in the set.
*/ */
if(!add_nbr_from_dio(from, dio)) {
PRINTF("RPL: Could not add parent based on DIO\n");
return;
}
p = rpl_find_parent(dag, from); p = rpl_find_parent(dag, from);
if(p == NULL) { if(p == NULL) {
previous_dag = find_parent_dag(instance, from); previous_dag = find_parent_dag(instance, from);

View file

@ -53,6 +53,7 @@
#include "net/rpl/rpl-private.h" #include "net/rpl/rpl-private.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include "net/ipv6/multicast/uip-mcast6.h" #include "net/ipv6/multicast/uip-mcast6.h"
#include "random.h"
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
@ -76,6 +77,9 @@ static void dio_input(void);
static void dao_input(void); static void dao_input(void);
static void dao_ack_input(void); static void dao_ack_input(void);
static void dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix,
uint8_t lifetime, uint8_t seq_no);
/* some debug callbacks useful when debugging RPL networks */ /* some debug callbacks useful when debugging RPL networks */
#ifdef RPL_DEBUG_DIO_INPUT #ifdef RPL_DEBUG_DIO_INPUT
void RPL_DEBUG_DIO_INPUT(uip_ipaddr_t *, rpl_dio_t *); void RPL_DEBUG_DIO_INPUT(uip_ipaddr_t *, rpl_dio_t *);
@ -99,6 +103,38 @@ UIP_ICMP6_HANDLER(dio_handler, ICMP6_RPL, RPL_CODE_DIO, dio_input);
UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input); UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input);
UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input); UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if RPL_WITH_DAO_ACK
static uip_ds6_route_t *
find_route_entry_by_dao_ack(uint8_t seq)
{
uip_ds6_route_t *re;
re = uip_ds6_route_head();
while(re != NULL) {
if(re->state.dao_seqno_out == seq && RPL_ROUTE_IS_DAO_PENDING(re)) {
/* found it! */
return re;
}
re = uip_ds6_route_next(re);
}
return NULL;
}
#endif /* RPL_WITH_DAO_ACK */
/* prepare for forwarding of DAO */
static uint8_t
prepare_for_dao_fwd(uint8_t sequence, uip_ds6_route_t *rep)
{
/* not pending - or pending but not a retransmission */
RPL_LOLLIPOP_INCREMENT(dao_sequence);
/* set DAO pending and sequence numbers */
rep->state.dao_seqno_in = sequence;
rep->state.dao_seqno_out = dao_sequence;
RPL_ROUTE_SET_DAO_PENDING(rep);
return dao_sequence;
}
/*---------------------------------------------------------------------------*/
static int static int
get_global_addr(uip_ipaddr_t *addr) get_global_addr(uip_ipaddr_t *addr)
{ {
@ -147,6 +183,34 @@ set16(uint8_t *buffer, int pos, uint16_t value)
buffer[pos++] = value & 0xff; buffer[pos++] = value & 0xff;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, nbr_table_reason_t reason, void *data)
{
uip_ds6_nbr_t *nbr;
if((nbr = uip_ds6_nbr_lookup(from)) == NULL) {
if((nbr = uip_ds6_nbr_add(from, (uip_lladdr_t *)
packetbuf_addr(PACKETBUF_ADDR_SENDER),
0, NBR_REACHABLE, reason, data)) != NULL) {
PRINTF("RPL: Neighbor added to neighbor cache ");
PRINT6ADDR(from);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n");
}
}
if(nbr != NULL) {
#if UIP_ND6_SEND_NA
/* set reachable timer if we added or found the nbr entry - and update
neighbor entry to reachable to avoid sending NS/NA, etc. */
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
nbr->state = NBR_REACHABLE;
#endif /* UIP_ND6_SEND_NA */
}
return nbr;
}
/*---------------------------------------------------------------------------*/
static void static void
dis_input(void) dis_input(void)
{ {
@ -170,8 +234,19 @@ dis_input(void)
rpl_reset_dio_timer(instance); rpl_reset_dio_timer(instance);
} else { } else {
#endif /* !RPL_LEAF_ONLY */ #endif /* !RPL_LEAF_ONLY */
PRINTF("RPL: Unicast DIS, reply to sender\n"); /* Check if this neighbor should be added according to the policy. */
dio_output(instance, &UIP_IP_BUF->srcipaddr); if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr,
NBR_TABLE_REASON_RPL_DIS, NULL) == NULL) {
PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n");
} else {
PRINTF("RPL: Unicast DIS, reply to sender\n");
dio_output(instance, &UIP_IP_BUF->srcipaddr);
}
/* } */
} }
} }
} }
@ -218,7 +293,6 @@ dio_input(void)
int i; int i;
int len; int len;
uip_ipaddr_t from; uip_ipaddr_t from;
uip_ds6_nbr_t *nbr;
memset(&dio, 0, sizeof(dio)); memset(&dio, 0, sizeof(dio));
@ -239,32 +313,6 @@ dio_input(void)
PRINT6ADDR(&from); PRINT6ADDR(&from);
PRINTF("\n"); PRINTF("\n");
if((nbr = uip_ds6_nbr_lookup(&from)) == NULL) {
if((nbr = uip_ds6_nbr_add(&from, (uip_lladdr_t *)
packetbuf_addr(PACKETBUF_ADDR_SENDER),
0, NBR_REACHABLE)) != NULL) {
#if UIP_ND6_SEND_NA
/* set reachable timer */
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
#endif /* UIP_ND6_SEND_NA */
PRINTF("RPL: Neighbor added to neighbor cache ");
PRINT6ADDR(&from);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
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");
goto discard;
}
} else {
PRINTF("RPL: Neighbor already in neighbor cache\n");
}
buffer_length = uip_len - uip_l3_icmp_hdr_len; buffer_length = uip_len - uip_l3_icmp_hdr_len;
/* Process the DIO base option. */ /* Process the DIO base option. */
@ -470,7 +518,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
buffer[pos++] = instance->dtsn_out; buffer[pos++] = instance->dtsn_out;
if(uc_addr == NULL) { if(RPL_DIO_REFRESH_DAO_ROUTES && uc_addr == NULL) {
/* Request new DAO to refresh route. We do not do this for unicast DIO /* Request new DAO to refresh route. We do not do this for unicast DIO
* in order to avoid DAO messages after a DIS-DIO update, * in order to avoid DAO messages after a DIS-DIO update,
* or upon unicast DIO probing. */ * or upon unicast DIO probing. */
@ -605,17 +653,13 @@ dao_input(void)
int learned_from; int learned_from;
rpl_parent_t *parent; rpl_parent_t *parent;
uip_ds6_nbr_t *nbr; uip_ds6_nbr_t *nbr;
int is_root;
prefixlen = 0; prefixlen = 0;
parent = NULL; parent = NULL;
uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr); uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr);
/* Destination Advertisement Object */
PRINTF("RPL: Received a DAO from ");
PRINT6ADDR(&dao_sender_addr);
PRINTF("\n");
buffer = UIP_ICMP_PAYLOAD; buffer = UIP_ICMP_PAYLOAD;
buffer_length = uip_len - uip_l3_icmp_hdr_len; buffer_length = uip_len - uip_l3_icmp_hdr_len;
@ -637,6 +681,8 @@ dao_input(void)
sequence = buffer[pos++]; sequence = buffer[pos++];
dag = instance->current_dag; dag = instance->current_dag;
is_root = (dag->rank == ROOT_RANK(instance));
/* Is the DAG ID present? */ /* Is the DAG ID present? */
if(flags & RPL_DAO_D_FLAG) { if(flags & RPL_DAO_D_FLAG) {
if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) {
@ -649,8 +695,12 @@ 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", /* Destination Advertisement Object */
learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast"); PRINTF("RPL: Received a (%s) DAO with sequence number %u from ",
learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast", sequence);
PRINT6ADDR(&dao_sender_addr);
PRINTF("\n");
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. */
parent = rpl_find_parent(dag, &dao_sender_addr); parent = rpl_find_parent(dag, &dao_sender_addr);
@ -723,86 +773,125 @@ dao_input(void)
PRINTF("RPL: No-Path DAO received\n"); 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 && if(rep != NULL &&
rep->state.nopath_received == 0 && !RPL_ROUTE_IS_NOPATH_RECEIVED(rep) &&
rep->length == prefixlen && rep->length == prefixlen &&
uip_ds6_route_nexthop(rep) != NULL && uip_ds6_route_nexthop(rep) != NULL &&
uip_ipaddr_cmp(uip_ds6_route_nexthop(rep), &dao_sender_addr)) { 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.nopath_received = 1; RPL_ROUTE_SET_NOPATH_RECEIVED(rep);
rep->state.lifetime = RPL_NOPATH_REMOVAL_DELAY; rep->state.lifetime = RPL_NOPATH_REMOVAL_DELAY;
/* We forward the incoming No-Path DAO to our parent, if we have /* We forward the incoming No-Path DAO to our parent, if we have
one. */ one. */
if(dag->preferred_parent != NULL && if(dag->preferred_parent != NULL &&
rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) { rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) {
PRINTF("RPL: Forwarding No-Path DAO to parent "); uint8_t out_seq;
out_seq = prepare_for_dao_fwd(sequence, rep);
PRINTF("RPL: Forwarding No-path DAO to parent - out_seq:%d",
out_seq);
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
PRINTF("\n"); PRINTF("\n");
buffer = UIP_ICMP_PAYLOAD;
buffer[3] = out_seq; /* add an outgoing seq no before fwd */
uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent), 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) { }
dao_ack_output(instance, &dao_sender_addr, sequence); /* independent if we remove or not - ACK the request */
} if(flags & RPL_DAO_K_FLAG) {
/* indicate that we accepted the no-path DAO */
dao_ack_output(instance, &dao_sender_addr, sequence,
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
} }
goto discard; goto discard;
} }
PRINTF("RPL: adding DAO route\n"); PRINTF("RPL: Adding DAO route\n");
if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) { /* Update and add neighbor - if no room - fail. */
if((nbr = uip_ds6_nbr_add(&dao_sender_addr, if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr, NBR_TABLE_REASON_RPL_DAO, instance)) == NULL) {
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER), PRINTF("RPL: Out of Memory, dropping DAO from ");
0, NBR_REACHABLE)) != NULL) { PRINT6ADDR(&dao_sender_addr);
#if UIP_ND6_SEND_NA PRINTF(", ");
/* set reachable timer */ PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000); PRINTF("\n");
#endif /* UIP_ND6_SEND_NA */ if(flags & RPL_DAO_K_FLAG) {
PRINTF("RPL: Neighbor added to neighbor cache "); /* signal the failure to add the node */
PRINT6ADDR(&dao_sender_addr); dao_ack_output(instance, &dao_sender_addr, sequence,
PRINTF(", "); is_root ? RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT :
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); RPL_DAO_ACK_UNABLE_TO_ACCEPT);
PRINTF("\n");
} else {
PRINTF("RPL: Out of Memory, dropping DAO from ");
PRINT6ADDR(&dao_sender_addr);
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n");
goto discard;
} }
} else { goto discard;
PRINTF("RPL: Neighbor already in neighbor cache\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++);
PRINTF("RPL: Could not add a route after receiving a DAO\n"); PRINTF("RPL: Could not add a route after receiving a DAO\n");
if(flags & RPL_DAO_K_FLAG) {
/* signal the failure to add the node */
dao_ack_output(instance, &dao_sender_addr, sequence,
is_root ? RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT :
RPL_DAO_ACK_UNABLE_TO_ACCEPT);
}
goto discard; goto discard;
} }
/* set lifetime and clear NOPATH bit */
rep->state.lifetime = RPL_LIFETIME(instance, lifetime); rep->state.lifetime = RPL_LIFETIME(instance, lifetime);
rep->state.learned_from = learned_from; RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep);
rep->state.nopath_received = 0;
#if RPL_CONF_MULTICAST #if RPL_CONF_MULTICAST
fwd_dao: fwd_dao:
#endif #endif
if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) { if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) {
int should_ack = 0;
if(flags & RPL_DAO_K_FLAG) {
/*
* check if this route is already installed and we can ack now!
* not pending - and same seq-no means that we can ack.
* (e.g. the route is installed already so it will not take any
* more room that it already takes - so should be ok!)
*/
if((!RPL_ROUTE_IS_DAO_PENDING(rep) &&
rep->state.dao_seqno_in == sequence) ||
dag->rank == ROOT_RANK(instance)) {
should_ack = 1;
}
}
if(dag->preferred_parent != NULL && if(dag->preferred_parent != NULL &&
rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) { rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) {
uint8_t out_seq = 0;
/* if this is pending and we get the same seq no it is a retrans */
if(RPL_ROUTE_IS_DAO_PENDING(rep) &&
rep->state.dao_seqno_in == sequence) {
/* keep the same seq-no as before for parent also */
out_seq = rep->state.dao_seqno_out;
} else {
out_seq = prepare_for_dao_fwd(sequence, rep);
}
PRINTF("RPL: Forwarding DAO to parent "); PRINTF("RPL: Forwarding DAO to parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
PRINTF("\n"); PRINTF(" in seq: %d out seq: %d\n", sequence, out_seq);
buffer = UIP_ICMP_PAYLOAD;
buffer[3] = out_seq; /* add an outgoing seq no before fwd */
uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent), 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) {
dao_ack_output(instance, &dao_sender_addr, sequence); if(should_ack) {
PRINTF("RPL: Sending DAO ACK\n");
dao_ack_output(instance, &dao_sender_addr, sequence,
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
} }
} }
@ -810,6 +899,61 @@ fwd_dao:
uip_clear_buf(); uip_clear_buf();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if RPL_WITH_DAO_ACK
static void
handle_dao_retransmission(void *ptr)
{
rpl_parent_t *parent;
uip_ipaddr_t prefix;
rpl_instance_t *instance;
parent = ptr;
if(parent == NULL || parent->dag == NULL || parent->dag->instance == NULL) {
return;
}
instance = parent->dag->instance;
if(instance->my_dao_transmissions >= RPL_DAO_MAX_RETRANSMISSIONS) {
/* No more retransmissions - give up. */
if(instance->lifetime_unit == 0xffff && instance->default_lifetime == 0xff) {
/*
* ContikiRPL was previously using infinite lifetime for routes
* and no DAO_ACK configured. This probably means that the root
* and possibly other nodes might be running an old version that
* does not support DAO ack. Assume that everything is ok for
* now and let the normal repair mechanisms detect any problems.
*/
return;
}
if(instance->of->dao_ack_callback) {
/* Inform the objective function about the timeout. */
instance->of->dao_ack_callback(parent, RPL_DAO_ACK_TIMEOUT);
}
/* Perform local repair and hope to find another parent. */
rpl_local_repair(instance);
return;
}
PRINTF("Should retransmit DAO - seq:%d trans:%d\n", instance->my_dao_seqno,
instance->my_dao_transmissions);
if(get_global_addr(&prefix) == 0) {
return;
}
ctimer_set(&instance->dao_retransmit_timer,
RPL_DAO_RETRANSMISSION_TIMEOUT / 2 +
(random_rand() % (RPL_DAO_RETRANSMISSION_TIMEOUT / 2)),
handle_dao_retransmission, parent);
instance->my_dao_transmissions++;
dao_output_target_seq(parent, &prefix,
instance->default_lifetime, instance->my_dao_seqno);
}
#endif /* RPL_WITH_DAO_ACK */
/*---------------------------------------------------------------------------*/
void void
dao_output(rpl_parent_t *parent, uint8_t lifetime) dao_output(rpl_parent_t *parent, uint8_t lifetime)
{ {
@ -821,12 +965,43 @@ dao_output(rpl_parent_t *parent, uint8_t lifetime)
return; return;
} }
if(parent == NULL || parent->dag == NULL || parent->dag->instance == NULL) {
return;
}
#if RPL_WITH_DAO_ACK
/* set up the state since this will be the first transmission of DAO */
/* retransmissions will call directly to dao_output_target_seq */
/* keep track of my own sending of DAO for handling ack and loss of ack */
if(lifetime != RPL_ZERO_LIFETIME) {
rpl_instance_t *instance;
instance = parent->dag->instance;
instance->my_dao_seqno = dao_sequence;
instance->my_dao_transmissions = 1;
ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT,
handle_dao_retransmission, parent);
}
#else
/* We know that we have tried to register so now we are assuming
that we have a down-link - unless this is a zero lifetime one */
parent->dag->instance->has_downward_route = lifetime != RPL_ZERO_LIFETIME;
#endif /* RPL_WITH_DAO_ACK */
/* Sending a DAO with own prefix as target */ /* Sending a DAO with own prefix as target */
dao_output_target(parent, &prefix, lifetime); dao_output_target(parent, &prefix, lifetime);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
{
RPL_LOLLIPOP_INCREMENT(dao_sequence);
dao_output_target_seq(parent, prefix, lifetime, dao_sequence);
}
/*---------------------------------------------------------------------------*/
static void
dao_output_target_seq(rpl_parent_t *parent, uip_ipaddr_t *prefix,
uint8_t lifetime, uint8_t seq_no)
{ {
rpl_dag_t *dag; rpl_dag_t *dag;
rpl_instance_t *instance; rpl_instance_t *instance;
@ -867,8 +1042,6 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
#endif #endif
buffer = UIP_ICMP_PAYLOAD; buffer = UIP_ICMP_PAYLOAD;
RPL_LOLLIPOP_INCREMENT(dao_sequence);
pos = 0; pos = 0;
buffer[pos++] = instance->instance_id; buffer[pos++] = instance->instance_id;
@ -876,12 +1049,12 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
#if RPL_DAO_SPECIFY_DAG #if RPL_DAO_SPECIFY_DAG
buffer[pos] |= RPL_DAO_D_FLAG; buffer[pos] |= RPL_DAO_D_FLAG;
#endif /* RPL_DAO_SPECIFY_DAG */ #endif /* RPL_DAO_SPECIFY_DAG */
#if RPL_CONF_DAO_ACK #if RPL_WITH_DAO_ACK
buffer[pos] |= RPL_DAO_K_FLAG; buffer[pos] |= RPL_DAO_K_FLAG;
#endif /* RPL_CONF_DAO_ACK */ #endif /* RPL_WITH_DAO_ACK */
++pos; ++pos;
buffer[pos++] = 0; /* reserved */ buffer[pos++] = 0; /* reserved */
buffer[pos++] = dao_sequence; buffer[pos++] = seq_no;
#if RPL_DAO_SPECIFY_DAG #if RPL_DAO_SPECIFY_DAG
memcpy(buffer + pos, &dag->dag_id, sizeof(dag->dag_id)); memcpy(buffer + pos, &dag->dag_id, sizeof(dag->dag_id));
pos+=sizeof(dag->dag_id); pos+=sizeof(dag->dag_id);
@ -904,7 +1077,8 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
buffer[pos++] = 0; /* path seq - ignored */ buffer[pos++] = 0; /* path seq - ignored */
buffer[pos++] = lifetime; buffer[pos++] = lifetime;
PRINTF("RPL: Sending %sDAO with prefix ", lifetime == RPL_ZERO_LIFETIME ? "No-Path " : ""); PRINTF("RPL: Sending a %sDAO with sequence number %u, lifetime %u, prefix ",
lifetime == RPL_ZERO_LIFETIME ? "No-Path " : "", seq_no, lifetime);
PRINT6ADDR(prefix); PRINT6ADDR(prefix);
PRINTF(" to "); PRINTF(" to ");
PRINT6ADDR(rpl_get_parent_ipaddr(parent)); PRINT6ADDR(rpl_get_parent_ipaddr(parent));
@ -918,41 +1092,113 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
static void static void
dao_ack_input(void) dao_ack_input(void)
{ {
#if DEBUG #if RPL_WITH_DAO_ACK
unsigned char *buffer;
uint8_t *buffer;
uint8_t instance_id;
uint8_t sequence; uint8_t sequence;
uint8_t status; uint8_t status;
rpl_instance_t *instance;
rpl_parent_t *parent;
buffer = UIP_ICMP_PAYLOAD; buffer = UIP_ICMP_PAYLOAD;
instance_id = buffer[0];
sequence = buffer[2]; sequence = buffer[2];
status = buffer[3]; status = buffer[3];
PRINTF("RPL: Received a DAO ACK with sequence number %d and status %d from ", instance = rpl_get_instance(instance_id);
sequence, status); if(instance == NULL) {
uip_clear_buf();
return;
}
parent = rpl_find_parent(instance->current_dag, &UIP_IP_BUF->srcipaddr);
if(parent == NULL) {
/* not a known instance - drop the packet and ignore */
uip_clear_buf();
return;
}
PRINTF("RPL: Received a DAO %s with sequence number %d (%d) and status %d from ",
status < 128 ? "ACK" : "NACK",
sequence, instance->my_dao_seqno, status);
PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("\n"); PRINTF("\n");
#endif /* DEBUG */
if(sequence == instance->my_dao_seqno) {
instance->has_downward_route = status < 128;
/* always stop the retransmit timer when the ACK arrived */
ctimer_stop(&instance->dao_retransmit_timer);
/* Inform objective function on status of the DAO ACK */
if(instance->of->dao_ack_callback) {
instance->of->dao_ack_callback(parent, status);
}
#if RPL_REPAIR_ON_DAO_NACK
if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) {
/*
* Failed the DAO transmission - need to remove the default route.
* Trigger a local repair since we can not get our DAO in.
*/
rpl_local_repair(instance);
}
#endif
} else {
/* this DAO ACK should be forwarded to another recently registered route */
uip_ds6_route_t *re;
uip_ipaddr_t *nexthop;
if((re = find_route_entry_by_dao_ack(sequence)) != NULL) {
/* pick the recorded seq no from that node and forward DAO ACK - and
clear the pending flag*/
RPL_ROUTE_CLEAR_DAO_PENDING(re);
nexthop = uip_ds6_route_nexthop(re);
if(nexthop == NULL) {
PRINTF("RPL: No next hop to fwd DAO ACK to\n");
} else {
PRINTF("RPL: Fwd DAO ACK to:");
PRINT6ADDR(nexthop);
PRINTF("\n");
buffer[2] = re->state.dao_seqno_in;
uip_icmp6_send(nexthop, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
}
if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) {
/* this node did not get in to the routing tables above... - remove */
uip_ds6_route_rm(re);
}
} else {
PRINTF("RPL: No route entry to fwd DAO ACK to\n");
}
}
#endif /* RPL_WITH_DAO_ACK */
uip_clear_buf(); uip_clear_buf();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence) dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence,
uint8_t status)
{ {
#if RPL_WITH_DAO_ACK
unsigned char *buffer; unsigned char *buffer;
PRINTF("RPL: Sending a DAO ACK with sequence number %d to ", sequence); PRINTF("RPL: Sending a DAO %s with sequence number %d to ", status < 128 ? "ACK" : "NACK", sequence);
PRINT6ADDR(dest); PRINT6ADDR(dest);
PRINTF("\n"); PRINTF(" with status %d\n", status);
buffer = UIP_ICMP_PAYLOAD; buffer = UIP_ICMP_PAYLOAD;
buffer[0] = instance->instance_id; buffer[0] = instance->instance_id;
buffer[1] = 0; buffer[1] = 0;
buffer[2] = sequence; buffer[2] = sequence;
buffer[3] = 0; buffer[3] = status;
uip_icmp6_send(dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4); uip_icmp6_send(dest, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
#endif /* RPL_WITH_DAO_ACK */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void

View file

@ -54,6 +54,9 @@
static void reset(rpl_dag_t *); static void reset(rpl_dag_t *);
static void neighbor_link_callback(rpl_parent_t *, int, int); static void neighbor_link_callback(rpl_parent_t *, int, int);
#if RPL_WITH_DAO_ACK
static void dao_ack_callback(rpl_parent_t *, int);
#endif
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);
@ -62,6 +65,9 @@ static void update_metric_container(rpl_instance_t *);
rpl_of_t rpl_mrhof = { rpl_of_t rpl_mrhof = {
reset, reset,
neighbor_link_callback, neighbor_link_callback,
#if RPL_WITH_DAO_ACK
dao_ack_callback,
#endif
best_parent, best_parent,
best_dag, best_dag,
calculate_rank, calculate_rank,
@ -117,6 +123,25 @@ reset(rpl_dag_t *dag)
PRINTF("RPL: Reset MRHOF\n"); PRINTF("RPL: Reset MRHOF\n");
} }
#if RPL_WITH_DAO_ACK
static void
dao_ack_callback(rpl_parent_t *p, int status)
{
if(status == RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT) {
return;
}
/* here we need to handle failed DAO's and other stuff */
PRINTF("RPL: MRHOF - DAO ACK received with status: %d\n", status);
if(status >= RPL_DAO_ACK_UNABLE_TO_ACCEPT) {
/* punish the ETX as if this was 10 packets lost */
neighbor_link_callback(p, MAC_TX_OK, 10);
} else if(status == RPL_DAO_ACK_TIMEOUT) { /* timeout = no ack */
/* punish the total lack of ACK with a similar punishment */
neighbor_link_callback(p, MAC_TX_OK, 10);
}
}
#endif /* RPL_WITH_DAO_ACK */
static void static void
neighbor_link_callback(rpl_parent_t *p, int status, int numtx) neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
{ {

View file

@ -0,0 +1,258 @@
/*
* Copyright (c) 2014-2015, Yanzi Networks AB.
* 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 copyright holders 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 COPYRIGHT HOLDERS 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
* COPYRIGHT HOLDERS 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.
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
*
* Default RPL NBR policy
* decides when to add a new discovered node to the nbr table from RPL.
*
* \author Joakim Eriksson <joakime@sics.se>
* Contributors: Niclas Finne <nfi@sics.se>, Oriol Piñol <oriol@yanzi.se>,
*
*/
#include "net/rpl/rpl-private.h"
#include "net/nbr-table.h"
#include "net/ipv6/uip-ds6-nbr.h"
#include "net/ipv6/uip-ds6-route.h"
#define DEBUG DEBUG_NONE
#include "net/ip/uip-debug.h"
/*
* Policy for neighbor adds
* - one node is locked (default route)
* - max X children (nexthops)
* - max Y "best parents"
* => at least MAX_NBRS - (Y + X + 1) free slots for other.
*
* NOTE: this policy assumes that all neighbors end up being IPv6
* neighbors and are not only MAC neighbors.
*/
#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 2)
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
static int num_parents; /* any node that are possible parents */
static int num_children; /* all children that we have as nexthop */
static int num_free;
static linkaddr_t *worst_rank_nbr; /* the parent that has the worst rank */
static rpl_rank_t worst_rank;
/*---------------------------------------------------------------------------*/
#if DEBUG == DEBUG_FULL
/*
* This create a periodic call of the update_nbr function that will print
* useful debugging information when in DEBUG_FULL mode
*/
static void update_nbr(void);
static struct ctimer periodic_timer;
static int timer_init = 0;
static void
handle_periodic_timer(void *ptr)
{
update_nbr();
ctimer_restart(&periodic_timer);
}
#endif /* DEBUG == DEBUG_FULL */
/*---------------------------------------------------------------------------*/
static void
update_nbr(void)
{
uip_ds6_nbr_t *nbr;
rpl_parent_t *parent;
int num_used;
int is_used;
rpl_rank_t rank;
#if DEBUG == DEBUG_FULL
if(!timer_init) {
timer_init = 1;
ctimer_set(&periodic_timer, 60 * CLOCK_SECOND,
&handle_periodic_timer, NULL);
}
#endif /* DEBUG == DEBUG_FULL */
worst_rank = 0;
worst_rank_nbr = NULL;
num_used = 0;
num_parents = 0;
num_children = 0;
nbr = nbr_table_head(ds6_neighbors);
while(nbr != NULL) {
linkaddr_t *lladdr = nbr_table_get_lladdr(ds6_neighbors, nbr);
is_used = 0;
/*
* Check if this neighbor is used as nexthop and therefor being a
* RPL child.
*/
if(uip_ds6_route_is_nexthop(&nbr->ipaddr) != 0) {
is_used++;
num_children++;
}
parent = rpl_get_parent((uip_lladdr_t *)lladdr);
if(parent != NULL) {
num_parents++;
if(parent->dag != NULL && parent->dag->preferred_parent == parent) {
/*
* This is the preferred parent for the DAG and must not be removed
* Note: this assumes that only RPL adds default routes.
*/
} else if(is_used == 0 && worst_rank < INFINITE_RANK &&
parent->rank > 0 &&
parent->dag != NULL &&
parent->dag->instance != NULL &&
(rank = parent->dag->instance->of->calculate_rank(parent, 0)) > worst_rank) {
/* This is the worst-rank neighbor - this is a good candidate for removal */
worst_rank = rank;
worst_rank_nbr = lladdr;
}
/* add to is_used after evaluation of is_used above */
is_used++;
}
if(is_used == 0) {
/* This neighbor is neither parent or child and can be safely removed */
worst_rank_nbr = lladdr;
worst_rank = INFINITE_RANK;
} else if(is_used > 1) {
PRINTF("NBR-POLICY: *** Neighbor is both child and candidate parent: ");
PRINTLLADDR((uip_lladdr_t *)lladdr);
PRINTF("\n");
}
nbr = nbr_table_next(ds6_neighbors, nbr);
num_used++;
}
/* how many more IP neighbors can be have? */
num_free = NBR_TABLE_MAX_NEIGHBORS - num_used;
PRINTF("NBR-POLICY: Free: %d, Children: %d, Parents: %d Routes: %d\n",
num_free, num_children, num_parents, uip_ds6_route_num_routes());
}
/*---------------------------------------------------------------------------*/
/* Called whenever we get a unicast DIS - e.g. someone that already
have this node in its table - since it is a unicast */
const linkaddr_t *
find_removable_dis(uip_ipaddr_t *from)
{
update_nbr();
if(num_free > 0) {
/* there are free entries (e.g. unsused by RPL and ND6) but since it is
used by other modules we can not pick these entries for removal. */
PRINTF("Num-free > 0 = %d - Other for RPL/ND6 unused NBR entry exists .",
num_free);
}
if(num_children < MAX_CHILDREN) {
return worst_rank_nbr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
const linkaddr_t *
find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
{
rpl_instance_t *instance;
rpl_rank_t rank;
update_nbr();
instance = rpl_get_instance(dio->instance_id);
if(instance == NULL || instance->current_dag == NULL) {
PRINTF("Did not find instance id: %d\n", dio->instance_id);
return NULL;
}
/* Add the new neighbor only if it is better than the worst parent. */
rank = instance->of->calculate_rank(NULL, dio->rank);
if(rank < worst_rank - instance->min_hoprankinc / 2) {
/* Found *great* neighbor - add! */
PRINTF("Found better neighbor %d < %d - add to cache...\n",
rank, worst_rank);
return worst_rank_nbr;
}
PRINTF("Found worse neighbor with new %d and old %d - NOT add to cache.\n",
rank, worst_rank);
return NULL;
}
/*---------------------------------------------------------------------------*/
const linkaddr_t *
find_removable_dao(uip_ipaddr_t *from, rpl_instance_t *instance)
{
int max = MAX_CHILDREN;
update_nbr();
if(instance != NULL) {
/* No need to reserve space for parents for RPL ROOT */
if(instance->current_dag->rank == ROOT_RANK(instance)) {
max = NBR_TABLE_MAX_NEIGHBORS;
}
}
/* Check if this DAO sender is not yet neighbor and there is already too
many children. */
if(num_children >= max) {
PRINTF("Can not add another child - already at max.\n");
return NULL;
}
/* remove the worst ranked nbr */
return worst_rank_nbr;
}
/*---------------------------------------------------------------------------*/
const linkaddr_t *
rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data)
{
/* When we get the DIO/DAO/DIS we know that UIP contains the
incoming packet */
switch(reason) {
case NBR_TABLE_REASON_RPL_DIO:
return find_removable_dio(&UIP_IP_BUF->srcipaddr, data);
case NBR_TABLE_REASON_RPL_DAO:
return find_removable_dao(&UIP_IP_BUF->srcipaddr, data);
case NBR_TABLE_REASON_RPL_DIS:
return find_removable_dis(&UIP_IP_BUF->srcipaddr);
default:
return NULL;
}
}
/*---------------------------------------------------------------------------*/
/** @}*/

View file

@ -55,6 +55,9 @@ static void update_metric_container(rpl_instance_t *);
rpl_of_t rpl_of0 = { rpl_of_t rpl_of0 = {
reset, reset,
NULL, NULL,
#if RPL_WITH_DAO_ACK
NULL,
#endif
best_parent, best_parent,
best_dag, best_dag,
calculate_rank, calculate_rank,

View file

@ -90,6 +90,14 @@
#define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */ #define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */
#define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */ #define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */
#define RPL_DAO_ACK_UNCONDITIONAL_ACCEPT 0
#define RPL_DAO_ACK_ACCEPT 1 /* 1 - 127 is OK but not good */
#define RPL_DAO_ACK_UNABLE_TO_ACCEPT 128 /* >127 is fail */
#define RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT 255 /* root can not accept */
#define RPL_DAO_ACK_TIMEOUT -1
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* RPL IPv6 extension header option. */ /* RPL IPv6 extension header option. */
#define RPL_HDR_OPT_LEN 4 #define RPL_HDR_OPT_LEN 4
@ -117,6 +125,18 @@
#define RPL_NOPATH_REMOVAL_DELAY 60 #define RPL_NOPATH_REMOVAL_DELAY 60
#endif /* RPL_CONF_NOPATH_REMOVAL_DELAY */ #endif /* RPL_CONF_NOPATH_REMOVAL_DELAY */
#ifdef RPL_CONF_DAO_MAX_RETRANSMISSIONS
#define RPL_DAO_MAX_RETRANSMISSIONS RPL_CONF_DAO_MAX_RETRANSMISSIONS
#else
#define RPL_DAO_MAX_RETRANSMISSIONS 5
#endif /* RPL_CONF_DAO_MAX_RETRANSMISSIONS */
#ifdef RPL_CONF_DAO_RETRANSMISSION_TIMEOUT
#define RPL_DAO_RETRANSMISSION_TIMEOUT RPL_CONF_DAO_RETRANSMISSION_TIMEOUT
#else
#define RPL_DAO_RETRANSMISSION_TIMEOUT (5 * CLOCK_SECOND)
#endif /* RPL_CONF_DAO_RETRANSMISSION_TIMEOUT */
/* Special value indicating immediate removal. */ /* Special value indicating immediate removal. */
#define RPL_ZERO_LIFETIME 0 #define RPL_ZERO_LIFETIME 0
@ -250,6 +270,8 @@ typedef struct rpl_stats rpl_stats_t;
extern rpl_stats_t rpl_stats; extern rpl_stats_t rpl_stats;
#endif #endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* RPL macros. */ /* RPL macros. */
@ -268,8 +290,10 @@ void dis_output(uip_ipaddr_t *addr);
void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr); void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr);
void dao_output(rpl_parent_t *, uint8_t lifetime); void dao_output(rpl_parent_t *, uint8_t lifetime);
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime); void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t); void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t, uint8_t);
void rpl_icmp6_register_handlers(void); void rpl_icmp6_register_handlers(void);
uip_ds6_nbr_t *rpl_icmp6_update_nbr_table(uip_ipaddr_t *from,
nbr_table_reason_t r, void *data);
/* RPL logic functions. */ /* RPL logic functions. */
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio); void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);

View file

@ -224,6 +224,8 @@ set_dao_lifetime_timer(rpl_instance_t *instance)
expiration_time = (clock_time_t)instance->default_lifetime * expiration_time = (clock_time_t)instance->default_lifetime *
(clock_time_t)instance->lifetime_unit * (clock_time_t)instance->lifetime_unit *
CLOCK_SECOND / 2; CLOCK_SECOND / 2;
/* make the time for the re registration be betwen 1/2 - 3/4 of lifetime */
expiration_time = expiration_time + (random_rand() % (expiration_time / 2));
PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n", PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n",
(unsigned)expiration_time); (unsigned)expiration_time);
ctimer_set(&instance->dao_lifetime_timer, expiration_time, ctimer_set(&instance->dao_lifetime_timer, expiration_time,

View file

@ -238,7 +238,8 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
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; /* always clear state flags for the no-path received when adding/refreshing */
RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep);
PRINTF("RPL: Added a route to "); PRINTF("RPL: Added a route to ");
PRINT6ADDR(prefix); PRINT6ADDR(prefix);

View file

@ -181,10 +181,19 @@ typedef struct rpl_instance rpl_instance_t;
* Updates the metric container for outgoing DIOs in a certain DAG. * Updates the metric container for outgoing DIOs in a certain DAG.
* If the objective function of the DAG does not use metric containers, * If the objective function of the DAG does not use metric containers,
* the function should set the object type to RPL_DAG_MC_NONE. * the function should set the object type to RPL_DAG_MC_NONE.
*
* dao_ack_callback(parent, status)
*
* A callback on the result of the DAO ACK. Similar to the neighbor link
* callback. A failed DAO_ACK (NACK) can be used for switching to another
* parent via changed link metric or other mechanisms.
*/ */
struct rpl_of { struct rpl_of {
void (*reset)(struct rpl_dag *); void (*reset)(struct rpl_dag *);
void (*neighbor_link_callback)(rpl_parent_t *, int, int); void (*neighbor_link_callback)(rpl_parent_t *, int, int);
#if RPL_WITH_DAO_ACK
void (*dao_ack_callback)(rpl_parent_t *, int status);
#endif
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);
@ -216,6 +225,11 @@ struct rpl_instance {
uint8_t dio_intcurrent; uint8_t dio_intcurrent;
uint8_t dio_send; /* for keeping track of which mode the timer is in */ uint8_t dio_send; /* for keeping track of which mode the timer is in */
uint8_t dio_counter; uint8_t dio_counter;
/* my last registered DAO that I might be waiting for ACK on */
uint8_t my_dao_seqno;
uint8_t my_dao_transmissions;
/* this is intended to keep track if this instance have a route downward */
uint8_t has_downward_route;
rpl_rank_t max_rankinc; rpl_rank_t max_rankinc;
rpl_rank_t min_hoprankinc; rpl_rank_t min_hoprankinc;
uint16_t lifetime_unit; /* lifetime in seconds = l_u * d_l */ uint16_t lifetime_unit; /* lifetime in seconds = l_u * d_l */
@ -233,6 +247,9 @@ struct rpl_instance {
struct ctimer dao_lifetime_timer; struct ctimer dao_lifetime_timer;
struct ctimer unicast_dio_timer; struct ctimer unicast_dio_timer;
rpl_parent_t *unicast_dio_target; rpl_parent_t *unicast_dio_target;
#if RPL_WITH_DAO_ACK
struct ctimer dao_retransmit_timer;
#endif /* RPL_WITH_DAO_ACK */
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -293,5 +310,13 @@ enum rpl_mode rpl_set_mode(enum rpl_mode mode);
*/ */
enum rpl_mode rpl_get_mode(void); enum rpl_mode rpl_get_mode(void);
/**
* Get the RPL's best guess on if we have downward route or not.
*
* \retval 1 if we have a downward route from RPL Root, 0 if not.
*/
int rpl_has_downward_route(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* RPL_H */ #endif /* RPL_H */

View file

@ -60,6 +60,9 @@
#undef NETSTACK_CONF_RDC #undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nullrdc_driver #define NETSTACK_CONF_RDC nullrdc_driver
#undef RPL_CONF_MAX_DAG_PER_INSTANCE
#define RPL_CONF_MAX_DAG_PER_INSTANCE 1
/* Disabling TCP on CoAP nodes. */ /* Disabling TCP on CoAP nodes. */
#undef UIP_CONF_TCP #undef UIP_CONF_TCP
#define UIP_CONF_TCP 0 #define UIP_CONF_TCP 0
@ -93,6 +96,13 @@
#undef COAP_PROXY_OPTION_PROCESSING #undef COAP_PROXY_OPTION_PROCESSING
#define COAP_PROXY_OPTION_PROCESSING 0 #define COAP_PROXY_OPTION_PROCESSING 0
/* Turn of DAO ACK to make code smaller */
#undef RPL_CONF_WITH_DAO_ACK
#define RPL_CONF_WITH_DAO_ACK 0
#undef RPL_CONF_OF
#define RPL_CONF_OF rpl_of0
/* Enable client-side support for COAP observe */ /* Enable client-side support for COAP observe */
#define COAP_OBSERVE_CLIENT 1 #define COAP_OBSERVE_CLIENT 1
#endif /* __PROJECT_ERBIUM_CONF_H__ */ #endif /* __PROJECT_ERBIUM_CONF_H__ */

View file

@ -3,6 +3,8 @@ APPS = powertrace collect-view
CONTIKI_PROJECT = udp-sender udp-sink CONTIKI_PROJECT = udp-sender udp-sink
PROJECT_SOURCEFILES += collect-common.c PROJECT_SOURCEFILES += collect-common.c
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
ifdef PERIOD ifdef PERIOD
CFLAGS=-DPERIOD=$(PERIOD) CFLAGS=-DPERIOD=$(PERIOD)
endif endif

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, 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.
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
#undef UIP_CONF_MAX_ROUTES
#ifdef TEST_MORE_ROUTES
/* configure number of neighbors and routes */
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#define UIP_CONF_MAX_ROUTES 30
#else
/* configure number of neighbors and routes */
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#define UIP_CONF_MAX_ROUTES 10
#endif /* TEST_MORE_ROUTES */
#undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nullrdc_driver
#undef NULLRDC_CONF_802154_AUTOACK
#define NULLRDC_CONF_802154_AUTOACK 1
/* Define as minutes */
#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60
/* 10 minutes lifetime of routes */
#define RPL_CONF_DEFAULT_LIFETIME 10
#define RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME 1
#endif /* PROJECT_CONF_H_ */

View file

@ -1,7 +1,8 @@
all: udp-client udp-server all: udp-client udp-server
APPS=servreg-hack
CONTIKI=../../.. CONTIKI=../../..
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
ifdef WITH_COMPOWER ifdef WITH_COMPOWER
APPS+=powertrace APPS+=powertrace
CFLAGS+= -DCONTIKIMAC_CONF_COMPOWER=1 -DWITH_COMPOWER=1 -DQUEUEBUF_CONF_NUM=4 CFLAGS+= -DCONTIKIMAC_CONF_COMPOWER=1 -DWITH_COMPOWER=1 -DQUEUEBUF_CONF_NUM=4

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, 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.
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
#undef UIP_CONF_MAX_ROUTES
#ifdef TEST_MORE_ROUTES
/* configure number of neighbors and routes */
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#define UIP_CONF_MAX_ROUTES 30
#else
/* configure number of neighbors and routes */
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#define UIP_CONF_MAX_ROUTES 10
#endif /* TEST_MORE_ROUTES */
#undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nullrdc_driver
#undef NULLRDC_CONF_802154_AUTOACK
#define NULLRDC_CONF_802154_AUTOACK 1
/* Define as minutes */
#define RPL_CONF_DEFAULT_LIFETIME_UNIT 60
/* 10 minutes lifetime of routes */
#define RPL_CONF_DEFAULT_LIFETIME 10
#define RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME 1
#endif /* PROJECT_CONF_H_ */

View file

@ -0,0 +1,721 @@
<?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>RPL up and downstream scaleability test network using IPv6 and RPL</title>
<randomseed>generated</randomseed>
<motedelay_us>5000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>150.0</transmitting_range>
<interference_range>150.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>
org.contikios.cooja.mspmote.WismoteMoteType
<identifier>sky1</identifier>
<description>WisMote Type #sky1</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c</source>
<commands EXPORT="discard">make SERVER_REPLY=1 clean udp-server.wismote TARGET=wismote DEFINES=TEST_MORE_ROUTES=1</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.wismote</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
</motetype>
<motetype>
org.contikios.cooja.mspmote.WismoteMoteType
<identifier>sky2</identifier>
<description>WisMote Type #sky2</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c</source>
<commands EXPORT="discard">make SERVER_REPLY=1 clean udp-client.wismote TARGET=wismote</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.wismote</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>48.435974731198804</x>
<y>-66.16503914182063</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-65.3176930733124</x>
<y>17.4304162608286</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>127.9689727848476</x>
<y>91.71883780610729</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>3</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>154.92605604103275</x>
<y>40.97896551774433</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>4</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>47.34887596588397</x>
<y>-30.341495695501195</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>5</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>47.13486576528276</x>
<y>32.944481932122315</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>6</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-11.42091423859419</x>
<y>17.879870626121914</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>7</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>118.92746659954325</x>
<y>57.05973076244069</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>8</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>56.66768196114595</x>
<y>74.35652008990945</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>9</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>16.45706316609417</x>
<y>23.9075414163248</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>10</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-13.423161364506493</x>
<y>-38.483037144768275</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>11</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-9.034961217472201</x>
<y>44.411389162165406</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>12</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>35.60049910164592</x>
<y>87.95154356223047</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>13</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>66.93880603404335</x>
<y>-42.39683727590697</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>14</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>94.81678343873172</x>
<y>26.921376811426246</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>15</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-49.449656689283934</x>
<y>57.924813144367945</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>16</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-34.02467970185502</x>
<y>-24.313824905298304</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>17</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-28.750467760427494</x>
<y>48.01822457713635</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>18</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>124.95513738974614</x>
<y>20.140247172447996</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>19</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>14.85247487703553</x>
<y>-34.478542892943686</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>20</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>154.43072661267115</x>
<y>-3.279765376986134</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>21</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>99.90960713878738</x>
<y>-21.76043658444847</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>22</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>88.4612185198951</x>
<y>-49.763990463932714</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>23</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>24.745110502623138</x>
<y>-1.7100594420374744</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>24</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>94.06332458995635</x>
<y>-2.4635182908128352</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>25</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-4.639784599615941</x>
<y>-10.849236218849724</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>26</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>2.4901685804620115</x>
<y>-60.89843789583528</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>27</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>100.55144245441083</x>
<y>97.41861446767646</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>28</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-12.355761328741393</x>
<y>82.72616691655692</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>29</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>57.79962925723111</x>
<y>0.6828700499064966</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>30</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>76.5550413097159</x>
<y>77.33875258624342</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>31</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>289</width>
<z>4</z>
<height>184</height>
<location_x>31</location_x>
<location_y>41</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<moterelations>true</moterelations>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
<viewport>2.349818846983307 0.0 0.0 2.349818846983307 187.19773526533345 190.95275613586946</viewport>
</plugin_config>
<width>659</width>
<z>2</z>
<height>622</height>
<location_x>296</location_x>
<location_y>11</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter>ID:22.*DAO</filter>
<formatted_time />
<coloring />
</plugin_config>
<width>937</width>
<z>3</z>
<height>442</height>
<location_x>20</location_x>
<location_y>297</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.ScriptRunner
<plugin_config>
<script>TIMEOUT(12000000, log.log("Total PRR " + totalPRR + "\n"));
packetsReceived= new Array();
packetsSent = new Array();
serverID = 1;
nodeCount = 31;
totalPRR = 0;
for(i = 0; i &lt;= nodeCount; i++) {
packetsReceived[i] = 0;
packetsSent[i] = 0;
}
while(1) {
YIELD();
msgArray = msg.split(' ');
if(msgArray[0].equals("#A")) {
if(msgArray[1].charAt(0) == 'r') {
// Received packet
senderID = id;
arr2 = msgArray[1].split(',')[0].slice(2).split('/');
recv = parseInt(arr2[0]);
sent = parseInt(arr2[1]);
log.log("Sent:" + sent + " Recv:" + recv + "\n");
packetsSent[senderID] = sent;
packetsReceived[senderID] = recv;
log.log("SenderID " + senderID + " PRR " + packetsReceived[senderID] / packetsSent[senderID] + "\n");
totalReceived = totalSent = 0;
for(i = serverID + 1; i &lt;= nodeCount; i++) {
totalReceived += packetsReceived[i];
totalSent += packetsSent[i];
}
totalPRR = totalReceived / totalSent;
log.log("Total PRR " + totalPRR + " recv " + totalReceived + " sent " + totalSent + "\n");
}
}
}</script>
<active>true</active>
</plugin_config>
<width>600</width>
<z>5</z>
<height>700</height>
<location_x>946</location_x>
<location_y>6</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.MoteInterfaceViewer
<mote_arg>3</mote_arg>
<plugin_config>
<interface>Position</interface>
<scrollpos>0,0</scrollpos>
</plugin_config>
<width>350</width>
<z>6</z>
<height>300</height>
<location_x>976</location_x>
<location_y>36</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,729 @@
<?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>RPL up and downstream scaleability test network using IPv6 and RPL</title>
<randomseed>generated</randomseed>
<motedelay_us>5000000</motedelay_us>
<radiomedium>
org.contikios.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>
org.contikios.cooja.mspmote.SkyMoteType
<identifier>sky1</identifier>
<description>Sky Mote Type #sky1</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c</source>
<commands EXPORT="discard">make SERVER_REPLY=1 clean udp-server.sky TARGET=sky DEFINES=TEST_MORE_ROUTES=1</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<motetype>
org.contikios.cooja.mspmote.SkyMoteType
<identifier>sky2</identifier>
<description>Sky Mote Type #sky2</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c</source>
<commands EXPORT="discard">make SERVER_REPLY=1 clean udp-client.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>48.435974731198804</x>
<y>-66.16503914182063</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-39.78380986481406</x>
<y>-48.10655064098382</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>127.9689727848476</x>
<y>91.71883780610729</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>3</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>154.92605604103275</x>
<y>40.97896551774433</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>4</id>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspSerial
<history>r~;</history>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>47.34887596588397</x>
<y>-30.341495695501195</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>5</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>47.13486576528276</x>
<y>32.944481932122315</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>6</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-11.42091423859419</x>
<y>17.879870626121914</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>7</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>118.92746659954325</x>
<y>57.05973076244069</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>8</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>53.68872892015448</x>
<y>59.887319605093715</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>9</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>16.45706316609417</x>
<y>23.9075414163248</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>10</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-13.423161364506493</x>
<y>-38.483037144768275</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>11</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-9.034961217472201</x>
<y>44.411389162165406</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>12</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-39.298891643282545</x>
<y>-3.9704359883635574</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>13</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>66.93880603404335</x>
<y>-42.39683727590697</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>14</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>94.81678343873172</x>
<y>26.921376811426246</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>15</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-43.06618588715935</x>
<y>30.68867105530305</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>16</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-34.02467970185502</x>
<y>-24.313824905298304</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>17</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-28.750467760427494</x>
<y>48.01822457713635</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>18</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>124.95513738974614</x>
<y>20.140247172447996</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>19</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>15.703604317318808</x>
<y>-47.6710492173345</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>20</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>154.43072661267115</x>
<y>-3.279765376986134</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>21</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>121.18784314586934</x>
<y>-24.313824905298304</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>22</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>88.4612185198951</x>
<y>-49.763990463932714</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>23</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>24.745110502623138</x>
<y>-1.7100594420374744</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>24</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>94.06332458995635</x>
<y>-2.4635182908128352</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>25</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>-4.639784599615941</x>
<y>-9.998106778566445</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>26</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>2.4901685804620115</x>
<y>-60.89843789583528</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>27</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>103.10483077526068</x>
<y>96.99304974753483</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>28</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>8.922474678340558</x>
<y>59.320107308766765</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>29</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>58.650758697514384</x>
<y>2.8106936506146916</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>30</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>90.59867707439</x>
<y>67.97632874312737</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>31</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>289</width>
<z>1</z>
<height>184</height>
<location_x>31</location_x>
<location_y>41</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
<viewport>2.349818846983307 0.0 0.0 2.349818846983307 187.19773526533345 190.95275613586946</viewport>
</plugin_config>
<width>659</width>
<z>3</z>
<height>523</height>
<location_x>296</location_x>
<location_y>11</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>937</width>
<z>4</z>
<height>349</height>
<location_x>21</location_x>
<location_y>464</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.ScriptRunner
<plugin_config>
<script>TIMEOUT(12000000, log.log("Total PRR " + totalPRR + "\n"));
packetsReceived= new Array();
packetsSent = new Array();
serverID = 1;
nodeCount = 31;
totalPRR = 0;
for(i = 0; i &lt;= nodeCount; i++) {
packetsReceived[i] = 0;
packetsSent[i] = 0;
}
while(1) {
YIELD();
msgArray = msg.split(' ');
if(msgArray[0].equals("#A")) {
if(msgArray[1].charAt(0) == 'r') {
// Received packet
senderID = id;
arr2 = msgArray[1].split(',')[0].slice(2).split('/');
recv = parseInt(arr2[0]);
sent = parseInt(arr2[1]);
log.log("Sent:" + sent + " Recv:" + recv + "\n");
packetsSent[senderID] = sent;
packetsReceived[senderID] = recv;
log.log("SenderID " + senderID + " PRR " + packetsReceived[senderID] / packetsSent[senderID] + "\n");
totalReceived = totalSent = 0;
for(i = serverID + 1; i &lt;= nodeCount; i++) {
totalReceived += packetsReceived[i];
totalSent += packetsSent[i];
}
totalPRR = totalReceived / totalSent;
log.log("Total PRR " + totalPRR + " recv " + totalReceived + " sent " + totalSent + "\n");
}
}
}</script>
<active>true</active>
</plugin_config>
<width>600</width>
<z>0</z>
<height>700</height>
<location_x>946</location_x>
<location_y>6</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.MoteInterfaceViewer
<mote_arg>3</mote_arg>
<plugin_config>
<interface>Serial port</interface>
<scrollpos>0,0</scrollpos>
</plugin_config>
<width>350</width>
<z>2</z>
<height>300</height>
<location_x>976</location_x>
<location_y>36</location_y>
</plugin>
</simconf>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<simconf> <simconf>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mrm</project> <project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mspsim</project> <project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/avrora</project> <project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mobility</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> <simulation>
<title>Data collection network using IPv6 and RPL</title> <title>Data collection network using IPv6 and RPL</title>
<delaytime>0</delaytime>
<randomseed>generated</randomseed> <randomseed>generated</randomseed>
<motedelay_us>5000000</motedelay_us> <motedelay_us>5000000</motedelay_us>
<radiomedium> <radiomedium>
@ -24,7 +25,7 @@
<identifier>sky1</identifier> <identifier>sky1</identifier>
<description>Sky Mote Type #sky1</description> <description>Sky Mote Type #sky1</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c</source> <source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.c</source>
<commands EXPORT="discard">make udp-server.sky TARGET=sky</commands> <commands EXPORT="discard">make clean udp-server.sky TARGET=sky DEFINES=TEST_MORE_ROUTES=1</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky</firmware> <firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-server.sky</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface> <moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface> <moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
@ -47,7 +48,7 @@
<identifier>sky2</identifier> <identifier>sky2</identifier>
<description>Sky Mote Type #sky2</description> <description>Sky Mote Type #sky2</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c</source> <source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.c</source>
<commands EXPORT="discard">make udp-client.sky TARGET=sky</commands> <commands EXPORT="discard">make clean udp-client.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky</firmware> <firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-udp/udp-client.sky</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface> <moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface> <moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
@ -73,6 +74,10 @@
<y>-66.16503914182063</y> <y>-66.16503914182063</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>1</id> <id>1</id>
@ -87,6 +92,10 @@
<y>98.28771308774003</y> <y>98.28771308774003</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>2</id> <id>2</id>
@ -101,6 +110,10 @@
<y>91.71883780610729</y> <y>91.71883780610729</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>3</id> <id>3</id>
@ -115,6 +128,10 @@
<y>92.47229665488265</y> <y>92.47229665488265</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>4</id> <id>4</id>
@ -129,6 +146,10 @@
<y>-30.341495695501195</y> <y>-30.341495695501195</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>5</id> <id>5</id>
@ -143,6 +164,10 @@
<y>32.944481932122315</y> <y>32.944481932122315</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>6</id> <id>6</id>
@ -157,6 +182,10 @@
<y>17.879870626121914</y> <y>17.879870626121914</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>7</id> <id>7</id>
@ -171,6 +200,10 @@
<y>57.05973076244069</y> <y>57.05973076244069</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>8</id> <id>8</id>
@ -185,6 +218,10 @@
<y>59.887319605093715</y> <y>59.887319605093715</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>9</id> <id>9</id>
@ -199,6 +236,10 @@
<y>23.9075414163248</y> <y>23.9075414163248</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>10</id> <id>10</id>
@ -213,6 +254,10 @@
<y>75.14274313304935</y> <y>75.14274313304935</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>11</id> <id>11</id>
@ -227,6 +272,10 @@
<y>85.6911670159044</y> <y>85.6911670159044</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>12</id> <id>12</id>
@ -241,6 +290,10 @@
<y>-3.9704359883635574</y> <y>-3.9704359883635574</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>13</id> <id>13</id>
@ -255,6 +308,10 @@
<y>-42.39683727590697</y> <y>-42.39683727590697</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>14</id> <id>14</id>
@ -269,6 +326,10 @@
<y>26.921376811426246</y> <y>26.921376811426246</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>15</id> <id>15</id>
@ -283,6 +344,10 @@
<y>30.68867105530305</y> <y>30.68867105530305</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>16</id> <id>16</id>
@ -297,6 +362,10 @@
<y>-24.313824905298304</y> <y>-24.313824905298304</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>17</id> <id>17</id>
@ -311,6 +380,10 @@
<y>48.01822457713635</y> <y>48.01822457713635</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>18</id> <id>18</id>
@ -325,6 +398,10 @@
<y>20.140247172447996</y> <y>20.140247172447996</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>19</id> <id>19</id>
@ -339,6 +416,10 @@
<y>-47.6710492173345</y> <y>-47.6710492173345</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>20</id> <id>20</id>
@ -353,6 +434,10 @@
<y>92.47229665488265</y> <y>92.47229665488265</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>21</id> <id>21</id>
@ -367,6 +452,10 @@
<y>-24.313824905298304</y> <y>-24.313824905298304</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>22</id> <id>22</id>
@ -381,6 +470,10 @@
<y>-44.657213822233054</y> <y>-44.657213822233054</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>23</id> <id>23</id>
@ -395,6 +488,10 @@
<y>-1.7100594420374744</y> <y>-1.7100594420374744</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>24</id> <id>24</id>
@ -409,6 +506,10 @@
<y>-2.4635182908128352</y> <y>-2.4635182908128352</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>25</id> <id>25</id>
@ -423,6 +524,10 @@
<y>-9.998106778566445</y> <y>-9.998106778566445</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>26</id> <id>26</id>
@ -437,6 +542,10 @@
<y>-50.684884612435944</y> <y>-50.684884612435944</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>27</id> <id>27</id>
@ -451,6 +560,10 @@
<y>96.99304974753483</y> <y>96.99304974753483</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>28</id> <id>28</id>
@ -465,6 +578,10 @@
<y>59.320107308766765</y> <y>59.320107308766765</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>29</id> <id>29</id>
@ -479,6 +596,10 @@
<y>2.8106936506146916</y> <y>2.8106936506146916</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>30</id> <id>30</id>
@ -493,6 +614,10 @@
<y>67.97632874312737</y> <y>67.97632874312737</y>
<z>0.0</z> <z>0.0</z>
</interface_config> </interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config> <interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>31</id> <id>31</id>
@ -503,10 +628,10 @@
<plugin> <plugin>
org.contikios.cooja.plugins.SimControl org.contikios.cooja.plugins.SimControl
<width>259</width> <width>259</width>
<z>1</z> <z>3</z>
<height>184</height> <height>184</height>
<location_x>0</location_x> <location_x>3</location_x>
<location_y>0</location_y> <location_y>15</location_y>
</plugin> </plugin>
<plugin> <plugin>
org.contikios.cooja.plugins.Visualizer org.contikios.cooja.plugins.Visualizer
@ -517,21 +642,23 @@
<viewport>2.349818846983307 0.0 0.0 2.349818846983307 150.19773526533348 176.95275613586946</viewport> <viewport>2.349818846983307 0.0 0.0 2.349818846983307 150.19773526533348 176.95275613586946</viewport>
</plugin_config> </plugin_config>
<width>520</width> <width>520</width>
<z>3</z> <z>2</z>
<height>523</height> <height>523</height>
<location_x>269</location_x> <location_x>14</location_x>
<location_y>14</location_y> <location_y>210</location_y>
</plugin> </plugin>
<plugin> <plugin>
org.contikios.cooja.plugins.LogListener org.contikios.cooja.plugins.LogListener
<plugin_config> <plugin_config>
<filter /> <filter />
<formatted_time />
<coloring />
</plugin_config> </plugin_config>
<width>937</width> <width>937</width>
<z>0</z> <z>0</z>
<height>213</height> <height>213</height>
<location_x>21</location_x> <location_x>265</location_x>
<location_y>464</location_y> <location_y>16</location_y>
</plugin> </plugin>
<plugin> <plugin>
org.contikios.cooja.plugins.ScriptRunner org.contikios.cooja.plugins.ScriptRunner
@ -574,11 +701,11 @@ while(1) {
}</script> }</script>
<active>true</active> <active>true</active>
</plugin_config> </plugin_config>
<width>600</width> <width>651</width>
<z>2</z> <z>1</z>
<height>700</height> <height>550</height>
<location_x>665</location_x> <location_x>547</location_x>
<location_y>6</location_y> <location_y>181</location_y>
</plugin> </plugin>
</simconf> </simconf>

View file

@ -40,12 +40,17 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
/* Only for TMOTE Sky? */
#include "dev/serial-line.h"
#include "dev/uart1.h"
#include "net/ipv6/uip-ds6-route.h"
#define UDP_CLIENT_PORT 8765 #define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678 #define UDP_SERVER_PORT 5678
#define UDP_EXAMPLE_ID 190 #define UDP_EXAMPLE_ID 190
#define DEBUG DEBUG_PRINT #define DEBUG DEBUG_FULL
#include "net/ip/uip-debug.h" #include "net/ip/uip-debug.h"
#ifndef PERIOD #ifndef PERIOD
@ -64,6 +69,9 @@ static uip_ipaddr_t server_ipaddr;
PROCESS(udp_client_process, "UDP client process"); PROCESS(udp_client_process, "UDP client process");
AUTOSTART_PROCESSES(&udp_client_process); AUTOSTART_PROCESSES(&udp_client_process);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int seq_id;
static int reply;
static void static void
tcpip_handler(void) tcpip_handler(void)
{ {
@ -72,16 +80,32 @@ tcpip_handler(void)
if(uip_newdata()) { if(uip_newdata()) {
str = uip_appdata; str = uip_appdata;
str[uip_datalen()] = '\0'; str[uip_datalen()] = '\0';
printf("DATA recv '%s'\n", str); reply++;
printf("DATA recv '%s' (s:%d, r:%d)\n", str, seq_id, reply);
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
send_packet(void *ptr) send_packet(void *ptr)
{ {
static int seq_id;
char buf[MAX_PAYLOAD_LEN]; char buf[MAX_PAYLOAD_LEN];
#ifdef SERVER_REPLY
uint8_t num_used = 0;
uip_ds6_nbr_t *nbr;
nbr = nbr_table_head(ds6_neighbors);
while(nbr != NULL) {
nbr = nbr_table_next(ds6_neighbors, nbr);
num_used++;
}
if(seq_id > 0) {
ANNOTATE("#A r=%d/%d,color=%s,n=%d %d\n", reply, seq_id,
reply == seq_id ? "GREEN" : "RED", uip_ds6_route_num_routes(), num_used);
}
#endif /* SERVER_REPLY */
seq_id++; seq_id++;
PRINTF("DATA send to %d 'Hello %d'\n", PRINTF("DATA send to %d 'Hello %d'\n",
server_ipaddr.u8[sizeof(server_ipaddr.u8) - 1], seq_id); server_ipaddr.u8[sizeof(server_ipaddr.u8) - 1], seq_id);
@ -156,8 +180,9 @@ PROCESS_THREAD(udp_client_process, ev, data)
PROCESS_PAUSE(); PROCESS_PAUSE();
set_global_address(); set_global_address();
PRINTF("UDP client process started\n"); PRINTF("UDP client process started nbr:%d routes:%d\n",
NBR_TABLE_CONF_MAX_NEIGHBORS, UIP_CONF_MAX_ROUTES);
print_local_addresses(); print_local_addresses();
@ -174,6 +199,11 @@ PROCESS_THREAD(udp_client_process, ev, data)
PRINTF(" local/remote port %u/%u\n", PRINTF(" local/remote port %u/%u\n",
UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport));
/* initialize serial line */
uart1_set_input(serial_line_input_byte);
serial_line_init();
#if WITH_COMPOWER #if WITH_COMPOWER
powertrace_sniff(POWERTRACE_ON); powertrace_sniff(POWERTRACE_ON);
#endif #endif
@ -184,7 +214,41 @@ PROCESS_THREAD(udp_client_process, ev, data)
if(ev == tcpip_event) { if(ev == tcpip_event) {
tcpip_handler(); tcpip_handler();
} }
if(ev == serial_line_event_message && data != NULL) {
char *str;
str = data;
if(str[0] == 'r') {
uip_ds6_route_t *r;
uip_ipaddr_t *nexthop;
uip_ds6_defrt_t *defrt;
uip_ipaddr_t *ipaddr;
defrt = NULL;
if((ipaddr = uip_ds6_defrt_choose()) != NULL) {
defrt = uip_ds6_defrt_lookup(ipaddr);
}
if(defrt != NULL) {
PRINTF("DefRT: :: -> %02d", defrt->ipaddr.u8[15]);
PRINTF(" lt:%lu inf:%d\n", stimer_remaining(&defrt->lifetime),
defrt->isinfinite);
} else {
PRINTF("DefRT: :: -> NULL\n");
}
for(r = uip_ds6_route_head();
r != NULL;
r = uip_ds6_route_next(r)) {
nexthop = uip_ds6_route_nexthop(r);
PRINTF("Route: %02d -> %02d", r->ipaddr.u8[15], nexthop->u8[15]);
/* PRINT6ADDR(&r->ipaddr); */
/* PRINTF(" -> "); */
/* PRINT6ADDR(nexthop); */
PRINTF(" lt:%lu\n", r->state.lifetime);
}
}
}
if(etimer_expired(&periodic)) { if(etimer_expired(&periodic)) {
etimer_reset(&periodic); etimer_reset(&periodic);
ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL); ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL);

View file

@ -107,7 +107,8 @@ PROCESS_THREAD(udp_server_process, ev, data)
SENSORS_ACTIVATE(button_sensor); SENSORS_ACTIVATE(button_sensor);
PRINTF("UDP server started\n"); PRINTF("UDP server started. nbr:%d routes:%d\n",
NBR_TABLE_CONF_MAX_NEIGHBORS, UIP_CONF_MAX_ROUTES);
#if UIP_CONF_ROUTER #if UIP_CONF_ROUTER
/* The choice of server address determines its 6LoPAN header compression. /* The choice of server address determines its 6LoPAN header compression.

View file

@ -127,8 +127,8 @@ process_request() CC_NON_BANKED
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->state.lifetime) + sizeof(rt->state.lifetime);
+ sizeof(rt->state.learned_from); /* + sizeof(rt->state.learned_from); */
memcpy(buf + len, &i, sizeof(i)); memcpy(buf + len, &i, sizeof(i));
len += sizeof(i); len += sizeof(i);
@ -147,11 +147,11 @@ process_request() CC_NON_BANKED
len += sizeof(flip); len += sizeof(flip);
PRINTF(" - %08lx", rt->state.lifetime); PRINTF(" - %08lx", rt->state.lifetime);
memcpy(buf + len, &rt->state.learned_from, /* memcpy(buf + len, &rt->state.learned_from, */
sizeof(rt->state.learned_from)); /* sizeof(rt->state.learned_from)); */
len += sizeof(rt->state.learned_from); /* len += sizeof(rt->state.learned_from); */
PRINTF(" - %02x [%u]\n", rt->state.learned_from, entry_size); PRINTF(" - [%u]\n", entry_size);
count++; count++;
left -= entry_size; left -= entry_size;

View file

@ -125,10 +125,11 @@
#define UIP_CONF_ROUTER 0 #define UIP_CONF_ROUTER 0
/* configure number of neighbors and routes */ /* configure number of neighbors and routes */
#define NBR_TABLE_CONF_MAX_NEIGHBORS 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 RPL_CONF_MAX_DAG_PER_INSTANCE 1
#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
@ -140,12 +141,12 @@
#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_IP_FORWARD 0 #define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_BUFFER_SIZE 240 #define UIP_CONF_BUFFER_SIZE 200
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
#ifndef SICSLOWPAN_CONF_FRAG #ifndef SICSLOWPAN_CONF_FRAG
#define SICSLOWPAN_CONF_FRAG 1 #define SICSLOWPAN_CONF_FRAG 1
#define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 4 #define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 3
#define SICSLOWPAN_CONF_MAXAGE 8 #define SICSLOWPAN_CONF_MAXAGE 8
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2

View file

@ -7057,5 +7057,4 @@ while(true) {&#xD;
<location_x>603</location_x> <location_x>603</location_x>
<location_y>43</location_y> <location_y>43</location_y>
</plugin> </plugin>
</simconf> </simconf>

View file

@ -10,6 +10,7 @@ static struct http_socket s;
static int bytes_received = 0; static int bytes_received = 0;
static int restarts; static int restarts;
static struct ctimer reconnect_timer; static struct ctimer reconnect_timer;
static int connect = 0;
static void callback(struct http_socket *s, void *ptr, static void callback(struct http_socket *s, void *ptr,
http_socket_event_t e, http_socket_event_t e,
@ -22,9 +23,9 @@ AUTOSTART_PROCESSES(&http_example_process);
static void static void
reconnect(void *dummy) reconnect(void *dummy)
{ {
printf("#A color=orange\n");
rpl_set_mode(RPL_MODE_MESH); rpl_set_mode(RPL_MODE_MESH);
http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, connect = 1;
callback, NULL);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
@ -33,6 +34,8 @@ restart(void)
int scale; int scale;
restarts++; restarts++;
printf("restart %d\n", restarts); printf("restart %d\n", restarts);
rpl_set_mode(RPL_MODE_FEATHER);
printf("#A color=red\n");
scale = restarts; scale = restarts;
if(scale > 5) { if(scale > 5) {
@ -62,6 +65,7 @@ callback(struct http_socket *s, void *ptr,
if(bytes_received > 0) { if(bytes_received > 0) {
printf("HTTP socket closed, %d bytes received\n", bytes_received); printf("HTTP socket closed, %d bytes received\n", bytes_received);
leds_off(LEDS_RED); leds_off(LEDS_RED);
printf("#A color=blue\n");
rpl_set_mode(RPL_MODE_FEATHER); rpl_set_mode(RPL_MODE_FEATHER);
} else { } else {
restart(); restart();
@ -72,6 +76,7 @@ callback(struct http_socket *s, void *ptr,
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS_THREAD(http_example_process, ev, data) PROCESS_THREAD(http_example_process, ev, data)
{ {
static struct etimer et; static struct etimer et;
@ -88,14 +93,26 @@ PROCESS_THREAD(http_example_process, ev, data)
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
http_socket_init(&s); http_socket_init(&s);
http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, connect = 1;
callback, NULL);
leds_on(LEDS_RED); leds_on(LEDS_RED);
restarts = 0; restarts = 0;
etimer_set(&et, CLOCK_SECOND); etimer_set(&et, CLOCK_SECOND * 5);
while(1) { while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
etimer_reset(&et); etimer_reset(&et);
if(connect && rpl_has_downward_route()) {
printf("#A color=green\n");
http_socket_get(&s, "http://www.contiki-os.org/", 0, 0,
callback, NULL);
connect = 0;
} else if(connect) {
connect++;
/* If connect have been "tried" 5 timer we quit trying now... */
if(connect > 5) {
restart();
connect = 0;
}
}
} }
PROCESS_END(); PROCESS_END();

View file

@ -7,5 +7,5 @@
#undef NBR_TABLE_CONF_MAX_NEIGHBORS #undef NBR_TABLE_CONF_MAX_NEIGHBORS
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 #define NBR_TABLE_CONF_MAX_NEIGHBORS 8
/*#define RPL_CONF_DEFAULT_LIFETIME_UNIT 10 /* #define RPL_CONF_DEFAULT_LIFETIME_UNIT 60 */
#define RPL_CONF_DEFAULT_LIFETIME 10*/ /* #define RPL_CONF_DEFAULT_LIFETIME 10 */

View file

@ -3,13 +3,23 @@
#include "ip64.h" #include "ip64.h"
#include "net/netstack.h" #include "net/netstack.h"
#include "net/rpl/rpl-dag-root.h" #include "net/rpl/rpl-dag-root.h"
#include "net/rpl/rpl.h"
#include "net/ipv6/uip-ds6-route.h"
#include <stdio.h>
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS(router_node_process, "Router node"); PROCESS(router_node_process, "Router node");
AUTOSTART_PROCESSES(&router_node_process); AUTOSTART_PROCESSES(&router_node_process);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uip_lladdr_t * uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route);
PROCESS_THREAD(router_node_process, ev, data) PROCESS_THREAD(router_node_process, ev, data)
{ {
uip_ipaddr_t *nexthop = NULL;
uip_ds6_defrt_t *defrt;
uip_ipaddr_t *ipaddr;
uip_ds6_route_t *r;
static struct etimer et;
PROCESS_BEGIN(); PROCESS_BEGIN();
/* Set us up as a RPL root node. */ /* Set us up as a RPL root node. */
@ -18,9 +28,41 @@ PROCESS_THREAD(router_node_process, ev, data)
/* Initialize the IP64 module so we'll start translating packets */ /* Initialize the IP64 module so we'll start translating packets */
ip64_init(); ip64_init();
/* etimer_set(&et, CLOCK_SECOND * 60); */
/* PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); */
/* ... and do nothing more. */ /* ... and do nothing more. */
while(1) { while(1) {
PROCESS_WAIT_EVENT(); etimer_set(&et, CLOCK_SECOND * 20);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
defrt = NULL;
if((ipaddr = uip_ds6_defrt_choose()) != NULL) {
defrt = uip_ds6_defrt_lookup(ipaddr);
}
if(defrt != NULL) {
printf("DefRT: :: -> %02d", defrt->ipaddr.u8[15]);
printf(" lt:%lu inf:%d\n", stimer_remaining(&defrt->lifetime),
defrt->isinfinite);
} else {
printf("DefRT: :: -> NULL\n");
}
if(uip_ds6_route_head() != NULL) {
printf("found head\n");
for(r = uip_ds6_route_head();
r != NULL;
r = uip_ds6_route_next(r)) {
nexthop = uip_ds6_route_nexthop(r);
if(nexthop != NULL) {
printf("Route: %02d -> %02d", r->ipaddr.u8[15], nexthop->u8[15]);
} else {
//printf("Route: %p %02d -> ? nbr-routes:%p", r, r->ipaddr.u8[15],
//r->neighbor_routes);
}
printf(" lt:%lu\n", r->state.lifetime);
}
}
} }
PROCESS_END(); PROCESS_END();