1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge branch 'master' of ssh://ukleos.org:2222/home/git/ukleos

This commit is contained in:
Oliver Hahm 2012-03-02 15:01:11 +01:00
commit 64039410e4
22 changed files with 298 additions and 106 deletions

View File

@ -103,7 +103,7 @@ void send_packet(char *str){
for(int j=0;j<100;j++){
test[0] = j;
for(int i=0;i<1000;i++){
sixlowpan_send(&ipaddr, test, 2, 0, NULL);
sixlowpan_send(&ipaddr, test, 2, 0);
}
//lib6lowpan_bootstrapping(&addr8);
}

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <string.h>
#include <transceiver.h>
#include <shell.h>
#include <board_uart0.h>
@ -9,7 +10,6 @@
#include <hwtimer.h>
#include <swtimer.h>
#include <msg.h>
#include <transceiver.h>
#include <cc110x_ng.h>
#define SHELL_STACK_SIZE (2048)
@ -30,6 +30,7 @@ msg_t msg_q[RCV_BUFFER_SIZE];
static msg_t mesg;
static transceiver_command_t tcmd;
static radio_packet_t p;
static uint16_t a;
static uint32_t sending_delay = SENDING_DELAY;
@ -135,6 +136,9 @@ void ignore(char *addr) {
tcmd.transceivers = TRANSCEIVER_CC1100;
tcmd.data = &a;
if (sscanf(addr, "ign %hu", &a) == 1) {
printf("msg_q: %hu/%hu/%lu Transceiver PID: %i (%p), rx_buffer_next: %u\n",
msg_q[63].sender_pid, msg_q[63].type, msg_q[63].content.value, transceiver_pid, &transceiver_pid, rx_buffer_next);
printf("sending to transceiver (%u): %u\n", transceiver_pid, (*(uint8_t*)tcmd.data));
msg_send(&mesg, transceiver_pid, 1);
}
else {

View File

@ -11,6 +11,7 @@
#include "sys/net/sixlowpan/sixlowpan.h"
#include "sys/net/sixlowpan/sixlowerror.h"
#include "sys/net/sixlowpan/rpl/rpl.h"
#include "sys/net/sixlowpan/rpl/rpl_dodag.h"
void init(char *str){
char command;
@ -74,9 +75,26 @@ void table(char *str){
}
}
void dodag(char *str){
printf("---------------------------\n");
rpl_dodag_t * mydodag = rpl_get_my_dodag();
if(mydodag == NULL){
printf("Not part of a dodag\n");
printf("---------------------------\n");
return;
}
printf("Part of Dodag:\n");
ipv6_print_addr(&mydodag->dodag_id);
printf("my rank: %d\n", mydodag->my_rank);
printf("my preferred parent:\n");
ipv6_print_addr(&mydodag->my_preferred_parent->addr);
printf("---------------------------\n");
}
const shell_command_t shell_commands[] = {
{"init", "", init},
{"table", "", table},
{"dodag", "", dodag},
{NULL, NULL, NULL}
};

View File

@ -30,19 +30,21 @@
#include "sys/net/net_help/net_help.h"
#include "sys/net/net_help/msg_help.h"
#define SEND_TCP_THREAD_SIZE 1536
#define TCP_CLOSE_THREAD_STACK_SIZE 1536
#define SEND_TCP_THREAD_SIZE 1024
#define TCP_CLOSE_THREAD_STACK_SIZE 1024
#define RECV_FROM_TCP_THREAD_STACK_SIZE1 512
#define RECV_FROM_TCP_THREAD_STACK_SIZE2 512
#define UDP_APP_STACK_SIZE 3072
#define TCP_APP_STACK_SIZE 3072
uint8_t udp_server_thread_pid;
char udp_server_stack_buffer[UDP_STACK_SIZE];
char udp_server_stack_buffer[UDP_APP_STACK_SIZE];
uint8_t tcp_server_thread_pid;
char tcp_server_stack_buffer[TCP_STACK_SIZE];
char tcp_server_stack_buffer[TCP_APP_STACK_SIZE];
uint8_t tcp_cht_pid;
char tcp_cht_stack_buffer[TCP_STACK_SIZE];
char tcp_cht_stack_buffer[TCP_APP_STACK_SIZE];
// Socket ID used for sending/receiving packets via different threads
int tcp_socket_id = -1;
@ -217,13 +219,13 @@ void init_tcp_server(void)
void init_udp_server_thread(char *str)
{
udp_server_thread_pid = thread_create(udp_server_stack_buffer, UDP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, init_udp_server, "init_udp_server");
udp_server_thread_pid = thread_create(udp_server_stack_buffer, UDP_APP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, init_udp_server, "init_udp_server");
printf("UDP SERVER THREAD PID: %i\n", udp_server_thread_pid);
}
void init_tcp_server_thread(char *str)
{
tcp_server_thread_pid = thread_create(tcp_server_stack_buffer, TCP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, init_tcp_server, "init_tcp_server");
tcp_server_thread_pid = thread_create(tcp_server_stack_buffer, TCP_APP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, init_tcp_server, "init_tcp_server");
printf("TCP SERVER THREAD PID: %i\n", tcp_server_thread_pid);
}
@ -231,7 +233,7 @@ void init_tcp_server_thread(char *str)
void init_tcp_cht(char *str)
{
tcp_cht_pid = thread_create( tcp_cht_stack_buffer,
TCP_STACK_SIZE,
TCP_APP_STACK_SIZE,
PRIORITY_MAIN,
CREATE_STACKTEST,
tcp_ch,
@ -245,6 +247,10 @@ void send_tcp_thread (void)
while (1)
{
msg_receive(&recv_msg);
if (tcp_socket_id == -1)
{
tcp_socket_id = recv_socket_id1;
}
if (send(tcp_socket_id, (void*) current_message.tcp_string_msg, strlen(current_message.tcp_string_msg)+1, 0) < 0)
{
printf("Could not send %s!\n", current_message.tcp_string_msg);

View File

@ -602,7 +602,7 @@ void calculate_rto(tcp_cb_t *tcp_control, long current_time)
// First calculation
srtt = rtt;
rttvar = 0.5*rtt;
rto = rtt + 4*rttvar;
rto = rtt + (((4*rttvar) < TCP_TIMER_RESOLUTION) ? (TCP_TIMER_RESOLUTION) : (4*rttvar));
}
else
{

View File

@ -108,7 +108,7 @@ void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socke
}
else if (getWaitingConnectionSocket(tcp_socket->socket_id, ipv6_header, tcp_header) != NULL)
{
printf("sending ACK to queued socket!\n");
// printf("sending ACK to queued socket!\n");
m_send_tcp.content.ptr = (char*)tcp_header;
net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, TCP_ACK);
return;
@ -249,7 +249,7 @@ void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
current_tcp_socket->tcp_control.send_wnd);
// Send packet
block_continue_thread();
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
@ -258,7 +258,7 @@ void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
// ACK packet probably got lost
else
{
block_continue_thread();
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
#endif

View File

@ -69,8 +69,7 @@ enum tcp_codes
#define SET_TCP_FIN(a) a = ((a & 0x00) | TCP_FIN)
#define SET_TCP_FIN_ACK(a) a = ((a & 0x00) | TCP_FIN_ACK)
// TODO: Probably stack size too high
#define TCP_STACK_SIZE 2048
#define TCP_STACK_SIZE 1024
#include "sys/net/sixlowpan/sixlowip.h"

View File

@ -29,7 +29,7 @@ void handle_synchro_timeout(socket_internal_t *current_socket)
{
current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
printf("FIRST RETRY!\n");
// printf("FIRST RETRY!\n");
}
else if ((current_socket->socket_values.tcp_control.no_of_retries > 0) &&
(timex_sub(vtimer_now(), current_socket->socket_values.tcp_control.last_packet_time).microseconds >
@ -39,33 +39,17 @@ void handle_synchro_timeout(socket_internal_t *current_socket)
if (current_socket->socket_values.tcp_control.no_of_retries > TCP_MAX_SYN_RETRIES)
{
net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT);
printf("TCP SYN TIMEOUT!!\n");
// printf("TCP SYN TIMEOUT!!\n");
}
else
{
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
printf("NEXT RETRY!\n");
// printf("NEXT RETRY!\n");
}
}
}
}
char *double2string (double d, int stellen) {
int num_int_digits = 0;
char* returnstr = NULL;
if ((int) d != 0)
num_int_digits = (int) log10 (abs((int) d)) + 1;
else
num_int_digits = 1;
returnstr = malloc (num_int_digits + 1 + stellen + 1);
sprintf (returnstr, "%.*f", stellen, d);
return returnstr;
}
void handle_established(socket_internal_t *current_socket)
{
msg_t send;
@ -85,18 +69,18 @@ void handle_established(socket_internal_t *current_socket)
if (current_timeout > TCP_ACK_MAX_TIMEOUT)
{
net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT);
printf("GOT NO ACK: TIMEOUT!\n");
// printf("GOT NO ACK: TIMEOUT!\n");
}
else if (timex_sub(vtimer_now(), current_socket->socket_values.tcp_control.last_packet_time).microseconds >
current_timeout)
{
printReasBuffers();
// printReasBuffers();
current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY);
printf("GOT NO ACK YET, %i. RETRY! Now: %lu Before: %lu, Diff: %lu, Cur Timeout: %f\n", current_socket->socket_values.tcp_control.no_of_retries,
vtimer_now().microseconds, current_socket->socket_values.tcp_control.last_packet_time.microseconds,
vtimer_now().microseconds - current_socket->socket_values.tcp_control.last_packet_time.microseconds,
current_timeout);
// printf("GOT NO ACK YET, %i. RETRY! Now: %lu Before: %lu, Diff: %lu, Cur Timeout: %f\n", current_socket->socket_values.tcp_control.no_of_retries,
// vtimer_now().microseconds, current_socket->socket_values.tcp_control.last_packet_time.microseconds,
// vtimer_now().microseconds - current_socket->socket_values.tcp_control.last_packet_time.microseconds,
// current_timeout);
}
}
}

View File

@ -11,7 +11,7 @@
#define TCP_TIMER_RESOLUTION 500*1000
#define SECOND 1000.0f*1000.0f
#define TCP_TIMER_STACKSIZE 2048
#define TCP_TIMER_STACKSIZE 512
#define TCP_SYN_INITIAL_TIMEOUT 6*SECOND
#define TCP_SYN_TIMEOUT 24*SECOND
#define TCP_MAX_SYN_RETRIES 3

View File

@ -51,7 +51,7 @@ void udp_packet_handler(void)
}
else
{
printf("Dropped UDP Message because no process ID was found for delivery!\n");
printf("Dropped UDP Message because no thread ID was found for delivery!\n");
}
}
else

