From d0579c8a818864bb11e222e602443ba6303a8985 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 3 Oct 2010 20:07:10 +0000 Subject: [PATCH] Cleaned up the collect neighbor management code --- core/net/rime/collect-neighbor.c | 164 ++++++++++++++----------------- core/net/rime/collect-neighbor.h | 23 ++--- 2 files changed, 86 insertions(+), 101 deletions(-) diff --git a/core/net/rime/collect-neighbor.c b/core/net/rime/collect-neighbor.c index 7cb5ce4ad..cdd26ee3d 100644 --- a/core/net/rime/collect-neighbor.c +++ b/core/net/rime/collect-neighbor.c @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: collect-neighbor.c,v 1.6 2010/09/22 22:04:55 adamdunkels Exp $ + * $Id: collect-neighbor.c,v 1.7 2010/10/03 20:07:10 adamdunkels Exp $ */ /** @@ -63,7 +63,8 @@ MEMB(collect_neighbors_mem, struct collect_neighbor, MAX_COLLECT_NEIGHBORS); -static int max_time = 2400; +#define MAX_AGE 60 +#define PERIODIC_INTERVAL CLOCK_SECOND * 60 #define DEBUG 0 #if DEBUG @@ -78,32 +79,22 @@ static void periodic(void *ptr) { struct collect_neighbor_list *neighbor_list; - struct collect_neighbor *n, *next; + struct collect_neighbor *n; neighbor_list = ptr; - /* Go through all collect_neighbors and remove old ones. */ - for(n = list_head(neighbor_list->list); n != NULL; n = next) { - next = NULL; - if(!rimeaddr_cmp(&n->addr, &rimeaddr_null) && - n->time < max_time) { - n->time++; - if(n->time == max_time) { - n->rtmetric = RTMETRIC_MAX; - PRINTF("%d.%d: removing old collect_neighbor %d.%d\n", - rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1], - n->addr.u8[0], n->addr.u8[1]); - rimeaddr_copy(&n->addr, &rimeaddr_null); - next = list_item_next(n); - list_remove(neighbor_list->list, n); - memb_free(&collect_neighbors_mem, n); - } - } - if(next == NULL) { - next = list_item_next(n); + /* Go through all collect_neighbors and increase their age. */ + for(n = list_head(neighbor_list->list); n != NULL; n = list_item_next(n)) { + n->age++; + } + for(n = list_head(neighbor_list->list); n != NULL; n = list_item_next(n)) { + if(n->age == MAX_AGE) { + list_remove(neighbor_list->list, n); + n = list_head(neighbor_list->list); } } - ctimer_set(&neighbor_list->periodic, CLOCK_SECOND, periodic, neighbor_list); + ctimer_set(&neighbor_list->periodic, PERIODIC_INTERVAL, + periodic, neighbor_list); } /*---------------------------------------------------------------------------*/ void @@ -137,20 +128,17 @@ collect_neighbor_list_find(struct collect_neighbor_list *neighbors_list, return NULL; } /*---------------------------------------------------------------------------*/ -void +int collect_neighbor_list_add(struct collect_neighbor_list *neighbors_list, - const rimeaddr_t *addr, uint8_t nrtmetric) + const rimeaddr_t *addr, uint16_t nrtmetric) { - uint16_t rtmetric; - uint16_t le; - struct collect_neighbor *n, *max; + struct collect_neighbor *n; PRINTF("collect_neighbor_add: adding %d.%d\n", addr->u8[0], addr->u8[1]); - + /* Check if the collect_neighbor is already on the list. */ for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) { - if(rimeaddr_cmp(&n->addr, &rimeaddr_null) || - rimeaddr_cmp(&n->addr, addr)) { + if(rimeaddr_cmp(&n->addr, addr)) { PRINTF("collect_neighbor_add: already on list %d.%d\n", addr->u8[0], addr->u8[1]); break; @@ -169,64 +157,63 @@ collect_neighbor_list_add(struct collect_neighbor_list *neighbors_list, } /* If we could not allocate memory, we try to recycle an old - collect_neighbor */ + neighbor. XXX Should also look for the one with the worst + rtmetric (not link esimate). XXX Also make sure that we don't + replace a neighbor with a neighbor that has a worse metric. */ if(n == NULL) { - PRINTF("collect_neighbor_add: not on list, not allocated, recycling %d.%d\n", - addr->u8[0], addr->u8[1]); - /* Find the first unused entry or the used entry with the highest - rtmetric and highest link estimate. */ - rtmetric = 0; - le = 0; - max = NULL; + uint16_t worst_rtmetric; + struct collect_neighbor *worst_neighbor; - for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) { - if(!rimeaddr_cmp(&n->addr, &rimeaddr_null)) { - if(n->rtmetric > rtmetric) { - rtmetric = n->rtmetric; - le = collect_neighbor_link_estimate(n); - max = n; - } else if(n->rtmetric == rtmetric) { - if(collect_neighbor_link_estimate(n) > le) { - rtmetric = n->rtmetric; - le = collect_neighbor_link_estimate(n); - max = n; - /* PRINTF("%d: found worst collect_neighbor %d with rtmetric %d, signal %d\n", - node_id, collect_neighbors[n].nodeid, rtmetric, signal);*/ - } - } + /* Find the neighbor that has the highest rtmetric. This is the + neighbor that we are least likely to be using in the + future. But we also need to make sure that the neighbor we are + currently adding is not worst than the one we would be + replacing. If so, we don't put the new neighbor on the list. */ + worst_rtmetric = 0; + worst_neighbor = NULL; + + for(n = list_head(neighbors_list->list); + n != NULL; n = list_item_next(n)) { + if(n->rtmetric > worst_rtmetric) { + worst_neighbor = n; + worst_rtmetric = n->rtmetric; } } - n = max; + + /* Only add this new neighbor if its rtmetric is lower than the + one it would replace. */ + if(nrtmetric < worst_rtmetric) { + n = worst_neighbor; + } + PRINTF("collect_neighbor_add: not on list, not allocated, recycling %d.%d\n", + n->addr.u8[0], n->addr.u8[1]); } - - /* PRINTF("%d: adding collect_neighbor %d with rtmetric %d, signal %d at %d\n", - node_id, collect_neighbors[n].nodeid, rtmetric, signal, n);*/ if(n != NULL) { - n->time = 0; + n->age = 0; rimeaddr_copy(&n->addr, addr); n->rtmetric = nrtmetric; collect_link_estimate_new(&n->le); + return 1; } + return 0; +} +/*---------------------------------------------------------------------------*/ +list_t +collect_neighbor_list(struct collect_neighbor_list *neighbors_list) +{ + return neighbors_list->list; } /*---------------------------------------------------------------------------*/ void collect_neighbor_list_remove(struct collect_neighbor_list *neighbors_list, const rimeaddr_t *addr) { - struct collect_neighbor *n; + struct collect_neighbor *n = collect_neighbor_list_find(neighbors_list, addr); - for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) { - if(rimeaddr_cmp(&n->addr, addr)) { - PRINTF("%d.%d: removing %d.%d\n", - rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], - addr->u8[0], addr->u8[1]); - rimeaddr_copy(&n->addr, &rimeaddr_null); - n->rtmetric = RTMETRIC_MAX; - list_remove(neighbors_list->list, n); - memb_free(&collect_neighbors_mem, n); - return; - } + if(n != NULL) { + list_remove(neighbors_list->list, n); + memb_free(&collect_neighbors_mem, n); } } /*---------------------------------------------------------------------------*/ @@ -243,15 +230,14 @@ collect_neighbor_list_best(struct collect_neighbor_list *neighbors_list) /* PRINTF("%d: ", node_id);*/ PRINTF("collect_neighbor_best: "); - - /* Find the lowest rtmetric. */ + + /* Find the neighbor with the lowest rtmetric + linkt estimate. */ for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) { PRINTF("%d.%d %d+%d=%d, ", n->addr.u8[0], n->addr.u8[1], n->rtmetric, collect_neighbor_link_estimate(n), collect_neighbor_rtmetric(n)); - if(!rimeaddr_cmp(&n->addr, &rimeaddr_null) && - rtmetric > collect_neighbor_rtmetric_link_estimate(n)) { + if(collect_neighbor_rtmetric_link_estimate(n) < rtmetric) { rtmetric = collect_neighbor_rtmetric_link_estimate(n); best = n; } @@ -297,59 +283,57 @@ collect_neighbor_list_purge(struct collect_neighbor_list *neighbors_list) } /*---------------------------------------------------------------------------*/ void -collect_neighbor_update_rtmetric(struct collect_neighbor *n, uint8_t rtmetric) +collect_neighbor_update_rtmetric(struct collect_neighbor *n, uint16_t rtmetric) { if(n != NULL) { PRINTF("%d.%d: collect_neighbor_update %d.%d rtmetric %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], n->addr.u8[0], n->addr.u8[1], rtmetric); n->rtmetric = rtmetric; - n->time = 0; + n->age = 0; } } /*---------------------------------------------------------------------------*/ void -collect_neighbor_tx_fail(struct collect_neighbor *n, uint8_t num_tx) +collect_neighbor_tx_fail(struct collect_neighbor *n, uint16_t num_tx) { collect_link_estimate_update_tx_fail(&n->le, num_tx); + n->age = 0; } /*---------------------------------------------------------------------------*/ void -collect_neighbor_tx(struct collect_neighbor *n, uint8_t num_tx) +collect_neighbor_tx(struct collect_neighbor *n, uint16_t num_tx) { collect_link_estimate_update_tx(&n->le, num_tx); - n->time = 0; + n->age = 0; } /*---------------------------------------------------------------------------*/ void collect_neighbor_rx(struct collect_neighbor *n) { collect_link_estimate_update_rx(&n->le); - n->time = 0; + n->age = 0; } /*---------------------------------------------------------------------------*/ -int +uint16_t collect_neighbor_link_estimate(struct collect_neighbor *n) { + n->age = 0; return collect_link_estimate(&n->le); } /*---------------------------------------------------------------------------*/ -int +uint16_t collect_neighbor_rtmetric_link_estimate(struct collect_neighbor *n) { + n->age = 0; return n->rtmetric + collect_link_estimate(&n->le); } /*---------------------------------------------------------------------------*/ -int +uint16_t collect_neighbor_rtmetric(struct collect_neighbor *n) { + n->age = 0; return n->rtmetric; } /*---------------------------------------------------------------------------*/ -void -collect_neighbor_set_lifetime(int seconds) -{ - max_time = seconds; -} -/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/core/net/rime/collect-neighbor.h b/core/net/rime/collect-neighbor.h index 28abace89..58dfd782e 100644 --- a/core/net/rime/collect-neighbor.h +++ b/core/net/rime/collect-neighbor.h @@ -39,7 +39,7 @@ * * This file is part of the Contiki operating system. * - * $Id: collect-neighbor.h,v 1.4 2010/09/22 22:04:55 adamdunkels Exp $ + * $Id: collect-neighbor.h,v 1.5 2010/10/03 20:07:10 adamdunkels Exp $ */ /** @@ -63,19 +63,20 @@ struct collect_neighbor_list { struct collect_neighbor { struct collect_neighbor *next; - uint16_t time; rimeaddr_t addr; uint16_t rtmetric; + uint16_t age; struct collect_link_estimate le; }; void collect_neighbor_init(void); +list_t collect_neighbor_list(struct collect_neighbor_list *neighbor_list); void collect_neighbor_list_new(struct collect_neighbor_list *neighbor_list); -void collect_neighbor_list_add(struct collect_neighbor_list *neighbor_list, - const rimeaddr_t *addr, uint8_t rtmetric); +int collect_neighbor_list_add(struct collect_neighbor_list *neighbor_list, + const rimeaddr_t *addr, uint16_t rtmetric); void collect_neighbor_list_remove(struct collect_neighbor_list *neighbor_list, const rimeaddr_t *addr); struct collect_neighbor *collect_neighbor_list_find(struct collect_neighbor_list *neighbor_list, @@ -85,14 +86,14 @@ int collect_neighbor_list_num(struct collect_neighbor_list *neighbor_list); struct collect_neighbor *collect_neighbor_list_get(struct collect_neighbor_list *neighbor_list, int num); void collect_neighbor_list_purge(struct collect_neighbor_list *neighbor_list); -void collect_neighbor_update_rtmetric(struct collect_neighbor *n, uint8_t rtmetric); -void collect_neighbor_set_lifetime(int seconds); -void collect_neighbor_tx(struct collect_neighbor *n, uint8_t num_tx); +void collect_neighbor_update_rtmetric(struct collect_neighbor *n, + uint16_t rtmetric); +void collect_neighbor_tx(struct collect_neighbor *n, uint16_t num_tx); void collect_neighbor_rx(struct collect_neighbor *n); -void collect_neighbor_tx_fail(struct collect_neighbor *n, uint8_t num_tx); -int collect_neighbor_link_estimate(struct collect_neighbor *n); -int collect_neighbor_rtmetric_link_estimate(struct collect_neighbor *n); -int collect_neighbor_rtmetric(struct collect_neighbor *n); +void collect_neighbor_tx_fail(struct collect_neighbor *n, uint16_t num_tx); +uint16_t collect_neighbor_link_estimate(struct collect_neighbor *n); +uint16_t collect_neighbor_rtmetric_link_estimate(struct collect_neighbor *n); +uint16_t collect_neighbor_rtmetric(struct collect_neighbor *n); #endif /* __COLLECT_NEIGHBOR_H__ */