From d766e419966d413d49721c340cda34166c89780f Mon Sep 17 00:00:00 2001 From: Eric Engel Date: Tue, 14 Feb 2012 22:22:01 +0100 Subject: [PATCH] Joined nodes now send DIOs, some minor bugfixes, routing table stubs --- projects/test_rpl/main.c | 9 +- sys/net/sixlowpan/rpl/of0.c | 2 +- sys/net/sixlowpan/rpl/rpl.c | 202 ++++++++++++++++++++++------ sys/net/sixlowpan/rpl/rpl.h | 17 ++- sys/net/sixlowpan/rpl/rpl_dodag.c | 23 +++- sys/net/sixlowpan/rpl/rpl_dodag.h | 1 + sys/net/sixlowpan/rpl/rpl_structs.h | 8 ++ sys/net/sixlowpan/rpl/trickle.h | 4 +- 8 files changed, 211 insertions(+), 55 deletions(-) diff --git a/projects/test_rpl/main.c b/projects/test_rpl/main.c index 23c680598d..188e85ef5d 100644 --- a/projects/test_rpl/main.c +++ b/projects/test_rpl/main.c @@ -4,16 +4,19 @@ #include #include "sys/net/sixlowpan/sixlowip.h" #include "sys/net/sixlowpan/sixlowpan.h" +#include "sys/net/sixlowpan/sixlowerror.h" #include "sys/net/sixlowpan/rpl/rpl.h" int main(void) { - uint16_t root = 0x0001; + uint16_t root = 0x0002; ipv6_addr_t std_addr; uint16_t r_addr = root; ipv6_init_address(&std_addr, 0xABCD,0,0,0,0x1234,0xFFFF,0xFEDC,r_addr); - sixlowpan_init(TRANSCEIVER_CC1100, r_addr, 0); - rpl_init(); + uint8_t state = rpl_init(TRANSCEIVER_CC1100, &std_addr); + if(state != SUCCESS){ + printf("Error initializing RPL\n"); + } if(root == 0x0001){ rpl_init_root(); } diff --git a/sys/net/sixlowpan/rpl/of0.c b/sys/net/sixlowpan/rpl/of0.c index c57f1e9531..52bf6a9b9a 100644 --- a/sys/net/sixlowpan/rpl/of0.c +++ b/sys/net/sixlowpan/rpl/of0.c @@ -2,7 +2,7 @@ #include "of0.h" rpl_of_t rpl_of0 = { - 0, + 0x0, calc_rank, which_parent, which_dodag, diff --git a/sys/net/sixlowpan/rpl/rpl.c b/sys/net/sixlowpan/rpl/rpl.c index 6e4522dd0e..fef01554e0 100644 --- a/sys/net/sixlowpan/rpl/rpl.c +++ b/sys/net/sixlowpan/rpl/rpl.c @@ -9,6 +9,7 @@ #include "sys/net/sixlowpan/sixlowmac.h" #include "sys/net/sixlowpan/sixlowip.h" #include "sys/net/sixlowpan/sixlowpan.h" +#include "sys/net/sixlowpan/sixlowerror.h" char rpl_process_buf[RPL_PROCESS_STACKSIZE]; //counters @@ -18,7 +19,9 @@ uint8_t path_sequence = 240; //other global variables rpl_of_t *objective_functions[NUMBER_IMPLEMENTED_OFS]; +rpl_routing_entry_t routing_table[RPL_MAX_ROUTING_ENTRIES]; unsigned int rpl_process_pid; +ipv6_addr_t my_address; msg_t msg_queue[RPL_PKT_RECV_BUF_SIZE]; @@ -55,7 +58,7 @@ static struct rpl_opt_dodag_conf_t* get_rpl_opt_dodag_conf_buf(uint8_t rpl_msg_l } rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp){ - for(uint8_t i; i < NUMBER_IMPLEMENTED_OFS; i++){ + for(uint16_t i=0; i < NUMBER_IMPLEMENTED_OFS; i++){ if(ocp == objective_functions[i]->ocp){ return objective_functions[i]; } @@ -63,14 +66,29 @@ rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp){ return NULL; } -void rpl_init(){ - +uint8_t rpl_init(transceiver_type_t trans, ipv6_addr_t *rpl_address){ + if(rpl_address == NULL){ + return SIXLOWERROR_ADDRESS; + } + //radio-address is 8-bit + if(rpl_address->uint8[14] != 0){ + return SIXLOWERROR_ADDRESS; + } + my_address = *rpl_address; + //initialize routing table + rpl_clear_routing_table(); init_trickle(); rpl_process_pid = thread_create(rpl_process_buf, RPL_PROCESS_STACKSIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, rpl_process, "rpl_process"); + + //INSERT NEW OBJECTIVE FUNCTIONS HERE objective_functions[0] = rpl_get_of0(); + //objective_functions[1] = rpl_get_of_ETX() + + sixlowpan_init(trans,rpl_address->uint8[15],0); set_rpl_process_pid(rpl_process_pid); + return SUCCESS; } @@ -86,12 +104,7 @@ void rpl_init_root(){ inst->id = RPL_DEFAULT_INSTANCE; inst->joined = 1; - ipv6_addr_t id; - ipv6_addr_t mcast; - ipv6_set_all_nds_mcast_addr(&mcast); - ipv6_get_saddr(&id, &mcast); - - dodag = rpl_new_dodag(RPL_DEFAULT_INSTANCE, &id); + dodag = rpl_new_dodag(RPL_DEFAULT_INSTANCE, &my_address); if(dodag != NULL) { dodag->of = rpl_get_of_for_ocp(RPL_DEFAULT_OCP); dodag->instance = inst; @@ -123,7 +136,6 @@ void rpl_init_root(){ void send_DIO(ipv6_addr_t* destination){ rpl_dodag_t * mydodag; - ipv6_buf = get_ipv6_buf(); icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); mydodag = rpl_get_my_dodag(); @@ -134,13 +146,6 @@ void send_DIO(ipv6_addr_t* destination){ icmp_buf->type = ICMP_RPL_CONTROL; icmp_buf->code = ICMP_CODE_DIO; - ipv6_buf->version_trafficclass = IPV6_VER; - ipv6_buf->trafficclass_flowlabel = 0; - ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = PROTO_NUM_ICMPV6; - ipv6_buf->hoplimit = 1; - ipv6_buf->destaddr = *destination; - ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); rpl_dio_buf = get_rpl_dio_buf(); memset(rpl_dio_buf, 0, sizeof(*rpl_dio_buf)); @@ -175,28 +180,43 @@ void send_DIO(ipv6_addr_t* destination){ opt_hdr_len += RPL_OPT_LEN + RPL_OPT_DODAG_CONF_LEN; - ipv6_buf->length = ICMPV6_HDR_LEN + DIO_BASE_LEN + opt_hdr_len; - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + uint16_t plen = ICMPV6_HDR_LEN + DIO_BASE_LEN + opt_hdr_len; + rpl_send(destination,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL); } void send_DIS(ipv6_addr_t *destination){ - ipv6_buf = get_ipv6_buf(); icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); icmp_buf->type = ICMP_RPL_CONTROL; icmp_buf->code = ICMP_CODE_DIO; - ipv6_buf->version_trafficclass = IPV6_VER; - ipv6_buf->trafficclass_flowlabel = 0; - ipv6_buf->flowlabel = 0; - ipv6_buf->nextheader = PROTO_NUM_ICMPV6; - ipv6_buf->hoplimit = 1; - ipv6_buf->destaddr = *destination; - ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); rpl_dis_buf = get_rpl_dis_buf(); - ipv6_buf->length = ICMPV6_HDR_LEN + DIS_BASE_LEN; - lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; + rpl_send(destination,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL); +} + +void send_DAO(){ + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + + icmp_buf->type = ICMP_RPL_CONTROL; + icmp_buf->code = ICMP_CODE_DAO; + + rpl_dodag_t * my_dodag; + my_dodag = rpl_get_my_dodag(); + if(my_dodag == NULL){ + return; + } + rpl_dao_buf = get_rpl_dao_buf(); + memset(rpl_dao_buf,0,sizeof(*rpl_dao_buf)); + rpl_dao_buf->rpl_instanceid = my_dodag->instance->id; + //rpl_dao_buf->k_d_flags = 0x00; + //TODO:dao_sequence handling + rpl_dao_buf->dao_sequence = 0x00; + + + 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); } void rpl_process(void){ @@ -211,6 +231,7 @@ void rpl_process(void){ //pakettypen unterscheiden switch(*code) { case(ICMP_CODE_DIS):{ + recv_rpl_dis(); break; } case(ICMP_CODE_DIO):{ @@ -237,12 +258,11 @@ void recv_rpl_dio(void){ rpl_dio_buf = get_rpl_dio_buf(); int len = DIO_BASE_LEN; - printf("Try to find instance with id: %d \n", rpl_dio_buf->rpl_instanceid); rpl_instance_t * dio_inst = rpl_get_instance(rpl_dio_buf->rpl_instanceid); rpl_instance_t * my_inst = rpl_get_my_instance(); if(dio_inst == NULL){ if(my_inst != NULL){ - //Knoten ist schon Teil eines DODAGS -> kein beitritt zu anderer Instanz moeglich + //Dieser Knoten ist schon Teil eines DODAGS -> kein beitritt zu anderer Instanz moeglich return; } dio_inst = rpl_new_instance(rpl_dio_buf->rpl_instanceid); @@ -250,22 +270,30 @@ void recv_rpl_dio(void){ return; } }else if(my_inst->id != dio_inst->id){ - //DIO von fremder Instanz ignorieren + printf("Andere Instanz, wir haben %d es kam aber %d\n",my_inst->id, dio_inst->id); + //DIO von fremder Instanz ignorieren, Knoten können Momentan nur einer Instanz beitreten und das wird + //die Instanz sein, der sie als erstes beitreten. Danach kann die Instanz nicht mehr gewechselt werden + //Unterstützung für mehrere Instanzen könnte in Zukunft implementiert werden return; } - printf("Try to find dodag with id:\n"); - ipv6_print_addr(&rpl_dio_buf->dodagid); + //printf("Try to find dodag with id:\n"); + //ipv6_print_addr(&rpl_dio_buf->dodagid); rpl_dodag_t dio_dodag; memset(&dio_dodag, 0,sizeof(dio_dodag)); + memcpy(&dio_dodag.dodag_id,&rpl_dio_buf->dodagid,sizeof(dio_dodag.dodag_id)); dio_dodag.dtsn = rpl_dio_buf->dtsn; dio_dodag.mop = ((rpl_dio_buf->g_mop_prf >> RPL_MOP_SHIFT ) & RPL_SHIFTED_MOP_MASK); dio_dodag.grounded = rpl_dio_buf->g_mop_prf >> RPL_GROUNDED_SHIFT; dio_dodag.prf = (rpl_dio_buf->g_mop_prf & RPL_PRF_MASK); dio_dodag.version = rpl_dio_buf->version_number; + dio_dodag.instance = dio_inst; uint8_t has_dodag_conf_opt = 0; - while(len < (ipv6_buf->length - LLHDR_ICMPV6HDR_LEN) ){ + //So lange das Paket größer ist, als die DIO Größe + Größe der bisher verarbeiteten Optionen, + //sind noch weitere Optionen zu bearbeiten + //dabei müssen wir jedoch von der ipv6_buf->length die Größe des ICMP Headers abziehen + while(len < (ipv6_buf->length - ICMPV6_HDR_LEN) ){ rpl_opt_buf = get_rpl_opt_buf(len); switch(rpl_opt_buf->type){ @@ -290,7 +318,6 @@ void recv_rpl_dio(void){ if(rpl_opt_buf->length != RPL_OPT_DODAG_CONF_LEN){ //error malformed } - len += RPL_OPT_DODAG_CONF_LEN +2; 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_min = rpl_opt_dodag_conf_buf->DIOIntMin; @@ -300,6 +327,7 @@ void recv_rpl_dio(void){ dio_dodag.default_lifetime = rpl_opt_dodag_conf_buf->default_lifetime; dio_dodag.lifetime_unit = rpl_opt_dodag_conf_buf->lifetime_unit; dio_dodag.of = rpl_get_of_for_ocp(rpl_opt_dodag_conf_buf->ocp); + len += RPL_OPT_DODAG_CONF_LEN +2; break; } case(RPL_OPT_PREFIX_INFO):{ @@ -310,7 +338,7 @@ void recv_rpl_dio(void){ break; } default: - //unsupported option -> error + printf("[Error] Unsupported DIO option\n"); break; } } @@ -336,6 +364,7 @@ void recv_rpl_dio(void){ return; } if(rpl_dio_buf->rank != INFINITE_RANK){ + printf("Will join DODAG\n"); rpl_join_dodag(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); } else{ @@ -350,7 +379,7 @@ void recv_rpl_dio(void){ printf("New Version of dodag\n"); if(my_dodag->my_rank == ROOT_RANK){ my_dodag->version = dio_dodag.version +1; - //TODO: reset trickle timer + reset_trickletimer(); } else{ rpl_global_repair(&dio_dodag); @@ -358,16 +387,16 @@ void recv_rpl_dio(void){ return; } else if( dio_dodag.version < my_dodag->version){ - //TODO: reset trickle timer + reset_trickletimer(); return; } } //Version stimmt, DODAG stimmt if(rpl_dio_buf->rank == INFINITE_RANK) { - //TODO: reset trickle timer + reset_trickletimer(); if(my_dodag->my_rank == ROOT_RANK){ - //TODO: DIO Counter ++ + trickle_increment_counter(); return; } } @@ -383,9 +412,14 @@ void recv_rpl_dio(void){ } else{ //DIO ok - //TODO: DIO Counter++ + trickle_increment_counter(); } +} + +void recv_rpl_dis(void){ + + } void recv_rpl_dao(void){ @@ -427,3 +461,87 @@ void recv_rpl_dao(void){ } } } + +void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket){ + uint8_t *p_ptr; + /*if (next_header == IPPROTO_TCP) + { + p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); + ipv6_buf = get_ipv6_buf_send(); + } + else + {*/ + ipv6_buf = get_ipv6_buf(); + p_ptr = get_payload_buf(ipv6_ext_hdr_len); + //} + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + packet_length = 0; + + ipv6_buf->version_trafficclass = IPV6_VER; + ipv6_buf->trafficclass_flowlabel = 0; + ipv6_buf->flowlabel = 0; + ipv6_buf->nextheader = next_header; + ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT; + ipv6_buf->length = p_len; + + memcpy(&(ipv6_buf->destaddr), destination, 16); + ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + + memcpy(p_ptr,payload,p_len); + + packet_length = IPV6_HDR_LEN + p_len; + +#ifdef MODULE_DESTINY + if (next_header == IPPROTO_TCP) { + print_tcp_status(OUT_PACKET, ipv6_buf, (tcp_hdr_t *)(payload), (socket_t *)tcp_socket); + } +#endif + if(ipv6_prefix_mcast_match(&ipv6_buf->destaddr)){ + lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + } + else{ + //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"); + } + lowpan_init((ieee_802154_long_t*)&(next_hop->uint16[4]),(uint8_t*)ipv6_buf); + } + +} + +ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr){ + for(uint8_t i=0; i #include #include +#include #include "sys/net/sixlowpan/sixlowip.h" #include "rpl_dodag.h" #define RPL_PKT_RECV_BUF_SIZE 20 #define RPL_PROCESS_STACKSIZE 3072 -void rpl_init(); +uint8_t rpl_init(transceiver_type_t trans, ipv6_addr_t *rpl_address); void rpl_init_root(); rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp); - -void rpl_process(void); -void recv_rpl_dio(void); -void recv_rpl_dao(void); void send_DIO(ipv6_addr_t *destination); void send_DIS(ipv6_addr_t *destination); +void send_DAO(); +void rpl_process(void); +void recv_rpl_dio(void); +void recv_rpl_dis(void); +void recv_rpl_dao(void); +void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header, void *tcp_socket); +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_del_routing_entry(ipv6_addr_t *addr); +void rpl_clear_routing_table(); diff --git a/sys/net/sixlowpan/rpl/rpl_dodag.c b/sys/net/sixlowpan/rpl/rpl_dodag.c index b4d7a63a33..19523252d8 100644 --- a/sys/net/sixlowpan/rpl/rpl_dodag.c +++ b/sys/net/sixlowpan/rpl/rpl_dodag.c @@ -2,6 +2,7 @@ #include #include "rpl_dodag.h" +#include "trickle.h" rpl_instance_t instances[RPL_MAX_INSTANCES]; rpl_dodag_t dodags[RPL_MAX_DODAGS]; @@ -14,6 +15,7 @@ rpl_instance_t *rpl_new_instance(uint8_t instanceid){ if(inst->used == 0){ memset(inst, 0, sizeof(*inst)); inst->used = 1; + inst->id = instanceid; return inst; } } @@ -54,7 +56,7 @@ rpl_dodag_t * rpl_new_dodag(uint8_t instanceid, ipv6_addr_t *dodagid){ dodag->instance = inst; dodag->my_rank = INFINITE_RANK; dodag->used = 1; - dodag->dodag_id = *dodagid; + memcpy(&dodag->dodag_id,dodagid,sizeof(*dodagid)); return dodag; } } @@ -126,6 +128,14 @@ rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){ return NULL; } +void rpl_delete_parent(ipv6_addr_t * address){ + for(int i=0;iinstance->joined = 1; my_dodag->of = dodag->of; my_dodag->mop = dodag->mop; my_dodag->dtsn = dodag->dtsn; @@ -156,7 +167,7 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran my_dodag->my_rank = dodag->of->calc_rank(preferred_parent, dodag->my_rank); my_dodag->min_rank = my_dodag->my_rank; - //TODO: reset trickle timer + start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy); //TODO: start sending DAOs } @@ -170,3 +181,11 @@ void rpl_global_repair(rpl_dodag_t *dodag){ my_dodag->version = dodag->version; my_dodag->dtsn = dodag->dtsn; } + +ipv6_addr_t *rpl_get_my_preferred_parent(){ + rpl_dodag_t * my_dodag = rpl_get_my_dodag(); + if(my_dodag == NULL){ + return NULL; + } + return &my_dodag->my_preferred_parent->addr; +} diff --git a/sys/net/sixlowpan/rpl/rpl_dodag.h b/sys/net/sixlowpan/rpl/rpl_dodag.h index 2af34a4f66..b6339db722 100644 --- a/sys/net/sixlowpan/rpl/rpl_dodag.h +++ b/sys/net/sixlowpan/rpl/rpl_dodag.h @@ -14,3 +14,4 @@ rpl_parent_t *rpl_find_parent(ipv6_addr_t *address); void rpl_leave_dodag(rpl_dodag_t * dodag); bool rpl_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2); void rpl_global_repair(rpl_dodag_t *dodag); +ipv6_addr_t *rpl_get_my_preferred_parent(); diff --git a/sys/net/sixlowpan/rpl/rpl_structs.h b/sys/net/sixlowpan/rpl/rpl_structs.h index 13f59882bb..108c62b088 100644 --- a/sys/net/sixlowpan/rpl/rpl_structs.h +++ b/sys/net/sixlowpan/rpl/rpl_structs.h @@ -72,6 +72,7 @@ #define RPL_MAX_DODAGS 3 #define RPL_MAX_INSTANCES 1 #define RPL_MAX_PARENTS 5 +#define RPL_MAX_ROUTING_ENTRIES 20 #define RPL_ROOT_RANK 1 #define RPL_DEFAULT_LIFETIME 0xff #define RPL_LIFETIME_UNIT 0xffff @@ -188,4 +189,11 @@ typedef struct rpl_of_t { void (*parent_state_callback)(rpl_parent_t *, int, int); } rpl_of_t; +typedef struct rpl_routing_entry_t { + uint8_t used; + ipv6_addr_t address; + ipv6_addr_t next_hop; + +} rpl_routing_entry_t; + #endif diff --git a/sys/net/sixlowpan/rpl/trickle.h b/sys/net/sixlowpan/rpl/trickle.h index f7e3f69525..b953b39be8 100644 --- a/sys/net/sixlowpan/rpl/trickle.h +++ b/sys/net/sixlowpan/rpl/trickle.h @@ -1,8 +1,8 @@ #include #include -#define TRICKLE_TIMER_STACKSIZE 1024 -#define TRICKLE_INTERVAL_STACKSIZE 3024 +#define TRICKLE_TIMER_STACKSIZE 3072 +#define TRICKLE_INTERVAL_STACKSIZE 3072 void reset_trickletimer(void); void init_trickle(void);