moved ETX storage variable from RPL to ds6-nbr

This commit is contained in:
Joakim Eriksson 2014-10-20 16:15:20 +02:00
parent 72679a819b
commit 5be43c6f8d
5 changed files with 69 additions and 20 deletions

View File

@ -74,6 +74,7 @@ typedef struct uip_ds6_nbr {
uint8_t nscount;
uint8_t isrouter;
uint8_t state;
uint16_t link_metric;
#if UIP_CONF_IPV6_QUEUE_PKT
struct uip_packetqueue_handle packethandle;
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4

View File

@ -47,6 +47,7 @@
#include "net/rpl/rpl-private.h"
#include "net/ip/uip.h"
#include "net/ipv6/uip-nd6.h"
#include "net/ipv6/uip-ds6-nbr.h"
#include "net/nbr-table.h"
#include "net/ipv6/multicast/uip-mcast6.h"
#include "lib/list.h"
@ -79,7 +80,22 @@ NBR_TABLE(rpl_parent_t, rpl_parents);
/* Allocate instance table. */
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
rpl_instance_t *default_instance;
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
rpl_get_nbr(rpl_parent_t *parent) {
linkaddr_t *lladdr = NULL;
lladdr = nbr_table_get_lladdr(rpl_parents, parent);
if(lladdr != NULL) {
return nbr_table_get_from_lladdr(ds6_neighbors, lladdr);
} else {
/* do nothing... can not update ETX Since there is no nbr struct */
return NULL;
}
}
/*---------------------------------------------------------------------------*/
static void
nbr_callback(void *ptr)
{
@ -113,9 +129,11 @@ rpl_get_parent_rank(uip_lladdr_t *addr)
uint16_t
rpl_get_parent_link_metric(const uip_lladdr_t *addr)
{
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (const linkaddr_t *)addr);
if(p != NULL) {
return p->link_metric;
uip_ds6_nbr_t *nbr;
nbr = nbr_table_get_from_lladdr(ds6_neighbors, (const linkaddr_t *)addr);
if(nbr != NULL) {
return nbr->link_metric;
} else {
return 0;
}
@ -567,10 +585,17 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
if(p == NULL) {
PRINTF("RPL: rpl_add_parent p NULL\n");
} else {
uip_ds6_nbr_t *nbr;
nbr = rpl_get_nbr(p);
p->dag = dag;
p->rank = dio->rank;
p->dtsn = dio->dtsn;
p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
/* check if we have a nbr and if we have no prev link_metric value */
if(nbr != NULL && nbr->link_metric == 0) {
nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
}
#if RPL_DAG_MC != RPL_DAG_MC_NONE
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */

View File

@ -90,16 +90,22 @@ typedef uint16_t rpl_path_metric_t;
static rpl_path_metric_t
calculate_path_metric(rpl_parent_t *p)
{
uip_ds6_nbr_t *nbr;
if(p == NULL) {
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
}
nbr = rpl_get_nbr(p);
if(nbr == NULL) {
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
}
#if RPL_DAG_MC == RPL_DAG_MC_NONE
return p->rank + (uint16_t)p->link_metric;
{
return p->rank + (uint16_t)nbr->link_metric;
}
#elif RPL_DAG_MC == RPL_DAG_MC_ETX
return p->mc.obj.etx + (uint16_t)p->link_metric;
return p->mc.obj.etx + (uint16_t)nbr->link_metric;
#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
return p->mc.obj.energy.energy_est + (uint16_t)p->link_metric;
return p->mc.obj.energy.energy_est + (uint16_t)nbr->link_metric;
#else
#error "Unsupported RPL_DAG_MC configured. See rpl.h."
#endif /* RPL_DAG_MC */
@ -114,9 +120,17 @@ reset(rpl_dag_t *dag)
static void
neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
{
uint16_t recorded_etx = p->link_metric;
uint16_t recorded_etx = 0;
uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
uint16_t new_etx;
uip_ds6_nbr_t *nbr = NULL;
nbr = rpl_get_nbr(p);
if(nbr == NULL) {
/* No neighbor for this parent - something bad has occured!??? */
return;
}
recorded_etx = nbr->link_metric;
/* Do not penalize the ETX when collisions or transmission errors occur. */
if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
@ -139,7 +153,8 @@ neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
(unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
(unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
(unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR));
p->link_metric = new_etx;
/* update the link metric for this nbr */
nbr->link_metric = new_etx;
}
}
@ -148,14 +163,15 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
{
rpl_rank_t new_rank;
rpl_rank_t rank_increase;
uip_ds6_nbr_t *nbr;
if(p == NULL) {
if(p == NULL || (nbr = rpl_get_nbr(p)) == NULL) {
if(base_rank == 0) {
return INFINITE_RANK;
}
rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
} else {
rank_increase = p->link_metric;
rank_increase = nbr->link_metric;
if(base_rank == 0) {
base_rank = p->rank;
}

View File

@ -126,26 +126,34 @@ static rpl_parent_t *
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
{
rpl_rank_t r1, r2;
rpl_dag_t *dag;
rpl_dag_t *dag;
uip_ds6_nbr_t *nbr1, *nbr2;
nbr1 = rpl_get_nbr(p1);
nbr2 = rpl_get_nbr(p2);
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
if(nbr1 == NULL || nbr2 == NULL) {
return dag->preferred_parent;
}
PRINTF("RPL: Comparing parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(p1));
PRINTF(" (confidence %d, rank %d) with parent ",
p1->link_metric, p1->rank);
nbr1->link_metric, p1->rank);
PRINT6ADDR(rpl_get_parent_ipaddr(p2));
PRINTF(" (confidence %d, rank %d)\n",
p2->link_metric, p2->rank);
nbr2->link_metric, p2->rank);
r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
p1->link_metric;
nbr1->link_metric;
r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
p2->link_metric;
nbr2->link_metric;
/* Compare two parents by looking both and their rank and at the ETX
for that parent. We choose the parent that has the most
favourable combination. */
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
if(r1 < r2 + MIN_DIFFERENCE &&
r1 > r2 - MIN_DIFFERENCE) {
return dag->preferred_parent;

View File

@ -114,7 +114,6 @@ struct rpl_parent {
rpl_metric_container_t mc;
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
rpl_rank_t rank;
uint16_t link_metric;
uint8_t dtsn;
uint8_t flags;
};
@ -251,7 +250,7 @@ rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
void rpl_dag_init(void);
uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
/**
* RPL modes