rpl nearly finished, rpl_test now with shell
This commit is contained in:
parent
8124389151
commit
f69fbfd686
@ -1,5 +1,5 @@
|
|||||||
SubDir TOP projects test_rpl ;
|
SubDir TOP projects test_rpl ;
|
||||||
|
|
||||||
Module test_rpl : main.c : auto_init vtimer 6lowpan uart0 posix_io cc110x_ng rpl ;
|
Module test_rpl : main.c : shell posix_io uart0 auto_init vtimer 6lowpan uart0 posix_io cc110x_ng rpl ;
|
||||||
|
|
||||||
UseModule test_rpl ;
|
UseModule test_rpl ;
|
||||||
|
|||||||
@ -2,25 +2,118 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <vtimer.h>
|
#include <vtimer.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
|
|
||||||
|
#include <posix_io.h>
|
||||||
|
#include <shell.h>
|
||||||
|
#include <board_uart0.h>
|
||||||
|
|
||||||
#include "sys/net/sixlowpan/sixlowip.h"
|
#include "sys/net/sixlowpan/sixlowip.h"
|
||||||
#include "sys/net/sixlowpan/sixlowpan.h"
|
#include "sys/net/sixlowpan/sixlowpan.h"
|
||||||
#include "sys/net/sixlowpan/sixlowerror.h"
|
#include "sys/net/sixlowpan/sixlowerror.h"
|
||||||
#include "sys/net/sixlowpan/rpl/rpl.h"
|
#include "sys/net/sixlowpan/rpl/rpl.h"
|
||||||
|
|
||||||
int main(void)
|
void init(char *str){
|
||||||
{
|
char command;
|
||||||
uint16_t root = 0x0002;
|
uint16_t r_addr;
|
||||||
ipv6_addr_t std_addr;
|
ipv6_addr_t std_addr;
|
||||||
uint16_t r_addr = root;
|
|
||||||
|
int res = sscanf(str, "init %c %hu", &command, &r_addr);
|
||||||
|
|
||||||
|
if(res < 1){
|
||||||
|
printf("Usage: init address\n");
|
||||||
|
printf("\tr\tinitialize as root\n");
|
||||||
|
printf("\tn\tinitialize as node router\n");
|
||||||
|
printf("\taddress must be an 8 bit integer\n");
|
||||||
|
}
|
||||||
|
|
||||||
ipv6_init_address(&std_addr, 0xABCD,0,0,0,0x1234,0xFFFF,0xFEDC,r_addr);
|
ipv6_init_address(&std_addr, 0xABCD,0,0,0,0x1234,0xFFFF,0xFEDC,r_addr);
|
||||||
uint8_t state = rpl_init(TRANSCEIVER_CC1100, &std_addr);
|
uint8_t state;
|
||||||
|
switch (command) {
|
||||||
|
case 'r':
|
||||||
|
printf("INFO: Initialize as root on address \n");
|
||||||
|
ipv6_print_addr(&std_addr);
|
||||||
|
if (r_addr > 255) {
|
||||||
|
printf("ERROR: address not an 8 bit integer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = rpl_init(TRANSCEIVER_CC1100, &std_addr);
|
||||||
if(state != SUCCESS){
|
if(state != SUCCESS){
|
||||||
printf("Error initializing RPL\n");
|
printf("Error initializing RPL\n");
|
||||||
}
|
}
|
||||||
if(root == 0x0001){
|
|
||||||
rpl_init_root();
|
rpl_init_root();
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
printf("INFO: Initialize as node on address \n");
|
||||||
|
ipv6_print_addr(&std_addr);
|
||||||
|
if (r_addr > 255) {
|
||||||
|
printf("ERROR: address not an 8 bit integer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = rpl_init(TRANSCEIVER_CC1100, &std_addr);
|
||||||
|
if(state != SUCCESS){
|
||||||
|
printf("Error initializing RPL\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("ERROR: Unknown command '%c'\n", command);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
printf("RPL INIT FINISHED\n");
|
}
|
||||||
while(1);
|
|
||||||
|
void table(char *str){
|
||||||
|
rpl_routing_entry_t * rtable;
|
||||||
|
rtable = rpl_get_routing_table();
|
||||||
|
printf("---------------------------\n");
|
||||||
|
printf("OUTPUT\n");
|
||||||
|
printf("---------------------------\n");
|
||||||
|
for(int i=0;i<RPL_MAX_ROUTING_ENTRIES;i++){
|
||||||
|
if(rtable[i].used){
|
||||||
|
ipv6_print_addr(&rtable[i].address);
|
||||||
|
printf("--------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shell_command_t shell_commands[] = {
|
||||||
|
{"init", "", init},
|
||||||
|
{"table", "", table},
|
||||||
|
{NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
printf("RPL Test Application\n");
|
||||||
|
vtimer_init();
|
||||||
|
|
||||||
|
posix_open(uart0_handler_pid, 0);
|
||||||
|
|
||||||
|
shell_t shell;
|
||||||
|
shell_init(&shell, shell_commands, uart0_readc, uart0_putc);
|
||||||
|
|
||||||
|
shell_run(&shell);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int old_main(void)
|
||||||
|
{
|
||||||
|
timex_t mytime = timex_set(10,0);
|
||||||
|
while(1){
|
||||||
|
|
||||||
|
rpl_routing_entry_t * rtable;
|
||||||
|
rtable = rpl_get_routing_table();
|
||||||
|
printf("---------------------------\n");
|
||||||
|
printf("OUTPUT\n");
|
||||||
|
printf("---------------------------\n");
|
||||||
|
for(int i=0;i<RPL_MAX_ROUTING_ENTRIES;i++){
|
||||||
|
if(rtable[i].used){
|
||||||
|
ipv6_print_addr(&rtable[i].address);
|
||||||
|
printf("--------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vtimer_sleep(mytime);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "sys/net/sixlowpan/sixlowmac.h"
|
#include "sys/net/sixlowpan/sixlowmac.h"
|
||||||
#include "sys/net/sixlowpan/sixlowip.h"
|
#include "sys/net/sixlowpan/sixlowip.h"
|
||||||
#include "sys/net/sixlowpan/sixlowpan.h"
|
#include "sys/net/sixlowpan/sixlowpan.h"
|
||||||
|
#include "sys/net/sixlowpan/sixlownd.h"
|
||||||
#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];
|
||||||
@ -152,6 +153,7 @@ void send_DIO(ipv6_addr_t* destination){
|
|||||||
|
|
||||||
icmp_buf->type = ICMP_RPL_CONTROL;
|
icmp_buf->type = ICMP_RPL_CONTROL;
|
||||||
icmp_buf->code = ICMP_CODE_DIO;
|
icmp_buf->code = ICMP_CODE_DIO;
|
||||||
|
icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
|
||||||
|
|
||||||
rpl_dio_buf = get_rpl_dio_buf();
|
rpl_dio_buf = get_rpl_dio_buf();
|
||||||
memset(rpl_dio_buf, 0, sizeof(*rpl_dio_buf));
|
memset(rpl_dio_buf, 0, sizeof(*rpl_dio_buf));
|
||||||
@ -163,8 +165,8 @@ void send_DIO(ipv6_addr_t* destination){
|
|||||||
rpl_dio_buf->flags = 0;
|
rpl_dio_buf->flags = 0;
|
||||||
rpl_dio_buf->reserved = 0;
|
rpl_dio_buf->reserved = 0;
|
||||||
rpl_dio_buf->dodagid = mydodag->dodag_id;
|
rpl_dio_buf->dodagid = mydodag->dodag_id;
|
||||||
printf("Send DIO with DODAGID: \n");
|
//printf("Send DIO with DODAGID: \n");
|
||||||
ipv6_print_addr(&rpl_dio_buf->dodagid);
|
//ipv6_print_addr(&rpl_dio_buf->dodagid);
|
||||||
|
|
||||||
int opt_hdr_len = 0;
|
int opt_hdr_len = 0;
|
||||||
//DODAG Configuration Option!
|
//DODAG Configuration Option!
|
||||||
@ -196,6 +198,8 @@ void send_DIS(ipv6_addr_t *destination){
|
|||||||
|
|
||||||
icmp_buf->type = ICMP_RPL_CONTROL;
|
icmp_buf->type = ICMP_RPL_CONTROL;
|
||||||
icmp_buf->code = ICMP_CODE_DIO;
|
icmp_buf->code = ICMP_CODE_DIO;
|
||||||
|
icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
|
||||||
|
|
||||||
rpl_dis_buf = get_rpl_dis_buf();
|
rpl_dis_buf = get_rpl_dis_buf();
|
||||||
|
|
||||||
uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN;
|
uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN;
|
||||||
@ -203,10 +207,14 @@ void send_DIS(ipv6_addr_t *destination){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void send_DAO(){
|
void send_DAO(){
|
||||||
|
if(i_am_root){
|
||||||
|
return;
|
||||||
|
}
|
||||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||||
|
|
||||||
icmp_buf->type = ICMP_RPL_CONTROL;
|
icmp_buf->type = ICMP_RPL_CONTROL;
|
||||||
icmp_buf->code = ICMP_CODE_DAO;
|
icmp_buf->code = ICMP_CODE_DAO;
|
||||||
|
icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
|
||||||
|
|
||||||
rpl_dodag_t * my_dodag;
|
rpl_dodag_t * my_dodag;
|
||||||
my_dodag = rpl_get_my_dodag();
|
my_dodag = rpl_get_my_dodag();
|
||||||
@ -217,25 +225,32 @@ void send_DAO(){
|
|||||||
memset(rpl_dao_buf,0,sizeof(*rpl_dao_buf));
|
memset(rpl_dao_buf,0,sizeof(*rpl_dao_buf));
|
||||||
rpl_dao_buf->rpl_instanceid = my_dodag->instance->id;
|
rpl_dao_buf->rpl_instanceid = my_dodag->instance->id;
|
||||||
//rpl_dao_buf->k_d_flags = 0x00;
|
//rpl_dao_buf->k_d_flags = 0x00;
|
||||||
//TODO:dao_sequence handling
|
rpl_dao_buf->dao_sequence = my_dodag->dao_seq;
|
||||||
rpl_dao_buf->dao_sequence = 0x00;
|
|
||||||
uint16_t opt_len = 0;
|
uint16_t opt_len = 0;
|
||||||
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN);
|
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN);
|
||||||
//Alle Ziele aus der Routing Tabelle als Target eintragen
|
//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++){
|
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES;i++){
|
||||||
if(routing_table[i].used){
|
if(routing_table[i].used){
|
||||||
rpl_opt_target_buf->type=RPL_OPT_TARGET;
|
rpl_opt_target_buf->type=RPL_OPT_TARGET;
|
||||||
rpl_opt_target_buf->length=RPL_OPT_TARGET_LEN;
|
rpl_opt_target_buf->length=RPL_OPT_TARGET_LEN;
|
||||||
rpl_opt_target_buf->flags=0x00;
|
rpl_opt_target_buf->flags=0x00;
|
||||||
rpl_opt_target_buf->prefix_length=16;
|
rpl_opt_target_buf->prefix_length= RPL_DODAG_ID_LEN;
|
||||||
memcpy(&rpl_opt_target_buf->target,&routing_table[i].address,sizeof(ipv6_addr_t));
|
memcpy(&rpl_opt_target_buf->target,&routing_table[i].address,sizeof(ipv6_addr_t));
|
||||||
opt_len += RPL_OPT_TARGET_LEN +2;
|
opt_len += RPL_OPT_TARGET_LEN +2;
|
||||||
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN + opt_len);
|
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN + opt_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Add own address
|
||||||
|
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= RPL_DODAG_ID_LEN;
|
||||||
|
memcpy(&rpl_opt_target_buf->target,&my_address,sizeof(ipv6_addr_t));
|
||||||
|
printf("Sending DAO with length %d\n",rpl_opt_target_buf->prefix_length);
|
||||||
|
opt_len += RPL_OPT_TARGET_LEN +2;
|
||||||
|
|
||||||
uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len;
|
uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len;
|
||||||
|
printf("Sending DAO\n");
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,9 +412,11 @@ void recv_rpl_dio(void){
|
|||||||
|
|
||||||
if(rpl_equal_id(&my_dodag->dodag_id, &dio_dodag.dodag_id)){
|
if(rpl_equal_id(&my_dodag->dodag_id, &dio_dodag.dodag_id)){
|
||||||
//Mein DODAG
|
//Mein DODAG
|
||||||
if( dio_dodag.version > my_dodag->version){
|
if(RPL_COUNTER_GREATER_THAN(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){
|
||||||
|
//Jemand hat ein DIO mit einer höheren Version als der richtigen gesendet
|
||||||
|
//Wir erhöhen diese Version noch einmal, und machen sie zur neuen
|
||||||
my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version);
|
my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version);
|
||||||
reset_trickletimer();
|
reset_trickletimer();
|
||||||
}
|
}
|
||||||
@ -408,7 +425,8 @@ void recv_rpl_dio(void){
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if( dio_dodag.version < my_dodag->version){
|
else if( RPL_COUNTER_GREATER_THAN(my_dodag->version, dio_dodag.version) ){
|
||||||
|
//ein Knoten hat noch eine kleinere Versionsnummer -> mehr DIOs senden
|
||||||
reset_trickletimer();
|
reset_trickletimer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -427,6 +445,7 @@ void recv_rpl_dio(void){
|
|||||||
parent = rpl_find_parent(&ipv6_buf->srcaddr);
|
parent = rpl_find_parent(&ipv6_buf->srcaddr);
|
||||||
if(parent == NULL){
|
if(parent == NULL){
|
||||||
//neuen Elternknoten hinzufuegen
|
//neuen Elternknoten hinzufuegen
|
||||||
|
//TODO: Checken, ob der Knoten parent sein darf
|
||||||
parent = rpl_new_parent(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank);
|
parent = rpl_new_parent(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank);
|
||||||
if(parent == NULL){
|
if(parent == NULL){
|
||||||
return;
|
return;
|
||||||
@ -492,10 +511,16 @@ void recv_rpl_dis(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void recv_rpl_dao(void){
|
void recv_rpl_dao(void){
|
||||||
|
printf("Receiving DAO\n");
|
||||||
|
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||||
|
if(my_dodag == NULL){
|
||||||
|
printf("[Error] got DAO without beeing part of a Dodag\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
ipv6_buf = get_ipv6_buf();
|
ipv6_buf = get_ipv6_buf();
|
||||||
|
|
||||||
rpl_dao_buf = get_rpl_dao_buf();
|
rpl_dao_buf = get_rpl_dao_buf();
|
||||||
int len = DAO_BASE_LEN;
|
int len = DAO_BASE_LEN;
|
||||||
|
uint8_t increment_seq = 0;
|
||||||
while(len < (ipv6_buf->length - ICMPV6_HDR_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){
|
||||||
@ -513,6 +538,12 @@ void recv_rpl_dao(void){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(RPL_OPT_TARGET):{
|
case(RPL_OPT_TARGET):{
|
||||||
|
rpl_opt_target_buf = get_rpl_opt_target_buf(len);
|
||||||
|
if(rpl_opt_target_buf->prefix_length != RPL_DODAG_ID_LEN){
|
||||||
|
printf("prefixes are not supported yet");
|
||||||
|
}
|
||||||
|
rpl_add_routing_entry(&rpl_opt_target_buf->target, &ipv6_buf->srcaddr);
|
||||||
|
increment_seq = 1;
|
||||||
len += rpl_opt_buf->length +2;
|
len += rpl_opt_buf->length +2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -529,6 +560,10 @@ void recv_rpl_dao(void){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(increment_seq){
|
||||||
|
RPL_COUNTER_INCREMENT(my_dodag->dao_seq);
|
||||||
|
delay_dao();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket){
|
void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket){
|
||||||
@ -573,13 +608,17 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
|||||||
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){
|
||||||
if(i_am_root){
|
if(i_am_root){
|
||||||
//oops... entweder bin ich root und weiß nicht wohin mit dem paket, oder es ist kein
|
//oops... ich bin root und weiß nicht wohin mit dem paketn
|
||||||
//preferred parent eingetragen, was nicht passieren sollte.
|
|
||||||
printf("[Error] destination unknown\n");
|
printf("[Error] destination unknown\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
next_hop = rpl_get_my_preferred_parent();
|
next_hop = rpl_get_my_preferred_parent();
|
||||||
|
if(next_hop == NULL){
|
||||||
|
//kein preferred parent eingetragen, was nicht passieren sollte.
|
||||||
|
printf("[Error] no preferred parent\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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);
|
||||||
@ -597,11 +636,12 @@ ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr){
|
|||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
routing_table[i].next_hop = *next_hop;
|
routing_table[i].next_hop = *next_hop;
|
||||||
|
routing_table[i].used = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,3 +661,8 @@ void rpl_clear_routing_table(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This function is for debug output purpose only...
|
||||||
|
rpl_routing_entry_t *rpl_get_routing_table(void){
|
||||||
|
return routing_table;
|
||||||
|
}
|
||||||
|
|||||||
@ -24,3 +24,4 @@ ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr);
|
|||||||
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);
|
||||||
void rpl_del_routing_entry(ipv6_addr_t *addr);
|
void rpl_del_routing_entry(ipv6_addr_t *addr);
|
||||||
void rpl_clear_routing_table();
|
void rpl_clear_routing_table();
|
||||||
|
rpl_routing_entry_t *rpl_get_routing_table(void);
|
||||||
|
|||||||
@ -87,7 +87,9 @@ void rpl_del_dodag(rpl_dodag_t *dodag){
|
|||||||
void rpl_leave_dodag(rpl_dodag_t * dodag){
|
void rpl_leave_dodag(rpl_dodag_t * dodag){
|
||||||
dodag->joined = 0;
|
dodag->joined = 0;
|
||||||
dodag->my_preferred_parent = NULL;
|
dodag->my_preferred_parent = NULL;
|
||||||
//TODO: parents aus Liste löschen?
|
//parents aus Liste löschen
|
||||||
|
rpl_delete_all_parents();
|
||||||
|
//TODO: Poison mit INFINITE_RANK
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){
|
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){
|
||||||
@ -97,6 +99,7 @@ bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank){
|
rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t rank){
|
||||||
@ -113,7 +116,8 @@ rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
rpl_delete_worst_parent();
|
||||||
|
return rpl_new_parent(dodag, address, rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){
|
rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){
|
||||||
@ -128,22 +132,54 @@ rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpl_delete_parent(ipv6_addr_t * address){
|
void rpl_delete_parent(rpl_parent_t * parent){
|
||||||
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
|
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
|
//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)){
|
char new_preferred_parent = 0;
|
||||||
//set_new_preferred_parent
|
if( (my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr, &parent->addr) ){
|
||||||
|
new_preferred_parent = 1;
|
||||||
|
memset(parent,0,sizeof(*parent));
|
||||||
}
|
}
|
||||||
|
uint8_t best = 0xFF;
|
||||||
|
uint16_t min_rank = 0xFFFF;
|
||||||
|
if(new_preferred_parent){
|
||||||
|
for(int i=0;i<RPL_MAX_PARENTS;i++){
|
||||||
|
if(parents[i].rank < min_rank){
|
||||||
|
best = i;
|
||||||
|
min_rank = parents[i].rank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(best == 0xFF){
|
||||||
|
//we have no more parents for this dodag -> leave dodag;
|
||||||
|
//TODO: Erst nach Ablauf eines Timers verlassen, siehe RPL draft 8.2.2.1 DODAG Version
|
||||||
|
rpl_leave_dodag(my_dodag);
|
||||||
|
}
|
||||||
|
my_dodag->my_preferred_parent = &parents[best];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpl_delete_worst_parent(void){
|
||||||
|
uint8_t worst = 0xFF;
|
||||||
|
uint16_t max_rank = 0x0000;
|
||||||
|
for(int i=0;i<RPL_MAX_PARENTS;i++){
|
||||||
|
if(parents[i].rank > max_rank){
|
||||||
|
worst = i;
|
||||||
|
max_rank = parents[i].rank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(worst == 0xFF){
|
||||||
|
//Fehler, keine parents -> sollte nicht passieren
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rpl_delete_parent(&parents[worst]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpl_delete_all_parents(void){
|
||||||
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)) ){
|
|
||||||
memset(&parents[i],0,sizeof(parents[i]));
|
memset(&parents[i],0,sizeof(parents[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
@ -174,6 +210,7 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran
|
|||||||
my_dodag->joined = 1;
|
my_dodag->joined = 1;
|
||||||
my_dodag->my_preferred_parent = preferred_parent;
|
my_dodag->my_preferred_parent = preferred_parent;
|
||||||
my_dodag->my_rank = dodag->of->calc_rank(preferred_parent, dodag->my_rank);
|
my_dodag->my_rank = dodag->of->calc_rank(preferred_parent, dodag->my_rank);
|
||||||
|
my_dodag->dao_seq = RPL_COUNTER_INIT;
|
||||||
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);
|
||||||
@ -186,6 +223,7 @@ void rpl_global_repair(rpl_dodag_t *dodag){
|
|||||||
printf("Error - no global repair possible, if not part of a DODAG\n");
|
printf("Error - no global repair possible, if not part of a DODAG\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//TODO: nachschauen - soll das wirklich so überschrieben werden?
|
||||||
my_dodag->version = dodag->version;
|
my_dodag->version = dodag->version;
|
||||||
my_dodag->dtsn = dodag->dtsn;
|
my_dodag->dtsn = dodag->dtsn;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,3 +15,6 @@ void rpl_leave_dodag(rpl_dodag_t * dodag);
|
|||||||
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2);
|
bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2);
|
||||||
void rpl_global_repair(rpl_dodag_t *dodag);
|
void rpl_global_repair(rpl_dodag_t *dodag);
|
||||||
ipv6_addr_t *rpl_get_my_preferred_parent();
|
ipv6_addr_t *rpl_get_my_preferred_parent();
|
||||||
|
void rpl_delete_parent(rpl_parent_t *parent);
|
||||||
|
void rpl_delete_worst_parent(void);
|
||||||
|
void rpl_delete_all_parents(void);
|
||||||
|
|||||||
@ -68,6 +68,7 @@
|
|||||||
#define DEFAULT_MIN_HOP_RANK_INCREASE 256
|
#define DEFAULT_MIN_HOP_RANK_INCREASE 256
|
||||||
//DAO_DELAY is in seconds
|
//DAO_DELAY is in seconds
|
||||||
#define DEFAULT_DAO_DELAY 1
|
#define DEFAULT_DAO_DELAY 1
|
||||||
|
#define RPL_DODAG_ID_LEN 16
|
||||||
|
|
||||||
//others
|
//others
|
||||||
|
|
||||||
@ -197,6 +198,7 @@ typedef struct rpl_dodag_t {
|
|||||||
uint8_t version;
|
uint8_t version;
|
||||||
uint8_t grounded;
|
uint8_t grounded;
|
||||||
uint16_t my_rank;
|
uint16_t my_rank;
|
||||||
|
uint8_t dao_seq;
|
||||||
uint16_t min_rank;
|
uint16_t min_rank;
|
||||||
uint8_t joined;
|
uint8_t joined;
|
||||||
rpl_parent_t *my_preferred_parent;
|
rpl_parent_t *my_preferred_parent;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user