Cleaned up the collect neighbor management code
This commit is contained in:
parent
b23a364397
commit
d0579c8a81
|
@ -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;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -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__ */
|
||||||
|
|
Loading…
Reference in a new issue