Merge pull request #904 from joakimeriksson/move-etx

moved ETX storage variable from RPL to ds6-nbr
This commit is contained in:
Nicolas Tsiftes 2015-02-06 12:25:35 +01:00
commit 010a338630
5 changed files with 68 additions and 20 deletions

View file

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

View file

@ -47,6 +47,7 @@
#include "net/rpl/rpl-private.h" #include "net/rpl/rpl-private.h"
#include "net/ip/uip.h" #include "net/ip/uip.h"
#include "net/ipv6/uip-nd6.h" #include "net/ipv6/uip-nd6.h"
#include "net/ipv6/uip-ds6-nbr.h"
#include "net/nbr-table.h" #include "net/nbr-table.h"
#include "net/ipv6/multicast/uip-mcast6.h" #include "net/ipv6/multicast/uip-mcast6.h"
#include "lib/list.h" #include "lib/list.h"
@ -79,6 +80,19 @@ NBR_TABLE(rpl_parent_t, rpl_parents);
/* Allocate instance table. */ /* Allocate instance table. */
rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t instance_table[RPL_MAX_INSTANCES];
rpl_instance_t *default_instance; 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 {
return NULL;
}
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
nbr_callback(void *ptr) nbr_callback(void *ptr)
@ -113,9 +127,11 @@ rpl_get_parent_rank(uip_lladdr_t *addr)
uint16_t uint16_t
rpl_get_parent_link_metric(const uip_lladdr_t *addr) 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); uip_ds6_nbr_t *nbr;
if(p != NULL) { nbr = nbr_table_get_from_lladdr(ds6_neighbors, (const linkaddr_t *)addr);
return p->link_metric;
if(nbr != NULL) {
return nbr->link_metric;
} else { } else {
return 0; return 0;
} }
@ -568,10 +584,17 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
if(p == NULL) { if(p == NULL) {
PRINTF("RPL: rpl_add_parent p NULL\n"); PRINTF("RPL: rpl_add_parent p NULL\n");
} else { } else {
uip_ds6_nbr_t *nbr;
nbr = rpl_get_nbr(p);
p->dag = dag; p->dag = dag;
p->rank = dio->rank; p->rank = dio->rank;
p->dtsn = dio->dtsn; p->dtsn = dio->dtsn;
p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
/* Check whether we have a neighbor that has not gotten a link metric yet */
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 #if RPL_DAG_MC != RPL_DAG_MC_NONE
memcpy(&p->mc, &dio->mc, sizeof(p->mc)); memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ #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 static rpl_path_metric_t
calculate_path_metric(rpl_parent_t *p) calculate_path_metric(rpl_parent_t *p)
{ {
uip_ds6_nbr_t *nbr;
if(p == NULL) { if(p == NULL) {
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; 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 #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 #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 #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 #else
#error "Unsupported RPL_DAG_MC configured. See rpl.h." #error "Unsupported RPL_DAG_MC configured. See rpl.h."
#endif /* RPL_DAG_MC */ #endif /* RPL_DAG_MC */
@ -114,9 +120,18 @@ reset(rpl_dag_t *dag)
static void static void
neighbor_link_callback(rpl_parent_t *p, int status, int numtx) 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 packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
uint16_t new_etx; 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 occurred */
return;
}
recorded_etx = nbr->link_metric;
/* Do not penalize the ETX when collisions or transmission errors occur. */ /* Do not penalize the ETX when collisions or transmission errors occur. */
if(status == MAC_TX_OK || status == MAC_TX_NOACK) { if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
@ -139,7 +154,8 @@ neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
(unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR), (unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
(unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR), (unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
(unsigned)(packet_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 +164,15 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
{ {
rpl_rank_t new_rank; rpl_rank_t new_rank;
rpl_rank_t rank_increase; 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) { if(base_rank == 0) {
return INFINITE_RANK; return INFINITE_RANK;
} }
rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
} else { } else {
rank_increase = p->link_metric; rank_increase = nbr->link_metric;
if(base_rank == 0) { if(base_rank == 0) {
base_rank = p->rank; base_rank = p->rank;
} }

View file

@ -127,25 +127,33 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
{ {
rpl_rank_t r1, r2; 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 "); PRINTF("RPL: Comparing parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(p1)); PRINT6ADDR(rpl_get_parent_ipaddr(p1));
PRINTF(" (confidence %d, rank %d) with parent ", PRINTF(" (confidence %d, rank %d) with parent ",
p1->link_metric, p1->rank); nbr1->link_metric, p1->rank);
PRINT6ADDR(rpl_get_parent_ipaddr(p2)); PRINT6ADDR(rpl_get_parent_ipaddr(p2));
PRINTF(" (confidence %d, rank %d)\n", 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 + 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 + 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 /* Compare two parents by looking both and their rank and at the ETX
for that parent. We choose the parent that has the most for that parent. We choose the parent that has the most
favourable combination. */ favourable combination. */
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
if(r1 < r2 + MIN_DIFFERENCE && if(r1 < r2 + MIN_DIFFERENCE &&
r1 > r2 - MIN_DIFFERENCE) { r1 > r2 - MIN_DIFFERENCE) {
return dag->preferred_parent; return dag->preferred_parent;

View file

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