Now sending DAOs, added DIS handling
This commit is contained in:
parent
60719051f3
commit
e6e336c77f
@ -12,12 +12,8 @@
|
||||
#include "sys/net/sixlowpan/sixlowerror.h"
|
||||
|
||||
char rpl_process_buf[RPL_PROCESS_STACKSIZE];
|
||||
//counters
|
||||
uint8_t act_dodag_version = 240;
|
||||
uint8_t dao_sequence = 240;
|
||||
uint8_t path_sequence = 240;
|
||||
//other global variables
|
||||
|
||||
//global variables
|
||||
char i_am_root = 0;
|
||||
rpl_of_t *objective_functions[NUMBER_IMPLEMENTED_OFS];
|
||||
rpl_routing_entry_t routing_table[RPL_MAX_ROUTING_ENTRIES];
|
||||
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_opt_t *rpl_opt_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(){
|
||||
@ -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]));
|
||||
}
|
||||
|
||||
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){
|
||||
for(uint16_t i=0; i < NUMBER_IMPLEMENTED_OFS; i++){
|
||||
if(ocp == objective_functions[i]->ocp){
|
||||
@ -118,7 +124,7 @@ void rpl_init_root(){
|
||||
dodag->minhoprankincrease = (uint16_t)DEFAULT_MIN_HOP_RANK_INCREASE;
|
||||
dodag->default_lifetime = (uint16_t)RPL_DEFAULT_LIFETIME;
|
||||
dodag->lifetime_unit = RPL_LIFETIME_UNIT;
|
||||
dodag->version = 0;
|
||||
dodag->version = RPL_COUNTER_INIT;
|
||||
dodag->grounded = RPL_GROUNDED;
|
||||
dodag->my_rank = RPL_ROOT_RANK;
|
||||
dodag->joined = 1;
|
||||
@ -128,7 +134,7 @@ void rpl_init_root(){
|
||||
printf("Error - could not generate DODAG\n");
|
||||
return;
|
||||
}
|
||||
|
||||
i_am_root = 1;
|
||||
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;
|
||||
//TODO:dao_sequence handling
|
||||
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;
|
||||
uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len;
|
||||
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;
|
||||
if(rpl_opt_buf->length != RPL_OPT_DODAG_CONF_LEN){
|
||||
//error malformed
|
||||
return;
|
||||
}
|
||||
rpl_opt_dodag_conf_buf = get_rpl_opt_dodag_conf_buf(len);
|
||||
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):{
|
||||
if(rpl_opt_buf->length != RPL_OPT_PREFIX_INFO_LEN){
|
||||
//error malformed
|
||||
return;
|
||||
}
|
||||
len += RPL_OPT_PREFIX_INFO_LEN +2;
|
||||
break;
|
||||
@ -378,7 +400,7 @@ void recv_rpl_dio(void){
|
||||
if( dio_dodag.version > my_dodag->version){
|
||||
printf("New Version of dodag\n");
|
||||
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();
|
||||
}
|
||||
else{
|
||||
@ -418,7 +440,54 @@ void recv_rpl_dio(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();
|
||||
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);
|
||||
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
|
||||
ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_buf->destaddr);
|
||||
if(next_hop == NULL){
|
||||
//oops... entweder bin ich root und weiß nicht wohin mit dem paket, oder es ist kein
|
||||
//preferred parent eingetragen, was nicht passieren sollte.
|
||||
printf("[Error] destination unknown\n");
|
||||
if(i_am_root){
|
||||
//oops... entweder bin ich root und weiß nicht wohin mit dem paket, oder es ist kein
|
||||
//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);
|
||||
}
|
||||
@ -518,10 +593,11 @@ ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr){
|
||||
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){
|
||||
//TODO: if no free entry, delete worst parent
|
||||
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES; i++){
|
||||
if(!routing_table[i].used){
|
||||
routing_table[i].address = *addr;
|
||||
|
||||
@ -129,6 +129,11 @@ rpl_parent_t *rpl_find_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++){
|
||||
if( parents[i].used && (rpl_equal_id(address, &parents[i].addr)) ){
|
||||
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){
|
||||
rpl_dodag_t *my_dodag;
|
||||
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;
|
||||
|
||||
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){
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
#define RPL_OPT_LEN 2
|
||||
#define RPL_OPT_DODAG_CONF_LEN 14
|
||||
#define RPL_OPT_PREFIX_INFO_LEN 30
|
||||
#define RPL_OPT_SOLICITED_INFO_LEN 19
|
||||
#define RPL_OPT_TARGET_LEN 18
|
||||
|
||||
//message options
|
||||
#define RPL_OPT_PAD1 0
|
||||
@ -64,6 +66,7 @@
|
||||
#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20
|
||||
#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10
|
||||
#define DEFAULT_MIN_HOP_RANK_INCREASE 256
|
||||
//DAO_DELAY is in seconds
|
||||
#define DEFAULT_DAO_DELAY 1
|
||||
|
||||
//others
|
||||
@ -80,6 +83,9 @@
|
||||
#define RPL_PRF_MASK 0x7
|
||||
#define RPL_MOP_SHIFT 3
|
||||
#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_DEFAULT_OCP 0
|
||||
|
||||
@ -137,6 +143,24 @@ typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t {
|
||||
uint16_t lifetime_unit;
|
||||
} 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;
|
||||
|
||||
typedef struct rpl_parent_t {
|
||||
|
||||
@ -6,8 +6,10 @@
|
||||
|
||||
char timer_over_buf[TRICKLE_TIMER_STACKSIZE];
|
||||
char interval_over_buf[TRICKLE_INTERVAL_STACKSIZE];
|
||||
char dao_delay_over_buf[DAO_DELAY_STACKSIZE];
|
||||
int timer_over_pid;
|
||||
int interval_over_pid;
|
||||
int dao_delay_over_pid;
|
||||
|
||||
uint8_t k;
|
||||
uint32_t Imin;
|
||||
@ -17,8 +19,10 @@ uint32_t t;
|
||||
uint16_t c;
|
||||
vtimer_t trickle_t_timer;
|
||||
vtimer_t trickle_I_timer;
|
||||
vtimer_t dao_timer;
|
||||
timex_t t_time;
|
||||
timex_t I_time;
|
||||
timex_t dao_time;
|
||||
|
||||
//struct für trickle parameter??
|
||||
void reset_trickletimer(void){
|
||||
@ -41,6 +45,9 @@ void init_trickle(void){
|
||||
interval_over_pid = thread_create(interval_over_buf, TRICKLE_INTERVAL_STACKSIZE,
|
||||
PRIORITY_MAIN-1, CREATE_SLEEPING,
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#define TRICKLE_TIMER_STACKSIZE 3072
|
||||
#define TRICKLE_INTERVAL_STACKSIZE 3072
|
||||
#define DAO_DELAY_STACKSIZE 2048
|
||||
|
||||
void reset_trickletimer(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_timer_over(void);
|
||||
void trickle_interval_over(void);
|
||||
|
||||
void delay_dao(void);
|
||||
void dao_delay_over(void);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user