Now sending DAOs, added DIS handling

This commit is contained in:
Eric Engel 2012-02-16 23:23:15 +01:00
parent 60719051f3
commit e6e336c77f
5 changed files with 149 additions and 20 deletions

View File

@ -12,12 +12,8 @@
#include "sys/net/sixlowpan/sixlowerror.h" #include "sys/net/sixlowpan/sixlowerror.h"
char rpl_process_buf[RPL_PROCESS_STACKSIZE]; char rpl_process_buf[RPL_PROCESS_STACKSIZE];
//counters //global variables
uint8_t act_dodag_version = 240; char i_am_root = 0;
uint8_t dao_sequence = 240;
uint8_t path_sequence = 240;
//other global variables
rpl_of_t *objective_functions[NUMBER_IMPLEMENTED_OFS]; rpl_of_t *objective_functions[NUMBER_IMPLEMENTED_OFS];
rpl_routing_entry_t routing_table[RPL_MAX_ROUTING_ENTRIES]; rpl_routing_entry_t routing_table[RPL_MAX_ROUTING_ENTRIES];
unsigned int rpl_process_pid; unsigned int rpl_process_pid;
@ -34,6 +30,8 @@ static struct rpl_dao_t *rpl_dao_buf;
//static struct rpl_dao_ack_t * rpl_dao_ack_buf; //static struct rpl_dao_ack_t * rpl_dao_ack_buf;
static struct rpl_opt_t *rpl_opt_buf; static struct rpl_opt_t *rpl_opt_buf;
static struct rpl_opt_dodag_conf_t * rpl_opt_dodag_conf_buf; static struct rpl_opt_dodag_conf_t * rpl_opt_dodag_conf_buf;
static struct rpl_opt_solicited_t * rpl_opt_solicited_buf;
static struct rpl_opt_target_t * rpl_opt_target_buf;
static struct rpl_dio_t* get_rpl_dio_buf(){ static struct rpl_dio_t* get_rpl_dio_buf(){
@ -57,6 +55,14 @@ static struct rpl_opt_dodag_conf_t* get_rpl_opt_dodag_conf_buf(uint8_t rpl_msg_l
return ((struct rpl_opt_dodag_conf_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len])); return ((struct rpl_opt_dodag_conf_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len]));
} }
static struct rpl_opt_solicited_t* get_rpl_opt_solicited_buf(uint8_t rpl_msg_len){
return ((struct rpl_opt_solicited_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len]));
}
static struct rpl_opt_target_t* get_rpl_opt_target_buf(uint8_t rpl_msg_len){
return ((struct rpl_opt_target_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len]));
}
rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp){ rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp){
for(uint16_t i=0; i < NUMBER_IMPLEMENTED_OFS; i++){ for(uint16_t i=0; i < NUMBER_IMPLEMENTED_OFS; i++){
if(ocp == objective_functions[i]->ocp){ if(ocp == objective_functions[i]->ocp){
@ -118,7 +124,7 @@ void rpl_init_root(){
dodag->minhoprankincrease = (uint16_t)DEFAULT_MIN_HOP_RANK_INCREASE; dodag->minhoprankincrease = (uint16_t)DEFAULT_MIN_HOP_RANK_INCREASE;
dodag->default_lifetime = (uint16_t)RPL_DEFAULT_LIFETIME; dodag->default_lifetime = (uint16_t)RPL_DEFAULT_LIFETIME;
dodag->lifetime_unit = RPL_LIFETIME_UNIT; dodag->lifetime_unit = RPL_LIFETIME_UNIT;
dodag->version = 0; dodag->version = RPL_COUNTER_INIT;
dodag->grounded = RPL_GROUNDED; dodag->grounded = RPL_GROUNDED;
dodag->my_rank = RPL_ROOT_RANK; dodag->my_rank = RPL_ROOT_RANK;
dodag->joined = 1; dodag->joined = 1;
@ -128,7 +134,7 @@ void rpl_init_root(){
printf("Error - could not generate DODAG\n"); printf("Error - could not generate DODAG\n");
return; return;
} }
i_am_root = 1;
start_trickle(dodag->dio_min, dodag->dio_interval_doubling, dodag->dio_redundancy); start_trickle(dodag->dio_min, dodag->dio_interval_doubling, dodag->dio_redundancy);
} }
@ -213,9 +219,23 @@ void send_DAO(){
//rpl_dao_buf->k_d_flags = 0x00; //rpl_dao_buf->k_d_flags = 0x00;
//TODO:dao_sequence handling //TODO:dao_sequence handling
rpl_dao_buf->dao_sequence = 0x00; rpl_dao_buf->dao_sequence = 0x00;
uint16_t opt_len = 0;
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN);
//Alle Ziele aus der Routing Tabelle als Target eintragen
//TODO: Ausnahme default_route zu Parent
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES;i++){
if(routing_table[i].used){
rpl_opt_target_buf->type=RPL_OPT_TARGET;
rpl_opt_target_buf->length=RPL_OPT_TARGET_LEN;
rpl_opt_target_buf->flags=0x00;
rpl_opt_target_buf->prefix_length=16;
memcpy(&rpl_opt_target_buf->target,&routing_table[i].address,sizeof(ipv6_addr_t));
opt_len += RPL_OPT_TARGET_LEN +2;
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN + opt_len);
}
}
uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len;
uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN;
rpl_send(&my_dodag->my_preferred_parent->addr,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL); rpl_send(&my_dodag->my_preferred_parent->addr,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL);
} }
@ -317,6 +337,7 @@ void recv_rpl_dio(void){
has_dodag_conf_opt = 1; has_dodag_conf_opt = 1;
if(rpl_opt_buf->length != RPL_OPT_DODAG_CONF_LEN){ if(rpl_opt_buf->length != RPL_OPT_DODAG_CONF_LEN){
//error malformed //error malformed
return;
} }
rpl_opt_dodag_conf_buf = get_rpl_opt_dodag_conf_buf(len); rpl_opt_dodag_conf_buf = get_rpl_opt_dodag_conf_buf(len);
dio_dodag.dio_interval_doubling = rpl_opt_dodag_conf_buf->DIOIntDoubl; dio_dodag.dio_interval_doubling = rpl_opt_dodag_conf_buf->DIOIntDoubl;
@ -333,6 +354,7 @@ void recv_rpl_dio(void){
case(RPL_OPT_PREFIX_INFO):{ case(RPL_OPT_PREFIX_INFO):{
if(rpl_opt_buf->length != RPL_OPT_PREFIX_INFO_LEN){ if(rpl_opt_buf->length != RPL_OPT_PREFIX_INFO_LEN){
//error malformed //error malformed
return;
} }
len += RPL_OPT_PREFIX_INFO_LEN +2; len += RPL_OPT_PREFIX_INFO_LEN +2;
break; break;
@ -378,7 +400,7 @@ void recv_rpl_dio(void){
if( dio_dodag.version > my_dodag->version){ if( dio_dodag.version > my_dodag->version){
printf("New Version of dodag\n"); printf("New Version of dodag\n");
if(my_dodag->my_rank == ROOT_RANK){ if(my_dodag->my_rank == ROOT_RANK){
my_dodag->version = dio_dodag.version +1; my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version);
reset_trickletimer(); reset_trickletimer();
} }
else{ else{
@ -418,7 +440,54 @@ void recv_rpl_dio(void){
} }
void recv_rpl_dis(void){ void recv_rpl_dis(void){
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
return;
}
ipv6_buf = get_ipv6_buf();
rpl_dis_buf = get_rpl_dis_buf();
int len = DIS_BASE_LEN;
while(len < (ipv6_buf->length - ICMPV6_HDR_LEN) ){
rpl_opt_buf = get_rpl_opt_buf(len);
switch(rpl_opt_buf->type){
case(RPL_OPT_PAD1):{
len += 1;
break;
}
case(RPL_OPT_PADN):{
len += rpl_opt_buf->length +2;
break;
}
case(RPL_OPT_SOLICITED_INFO):{
len+= RPL_OPT_SOLICITED_INFO_LEN+2;
//extract + check
if(rpl_opt_buf->length != RPL_OPT_SOLICITED_INFO_LEN){
//error malformed
return;
}
rpl_opt_solicited_buf = get_rpl_opt_solicited_buf(len);
if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_I_MASK){
if(my_dodag->instance->id != rpl_opt_solicited_buf->rplinstanceid){
return;
}
}
if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_D_MASK){
if(!rpl_equal_id(&my_dodag->dodag_id, &rpl_opt_solicited_buf->dodagid)){
return;
}
}
if(rpl_opt_solicited_buf->VID_Flags & RPL_DIS_V_MASK){
if(my_dodag->version != rpl_opt_solicited_buf->version){
return;
}
}
break;
}
default:
break;
}
}
send_DIO(&ipv6_buf->srcaddr);
} }
@ -427,7 +496,7 @@ void recv_rpl_dao(void){
rpl_dao_buf = get_rpl_dao_buf(); rpl_dao_buf = get_rpl_dao_buf();
int len = DAO_BASE_LEN; int len = DAO_BASE_LEN;
while(len < (ipv6_buf->length - LLHDR_ICMPV6HDR_LEN) ){ while(len < (ipv6_buf->length - ICMPV6_HDR_LEN) ){
rpl_opt_buf = get_rpl_opt_buf(len); rpl_opt_buf = get_rpl_opt_buf(len);
switch(rpl_opt_buf->type){ switch(rpl_opt_buf->type){
@ -503,9 +572,15 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
//find right next hop before sending //find right next hop before sending
ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_buf->destaddr); ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_buf->destaddr);
if(next_hop == NULL){ if(next_hop == NULL){
//oops... entweder bin ich root und weiß nicht wohin mit dem paket, oder es ist kein if(i_am_root){
//preferred parent eingetragen, was nicht passieren sollte. //oops... entweder bin ich root und weiß nicht wohin mit dem paket, oder es ist kein
printf("[Error] destination unknown\n"); //preferred parent eingetragen, was nicht passieren sollte.
printf("[Error] destination unknown\n");
return;
}
else{
next_hop = rpl_get_my_preferred_parent();
}
} }
lowpan_init((ieee_802154_long_t*)&(next_hop->uint16[4]),(uint8_t*)ipv6_buf); lowpan_init((ieee_802154_long_t*)&(next_hop->uint16[4]),(uint8_t*)ipv6_buf);
} }
@ -518,10 +593,11 @@ ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr){
return &routing_table[i].next_hop; return &routing_table[i].next_hop;
} }
} }
return rpl_get_my_preferred_parent(); return NULL;
} }
void rpl_add_routing_entry(ipv6_addr_t *addr, ipv6_addr_t *next_hop){ void rpl_add_routing_entry(ipv6_addr_t *addr, ipv6_addr_t *next_hop){
//TODO: if no free entry, delete worst parent
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES; i++){ for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES; i++){
if(!routing_table[i].used){ if(!routing_table[i].used){
routing_table[i].address = *addr; routing_table[i].address = *addr;

View File

@ -129,6 +129,11 @@ rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){
} }
void rpl_delete_parent(ipv6_addr_t * address){ void rpl_delete_parent(ipv6_addr_t * address){
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
//TODO:check if this was the preferred parent, find new parent, if it was last parent leave dodag
if(rpl_equal_id(&my_dodag->my_preferred_parent->addr,address)){
//set_new_preferred_parent
}
for(int i=0;i<RPL_MAX_PARENTS;i++){ for(int i=0;i<RPL_MAX_PARENTS;i++){
if( parents[i].used && (rpl_equal_id(address, &parents[i].addr)) ){ if( parents[i].used && (rpl_equal_id(address, &parents[i].addr)) ){
memset(&parents[i], 0, sizeof(parents[i])); memset(&parents[i], 0, sizeof(parents[i]));
@ -136,6 +141,10 @@ void rpl_delete_parent(ipv6_addr_t * address){
} }
} }
void rpl_delete_parents_for_dodag(ipv6_addr_t * dodag_id){
}
void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank){ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank){
rpl_dodag_t *my_dodag; rpl_dodag_t *my_dodag;
rpl_parent_t *preferred_parent; rpl_parent_t *preferred_parent;
@ -168,8 +177,7 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran
my_dodag->min_rank = my_dodag->my_rank; my_dodag->min_rank = my_dodag->my_rank;
start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy); start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy);
//TODO: start sending DAOs delay_dao();
} }
void rpl_global_repair(rpl_dodag_t *dodag){ void rpl_global_repair(rpl_dodag_t *dodag){

View File

@ -26,6 +26,8 @@
#define RPL_OPT_LEN 2 #define RPL_OPT_LEN 2
#define RPL_OPT_DODAG_CONF_LEN 14 #define RPL_OPT_DODAG_CONF_LEN 14
#define RPL_OPT_PREFIX_INFO_LEN 30 #define RPL_OPT_PREFIX_INFO_LEN 30
#define RPL_OPT_SOLICITED_INFO_LEN 19
#define RPL_OPT_TARGET_LEN 18
//message options //message options
#define RPL_OPT_PAD1 0 #define RPL_OPT_PAD1 0
@ -64,6 +66,7 @@
#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 #define DEFAULT_DIO_INTERVAL_DOUBLINGS 20
#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10 #define DEFAULT_DIO_REDUNDANCY_CONSTANT 10
#define DEFAULT_MIN_HOP_RANK_INCREASE 256 #define DEFAULT_MIN_HOP_RANK_INCREASE 256
//DAO_DELAY is in seconds
#define DEFAULT_DAO_DELAY 1 #define DEFAULT_DAO_DELAY 1
//others //others
@ -80,6 +83,9 @@
#define RPL_PRF_MASK 0x7 #define RPL_PRF_MASK 0x7
#define RPL_MOP_SHIFT 3 #define RPL_MOP_SHIFT 3
#define RPL_SHIFTED_MOP_MASK 0x7 #define RPL_SHIFTED_MOP_MASK 0x7
#define RPL_DIS_V_MASK 0x80
#define RPL_DIS_I_MASK 0x40
#define RPL_DIS_D_MASK 0x20
#define RPL_GROUNDED_SHIFT 7 #define RPL_GROUNDED_SHIFT 7
#define RPL_DEFAULT_OCP 0 #define RPL_DEFAULT_OCP 0
@ -137,6 +143,24 @@ typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t {
uint16_t lifetime_unit; uint16_t lifetime_unit;
} rpl_opt_dodag_conf_t; } rpl_opt_dodag_conf_t;
typedef struct __attribute__((packed)) rpl_opt_solicited_t {
uint8_t type;
uint8_t length;
uint8_t rplinstanceid;
uint8_t VID_Flags;
ipv6_addr_t dodagid;
uint8_t version;
} rpl_opt_solicited_t;
//ipv6_addr_t target may be replaced by a target prefix of variable length
typedef struct __attribute__((packed)) rpl_opt_target_t {
uint8_t type;
uint8_t length;
uint8_t flags;
uint8_t prefix_length;
ipv6_addr_t target;
} rpl_opt_target_t;
struct rpl_dodag_t; struct rpl_dodag_t;
typedef struct rpl_parent_t { typedef struct rpl_parent_t {

View File

@ -6,8 +6,10 @@
char timer_over_buf[TRICKLE_TIMER_STACKSIZE]; char timer_over_buf[TRICKLE_TIMER_STACKSIZE];
char interval_over_buf[TRICKLE_INTERVAL_STACKSIZE]; char interval_over_buf[TRICKLE_INTERVAL_STACKSIZE];
char dao_delay_over_buf[DAO_DELAY_STACKSIZE];
int timer_over_pid; int timer_over_pid;
int interval_over_pid; int interval_over_pid;
int dao_delay_over_pid;
uint8_t k; uint8_t k;
uint32_t Imin; uint32_t Imin;
@ -17,8 +19,10 @@ uint32_t t;
uint16_t c; uint16_t c;
vtimer_t trickle_t_timer; vtimer_t trickle_t_timer;
vtimer_t trickle_I_timer; vtimer_t trickle_I_timer;
vtimer_t dao_timer;
timex_t t_time; timex_t t_time;
timex_t I_time; timex_t I_time;
timex_t dao_time;
//struct für trickle parameter?? //struct für trickle parameter??
void reset_trickletimer(void){ void reset_trickletimer(void){
@ -41,6 +45,9 @@ void init_trickle(void){
interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE, interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE,
PRIORITY_MAIN-1, CREATE_SLEEPING, PRIORITY_MAIN-1, CREATE_SLEEPING,
trickle_interval_over, "trickle_interval_over"); trickle_interval_over, "trickle_interval_over");
dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE,
PRIORITY_MAIN-1, CREATE_SLEEPING,
dao_delay_over, "dao_delay_over");
} }
@ -96,3 +103,15 @@ void trickle_interval_over(void){
} }
} }
void delay_dao(void){
dao_time = timex_set(DEFAULT_DAO_DELAY,0);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
}
void dao_delay_over(void){
while(1){
send_DAO();
thread_sleep();
}
}

View File

@ -3,6 +3,7 @@
#define TRICKLE_TIMER_STACKSIZE 3072 #define TRICKLE_TIMER_STACKSIZE 3072
#define TRICKLE_INTERVAL_STACKSIZE 3072 #define TRICKLE_INTERVAL_STACKSIZE 3072
#define DAO_DELAY_STACKSIZE 2048
void reset_trickletimer(void); void reset_trickletimer(void);
void init_trickle(void); void init_trickle(void);
@ -10,4 +11,5 @@ void start_trickle(uint8_t DIOINtMin, uint8_t DIOIntDoubl, uint8_t DIORedundancy
void trickle_increment_counter(void); void trickle_increment_counter(void);
void trickle_timer_over(void); void trickle_timer_over(void);
void trickle_interval_over(void); void trickle_interval_over(void);
void delay_dao(void);
void dao_delay_over(void);