View File

@ -10,9 +10,7 @@
#define UDP_HDR_LEN 8
// TODO: Probably stack size too high
#define UDP_STACK_SIZE 2048
#define UDP_STACK_SIZE 512
#include "sys/net/sixlowpan/sixlowip.h"

View File

@ -39,8 +39,12 @@ uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank){
return base_rank + add;
}
//We simply return the Parent with lower rank
rpl_parent_t * which_parent(rpl_parent_t *p1, rpl_parent_t *p2){
return p1;
if(p1->rank < p2->rank){
return p1;
}
return p2;
}
rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2){

View File

@ -33,6 +33,7 @@ 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_opt_transit_t * rpl_opt_transit_buf;
static struct rpl_dio_t* get_rpl_dio_buf(){
@ -64,6 +65,11 @@ 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]));
}
static struct rpl_opt_transit_t* get_rpl_opt_transit_buf(uint8_t rpl_msg_len){
return ((struct rpl_opt_transit_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len]));
}
//Diese Funktion findet eine implementierte OF anhand des Objective Code Point
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){
@ -206,25 +212,33 @@ void send_DIS(ipv6_addr_t *destination){
rpl_send(destination,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL);
}
void send_DAO(){
void send_DAO(ipv6_addr_t *destination, uint8_t lifetime){
if(i_am_root){
return;
}
rpl_dodag_t * my_dodag;
my_dodag = rpl_get_my_dodag();
if(destination == NULL){
destination = &my_dodag->my_preferred_parent->addr;
}
printf("Sending DAO to\n");
ipv6_print_addr(destination);
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
icmp_buf->type = ICMP_RPL_CONTROL;
icmp_buf->code = ICMP_CODE_DAO;
icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
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;
rpl_dao_buf->k_d_flags = 0x00;
rpl_dao_buf->dao_sequence = my_dodag->dao_seq;
uint16_t opt_len = 0;
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN);
@ -237,6 +251,14 @@ void send_DAO(){
rpl_opt_target_buf->prefix_length= RPL_DODAG_ID_LEN;
memcpy(&rpl_opt_target_buf->target,&routing_table[i].address,sizeof(ipv6_addr_t));
opt_len += RPL_OPT_TARGET_LEN +2;
rpl_opt_transit_buf = get_rpl_opt_transit_buf(DAO_BASE_LEN + opt_len);
rpl_opt_transit_buf->type=RPL_OPT_TRANSIT;
rpl_opt_transit_buf->length=RPL_OPT_TRANSIT_LEN;
rpl_opt_transit_buf->e_flags=0x00;
rpl_opt_transit_buf->path_control=0x00;//not used
rpl_opt_transit_buf->path_sequence=0x00;//not used
rpl_opt_transit_buf->path_lifetime=lifetime;
opt_len += RPL_OPT_TRANSIT_LEN +2;
rpl_opt_target_buf = get_rpl_opt_target_buf(DAO_BASE_LEN + opt_len);
}
}
@ -246,12 +268,19 @@ void send_DAO(){
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;
rpl_opt_transit_buf = get_rpl_opt_transit_buf(DAO_BASE_LEN + opt_len);
rpl_opt_transit_buf->type=RPL_OPT_TRANSIT;
rpl_opt_transit_buf->length=RPL_OPT_TRANSIT_LEN;
rpl_opt_transit_buf->e_flags=0x00;
rpl_opt_transit_buf->path_control=0x00;
rpl_opt_transit_buf->path_sequence=0x00;
rpl_opt_transit_buf->path_lifetime=lifetime;
opt_len += RPL_OPT_TRANSIT_LEN +2;
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(destination,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL);
}
void rpl_process(void){
@ -413,15 +442,16 @@ void recv_rpl_dio(void){
if(rpl_equal_id(&my_dodag->dodag_id, &dio_dodag.dodag_id)){
//Mein DODAG
if(RPL_COUNTER_GREATER_THAN(dio_dodag.version,my_dodag->version) ){
printf("New Version of dodag\n");
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
printf("[Warning] Inconsistent Dodag Version\n");
my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version);
reset_trickletimer();
}
else{
rpl_global_repair(&dio_dodag);
printf("[Info] New Version of dodag %d\n", dio_dodag.version);
rpl_global_repair(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank);
}
return;
}
@ -435,18 +465,25 @@ void recv_rpl_dio(void){
//Version stimmt, DODAG stimmt
if(rpl_dio_buf->rank == INFINITE_RANK) {
reset_trickletimer();
if(my_dodag->my_rank == ROOT_RANK){
trickle_increment_counter();
return;
}
}
//Wenn wir root sind, ist nichts weiter zu tun
if(my_dodag->my_rank == ROOT_RANK){
if(rpl_dio_buf->rank != INFINITE_RANK){
trickle_increment_counter();
}
return;
}
//
// Parent Handling
//
//Ist Knoten bereits Parent?
rpl_parent_t *parent;
parent = rpl_find_parent(&ipv6_buf->srcaddr);
if(parent == NULL){
//neuen Elternknoten hinzufuegen
//TODO: Checken, ob der Knoten parent sein darf
parent = rpl_new_parent(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank);
//neuen möglichen Elternknoten hinzufuegen
parent = rpl_new_parent(my_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank);
if(parent == NULL){
return;
}
@ -456,6 +493,14 @@ void recv_rpl_dio(void){
trickle_increment_counter();
}
//update parent rank
parent->rank = rpl_dio_buf->rank;
rpl_parent_update(parent);
if(rpl_equal_id(&parent->addr, &my_dodag->my_preferred_parent->addr) && (parent->dtsn != rpl_dio_buf->dtsn)){
delay_dao();
}
parent->dtsn = rpl_dio_buf->dtsn;
}
void recv_rpl_dis(void){
@ -541,10 +586,18 @@ void recv_rpl_dao(void){
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");
break;
}
rpl_add_routing_entry(&rpl_opt_target_buf->target, &ipv6_buf->srcaddr);
increment_seq = 1;
len += rpl_opt_buf->length +2;
rpl_opt_transit_buf = get_rpl_opt_transit_buf(len);
if(rpl_opt_transit_buf->type != RPL_OPT_TRANSIT){
printf("[Error] - no Transit Inforamtion to Target Option\n");
break;
}
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);
break;
}
case(RPL_OPT_TRANSIT):{
@ -567,7 +620,7 @@ 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;
uint8_t *p_ptr;
/*if (next_header == IPPROTO_TCP)
{
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
@ -635,7 +688,7 @@ ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr){
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, uint8_t lifetime){
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES; i++){
if(!routing_table[i].used){
routing_table[i].address = *addr;
@ -662,7 +715,6 @@ 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;
}

View File

@ -6,7 +6,7 @@
#include "rpl_dodag.h"
#define RPL_PKT_RECV_BUF_SIZE 20
#define RPL_PROCESS_STACKSIZE 3072
#define RPL_PROCESS_STACKSIZE 4096
uint8_t rpl_init(transceiver_type_t trans, ipv6_addr_t *rpl_address);
void rpl_init_root();
@ -14,14 +14,14 @@ 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();
void send_DAO(ipv6_addr_t *destination, uint8_t lifetime);
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_add_routing_entry(ipv6_addr_t *addr, ipv6_addr_t *next_hop, uint8_t lifetime);
void rpl_del_routing_entry(ipv6_addr_t *addr);
void rpl_clear_routing_table();
rpl_routing_entry_t *rpl_get_routing_table(void);

View File

@ -3,6 +3,7 @@
#include "rpl_dodag.h"
#include "trickle.h"
#include "rpl.h"
rpl_instance_t instances[RPL_MAX_INSTANCES];
rpl_dodag_t dodags[RPL_MAX_DODAGS];
@ -87,9 +88,7 @@ void rpl_del_dodag(rpl_dodag_t *dodag){
void rpl_leave_dodag(rpl_dodag_t * dodag){
dodag->joined = 0;
dodag->my_preferred_parent = NULL;
//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){
@ -113,6 +112,8 @@ rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t
parent->addr = *address;
parent->rank = rank;
parent->dodag = dodag;
//dtsn is set at the end of recv_dio function
parent->dtsn = 0;
return parent;
}
}
@ -134,28 +135,10 @@ rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){
void rpl_delete_parent(rpl_parent_t * parent){
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
//check if this was the preferred parent, find new parent, if it was last parent leave dodag
char new_preferred_parent = 0;
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];
my_dodag->my_preferred_parent = NULL;
}
memset(parent,0,sizeof(*parent));
}
void rpl_delete_worst_parent(void){
@ -176,11 +159,66 @@ void rpl_delete_worst_parent(void){
}
void rpl_delete_all_parents(void){
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
my_dodag->my_preferred_parent = NULL;
for(int i=0;i<RPL_MAX_PARENTS;i++){
memset(&parents[i],0,sizeof(parents[i]));
}
}
rpl_parent_t * rpl_find_preferred_parent(void){
rpl_parent_t * best = NULL;
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
for(uint8_t i=0;i<RPL_MAX_PARENTS;i++){
if(parents[i].used){
if(parents[i].rank == INFINITE_RANK){
continue;
}
else if(best == NULL){
best = &parents[i];
} else{
best = my_dodag->of->which_parent(best, &parents[i]);
}
}
}
if(best == NULL){
return NULL;
}
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);
}
my_dodag->my_preferred_parent = best;
if(my_dodag->mop != NO_DOWNWARD_ROUTES){
delay_dao();
}
reset_trickletimer();
}
return best;
}
void rpl_parent_update(rpl_parent_t * parent){
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
uint16_t old_rank = my_dodag->my_rank;
if(rpl_find_preferred_parent() == NULL){
rpl_local_repair();
}
if(rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) != rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)){
if(my_dodag->my_rank < my_dodag->min_rank){
my_dodag->min_rank = my_dodag->my_rank;
}
reset_trickletimer();
}
}
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;
@ -217,15 +255,42 @@ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_ran
delay_dao();
}
void rpl_global_repair(rpl_dodag_t *dodag){
void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t * p_addr, uint16_t rank){
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
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;
}
//TODO: nachschauen - soll das wirklich so überschrieben werden?
rpl_delete_all_parents();
my_dodag->version = dodag->version;
my_dodag->dtsn = dodag->dtsn;
my_dodag->dtsn++;
my_dodag->my_preferred_parent = rpl_new_parent(my_dodag, p_addr, rank);
if(my_dodag->my_preferred_parent == NULL){
printf("[Error] no more parent after global repair\n");
my_dodag->my_rank = INFINITE_RANK;
}else{
//Calc new Rank
my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent, my_dodag->my_rank);
my_dodag->min_rank = my_dodag->my_rank;
reset_trickletimer();
delay_dao();
}
printf("Migrated to DODAG Version %d. My new Rank: %d\n", my_dodag->version, my_dodag->my_rank);
}
void rpl_local_repair(void){
rpl_dodag_t * my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
printf("[Error] - no local repair possible, if not part of a DODAG\n");
return;
}
my_dodag->my_rank = INFINITE_RANK;
my_dodag->dtsn++;
rpl_delete_all_parents();
reset_trickletimer();
}
ipv6_addr_t *rpl_get_my_preferred_parent(){
@ -235,3 +300,7 @@ ipv6_addr_t *rpl_get_my_preferred_parent(){
}
return &my_dodag->my_preferred_parent->addr;
}
uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease){
return abs_rank / minhoprankincrease;
}

View File

@ -13,8 +13,12 @@ rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t
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();
void rpl_delete_parent(rpl_parent_t *parent);
void rpl_delete_worst_parent(void);
void rpl_delete_all_parents(void);
rpl_parent_t * rpl_find_preferred_parent(void);
void rpl_parent_update(rpl_parent_t * parent);
void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t * p_addr, uint16_t rank);
void rpl_local_repair(void);
uint16_t rpl_calc_rank(uint16_t abs_rank, uint16_t minhoprankincrease);

View File

@ -28,6 +28,7 @@
#define RPL_OPT_PREFIX_INFO_LEN 30
#define RPL_OPT_SOLICITED_INFO_LEN 19
#define RPL_OPT_TARGET_LEN 18
#define RPL_OPT_TRANSIT_LEN 4
//message options
#define RPL_OPT_PAD1 0
@ -79,7 +80,7 @@
#define RPL_MAX_ROUTING_ENTRIES 20
#define RPL_ROOT_RANK 1
#define RPL_DEFAULT_LIFETIME 0xff
#define RPL_LIFETIME_UNIT 0xffff
#define RPL_LIFETIME_UNIT 0x0001
#define RPL_GROUNDED 1
#define RPL_PRF_MASK 0x7
#define RPL_MOP_SHIFT 3
@ -162,11 +163,21 @@ typedef struct __attribute__((packed)) rpl_opt_target_t {
ipv6_addr_t target;
} rpl_opt_target_t;
typedef struct __attribute__((packed)) rpl_opt_transit_t {
uint8_t type;
uint8_t length;
uint8_t e_flags;
uint8_t path_control;
uint8_t path_sequence;
uint8_t path_lifetime;
} rpl_opt_transit_t;
struct rpl_dodag_t;
typedef struct rpl_parent_t {
ipv6_addr_t addr;
uint16_t rank;
uint8_t dtsn;
struct rpl_dodag_t *dodag;
uint8_t used;
} rpl_parent_t;
@ -219,6 +230,7 @@ typedef struct rpl_routing_entry_t {
uint8_t used;
ipv6_addr_t address;
ipv6_addr_t next_hop;
uint8_t lifetime;
} rpl_routing_entry_t;

View File

@ -1,3 +1,4 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
@ -7,9 +8,11 @@
char timer_over_buf[TRICKLE_TIMER_STACKSIZE];
char interval_over_buf[TRICKLE_INTERVAL_STACKSIZE];
char dao_delay_over_buf[DAO_DELAY_STACKSIZE];
char routing_table_buf[RT_STACKSIZE];
int timer_over_pid;
int interval_over_pid;
int dao_delay_over_pid;
int rt_timer_over_pid;
uint8_t k;
uint32_t Imin;
@ -20,9 +23,11 @@ uint16_t c;
vtimer_t trickle_t_timer;
vtimer_t trickle_I_timer;
vtimer_t dao_timer;
vtimer_t rt_timer;
timex_t t_time;
timex_t I_time;
timex_t dao_time;
timex_t rt_time;
//struct für trickle parameter??
void reset_trickletimer(void){
@ -32,6 +37,8 @@ void reset_trickletimer(void){
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
t_time = timex_set(0,t*1000);
I_time = timex_set(0,I*1000);
vtimer_remove(&trickle_t_timer);
vtimer_remove(&trickle_I_timer);
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
@ -48,6 +55,9 @@ void init_trickle(void){
dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE,
PRIORITY_MAIN-1, CREATE_SLEEPING,
dao_delay_over, "dao_delay_over");
rt_timer_over_pid = thread_create(routing_table_buf, RT_STACKSIZE,
PRIORITY_MAIN-1, CREATE_SLEEPING,
rt_timer_over, "rt_timer_over");
}
@ -62,6 +72,8 @@ void start_trickle(uint8_t DIOIntMin, uint8_t DIOIntDoubl, uint8_t DIORedundancy
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
t_time = timex_set(0,t*1000);
I_time = timex_set(0,I*1000);
vtimer_remove(&trickle_t_timer);
vtimer_remove(&trickle_I_timer);
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
@ -97,6 +109,8 @@ void trickle_interval_over(void){
//start timer
t_time = timex_set(0,t*1000);
I_time = timex_set(0,I*1000);
vtimer_remove(&trickle_t_timer);
vtimer_remove(&trickle_I_timer);
vtimer_set_wakeup(&trickle_t_timer, t_time, timer_over_pid);
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
thread_sleep();
@ -106,12 +120,33 @@ void trickle_interval_over(void){
void delay_dao(void){
dao_time = timex_set(DEFAULT_DAO_DELAY,0);
vtimer_remove(&dao_timer);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
}
void dao_delay_over(void){
while(1){
send_DAO();
send_DAO(NULL, false);
thread_sleep();
}
}
void rt_timer_over(void){
while(1){
rpl_routing_entry_t * rt = rpl_get_routing_table();
for(uint8_t i=0; i<RPL_MAX_ROUTING_ENTRIES;i++){
if(rt[i].used){
if(rt[i].lifetime <= 1){
memset(&rt[i], 0,sizeof(rt[i]));
}
else{
rt[i].lifetime--;
}
}
}
//Wake up every second
rt_time = timex_set(1,0);
vtimer_set_wakeup(&rt_timer, rt_time, rt_timer_over_pid);
thread_sleep();
}
}

View File

@ -3,7 +3,11 @@
#define TRICKLE_TIMER_STACKSIZE 3072
#define TRICKLE_INTERVAL_STACKSIZE 3072
#define DAO_DELAY_STACKSIZE 2048
//#define DAO_DELAY_STACKSIZE 2048
//#define DAO_DELAY_STACKSIZE 3072
#define DAO_DELAY_STACKSIZE 4096
//#define RT_STACKSIZE 2048
#define RT_STACKSIZE 3072
void reset_trickletimer(void);
void init_trickle(void);
@ -13,3 +17,4 @@ void trickle_timer_over(void);
void trickle_interval_over(void);
void delay_dao(void);
void dao_delay_over(void);
void rt_timer_over(void);

View File

@ -9,7 +9,7 @@
#include "radio/radio.h"
#include <transceiver.h>
#define RADIO_STACK_SIZE 2048
#define RADIO_STACK_SIZE 512
#define RADIO_RCV_BUF_SIZE 64
#define RADIO_SND_BUF_SIZE 100
#define RADIO_SENDING_DELAY 1000

View File

@ -4,7 +4,7 @@
#define IP_PROCESS_STACKSIZE 3072
#define NC_STACKSIZE 512
#define CON_STACKSIZE 512
#define LOWPAN_TRANSFER_BUF_STACKSIZE 1024
#define LOWPAN_TRANSFER_BUF_STACKSIZE 512
/* fragment size in bytes*/
#define FRAG_PART_ONE_HDR_LEN 4

View File

@ -210,12 +210,13 @@ int vtimer_init() {
}
int vtimer_set_wakeup(vtimer_t *t, timex_t interval, int pid) {
int ret;
t->action = (void*) thread_wakeup;
t->arg = (void*) pid;
t->absolute = interval;
t->pid = 0;
vtimer_set(t);
return 0;
ret = vtimer_set(t);
return ret;
}
int vtimer_usleep(uint32_t usecs) {
@ -224,10 +225,11 @@ int vtimer_usleep(uint32_t usecs) {
}
int vtimer_sleep(timex_t time) {
int ret;
vtimer_t t;
vtimer_set_wakeup(&t, time, thread_getpid());
ret = vtimer_set_wakeup(&t, time, thread_getpid());
thread_sleep();
return 0;
return ret;
}
int vtimer_remove(vtimer_t *t){