1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge branch 'mac' of ssh://ukleos/home/git/ukleos into mac

This commit is contained in:
Oliver Hahm 2012-03-28 10:36:43 +02:00
commit 34611e6080
8 changed files with 126 additions and 60 deletions

View File

@ -17,7 +17,6 @@
void init(char *str){
char command;
uint16_t r_addr;
ipv6_addr_t std_addr;
int res = sscanf(str, "init %c %hu", &command, &r_addr);
@ -28,30 +27,27 @@ void init(char *str){
printf("\taddress must be an 8 bit integer\n");
}
ipv6_init_address(&std_addr, 0xABCD,0,0,0,0x1234,0xFFFF,0xFEDC,r_addr);
uint8_t state;
switch (command) {
case 'r':
printf("INFO: Initialize as root on address \n");
ipv6_print_addr(&std_addr);
printf("INFO: Initialize as root on address %d\n", r_addr);
if (r_addr > 255) {
printf("ERROR: address not an 8 bit integer\n");
return;
}
state = rpl_init(TRANSCEIVER_CC1100, &std_addr);
state = rpl_init(TRANSCEIVER_CC1100, r_addr);
if(state != SUCCESS){
printf("Error initializing RPL\n");
}
rpl_init_root();
break;
case 'n':
printf("INFO: Initialize as node on address \n");
ipv6_print_addr(&std_addr);
printf("INFO: Initialize as node on address %d\n", r_addr);
if (r_addr > 255) {
printf("ERROR: address not an 8 bit integer\n");
return;
}
state = rpl_init(TRANSCEIVER_CC1100, &std_addr);
state = rpl_init(TRANSCEIVER_CC1100, r_addr);
if(state != SUCCESS){
printf("Error initializing RPL\n");
}

View File

@ -34,6 +34,7 @@ static struct icmpv6_hdr_t* icmp_send_buf;
static struct rpl_dio_t *rpl_send_dio_buf;
static struct rpl_dis_t *rpl_send_dis_buf;
static struct rpl_dao_t *rpl_send_dao_buf;
static struct rpl_dao_ack_t * rpl_send_dao_ack_buf;
static struct rpl_opt_dodag_conf_t * rpl_send_opt_dodag_conf_buf;
static struct rpl_opt_solicited_t * rpl_send_opt_solicited_buf;
static struct rpl_opt_target_t * rpl_send_opt_target_buf;
@ -45,7 +46,7 @@ static struct ipv6_hdr_t* ipv6_buf;
static struct rpl_dio_t *rpl_dio_buf;
static struct rpl_dis_t *rpl_dis_buf;
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_dodag_conf_t * rpl_opt_dodag_conf_buf;
static struct rpl_opt_solicited_t * rpl_opt_solicited_buf;
@ -72,6 +73,9 @@ static struct rpl_dao_t* get_rpl_send_dao_buf(){
//return ((struct rpl_dao_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN]));
return ((struct rpl_dao_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
}
static struct rpl_dao_ack_t* get_rpl_send_dao_ack_buf(){
return ((struct rpl_dao_ack_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
}
static struct rpl_dis_t* get_rpl_send_dis_buf(){
//return ((struct rpl_dis_t*)&(rpl_send_buffer[LLHDR_ICMPV6HDR_LEN]));
return ((struct rpl_dis_t*)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
@ -94,9 +98,6 @@ static struct rpl_opt_transit_t* get_rpl_send_opt_transit_buf(uint8_t rpl_msg_le
static struct ipv6_hdr_t * get_rpl_ipv6_buf(void){
return ((struct ipv6_hdr_t*)&(rpl_buffer[0]));
}
//static struct icmpv6_hdr_t * get_rpl_icmpv6_buf(uint8_t ext_len){
// return ((struct icmpv6_hdr_t*)&(rpl_buffer[IPV6_HDR_LEN + ext_len]));
//}
static struct rpl_dio_t* get_rpl_dio_buf(){
return ((struct rpl_dio_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
}
@ -104,9 +105,9 @@ static struct rpl_dio_t* get_rpl_dio_buf(){
static struct rpl_dao_t* get_rpl_dao_buf(){
return ((struct rpl_dao_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
}
/*static struct rpl_dao_ack_t* get_rpl_dao_ack_buf(){
static struct rpl_dao_ack_t* get_rpl_dao_ack_buf(){
return ((struct rpl_dao_ack_t*)&(buffer[LLHDR_ICMPV6HDR_LEN]));
}*/
}
static struct rpl_dis_t* get_rpl_dis_buf(){
return ((struct rpl_dis_t*)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
}
@ -140,18 +141,13 @@ rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp){
return NULL;
}
uint8_t rpl_init(transceiver_type_t trans, ipv6_addr_t *rpl_address){
uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address){
vtimer_init();
mutex_init(&rpl_send_mutex);
mutex_init(&rpl_recv_mutex);
if(rpl_address == NULL){
if(rpl_address == 0){
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();
@ -163,7 +159,11 @@ uint8_t rpl_init(transceiver_type_t trans, ipv6_addr_t *rpl_address){
objective_functions[0] = rpl_get_of0();
//objective_functions[1] = rpl_get_of_ETX()
sixlowpan_init(trans,rpl_address->uint8[15],0);
sixlowpan_init(trans,rpl_address,0);
//Wir benötigen einen Link Local prefix, um unsere entsprechende Addresse im Netz abzufragen
ipv6_addr_t ll_address;
ipv6_set_ll_prefix(&ll_address);
ipv6_get_saddr(&my_address, &ll_address);
set_rpl_process_pid(rpl_process_pid);
return SUCCESS;
@ -193,7 +193,7 @@ void rpl_init_root(){
dodag->dio_redundancy = DEFAULT_DIO_REDUNDANCY_CONSTANT;
dodag->maxrankincrease = 0;
dodag->minhoprankincrease = (uint16_t)DEFAULT_MIN_HOP_RANK_INCREASE;
dodag->default_lifetime = (uint16_t)RPL_DEFAULT_LIFETIME;
dodag->default_lifetime = (uint8_t)RPL_DEFAULT_LIFETIME;
dodag->lifetime_unit = RPL_LIFETIME_UNIT;
dodag->version = RPL_COUNTER_INIT;
dodag->grounded = RPL_GROUNDED;
@ -207,9 +207,6 @@ void rpl_init_root(){
}
i_am_root = 1;
start_trickle(dodag->dio_min, dodag->dio_interval_doubling, dodag->dio_redundancy);
//ipv6_addr_t mcast;
//ipv6_set_all_nds_mcast_addr(&mcast);
//send_DIO(&mcast);
puts("ROOT INIT FINISHED");
}
@ -271,6 +268,7 @@ void send_DIO(ipv6_addr_t* destination){
}
void send_DIS(ipv6_addr_t *destination){
puts("Send DIS");
mutex_lock(&rpl_send_mutex);
icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
@ -279,7 +277,7 @@ void send_DIS(ipv6_addr_t *destination){
icmp_send_buf->code = ICMP_CODE_DIO;
icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
rpl_dis_buf = get_rpl_dis_buf();
rpl_send_dis_buf = get_rpl_send_dis_buf();
uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN;
rpl_send(destination,(uint8_t*)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL);
@ -287,7 +285,7 @@ void send_DIS(ipv6_addr_t *destination){
}
void send_DAO(ipv6_addr_t *destination, uint8_t lifetime){
void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime){
if(i_am_root){
return;
}
@ -298,8 +296,10 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime){
if(destination == NULL){
destination = &my_dodag->my_preferred_parent->addr;
}
printf("Sending DAO to\n");
ipv6_print_addr(destination);
if(default_lifetime){
lifetime=my_dodag->default_lifetime;
}
puts("sending DAO");
icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
@ -360,6 +360,34 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime){
mutex_unlock(&rpl_send_mutex, 0);
}
void send_DAO_ACK(ipv6_addr_t *destination){
puts("Send DAO_ACK to");
ipv6_print_addr(destination);
rpl_dodag_t * my_dodag;
my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
return;
}
mutex_lock(&rpl_send_mutex);
icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
icmp_send_buf->type = ICMP_RPL_CONTROL;
icmp_send_buf->code = ICMP_CODE_DAO_ACK;
icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
rpl_send_dao_ack_buf = get_rpl_send_dao_ack_buf();
rpl_send_dao_ack_buf->rpl_instanceid = my_dodag->instance->id;
rpl_send_dao_ack_buf->d_reserved = 0;
rpl_send_dao_ack_buf->dao_sequence = my_dodag->dao_seq;
rpl_send_dao_ack_buf->status = 0;
uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN;
rpl_send(destination,(uint8_t*)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL);
mutex_unlock(&rpl_send_mutex, 0);
}
void rpl_process(void){
msg_t m_recv;
@ -367,7 +395,6 @@ void rpl_process(void){
while(1){
msg_receive(&m_recv);
puts("Got a RPL Package");
uint8_t *code;
code = ((uint8_t*)m_recv.content.ptr);
//pakettypen unterscheiden
@ -378,27 +405,24 @@ void rpl_process(void){
switch(*code) {
case(ICMP_CODE_DIS):{
recv_rpl_dis();
puts("unlock after dis recv");
mutex_unlock(&rpl_recv_mutex, 0);
//mutex_unlock(&rpl_send_mutex, 0);
break;
}
case(ICMP_CODE_DIO):{
recv_rpl_dio();
puts("unlock after dio recv");
mutex_unlock(&rpl_recv_mutex, 0);
//mutex_unlock(&rpl_send_mutex, 0);
break;
}
case(ICMP_CODE_DAO):{
recv_rpl_dao();
puts("unlock after dao recv");
mutex_unlock(&rpl_recv_mutex, 0);
//mutex_unlock(&rpl_send_mutex, 0);
break;
}
case(ICMP_CODE_DAO_ACK):{
puts("unlock after dao_ack recv");
recv_rpl_dao_ack();
mutex_unlock(&rpl_recv_mutex, 0);
//mutex_unlock(&rpl_send_mutex, 0);
break;
@ -508,7 +532,7 @@ void recv_rpl_dio(void){
}
default:
printf("[Error] Unsupported DIO option\n");
break;
return;
}
}
@ -652,7 +676,7 @@ void recv_rpl_dis(void){
break;
}
default:
break;
return;
}
}
send_DIO(&ipv6_buf->srcaddr);
@ -660,7 +684,6 @@ void recv_rpl_dis(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");
@ -701,7 +724,7 @@ void recv_rpl_dao(void){
len += rpl_opt_transit_buf->length +2;
//Die eigentliche Lebenszeit einer Route errechnet sich aus (Lifetime aus DAO) * (Lifetime Unit) Sekunden
rpl_add_routing_entry(&rpl_opt_target_buf->target, &ipv6_buf->srcaddr, rpl_opt_transit_buf->path_lifetime * my_dodag->lifetime_unit);
printf("new route added\n");
puts("Updated route \n");
increment_seq = 1;
break;
}
@ -715,15 +738,33 @@ void recv_rpl_dao(void){
}
default:
break;
return;
}
}
send_DAO_ACK(&ipv6_buf->srcaddr);
if(increment_seq){
RPL_COUNTER_INCREMENT(my_dodag->dao_seq);
delay_dao();
}
}
void recv_rpl_dao_ack(void){
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
return;
}
rpl_dao_ack_buf = get_rpl_dao_ack_buf();
if(rpl_dao_ack_buf->rpl_instanceid != my_dodag->instance->id){
return;
}
if(rpl_dao_ack_buf->status != 0){
return;
}
puts("Received DAO ACK");
dao_ack_received();
}
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;
ipv6_send_buf = get_rpl_send_ipv6_buf();
@ -739,8 +780,6 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
memcpy(&(ipv6_send_buf->destaddr), destination, 16);
ipv6_get_saddr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr));
//memcpy(&(ipv6_send_buf->srcaddr), &my_address, 16);
ipv6_print_addr(&ipv6_send_buf->srcaddr);
//Wenn das Paket in der rpl.c "zusammegebaut" wurde, wurde dafür ohnehin der rpl_send_buf verwendet.
//In diesem Fall muss also keine memcopy Aktion durchgeführt werden, da sich der payload bereits
@ -755,8 +794,6 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
lowpan_init((ieee_802154_long_t*)&(ipv6_send_buf->destaddr.uint16[4]),(uint8_t*)ipv6_send_buf);
}
else{
puts("sending packet to");
ipv6_print_addr(&ipv6_send_buf->destaddr);
//find right next hop before sending
ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_send_buf->destaddr);
if(next_hop == NULL){
@ -789,10 +826,16 @@ 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, uint8_t lifetime){
rpl_routing_entry_t * entry = rpl_find_routing_entry(addr);
if(entry != NULL){
entry->lifetime = lifetime;
return;
}
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES; i++){
if(!routing_table[i].used){
routing_table[i].address = *addr;
routing_table[i].next_hop = *next_hop;
routing_table[i].lifetime = lifetime;
routing_table[i].used = 1;
break;
}
@ -808,9 +851,18 @@ void rpl_del_routing_entry(ipv6_addr_t *addr){
}
}
rpl_routing_entry_t *rpl_find_routing_entry(ipv6_addr_t *addr){
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES; i++){
if(routing_table[i].used && rpl_equal_id(&routing_table[i].address, addr)){
return &routing_table[i];
}
}
return NULL;
}
void rpl_clear_routing_table(){
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES; i++){
routing_table[i].used = 0;
memset(&routing_table[i], 0, sizeof(routing_table[i]));
}
}

View File

@ -8,20 +8,23 @@
#define RPL_PKT_RECV_BUF_SIZE 20
#define RPL_PROCESS_STACKSIZE 4096
uint8_t rpl_init(transceiver_type_t trans, ipv6_addr_t *rpl_address);
uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address);
void rpl_init_root();
rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp);
void send_DIO(ipv6_addr_t *destination);
void send_DIS(ipv6_addr_t *destination);
void send_DAO(ipv6_addr_t *destination, uint8_t lifetime);
void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime);
void send_DAO_ACK(ipv6_addr_t *destination);
void rpl_process(void);
void recv_rpl_dio(void);
void recv_rpl_dis(void);
void recv_rpl_dao(void);
void recv_rpl_dao_ack(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, uint8_t lifetime);
void rpl_del_routing_entry(ipv6_addr_t *addr);
rpl_routing_entry_t * rpl_find_routing_entry(ipv6_addr_t *addr);
void rpl_clear_routing_table();
rpl_routing_entry_t *rpl_get_routing_table(void);

View File

@ -191,7 +191,7 @@ rpl_parent_t * rpl_find_preferred_parent(void){
if(!rpl_equal_id(&my_dodag->my_preferred_parent->addr, &best->addr)){
if(my_dodag->mop != NO_DOWNWARD_ROUTES){
//send DAO with ZERO_LIFETIME to old parent
send_DAO(&my_dodag->my_preferred_parent->addr, 0);
send_DAO(&my_dodag->my_preferred_parent->addr, 0, false);
}
my_dodag->my_preferred_parent = best;
if(my_dodag->mop != NO_DOWNWARD_ROUTES){

View File

@ -70,6 +70,7 @@
#define DEFAULT_MIN_HOP_RANK_INCREASE 256
//DAO_DELAY is in seconds
#define DEFAULT_DAO_DELAY 3
#define DEFAULT_WAIT_FOR_DAO_ACK 10
#define RPL_DODAG_ID_LEN 16
//others

View File

@ -14,6 +14,9 @@ int interval_over_pid;
int dao_delay_over_pid;
int rt_timer_over_pid;
bool ack_received;
uint8_t dao_counter;
uint8_t k;
uint32_t Imin;
uint8_t Imax;
@ -48,9 +51,7 @@ void reset_trickletimer(void){
void init_trickle(void){
//Create threads
// timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE,
// PRIORITY_MAIN-1,CREATE_SLEEPING,
// trickle_timer_over, "trickle_timer_over");
ack_received = true;
timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE,
PRIORITY_MAIN-1,CREATE_STACKTEST,
trickle_timer_over, "trickle_timer_over");
@ -74,7 +75,7 @@ void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl, uint8_t DIORedundancy
Imax = DIOIntDoubl;
//Eigentlich laut Spezifikation erste Bestimmung von I wie auskommentiert:
//I = Imin + ( rand() % ( (Imin << Imax) - Imin + 1 ) );
I = Imin + ( rand() % ( (4*Imin) - Imin + 1 ) );
I = Imin + ( rand() % ( (4*Imin) - Imin + 1 ) ) ;
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
t_time = timex_set(0,t*1000);
@ -135,6 +136,8 @@ void trickle_interval_over(void){
void delay_dao(void){
dao_time = timex_set(DEFAULT_DAO_DELAY,0);
ack_received = false;
dao_counter = 0;
vtimer_remove(&dao_timer);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
}
@ -142,10 +145,20 @@ void delay_dao(void){
void dao_delay_over(void){
while(1){
thread_sleep();
send_DAO(NULL, false);
//10 DAOs will do... TODO: define
if((ack_received == false) && (dao_counter < 10)){
dao_counter++;
send_DAO(NULL, 0, true);
dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK,0);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
}
}
}
void dao_ack_received(){
ack_received = true;
}
void rt_timer_over(void){
rpl_routing_entry_t * rt;
while(1){

View File

@ -17,4 +17,5 @@ void trickle_timer_over(void);
void trickle_interval_over(void);
void delay_dao(void);
void dao_delay_over(void);
void dao_ack_received(void);
void rt_timer_over(void);

View File

@ -86,38 +86,38 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t
int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) {
switch(hdr->type) {
case(ICMP_RTR_SOL):{
printf("INFO: packet type: icmp router solicitation\n");
puts("INFO: packet type: icmp router solicitation");
/* processing router solicitation */
recv_rtr_sol();
/* init solicited router advertisment*/
break;
}
case(ICMP_RTR_ADV):{
printf("INFO: packet type: icmp router advertisment\n");
puts("INFO: packet type: icmp router advertisment");
/* processing router advertisment */
recv_rtr_adv();
/* init neighbor solicitation */
break;
}
case(ICMP_NBR_SOL):{
printf("INFO: packet type: icmp neighbor solicitation\n");
puts("INFO: packet type: icmp neighbor solicitation");
recv_nbr_sol();
break;
}
case(ICMP_NBR_ADV):{
printf("INFO: packet type: icmp neighbor advertisment\n");
puts("INFO: packet type: icmp neighbor advertisment");
recv_nbr_adv();
break;
}
case(ICMP_RPL_CONTROL):{
printf("INFO: packet type: RPL message\n");
puts("INFO: packet type: RPL message");
if(rpl_process_pid != 0){
msg_t m_send;
m_send.content.ptr = (char*) &hdr->code;
msg_send(&m_send, rpl_process_pid, 1);
}
else{
printf("INFO: no RPL handler registered\n");
puts("INFO: no RPL handler registered");
}
break;
}