Cleaned up the collect neighbor management code

This commit is contained in:
adamdunkels 2010-10-03 20:07:10 +00:00
parent b23a364397
commit d0579c8a81
2 changed files with 86 additions and 101 deletions

View file

@ -33,7 +33,7 @@
* *
* This file is part of the Contiki operating system. * 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); 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 #define DEBUG 0
#if DEBUG #if DEBUG
@ -78,32 +79,22 @@ static void
periodic(void *ptr) periodic(void *ptr)
{ {
struct collect_neighbor_list *neighbor_list; struct collect_neighbor_list *neighbor_list;
struct collect_neighbor *n, *next; struct collect_neighbor *n;
neighbor_list = ptr; neighbor_list = ptr;
/* Go through all collect_neighbors and remove old ones. */ /* Go through all collect_neighbors and increase their age. */
for(n = list_head(neighbor_list->list); n != NULL; n = next) { for(n = list_head(neighbor_list->list); n != NULL; n = list_item_next(n)) {
next = NULL; n->age++;
if(!rimeaddr_cmp(&n->addr, &rimeaddr_null) && }
n->time < max_time) { for(n = list_head(neighbor_list->list); n != NULL; n = list_item_next(n)) {
n->time++; if(n->age == MAX_AGE) {
if(n->time == max_time) { list_remove(neighbor_list->list, n);
n->rtmetric = RTMETRIC_MAX; n = list_head(neighbor_list->list);
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);
} }
} }
ctimer_set(&neighbor_list->periodic, CLOCK_SECOND, periodic, neighbor_list); ctimer_set(&neighbor_list->periodic, PERIODIC_INTERVAL,
periodic, neighbor_list);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
@ -137,20 +128,17 @@ collect_neighbor_list_find(struct collect_neighbor_list *neighbors_list,
return NULL; return NULL;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void int
collect_neighbor_list_add(struct collect_neighbor_list *neighbors_list, 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; struct collect_neighbor *n;
uint16_t le;
struct collect_neighbor *n, *max;
PRINTF("collect_neighbor_add: adding %d.%d\n", addr->u8[0], addr->u8[1]); PRINTF("collect_neighbor_add: adding %d.%d\n", addr->u8[0], addr->u8[1]);
/* Check if the collect_neighbor is already on the list. */ /* Check if the collect_neighbor is already on the list. */
for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) { for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) {
if(rimeaddr_cmp(&n->addr, &rimeaddr_null) || if(rimeaddr_cmp(&n->addr, addr)) {
rimeaddr_cmp(&n->addr, addr)) {
PRINTF("collect_neighbor_add: already on list %d.%d\n", PRINTF("collect_neighbor_add: already on list %d.%d\n",
addr->u8[0], addr->u8[1]); addr->u8[0], addr->u8[1]);
break; 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 /* 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) { if(n == NULL) {
PRINTF("collect_neighbor_add: not on list, not allocated, recycling %d.%d\n", uint16_t worst_rtmetric;
addr->u8[0], addr->u8[1]); struct collect_neighbor *worst_neighbor;
/* Find the first unused entry or the used entry with the highest
rtmetric and highest link estimate. */
rtmetric = 0;
le = 0;
max = NULL;
for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) { /* Find the neighbor that has the highest rtmetric. This is the
if(!rimeaddr_cmp(&n->addr, &rimeaddr_null)) { neighbor that we are least likely to be using in the
if(n->rtmetric > rtmetric) { future. But we also need to make sure that the neighbor we are
rtmetric = n->rtmetric; currently adding is not worst than the one we would be
le = collect_neighbor_link_estimate(n); replacing. If so, we don't put the new neighbor on the list. */
max = n; worst_rtmetric = 0;
} else if(n->rtmetric == rtmetric) { worst_neighbor = NULL;
if(collect_neighbor_link_estimate(n) > le) {
rtmetric = n->rtmetric; for(n = list_head(neighbors_list->list);
le = collect_neighbor_link_estimate(n); n != NULL; n = list_item_next(n)) {
max = n; if(n->rtmetric > worst_rtmetric) {
/* PRINTF("%d: found worst collect_neighbor %d with rtmetric %d, signal %d\n", worst_neighbor = n;
node_id, collect_neighbors[n].nodeid, rtmetric, signal);*/ 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) { if(n != NULL) {
n->time = 0; n->age = 0;
rimeaddr_copy(&n->addr, addr); rimeaddr_copy(&n->addr, addr);
n->rtmetric = nrtmetric; n->rtmetric = nrtmetric;
collect_link_estimate_new(&n->le); 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 void
collect_neighbor_list_remove(struct collect_neighbor_list *neighbors_list, collect_neighbor_list_remove(struct collect_neighbor_list *neighbors_list,
const rimeaddr_t *addr) 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(n != NULL) {
if(rimeaddr_cmp(&n->addr, addr)) { list_remove(neighbors_list->list, n);
PRINTF("%d.%d: removing %d.%d\n", memb_free(&collect_neighbors_mem, 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;
}
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -243,15 +230,14 @@ collect_neighbor_list_best(struct collect_neighbor_list *neighbors_list)
/* PRINTF("%d: ", node_id);*/ /* PRINTF("%d: ", node_id);*/
PRINTF("collect_neighbor_best: "); 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)) { for(n = list_head(neighbors_list->list); n != NULL; n = list_item_next(n)) {
PRINTF("%d.%d %d+%d=%d, ", PRINTF("%d.%d %d+%d=%d, ",
n->addr.u8[0], n->addr.u8[1], n->addr.u8[0], n->addr.u8[1],
n->rtmetric, collect_neighbor_link_estimate(n), n->rtmetric, collect_neighbor_link_estimate(n),
collect_neighbor_rtmetric(n)); collect_neighbor_rtmetric(n));
if(!rimeaddr_cmp(&n->addr, &rimeaddr_null) && if(collect_neighbor_rtmetric_link_estimate(n) < rtmetric) {
rtmetric > collect_neighbor_rtmetric_link_estimate(n)) {
rtmetric = collect_neighbor_rtmetric_link_estimate(n); rtmetric = collect_neighbor_rtmetric_link_estimate(n);
best = n; best = n;
} }
@ -297,59 +283,57 @@ collect_neighbor_list_purge(struct collect_neighbor_list *neighbors_list)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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) { if(n != NULL) {
PRINTF("%d.%d: collect_neighbor_update %d.%d rtmetric %d\n", PRINTF("%d.%d: collect_neighbor_update %d.%d rtmetric %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
n->addr.u8[0], n->addr.u8[1], rtmetric); n->addr.u8[0], n->addr.u8[1], rtmetric);
n->rtmetric = rtmetric; n->rtmetric = rtmetric;
n->time = 0; n->age = 0;
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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); collect_link_estimate_update_tx_fail(&n->le, num_tx);
n->age = 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void 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); collect_link_estimate_update_tx(&n->le, num_tx);
n->time = 0; n->age = 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
collect_neighbor_rx(struct collect_neighbor *n) collect_neighbor_rx(struct collect_neighbor *n)
{ {
collect_link_estimate_update_rx(&n->le); collect_link_estimate_update_rx(&n->le);
n->time = 0; n->age = 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int uint16_t
collect_neighbor_link_estimate(struct collect_neighbor *n) collect_neighbor_link_estimate(struct collect_neighbor *n)
{ {
n->age = 0;
return collect_link_estimate(&n->le); return collect_link_estimate(&n->le);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int uint16_t
collect_neighbor_rtmetric_link_estimate(struct collect_neighbor *n) collect_neighbor_rtmetric_link_estimate(struct collect_neighbor *n)
{ {
n->age = 0;
return n->rtmetric + collect_link_estimate(&n->le); return n->rtmetric + collect_link_estimate(&n->le);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int uint16_t
collect_neighbor_rtmetric(struct collect_neighbor *n) collect_neighbor_rtmetric(struct collect_neighbor *n)
{ {
n->age = 0;
return n->rtmetric; return n->rtmetric;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void
collect_neighbor_set_lifetime(int seconds)
{
max_time = seconds;
}
/*---------------------------------------------------------------------------*/
/** @} */ /** @} */

View file

@ -39,7 +39,7 @@
* *
* This file is part of the Contiki operating system. * 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 {
struct collect_neighbor *next; struct collect_neighbor *next;
uint16_t time;
rimeaddr_t addr; rimeaddr_t addr;
uint16_t rtmetric; uint16_t rtmetric;
uint16_t age;
struct collect_link_estimate le; struct collect_link_estimate le;
}; };
void collect_neighbor_init(void); 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_new(struct collect_neighbor_list *neighbor_list);
void collect_neighbor_list_add(struct collect_neighbor_list *neighbor_list, int collect_neighbor_list_add(struct collect_neighbor_list *neighbor_list,
const rimeaddr_t *addr, uint8_t rtmetric); const rimeaddr_t *addr, uint16_t rtmetric);
void collect_neighbor_list_remove(struct collect_neighbor_list *neighbor_list, void collect_neighbor_list_remove(struct collect_neighbor_list *neighbor_list,
const rimeaddr_t *addr); const rimeaddr_t *addr);
struct collect_neighbor *collect_neighbor_list_find(struct collect_neighbor_list *neighbor_list, 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); 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_list_purge(struct collect_neighbor_list *neighbor_list);
void collect_neighbor_update_rtmetric(struct collect_neighbor *n, uint8_t rtmetric); void collect_neighbor_update_rtmetric(struct collect_neighbor *n,
void collect_neighbor_set_lifetime(int seconds); uint16_t rtmetric);
void collect_neighbor_tx(struct collect_neighbor *n, uint8_t num_tx); void collect_neighbor_tx(struct collect_neighbor *n, uint16_t num_tx);
void collect_neighbor_rx(struct collect_neighbor *n); void collect_neighbor_rx(struct collect_neighbor *n);
void collect_neighbor_tx_fail(struct collect_neighbor *n, uint8_t num_tx); void collect_neighbor_tx_fail(struct collect_neighbor *n, uint16_t num_tx);
int collect_neighbor_link_estimate(struct collect_neighbor *n); uint16_t collect_neighbor_link_estimate(struct collect_neighbor *n);
int collect_neighbor_rtmetric_link_estimate(struct collect_neighbor *n); uint16_t collect_neighbor_rtmetric_link_estimate(struct collect_neighbor *n);
int collect_neighbor_rtmetric(struct collect_neighbor *n); uint16_t collect_neighbor_rtmetric(struct collect_neighbor *n);
#endif /* __COLLECT_NEIGHBOR_H__ */ #endif /* __COLLECT_NEIGHBOR_H__ */