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) {
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); list_remove(neighbor_list->list, n);
memb_free(&collect_neighbors_mem, n); n = list_head(neighbor_list->list);
} }
} }
if(next == NULL) { ctimer_set(&neighbor_list->periodic, PERIODIC_INTERVAL,
next = list_item_next(n); periodic, neighbor_list);
}
}
ctimer_set(&neighbor_list->periodic, CLOCK_SECOND, 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) {
uint16_t worst_rtmetric;
struct collect_neighbor *worst_neighbor;
/* 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;
}
}
/* 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", PRINTF("collect_neighbor_add: not on list, not allocated, recycling %d.%d\n",
addr->u8[0], addr->u8[1]); n->addr.u8[0], n->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;
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);*/
}
}
}
}
n = max;
} }
/* 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)) {
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); list_remove(neighbors_list->list, n);
memb_free(&collect_neighbors_mem, n); memb_free(&collect_neighbors_mem, n);
return;
}
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -244,14 +231,13 @@ 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__ */