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/home/git/ukleos

This commit is contained in:
Oliver Hahm 2012-03-01 17:32:41 +01:00
commit b81b7d6429
28 changed files with 773 additions and 304 deletions

View File

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

View File

@ -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 ;

View File

@ -2,25 +2,136 @@
#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"
#include "sys/net/sixlowpan/rpl/rpl_dodag.h"
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);
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");
}
int main(void)
{
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); 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;
if(state != SUCCESS){ switch (command) {
printf("Error initializing RPL\n"); case 'r':
} printf("INFO: Initialize as root on address \n");
if(root == 0x0001){ ipv6_print_addr(&std_addr);
rpl_init_root(); if (r_addr > 255) {
} printf("ERROR: address not an 8 bit integer\n");
printf("RPL INIT FINISHED\n"); return;
while(1); }
state = rpl_init(TRANSCEIVER_CC1100, &std_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);
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;
}
}
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");
}
}
}
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}
};
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);
};
} }

View File

@ -30,19 +30,21 @@
#include "sys/net/net_help/net_help.h" #include "sys/net/net_help/net_help.h"
#include "sys/net/net_help/msg_help.h" #include "sys/net/net_help/msg_help.h"
#define SEND_TCP_THREAD_SIZE 1536 #define SEND_TCP_THREAD_SIZE 1024
#define TCP_CLOSE_THREAD_STACK_SIZE 1536 #define TCP_CLOSE_THREAD_STACK_SIZE 1024
#define RECV_FROM_TCP_THREAD_STACK_SIZE1 512 #define RECV_FROM_TCP_THREAD_STACK_SIZE1 512
#define RECV_FROM_TCP_THREAD_STACK_SIZE2 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; 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; 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; 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 // Socket ID used for sending/receiving packets via different threads
int tcp_socket_id = -1; int tcp_socket_id = -1;
@ -125,7 +127,7 @@ void init_udp_server(void)
ssize_t recsize; ssize_t recsize;
uint32_t fromlen; uint32_t fromlen;
int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
memset(&sa, 0, sizeof sa); memset(&sa, 0, sizeof(sa));
sa.sin6_family = AF_INET; sa.sin6_family = AF_INET;
sa.sin6_port = HTONS(7654); sa.sin6_port = HTONS(7654);
@ -146,6 +148,7 @@ void init_udp_server(void)
printf("recsize: %i\n ", recsize); printf("recsize: %i\n ", recsize);
printf("datagram: %s\n", buffer_main); printf("datagram: %s\n", buffer_main);
} }
close(sock);
} }
void init_tcp_server(void) void init_tcp_server(void)
@ -216,13 +219,13 @@ void init_tcp_server(void)
void init_udp_server_thread(char *str) 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); printf("UDP SERVER THREAD PID: %i\n", udp_server_thread_pid);
} }
void init_tcp_server_thread(char *str) 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); printf("TCP SERVER THREAD PID: %i\n", tcp_server_thread_pid);
} }
@ -230,7 +233,7 @@ void init_tcp_server_thread(char *str)
void init_tcp_cht(char *str) void init_tcp_cht(char *str)
{ {
tcp_cht_pid = thread_create( tcp_cht_stack_buffer, tcp_cht_pid = thread_create( tcp_cht_stack_buffer,
TCP_STACK_SIZE, TCP_APP_STACK_SIZE,
PRIORITY_MAIN, PRIORITY_MAIN,
CREATE_STACKTEST, CREATE_STACKTEST,
tcp_ch, tcp_ch,
@ -244,6 +247,10 @@ void send_tcp_thread (void)
while (1) while (1)
{ {
msg_receive(&recv_msg); 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) 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); printf("Could not send %s!\n", current_message.tcp_string_msg);
@ -304,7 +311,7 @@ void send_tcp_bandwidth_test(char *str)
end = vtimer_now(); end = vtimer_now();
total = timex_sub(end, start); total = timex_sub(end, start);
secs = total.microseconds / 1000000.0f; secs = total.microseconds / 1000000.0f;
printf("Used power: %f\n", ltc4150_get_total_mAh()); printf("Used power: %f\n", ltc4150_get_total_Joule());
printf("Start: %lu, End: %lu, Total: %lu\n", start.microseconds, end.microseconds, total.microseconds); printf("Start: %lu, End: %lu, Total: %lu\n", start.microseconds, end.microseconds, total.microseconds);
printf("Time: %f seconds, Bandwidth: %f byte/second\n", secs, (count*48)/secs); printf("Time: %f seconds, Bandwidth: %f byte/second\n", secs, (count*48)/secs);
} }
@ -337,7 +344,7 @@ void recv_from_tcp_thread2 (void)
if (read_bytes > 0) if (read_bytes > 0)
{ {
printf("--- Read bytes: %i, Strlen(): %i, Message: %s ---\n", read_bytes, strlen(buff_msg), buff_msg); // printf("--- Read bytes: %i, Strlen(): %i, Message: %s ---\n", read_bytes, strlen(buff_msg), buff_msg);
} }
} }
} }
@ -354,7 +361,7 @@ void recv_from_tcp_thread1 (void)
if (read_bytes > 0) if (read_bytes > 0)
{ {
printf("--- Read bytes: %i, Strlen(): %i, Message: %s ---\n", read_bytes, strlen(buff_msg), buff_msg); // printf("--- Read bytes: %i, Strlen(): %i, Message: %s ---\n", read_bytes, strlen(buff_msg), buff_msg);
} }
} }
} }
@ -442,8 +449,8 @@ void send_udp(char *str)
ipv6_addr_t ipaddr; ipv6_addr_t ipaddr;
int bytes_sent; int bytes_sent;
int address, count; int address, count;
uint8_t text[] = "abcdefghijklmnopqrstuvwxyz0123456789!-=$%&/()"; char text[] = "abcdefghijklmnopqrstuvwxyz0123456789!-=$%&/()";
sscanf(str, "send_udp %i %i", &count, &address); sscanf(str, "send_udp %i %i %s", &count, &address, text);
sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (-1 == sock) if (-1 == sock)
@ -461,7 +468,7 @@ void send_udp(char *str)
memcpy(&sa.sin6_addr, &ipaddr, 16); memcpy(&sa.sin6_addr, &ipaddr, 16);
sa.sin6_port = HTONS(7654); sa.sin6_port = HTONS(7654);
ltc4150_start(); ltc4150_start();
printf("Start power: %f\n", ltc4150_get_total_mAh()); printf("Start power: %f\n", ltc4150_get_total_Joule());
start = vtimer_now(); start = vtimer_now();
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@ -470,11 +477,12 @@ void send_udp(char *str)
{ {
printf("Error sending packet!\n"); printf("Error sending packet!\n");
} }
// hwtimer_wait(20*1000);
} }
end = vtimer_now(); end = vtimer_now();
total = timex_sub(end, start); total = timex_sub(end, start);
secs = total.microseconds / 1000000; secs = total.microseconds / 1000000;
printf("Used power: %f\n", ltc4150_get_total_mAh()); printf("Used power: %f\n", ltc4150_get_total_Joule());
printf("Start: %lu, End: %lu, Total: %lu\n", start.microseconds, end.microseconds, total.microseconds); printf("Start: %lu, End: %lu, Total: %lu\n", start.microseconds, end.microseconds, total.microseconds);
secs = total.microseconds / 1000000; secs = total.microseconds / 1000000;
printf("Time: %lu seconds, Bandwidth: %lu byte/second\n", secs, (count*48)/secs); printf("Time: %lu seconds, Bandwidth: %lu byte/second\n", secs, (count*48)/secs);
@ -587,48 +595,56 @@ void ignore(char *addr) {
} }
#endif #endif
/* HACK: Simple mesh routing on MAC layer: /* HACK: Simple routing on IP layer:
* *
* This routing method is used to forward layer 3 fragments over N hops in 2 directions. * This routing method is used to forward IP packets over N hops in 2 directions.
* *
* Example: A <--> B <--> C <--> D (N = 4) * Example: A <--> B <--> C <--> D (N = 4)
* *
* To achieve the network topology described in the example above one has to * To achieve the network topology described in the example above one has to
* declare the nodes A and D as "head nodes" and the nodes B and C as "routing nodes". * declare the nodes A to D as "static_routes" and assign them radio addresses in ascending or descending order
* For every static route with N hops there are always N-2 nodes which are * without gaps (ie 2-3-4-5 is OK, 2-3-5-6 is NOT OK).
* routing nodes and 2 head nodes (start and end).
* *
* A "head node" is a node receiving or sending packets of higher layers (i.e. layer 3 or higher) * The variable which needs to be set in every node is static_route in sys/net/sixlowpan/sixlowpan.c. */
* and does not route any fragments on the MAC layer.
* A "routing node" is a node forwarding fragments from local addresses < its own address to
* nodes (head or routing) with local address > its own address (own_address+1).
* It also forwards fragments from local addresses > its own address to nodes with
* local address < its own address (own_address-1).
*
* The variables which need to be set are static_route in sys/net/sixlowpan/sixlowmac.c for
* routing nodes and route_head in sys/net/sixlowpan/sixlowpan.c for head nodes. */
void static_routing (char *str) void static_routing (char *str)
{ {
if (static_route == 0) if (static_route == 0)
{ {
static_route = 1; static_route = 1;
printf("Static Routing: TRUE\n");
} }
else else
{ {
static_route = 0; static_route = 0;
printf("Static Routing: FALSE\n");
} }
} }
void static_head (char *str) void print_fragment_counter (char *str)
{ {
if (route_head == 0) printf("Fragment Counter: %u\n", fragmentcounter);
{ }
route_head = 1;
} void pfifo_buf (char *str)
else {
{ printFIFOBuffers();
route_head = 0; }
}
void sleep_now(char *str)
{
int time;
sscanf(str, "sleep %i", &time);
vtimer_usleep(time*1000*1000);
}
void get_rtt (char *str)
{
int socket;
sscanf(str, "get_rtt %i", &socket);
printf("SRTT: %f, RTO: %f, RTTVAR: %f\n", getSocket(socket)->socket_values.tcp_control.srtt,
getSocket(socket)->socket_values.tcp_control.rto,
getSocket(socket)->socket_values.tcp_control.rttvar);
} }
const shell_command_t shell_commands[] = { const shell_command_t shell_commands[] = {
@ -655,7 +671,11 @@ const shell_command_t shell_commands[] = {
{"bootc", "", boot_client}, {"bootc", "", boot_client},
{"print_nbr_cache", "", show_nbr_cache}, {"print_nbr_cache", "", show_nbr_cache},
{"static_routing", "", static_routing}, {"static_routing", "", static_routing},
{"static_head", "", static_head}, // {"static_head", "", static_head},
{"pfrag", "", print_fragment_counter},
{"show_fifo", "", pfifo_buf},
{"sleep", "", sleep_now},
{"get_rtt", "", get_rtt},
#ifdef DBG_IGNORE #ifdef DBG_IGNORE
{"ign", "ignore node", ignore}, {"ign", "ignore node", ignore},
#endif #endif

View File

@ -29,6 +29,7 @@ void init_transport_layer(void)
// TCP // TCP
srand(vtimer_now().microseconds); srand(vtimer_now().microseconds);
#ifdef TCP_HC #ifdef TCP_HC
printf("TCP_HC enabled!\n");
global_context_counter = rand(); global_context_counter = rand();
#endif #endif
global_sequence_counter = rand(); global_sequence_counter = rand();

View File

@ -8,8 +8,6 @@
#ifndef DESTINY_H_ #ifndef DESTINY_H_
#define DESTINY_H_ #define DESTINY_H_
#define TCP_HC
void init_transport_layer(void); void init_transport_layer(void);
#endif /* DESTINY_H_ */ #endif /* DESTINY_H_ */

View File

@ -13,6 +13,7 @@
#include "tcp.h" #include "tcp.h"
#include "socket.h" #include "socket.h"
#include "vtimer.h" #include "vtimer.h"
#include "hwtimer.h"
#include "tcp_timer.h" #include "tcp_timer.h"
#include "tcp_hc.h" #include "tcp_hc.h"
#include "sys/net/net_help/net_help.h" #include "sys/net/net_help/net_help.h"
@ -377,7 +378,7 @@ void switch_tcp_packet_byte_order(tcp_hdr_t *current_tcp_packet)
} }
if (*(((uint8_t*)current_tcp_packet)+TCP_HDR_LEN) == TCP_TS_OPTION) if (*(((uint8_t*)current_tcp_packet)+TCP_HDR_LEN) == TCP_TS_OPTION)
{ {
// TODO: Timestamp option nit implemented // TODO: Timestamp option not implemented
} }
} }
@ -423,9 +424,7 @@ int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, i
// Error in compressing tcp packet header // Error in compressing tcp packet header
return -1; return -1;
} }
sixlowpan_send(&current_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), compressed_size, IPPROTO_TCP); sixlowpan_send(&current_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), compressed_size, IPPROTO_TCP);
return 1; return 1;
#else #else
// print_tcp_status(OUT_PACKET, temp_ipv6_header, current_tcp_packet, current_tcp_socket); // print_tcp_status(OUT_PACKET, temp_ipv6_header, current_tcp_packet, current_tcp_socket);
@ -591,9 +590,9 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
return 0; return 0;
} }
void calculate_rto(tcp_cb_t *tcp_control, timex_t current_time) void calculate_rto(tcp_cb_t *tcp_control, long current_time)
{ {
double rtt = timex_sub(current_time, tcp_control->last_packet_time).microseconds; double rtt = current_time - tcp_control->last_packet_time.microseconds;
double srtt = tcp_control->srtt; double srtt = tcp_control->srtt;
double rttvar = tcp_control->rttvar; double rttvar = tcp_control->rttvar;
double rto = tcp_control->rto; double rto = tcp_control->rto;
@ -603,7 +602,7 @@ void calculate_rto(tcp_cb_t *tcp_control, timex_t current_time)
// First calculation // First calculation
srtt = rtt; srtt = rtt;
rttvar = 0.5*rtt; rttvar = 0.5*rtt;
rto = rtt + 4*rttvar; rto = rtt + (((4*rttvar) < TCP_TIMER_RESOLUTION) ? (TCP_TIMER_RESOLUTION) : (4*rttvar));
} }
else else
{ {
@ -616,17 +615,12 @@ void calculate_rto(tcp_cb_t *tcp_control, timex_t current_time)
{ {
rto = SECOND; rto = SECOND;
} }
// if (((rto > (SECOND-1)) && (rto < (SECOND+1))))
// {
// printf("RTO is correct!\n");
// }
tcp_control->srtt = srtt; tcp_control->srtt = srtt;
tcp_control->rttvar = rttvar; tcp_control->rttvar = rttvar;
tcp_control->rto = rto; tcp_control->rto = rto;
} }
int32_t send(int s, void *msg, uint64_t len, int flags) int32_t send(int s, void *msg, uint32_t len, int flags)
{ {
// Variables // Variables
msg_t recv_msg; msg_t recv_msg;
@ -638,6 +632,7 @@ int32_t send(int s, void *msg, uint64_t len, int flags)
ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer));
tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN]));
// Check if socket exists and is TCP socket // Check if socket exists and is TCP socket
if (!isTCPSocket(s)) if (!isTCPSocket(s))
{ {
@ -722,8 +717,7 @@ int32_t send(int s, void *msg, uint64_t len, int flags)
} }
// Remember current time // Remember current time
current_tcp_socket->tcp_control.last_packet_time = vtimer_now(); current_tcp_socket->tcp_control.last_packet_time.microseconds = hwtimer_now();
net_msg_receive(&recv_msg); net_msg_receive(&recv_msg);
switch (recv_msg.type) switch (recv_msg.type)
{ {
@ -731,7 +725,7 @@ int32_t send(int s, void *msg, uint64_t len, int flags)
{ {
if (current_tcp_socket->tcp_control.no_of_retries == 0) if (current_tcp_socket->tcp_control.no_of_retries == 0)
{ {
calculate_rto(&current_tcp_socket->tcp_control, vtimer_now()); calculate_rto(&current_tcp_socket->tcp_control, hwtimer_now());
} }
tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(recv_msg.content.ptr)); tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(recv_msg.content.ptr));
if ((current_tcp_socket->tcp_control.send_nxt == tcp_header->ack_nr) && (total_sent_bytes == len)) if ((current_tcp_socket->tcp_control.send_nxt == tcp_header->ack_nr) && (total_sent_bytes == len))
@ -815,7 +809,7 @@ uint8_t read_from_socket(socket_internal_t *current_int_tcp_socket, void *buf, i
} }
} }
int recv(int s, void *buf, uint64_t len, int flags) int recv(int s, void *buf, uint32_t len, int flags)
{ {
// Variables // Variables
uint8_t read_bytes; uint8_t read_bytes;
@ -836,7 +830,6 @@ int recv(int s, void *buf, uint64_t len, int flags)
{ {
return read_from_socket(current_int_tcp_socket, buf, len); return read_from_socket(current_int_tcp_socket, buf, len);
} }
msg_receive(&m_recv); msg_receive(&m_recv);
if ((exists_socket(s)) && (current_int_tcp_socket->tcp_input_buffer_end > 0)) if ((exists_socket(s)) && (current_int_tcp_socket->tcp_input_buffer_end > 0))
{ {
@ -857,7 +850,7 @@ int recv(int s, void *buf, uint64_t len, int flags)
return -1; return -1;
} }
int32_t recvfrom(int s, void *buf, uint64_t len, int flags, sockaddr6_t *from, uint32_t *fromlen) int32_t recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen)
{ {
if (isUDPSocket(s)) if (isUDPSocket(s))
{ {
@ -865,20 +858,24 @@ int32_t recvfrom(int s, void *buf, uint64_t len, int flags, sockaddr6_t *from, u
ipv6_hdr_t *ipv6_header; ipv6_hdr_t *ipv6_header;
udp_hdr_t *udp_header; udp_hdr_t *udp_header;
uint8_t *payload; uint8_t *payload;
getSocket(s)->recv_pid = thread_getpid();
msg_receive(&m_recv); msg_receive(&m_recv);
ipv6_header = ((ipv6_hdr_t*)m_recv.content.ptr); ipv6_header = ((ipv6_hdr_t*)m_recv.content.ptr);
udp_header = ((udp_hdr_t*)(m_recv.content.ptr + IPV6_HDR_LEN)); udp_header = ((udp_hdr_t*)(m_recv.content.ptr + IPV6_HDR_LEN));
payload = (uint8_t*)(m_recv.content.ptr + IPV6_HDR_LEN+UDP_HDR_LEN); payload = (uint8_t*)(m_recv.content.ptr + IPV6_HDR_LEN+UDP_HDR_LEN);
memset(buf, 0, len); memset(buf, 0, len);
memcpy(buf, payload, udp_header->length); memcpy(buf, payload, udp_header->length-UDP_HDR_LEN);
memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16); memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16);
from->sin6_family = AF_INET6; from->sin6_family = AF_INET6;
from->sin6_flowinfo = 0; from->sin6_flowinfo = 0;
from->sin6_port = udp_header->src_port; from->sin6_port = udp_header->src_port;
memcpy(fromlen, (void*)(sizeof(sockaddr6_t)), sizeof(fromlen)); *fromlen = sizeof(sockaddr6_t);
msg_reply(&m_recv, &m_send); msg_reply(&m_recv, &m_send);
return udp_header->length; return udp_header->length-UDP_HDR_LEN;
} }
else if (isTCPSocket(s)) else if (isTCPSocket(s))
{ {
@ -891,7 +888,7 @@ int32_t recvfrom(int s, void *buf, uint64_t len, int flags, sockaddr6_t *from, u
} }
} }
int32_t sendto(int s, void *msg, uint64_t len, int flags, sockaddr6_t *to, uint32_t tolen) int32_t sendto(int s, void *msg, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen)
{ {
if (isUDPSocket(s) && (getSocket(s)->socket_values.foreign_address.sin6_port == 0)) if (isUDPSocket(s) && (getSocket(s)->socket_values.foreign_address.sin6_port == 0))
{ {

View File

@ -14,8 +14,6 @@
#include "in.h" #include "in.h"
#include "sys/net/sixlowpan/sixlowip.h" #include "sys/net/sixlowpan/sixlowip.h"
#define TCP_HC
/* /*
* Types * Types
*/ */
@ -195,10 +193,10 @@ int socket(int domain, int type, int protocol);
int connect(int socket, sockaddr6_t *addr, uint32_t addrlen); int connect(int socket, sockaddr6_t *addr, uint32_t addrlen);
socket_internal_t *getWaitingConnectionSocket(int socket, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header); socket_internal_t *getWaitingConnectionSocket(int socket, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header);
void close_socket(socket_internal_t *current_socket); void close_socket(socket_internal_t *current_socket);
int32_t recvfrom( int s, void *buf, uint64_t len, int flags, sockaddr6_t *from, uint32_t *fromlen ); int32_t recvfrom( int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen );
int32_t sendto( int s, void *msg, uint64_t len, int flags, sockaddr6_t *to, uint32_t tolen); int32_t sendto( int s, void *msg, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen);
int32_t send(int s, void *msg, uint64_t len, int flags); int32_t send(int s, void *msg, uint32_t len, int flags);
int recv(int s, void *buf, uint64_t len, int flags); int recv(int s, void *buf, uint32_t len, int flags);
int close(int s); int close(int s);
int bind(int s, sockaddr6_t *name, int namelen); int bind(int s, sockaddr6_t *name, int namelen);
int listen(int s, int backlog); int listen(int s, int backlog);

View File

@ -106,10 +106,9 @@ void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socke
msg_send(&m_send_tcp, tcp_socket->send_pid, 0); msg_send(&m_send_tcp, tcp_socket->send_pid, 0);
return; return;
} }
// TODO: Find better way of handling queued sockets ACK packets
else if (getWaitingConnectionSocket(tcp_socket->socket_id, ipv6_header, tcp_header) != NULL) 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; m_send_tcp.content.ptr = (char*)tcp_header;
net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, TCP_ACK); net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, TCP_ACK);
return; return;
@ -250,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); current_tcp_socket->tcp_control.send_wnd);
// Send packet // Send packet
block_continue_thread(); // block_continue_thread();
#ifdef TCP_HC #ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif #endif
@ -259,7 +258,7 @@ void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
// ACK packet probably got lost // ACK packet probably got lost
else else
{ {
block_continue_thread(); // block_continue_thread();
#ifdef TCP_HC #ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
#endif #endif

View File

@ -8,8 +8,6 @@
#ifndef TCP_H_ #ifndef TCP_H_
#define TCP_H_ #define TCP_H_
#define TCP_HC
#define TCP_HDR_LEN 20 #define TCP_HDR_LEN 20
#define TCP_EOO_OPTION 0x00 // End of option list #define TCP_EOO_OPTION 0x00 // End of option list
@ -71,8 +69,7 @@ enum tcp_codes
#define SET_TCP_FIN(a) a = ((a & 0x00) | TCP_FIN) #define SET_TCP_FIN(a) a = ((a & 0x00) | TCP_FIN)
#define SET_TCP_FIN_ACK(a) a = ((a & 0x00) | TCP_FIN_ACK) #define SET_TCP_FIN_ACK(a) a = ((a & 0x00) | TCP_FIN_ACK)
// TODO: Probably stack size too high #define TCP_STACK_SIZE 1024
#define TCP_STACK_SIZE 3072
#include "sys/net/sixlowpan/sixlowip.h" #include "sys/net/sixlowpan/sixlowip.h"

View File

@ -8,8 +8,6 @@
#ifndef TCP_HC_H_ #ifndef TCP_HC_H_
#define TCP_HC_H_ #define TCP_HC_H_
#define TCP_HC
#include "tcp.h" #include "tcp.h"
#include "sys/net/sixlowpan/sixlowip.h" #include "sys/net/sixlowpan/sixlowip.h"
#include "socket.h" #include "socket.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++; current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY); 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) && 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 > (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) 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); net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT);
printf("TCP SYN TIMEOUT!!\n"); // printf("TCP SYN TIMEOUT!!\n");
} }
else else
{ {
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY); 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) void handle_established(socket_internal_t *current_socket)
{ {
msg_t send; msg_t send;
@ -85,18 +69,18 @@ void handle_established(socket_internal_t *current_socket)
if (current_timeout > TCP_ACK_MAX_TIMEOUT) if (current_timeout > TCP_ACK_MAX_TIMEOUT)
{ {
net_msg_send(&send, current_socket->send_pid, 0, TCP_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 > else if (timex_sub(vtimer_now(), current_socket->socket_values.tcp_control.last_packet_time).microseconds >
current_timeout) current_timeout)
{ {
printReasBuffers(); // printReasBuffers();
current_socket->socket_values.tcp_control.no_of_retries++; current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY); 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, // 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,
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); // current_timeout);
} }
} }
} }

View File

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

View File

@ -51,7 +51,7 @@ void udp_packet_handler(void)
} }
else 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 else

View File

@ -10,9 +10,7 @@
#define UDP_HDR_LEN 8 #define UDP_HDR_LEN 8
#define UDP_STACK_SIZE 512
// TODO: Probably stack size too high
#define UDP_STACK_SIZE 3072
#include "sys/net/sixlowpan/sixlowip.h" #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; 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){ 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){ rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2){

View File

@ -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];
@ -32,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_dodag_conf_t * rpl_opt_dodag_conf_buf;
static struct rpl_opt_solicited_t * rpl_opt_solicited_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_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(){ static struct rpl_dio_t* get_rpl_dio_buf(){
@ -63,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])); 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){ rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp){
for(uint16_t i=0; i < NUMBER_IMPLEMENTED_OFS; i++){ for(uint16_t i=0; i < NUMBER_IMPLEMENTED_OFS; i++){
if(ocp == objective_functions[i]->ocp){ if(ocp == objective_functions[i]->ocp){
@ -152,6 +159,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 +171,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!
@ -195,48 +203,84 @@ void send_DIS(ipv6_addr_t *destination){
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_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;
rpl_send(destination,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL); 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 = 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;
my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){ if(my_dodag == NULL){
return; return;
} }
rpl_dao_buf = get_rpl_dao_buf(); rpl_dao_buf = get_rpl_dao_buf();
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_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); 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));
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; 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); rpl_send(destination,(uint8_t*)icmp_buf, plen, PROTO_NUM_ICMPV6, NULL);
} }
void rpl_process(void){ void rpl_process(void){
@ -397,18 +441,22 @@ 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");
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
printf("[Warning] Inconsistent Dodag Version\n");
my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version); my_dodag->version = RPL_COUNTER_INCREMENT(dio_dodag.version);
reset_trickletimer(); reset_trickletimer();
} }
else{ 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; 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;
} }
@ -417,17 +465,25 @@ void recv_rpl_dio(void){
//Version stimmt, DODAG stimmt //Version stimmt, DODAG stimmt
if(rpl_dio_buf->rank == INFINITE_RANK) { if(rpl_dio_buf->rank == INFINITE_RANK) {
reset_trickletimer(); 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? //Ist Knoten bereits Parent?
rpl_parent_t *parent; rpl_parent_t *parent;
parent = rpl_find_parent(&ipv6_buf->srcaddr); parent = rpl_find_parent(&ipv6_buf->srcaddr);
if(parent == NULL){ if(parent == NULL){
//neuen Elternknoten hinzufuegen //neuen möglichen Elternknoten hinzufuegen
parent = rpl_new_parent(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank); parent = rpl_new_parent(my_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank);
if(parent == NULL){ if(parent == NULL){
return; return;
} }
@ -437,6 +493,14 @@ void recv_rpl_dio(void){
trickle_increment_counter(); 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){ void recv_rpl_dis(void){
@ -492,10 +556,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,7 +583,21 @@ 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");
break;
}
increment_seq = 1;
len += rpl_opt_buf->length +2; 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; break;
} }
case(RPL_OPT_TRANSIT):{ case(RPL_OPT_TRANSIT):{
@ -529,10 +613,14 @@ 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){
uint8_t *p_ptr; uint8_t *p_ptr;
/*if (next_header == IPPROTO_TCP) /*if (next_header == IPPROTO_TCP)
{ {
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len); p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
@ -573,13 +661,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);
@ -596,12 +688,13 @@ ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t * addr){
return NULL; 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){
//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 +714,7 @@ void rpl_clear_routing_table(){
} }
} }
rpl_routing_entry_t *rpl_get_routing_table(void){
return routing_table;
}

View File

@ -6,7 +6,7 @@
#include "rpl_dodag.h" #include "rpl_dodag.h"
#define RPL_PKT_RECV_BUF_SIZE 20 #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); uint8_t rpl_init(transceiver_type_t trans, ipv6_addr_t *rpl_address);
void rpl_init_root(); void rpl_init_root();
@ -14,13 +14,14 @@ rpl_of_t *rpl_get_of_for_ocp(uint16_t ocp);
void send_DIO(ipv6_addr_t *destination); void send_DIO(ipv6_addr_t *destination);
void send_DIS(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 rpl_process(void);
void recv_rpl_dio(void); void recv_rpl_dio(void);
void recv_rpl_dis(void); void recv_rpl_dis(void);
void recv_rpl_dao(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); 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); 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_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);

View File

@ -3,6 +3,7 @@
#include "rpl_dodag.h" #include "rpl_dodag.h"
#include "trickle.h" #include "trickle.h"
#include "rpl.h"
rpl_instance_t instances[RPL_MAX_INSTANCES]; rpl_instance_t instances[RPL_MAX_INSTANCES];
rpl_dodag_t dodags[RPL_MAX_DODAGS]; rpl_dodag_t dodags[RPL_MAX_DODAGS];
@ -87,7 +88,7 @@ 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? rpl_delete_all_parents();
} }
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 +98,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){
@ -110,10 +112,13 @@ rpl_parent_t *rpl_new_parent(rpl_dodag_t *dodag, ipv6_addr_t *address, uint16_t
parent->addr = *address; parent->addr = *address;
parent->rank = rank; parent->rank = rank;
parent->dodag = dodag; parent->dodag = dodag;
//dtsn is set at the end of recv_dio function
parent->dtsn = 0;
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,21 +133,90 @@ 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 if( (my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr, &parent->addr) ){
if(rpl_equal_id(&my_dodag->my_preferred_parent->addr,address)){ my_dodag->my_preferred_parent = NULL;
//set_new_preferred_parent
} }
memset(parent,0,sizeof(*parent));
}
void rpl_delete_worst_parent(void){
uint8_t worst = 0xFF;
uint16_t max_rank = 0x0000;
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)) ){ if(parents[i].rank > max_rank){
memset(&parents[i], 0, sizeof(parents[i])); 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){
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]));
}
} }
void rpl_delete_parents_for_dodag(ipv6_addr_t * dodag_id){ 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){ void rpl_join_dodag(rpl_dodag_t *dodag, ipv6_addr_t *parent, uint16_t parent_rank){
@ -174,20 +248,49 @@ 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);
delay_dao(); 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(); rpl_dodag_t * my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){ 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; return;
} }
rpl_delete_all_parents();
my_dodag->version = dodag->version; 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(){ ipv6_addr_t *rpl_get_my_preferred_parent(){
@ -197,3 +300,7 @@ ipv6_addr_t *rpl_get_my_preferred_parent(){
} }
return &my_dodag->my_preferred_parent->addr; 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,5 +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); rpl_parent_t *rpl_find_parent(ipv6_addr_t *address);
void rpl_leave_dodag(rpl_dodag_t * dodag); 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);
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);
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_PREFIX_INFO_LEN 30
#define RPL_OPT_SOLICITED_INFO_LEN 19 #define RPL_OPT_SOLICITED_INFO_LEN 19
#define RPL_OPT_TARGET_LEN 18 #define RPL_OPT_TARGET_LEN 18
#define RPL_OPT_TRANSIT_LEN 4
//message options //message options
#define RPL_OPT_PAD1 0 #define RPL_OPT_PAD1 0
@ -68,6 +69,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
@ -78,7 +80,7 @@
#define RPL_MAX_ROUTING_ENTRIES 20 #define RPL_MAX_ROUTING_ENTRIES 20
#define RPL_ROOT_RANK 1 #define RPL_ROOT_RANK 1
#define RPL_DEFAULT_LIFETIME 0xff #define RPL_DEFAULT_LIFETIME 0xff
#define RPL_LIFETIME_UNIT 0xffff #define RPL_LIFETIME_UNIT 0x0001
#define RPL_GROUNDED 1 #define RPL_GROUNDED 1
#define RPL_PRF_MASK 0x7 #define RPL_PRF_MASK 0x7
#define RPL_MOP_SHIFT 3 #define RPL_MOP_SHIFT 3
@ -161,11 +163,21 @@ typedef struct __attribute__((packed)) rpl_opt_target_t {
ipv6_addr_t target; ipv6_addr_t target;
} rpl_opt_target_t; } 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; struct rpl_dodag_t;
typedef struct rpl_parent_t { typedef struct rpl_parent_t {
ipv6_addr_t addr; ipv6_addr_t addr;
uint16_t rank; uint16_t rank;
uint8_t dtsn;
struct rpl_dodag_t *dodag; struct rpl_dodag_t *dodag;
uint8_t used; uint8_t used;
} rpl_parent_t; } rpl_parent_t;
@ -197,6 +209,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;
@ -217,6 +230,7 @@ typedef struct rpl_routing_entry_t {
uint8_t used; uint8_t used;
ipv6_addr_t address; ipv6_addr_t address;
ipv6_addr_t next_hop; ipv6_addr_t next_hop;
uint8_t lifetime;
} rpl_routing_entry_t; } rpl_routing_entry_t;

View File

@ -1,3 +1,4 @@
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
@ -7,9 +8,11 @@
char timer_over_buf[TRICKLE_TIMER_STACKSIZE]; char timer_over_buf[TRICKLE_TIMER_STACKSIZE];
char interval_over_buf[TRICKLE_INTERVAL_STACKSIZE]; char interval_over_buf[TRICKLE_INTERVAL_STACKSIZE];
char dao_delay_over_buf[DAO_DELAY_STACKSIZE]; char dao_delay_over_buf[DAO_DELAY_STACKSIZE];
char routing_table_buf[RT_STACKSIZE];
int timer_over_pid; int timer_over_pid;
int interval_over_pid; int interval_over_pid;
int dao_delay_over_pid; int dao_delay_over_pid;
int rt_timer_over_pid;
uint8_t k; uint8_t k;
uint32_t Imin; uint32_t Imin;
@ -20,9 +23,11 @@ uint16_t c;
vtimer_t trickle_t_timer; vtimer_t trickle_t_timer;
vtimer_t trickle_I_timer; vtimer_t trickle_I_timer;
vtimer_t dao_timer; vtimer_t dao_timer;
vtimer_t rt_timer;
timex_t t_time; timex_t t_time;
timex_t I_time; timex_t I_time;
timex_t dao_time; timex_t dao_time;
timex_t rt_time;
//struct für trickle parameter?? //struct für trickle parameter??
void reset_trickletimer(void){ void reset_trickletimer(void){
@ -32,6 +37,8 @@ void reset_trickletimer(void){
t = (I/2) + ( rand() % ( I - (I/2) + 1 ) ); t = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
t_time = timex_set(0,t*1000); t_time = timex_set(0,t*1000);
I_time = timex_set(0,I*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_t_timer, t_time, timer_over_pid);
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_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, dao_delay_over_pid = thread_create(dao_delay_over_buf, DAO_DELAY_STACKSIZE,
PRIORITY_MAIN-1, CREATE_SLEEPING, PRIORITY_MAIN-1, CREATE_SLEEPING,
dao_delay_over, "dao_delay_over"); 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 = (I/2) + ( rand() % ( I - (I/2) + 1 ) );
t_time = timex_set(0,t*1000); t_time = timex_set(0,t*1000);
I_time = timex_set(0,I*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_t_timer, t_time, timer_over_pid);
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid); vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
@ -97,6 +109,8 @@ void trickle_interval_over(void){
//start timer //start timer
t_time = timex_set(0,t*1000); t_time = timex_set(0,t*1000);
I_time = timex_set(0,I*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_t_timer, t_time, timer_over_pid);
vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid); vtimer_set_wakeup(&trickle_I_timer, I_time, interval_over_pid);
thread_sleep(); thread_sleep();
@ -106,12 +120,33 @@ void trickle_interval_over(void){
void delay_dao(void){ void delay_dao(void){
dao_time = timex_set(DEFAULT_DAO_DELAY,0); dao_time = timex_set(DEFAULT_DAO_DELAY,0);
vtimer_remove(&dao_timer);
vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid); vtimer_set_wakeup(&dao_timer, dao_time, dao_delay_over_pid);
} }
void dao_delay_over(void){ void dao_delay_over(void){
while(1){ 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(); thread_sleep();
} }
} }

View File

@ -3,7 +3,11 @@
#define TRICKLE_TIMER_STACKSIZE 3072 #define TRICKLE_TIMER_STACKSIZE 3072
#define TRICKLE_INTERVAL_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 reset_trickletimer(void);
void init_trickle(void); void init_trickle(void);
@ -13,3 +17,4 @@ void trickle_timer_over(void);
void trickle_interval_over(void); void trickle_interval_over(void);
void delay_dao(void); void delay_dao(void);
void dao_delay_over(void); void dao_delay_over(void);
void rt_timer_over(void);

View File

@ -80,8 +80,6 @@ void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t
packet_length = IPV6_HDR_LEN + p_len; packet_length = IPV6_HDR_LEN + p_len;
// printArrayRange(payload, p_len, "Outgoing");
lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf);
} }
@ -133,63 +131,68 @@ int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) {
void ipv6_process(void){ void ipv6_process(void){
msg_t m_recv_lowpan, m_send_lowpan; msg_t m_recv_lowpan, m_send_lowpan;
msg_t m_recv, m_send; msg_t m_recv, m_send;
ipv6_addr_t myaddr;
ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00, get_radio_address());
while(1){ while(1){
msg_receive(&m_recv_lowpan); msg_receive(&m_recv_lowpan);
//ipv6_buf = get_ipv6_buf();
ipv6_buf = (struct ipv6_hdr_t*) m_recv_lowpan.content.ptr; ipv6_buf = (struct ipv6_hdr_t*) m_recv_lowpan.content.ptr;
/* identifiy packet */ /* identifiy packet */
nextheader = &ipv6_buf->nextheader; nextheader = &ipv6_buf->nextheader;
switch(*nextheader) { if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15]))
case(PROTO_NUM_ICMPV6):{ {
/* checksum test*/ memcpy(get_ipv6_buf_send(), get_ipv6_buf(), IPV6_HDR_LEN+ipv6_buf->length);
if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff){ lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)get_ipv6_buf_send());
printf("ERROR: wrong checksum\n");
}
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
icmpv6_demultiplex(icmp_buf);
break;
} }
case(IPPROTO_TCP): else
{ {
// printf("INFO: TCP Packet received.\n"); switch(*nextheader) {
case(PROTO_NUM_ICMPV6):{
if (tcp_packet_handler_pid != 0) /* checksum test*/
{ if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff){
m_send.content.ptr = (char*) ipv6_buf; printf("ERROR: wrong checksum\n");
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
} }
else icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
{ icmpv6_demultiplex(icmp_buf);
printf("INFO: No TCP handler registered.\n"); break;
}
break;
} }
case(IPPROTO_UDP): case(IPPROTO_TCP):
{
// printf("INFO: UDP Packet received.\n");
if (udp_packet_handler_pid != 0)
{ {
m_send.content.ptr = (char*) ipv6_buf; if (tcp_packet_handler_pid != 0)
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid); {
m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
}
else
{
printf("INFO: No TCP handler registered.\n");
}
break;
} }
else case(IPPROTO_UDP):
{ {
printf("INFO: No UDP handler registered.\n"); if (udp_packet_handler_pid != 0)
{
m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
}
else
{
printf("INFO: No UDP handler registered.\n");
}
break;
} }
break; case(PROTO_NUM_NONE):
} {
case(PROTO_NUM_NONE): printf("INFO: Packet with no Header following the IPv6 Header received.\n");
{ break;
printf("INFO: Packet with no Header following the IPv6 Header received.\n"); }
break; default:
} break;
default: }
break;
} }
msg_reply(&m_recv_lowpan, &m_send_lowpan); msg_reply(&m_recv_lowpan, &m_send_lowpan);
} }

View File

@ -32,7 +32,7 @@ static radio_packet_t p;
static msg_t mesg; static msg_t mesg;
int transceiver_type; int transceiver_type;
static transceiver_command_t tcmd; static transceiver_command_t tcmd;
uint8_t static_route = 0; uint16_t fragmentcounter = 0;
uint8_t get_radio_address(void){ uint8_t get_radio_address(void){
int16_t address; int16_t address;
@ -111,30 +111,11 @@ void recv_ieee802154_frame(void){
p = (radio_packet_t*) m.content.ptr; p = (radio_packet_t*) m.content.ptr;
hdrlen = read_802154_frame(p->data, &frame, p->length); hdrlen = read_802154_frame(p->data, &frame, p->length);
length = p->length - hdrlen; length = p->length - hdrlen;
if (static_route == 1) /* deliver packet to network(6lowpan)-layer */
{ fragmentcounter++;
if (frame.src_addr[7] < frame.dest_addr[7]) lowpan_read(frame.payload, length, (ieee_802154_long_t*)&frame.src_addr,
{ (ieee_802154_long_t*)&frame.dest_addr);
ieee_802154_long_t dest_addr;
frame.dest_addr[7] += 1;
memcpy(&dest_addr, &frame.dest_addr, 8);
send_ieee802154_frame(&dest_addr, frame.payload, frame.payload_len, 0);
}
else
{
ieee_802154_long_t dest_addr;
frame.dest_addr[7] -= 1;
memcpy(&dest_addr, &frame.dest_addr, 8);
send_ieee802154_frame(&dest_addr, frame.payload, frame.payload_len, 0);
}
}
else
{
/* deliver packet to network(6lowpan)-layer */
lowpan_read(frame.payload, length, (ieee_802154_long_t*)&frame.src_addr,
(ieee_802154_long_t*)&frame.dest_addr);
}
p->processing--; p->processing--;
} }
@ -170,7 +151,7 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame){
void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload, void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
uint8_t length, uint8_t mcast){ uint8_t length, uint8_t mcast){
uint16_t daddr; uint16_t daddr;
r_src_addr = get_radio_address(); r_src_addr = local_address;
mesg.type = SND_PKT; mesg.type = SND_PKT;
mesg.content.ptr = (char*) &tcmd; mesg.content.ptr = (char*) &tcmd;

View File

@ -14,7 +14,7 @@
#define RADIO_SND_BUF_SIZE 100 #define RADIO_SND_BUF_SIZE 100
#define RADIO_SENDING_DELAY 1000 #define RADIO_SENDING_DELAY 1000
extern uint8_t static_route; extern uint16_t fragmentcounter;
uint8_t get_radio_address(void); uint8_t get_radio_address(void);
void set_radio_address(uint8_t addr); void set_radio_address(uint8_t addr);

View File

@ -40,6 +40,8 @@ uint8_t comp_buf[512];
uint8_t byte_offset; uint8_t byte_offset;
uint8_t first_frag = 0; uint8_t first_frag = 0;
lowpan_reas_buf_t *head = NULL; lowpan_reas_buf_t *head = NULL;
lowpan_reas_buf_t *packet_fifo = NULL;
mutex_t fifo_mutex;
unsigned int ip_process_pid; unsigned int ip_process_pid;
unsigned int nd_nbr_cache_rem_pid = 0; unsigned int nd_nbr_cache_rem_pid = 0;
@ -58,7 +60,8 @@ char con_buf[CON_STACKSIZE];
char lowpan_transfer_buf[LOWPAN_TRANSFER_BUF_STACKSIZE]; char lowpan_transfer_buf[LOWPAN_TRANSFER_BUF_STACKSIZE];
lowpan_context_t contexts[LOWPAN_CONTEXT_MAX]; lowpan_context_t contexts[LOWPAN_CONTEXT_MAX];
uint8_t context_len = 0; uint8_t context_len = 0;
uint8_t route_head = 0; uint8_t static_route = 0;
uint16_t local_address = 0;
void lowpan_context_auto_remove(void); void lowpan_context_auto_remove(void);
@ -79,15 +82,15 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data){
data = &comp_buf[0]; data = &comp_buf[0];
packet_length = comp_len; packet_length = comp_len;
if (route_head == 1) if (static_route == 1)
{ {
if (laddr.uint8[7] < get_radio_address()) if (laddr.uint8[7] < local_address)
{ {
laddr.uint8[7] = get_radio_address() - 1; laddr.uint8[7] = local_address - 1;
} }
else else
{ {
laddr.uint8[7] = get_radio_address() + 1; laddr.uint8[7] = local_address + 1;
} }
} }
@ -160,7 +163,7 @@ void printLongLocalAddr(ieee_802154_long_t *saddr)
((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]); ((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]);
} }
void printReasBuffers() void printReasBuffers(void)
{ {
lowpan_reas_buf_t *temp_buffer; lowpan_reas_buf_t *temp_buffer;
lowpan_interval_list_t *temp_interval; lowpan_interval_list_t *temp_interval;
@ -182,62 +185,75 @@ void printReasBuffers()
} }
} }
void printFIFOBuffers(void)
{
lowpan_reas_buf_t *temp_buffer;
lowpan_interval_list_t *temp_interval;
temp_buffer = packet_fifo;
printf("\n\n--- Reassembly Buffers ---\n");
while (temp_buffer != NULL)
{
printLongLocalAddr(&temp_buffer->s_laddr);
printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n", temp_buffer->ident_no, temp_buffer->current_packet_size, temp_buffer->packet_size, temp_buffer->timestamp);
temp_interval = temp_buffer->interval_list_head;
while (temp_interval != NULL)
{
printf("\t%i - %i\n", temp_interval->start, temp_interval->end);
temp_interval = temp_interval->next;
}
temp_buffer = temp_buffer->next;
}
}
void lowpan_transfer(void) void lowpan_transfer(void)
{ {
msg_t m_recv, m_send; msg_t m_recv, m_send;
ipv6_hdr_t *ipv6_buf; ipv6_hdr_t *ipv6_buf;
lowpan_reas_buf_t *current_buf, *temp_buf; lowpan_reas_buf_t *current_buf;
long temp_time; long temp_time;
uint8_t gotosleep; uint8_t gotosleep;
while (1) while (1)
{ {
temp_buf = NULL;
temp_time = LONG_MAX; temp_time = LONG_MAX;
gotosleep = 1; gotosleep = 1;
current_buf = head; mutex_lock(&fifo_mutex);
current_buf = packet_fifo;
while(current_buf != NULL) if (current_buf != NULL)
{ {
if ((current_buf->current_packet_size == current_buf->packet_size) && mutex_unlock(&fifo_mutex, 0);
(current_buf->timestamp < temp_time)) if((current_buf->packet)[0] == LOWPAN_IPV6_DISPATCH)
{
temp_time = current_buf->timestamp;
temp_buf = current_buf;
}
current_buf = current_buf->next;
}
if (temp_buf != NULL)
{
if((temp_buf->packet)[0] == LOWPAN_IPV6_DISPATCH)
{ {
ipv6_buf = get_ipv6_buf(); ipv6_buf = get_ipv6_buf();
memcpy(ipv6_buf, (temp_buf->packet)+1, temp_buf->packet_size - 1); memcpy(ipv6_buf, (current_buf->packet)+1, current_buf->packet_size - 1);
m_send.content.ptr = (char*) ipv6_buf; m_send.content.ptr = (char*) ipv6_buf;
packet_length = temp_buf->packet_size - 1; packet_length = current_buf->packet_size - 1;
msg_send_receive(&m_send, &m_recv, ip_process_pid); msg_send_receive(&m_send, &m_recv, ip_process_pid);
} }
else if(((temp_buf->packet)[0] & 0xe0) == LOWPAN_IPHC_DISPATCH) else if(((current_buf->packet)[0] & 0xe0) == LOWPAN_IPHC_DISPATCH)
{ {
lowpan_iphc_decoding(temp_buf->packet, temp_buf->packet_size, &temp_buf->s_laddr, &temp_buf->d_laddr); lowpan_iphc_decoding(current_buf->packet, current_buf->packet_size, &current_buf->s_laddr, &current_buf->d_laddr);
ipv6_buf = get_ipv6_buf(); ipv6_buf = get_ipv6_buf();
m_send.content.ptr = (char*) ipv6_buf; m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, ip_process_pid); msg_send_receive(&m_send, &m_recv, ip_process_pid);
} }
else else
{ {
printf("ERROR: packet with unknown dispatch received\n"); // printf("ERROR: packet with unknown dispatch received\n");
} }
collect_garbage(temp_buf); collect_garbage_fifo(current_buf);
gotosleep = 0; gotosleep = 0;
} }
check_timeout();
if (gotosleep == 1) if (gotosleep == 1)
{ {
vtimer_usleep(1000); mutex_unlock(&fifo_mutex, 0);
thread_sleep();
} }
} }
} }
@ -284,7 +300,7 @@ lowpan_reas_buf_t *new_packet_buffer(uint16_t datagram_size, uint16_t datagram_t
new_buf->ident_no = datagram_tag; new_buf->ident_no = datagram_tag;
new_buf->packet_size = datagram_size; new_buf->packet_size = datagram_size;
new_buf->timestamp = rtc_time(NULL); new_buf->timestamp = vtimer_now().microseconds;
if ((current_buf == NULL) && (temp_buf == NULL)) if ((current_buf == NULL) && (temp_buf == NULL))
{ {
@ -292,9 +308,7 @@ lowpan_reas_buf_t *new_packet_buffer(uint16_t datagram_size, uint16_t datagram_t
} }
else else
{ {
mutex_lock(&temp_buf->mu);
temp_buf->next = new_buf; temp_buf->next = new_buf;
mutex_unlock(&temp_buf->mu, 0);
} }
return new_buf; return new_buf;
} }
@ -322,9 +336,7 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, uint16_t datagram
current_buf->interval_list_head != NULL) current_buf->interval_list_head != NULL)
{ {
/* Found buffer for current packet fragment */ /* Found buffer for current packet fragment */
mutex_lock(&current_buf->mu); current_buf->timestamp = vtimer_now().microseconds;
current_buf->timestamp = rtc_time(NULL);
mutex_unlock(&current_buf->mu, 0);
return current_buf; return current_buf;
} }
temp_buf = current_buf; temp_buf = current_buf;
@ -388,6 +400,51 @@ uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf, uint8_t data
return 0; return 0;
} }
lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf)
{
lowpan_interval_list_t *temp_list, *current_list;
lowpan_reas_buf_t *temp_buf, *my_buf, *return_buf;
mutex_lock(&fifo_mutex);
temp_buf = packet_fifo;
my_buf = temp_buf;
if (packet_fifo == current_buf)
{
packet_fifo = current_buf->next;
return_buf = packet_fifo;
}
else
{
while (temp_buf != current_buf)
{
my_buf = temp_buf;
temp_buf = temp_buf->next;
}
my_buf->next = current_buf->next;
return_buf = my_buf->next;
}
mutex_unlock(&fifo_mutex, 0);
current_list = current_buf->interval_list_head;
temp_list = current_list;
while (current_list != NULL)
{
temp_list = current_list->next;
free(current_list);
current_list = temp_list;
}
free(current_buf->packet);
free(current_buf);
return return_buf;
}
lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf) lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf)
{ {
lowpan_interval_list_t *temp_list, *current_list; lowpan_interval_list_t *temp_list, *current_list;
@ -408,9 +465,9 @@ lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf)
my_buf = temp_buf; my_buf = temp_buf;
temp_buf = temp_buf->next; temp_buf = temp_buf->next;
} }
mutex_lock(&my_buf->mu);
my_buf->next = current_buf->next; my_buf->next = current_buf->next;
mutex_unlock(&my_buf->mu, 0);
return_buf = my_buf->next; return_buf = my_buf->next;
} }
@ -425,10 +482,7 @@ lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf)
} }
free(current_buf->packet); free(current_buf->packet);
mutex_lock(&current_buf->mu);
free(current_buf); free(current_buf);
mutex_unlock(&current_buf->mu, 0);
return return_buf; return return_buf;
} }
@ -444,13 +498,14 @@ void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t da
{ {
/* Copy fragment bytes into corresponding packet space area */ /* Copy fragment bytes into corresponding packet space area */
memcpy(current_buf->packet+datagram_offset, data+hdr_length, frag_size); memcpy(current_buf->packet+datagram_offset, data+hdr_length, frag_size);
mutex_lock(&current_buf->mu);
current_buf->current_packet_size += frag_size; current_buf->current_packet_size += frag_size;
mutex_unlock(&current_buf->mu, 0); if (current_buf->current_packet_size == current_buf->packet_size)
if (thread_getstatus(transceiver_pid) == STATUS_SLEEPING)
{ {
thread_wakeup(transfer_pid); add_fifo_packet(current_buf);
if (thread_getstatus(transfer_pid) == STATUS_SLEEPING)
{
thread_wakeup(transfer_pid);
}
} }
} }
else else
@ -469,24 +524,75 @@ void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t da
void check_timeout(void) void check_timeout(void)
{ {
lowpan_reas_buf_t *temp_buf; lowpan_reas_buf_t *temp_buf, *smallest_time = NULL;
time_t cur_time; long cur_time;
int count = 0;
cur_time = rtc_time(NULL); cur_time = vtimer_now().microseconds;
temp_buf = head; temp_buf = head;
while (temp_buf != NULL) while (temp_buf != NULL)
{ {
if ((cur_time - temp_buf->timestamp) >= LOWPAN_REAS_BUF_TIMEOUT) if ((cur_time - temp_buf->timestamp) >= LOWPAN_REAS_BUF_TIMEOUT)
{ {
// printf("TIMEOUT! cur_time: %li, temp_buf: %li\n", cur_time, temp_buf->timestamp); printf("TIMEOUT! cur_time: %li, temp_buf: %li\n", cur_time, temp_buf->timestamp);
temp_buf = collect_garbage(temp_buf); temp_buf = collect_garbage(temp_buf);
} }
else else
{ {
if (smallest_time == NULL)
{
smallest_time = temp_buf;
}
else if (temp_buf->timestamp < smallest_time->timestamp)
{
smallest_time = temp_buf;
}
temp_buf = temp_buf->next; temp_buf = temp_buf->next;
count++;
} }
} }
if ((count > 10) && (smallest_time != NULL))
{
collect_garbage(smallest_time);
}
}
void add_fifo_packet(lowpan_reas_buf_t *current_packet)
{
lowpan_reas_buf_t *temp_buf, *my_buf;
if (head == current_packet)
{
head = current_packet->next;
}
else
{
temp_buf = head;
while (temp_buf != current_packet)
{
my_buf = temp_buf;
temp_buf = temp_buf->next;
}
my_buf->next = current_packet->next;
}
mutex_lock(&fifo_mutex);
if (packet_fifo == NULL)
{
packet_fifo = current_packet;
}
else
{
temp_buf = packet_fifo;
while (temp_buf != NULL)
{
my_buf = temp_buf;
temp_buf = temp_buf->next;
}
my_buf->next = current_packet;
}
mutex_unlock(&fifo_mutex, 0);
current_packet->next = NULL;
} }
void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr, void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
@ -497,6 +603,8 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
uint16_t datagram_size = 0; uint16_t datagram_size = 0;
uint16_t datagram_tag = 0; uint16_t datagram_tag = 0;
check_timeout();
/* Fragmented Packet */ /* Fragmented Packet */
if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0)))
{ {
@ -542,10 +650,9 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
lowpan_reas_buf_t *current_buf = get_packet_frag_buf(length, 0, s_laddr, d_laddr); lowpan_reas_buf_t *current_buf = get_packet_frag_buf(length, 0, s_laddr, d_laddr);
/* Copy packet bytes into corresponding packet space area */ /* Copy packet bytes into corresponding packet space area */
memcpy(current_buf->packet, data, length); memcpy(current_buf->packet, data, length);
mutex_lock(&current_buf->mu);
current_buf->current_packet_size += length; current_buf->current_packet_size += length;
mutex_unlock(&current_buf->mu, 0); add_fifo_packet(current_buf);
if (thread_getstatus(transceiver_pid) == STATUS_SLEEPING) if (thread_getstatus(transfer_pid) == STATUS_SLEEPING)
{ {
thread_wakeup(transfer_pid); thread_wakeup(transfer_pid);
} }
@ -1283,7 +1390,6 @@ void init_reas_bufs(lowpan_reas_buf_t *buf) {
buf->packet = NULL; buf->packet = NULL;
buf->interval_list_head = NULL; buf->interval_list_head = NULL;
buf->next = NULL; buf->next = NULL;
mutex_init(&buf->mu);
} }
void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){
@ -1305,6 +1411,11 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){
/* init lowpan context mutex */ /* init lowpan context mutex */
mutex_init(&lowpan_context_mutex); mutex_init(&lowpan_context_mutex);
/* init packet_fifo mutex */
mutex_init(&fifo_mutex);
local_address = r_addr;
/* init link-local address */ /* init link-local address */
ipv6_set_ll_prefix(&lladdr); ipv6_set_ll_prefix(&lladdr);

View File

@ -23,7 +23,7 @@
#define LOWPAN_IPV6_DISPATCH 0x41 #define LOWPAN_IPV6_DISPATCH 0x41
#define LOWPAN_CONTEXT_MAX 16 #define LOWPAN_CONTEXT_MAX 16
#define LOWPAN_REAS_BUF_TIMEOUT 60 #define LOWPAN_REAS_BUF_TIMEOUT 3 * 1000 * 1000 // TODO: Set back to 3 * 1000 * 1000
#include "transceiver.h" #include "transceiver.h"
#include "sixlowip.h" #include "sixlowip.h"
@ -32,7 +32,8 @@
#include <time.h> #include <time.h>
extern mutex_t lowpan_context_mutex; extern mutex_t lowpan_context_mutex;
extern uint8_t route_head; extern uint8_t static_route;
extern uint16_t local_address;
typedef struct lowpan_context_t { typedef struct lowpan_context_t {
uint8_t num; uint8_t num;
@ -55,7 +56,6 @@ typedef struct lowpan_reas_buf_t {
long timestamp; // Timestamp of last packet fragment long timestamp; // Timestamp of last packet fragment
uint16_t packet_size; // Size of reassembled packet with possible IPHC header uint16_t packet_size; // Size of reassembled packet with possible IPHC header
uint16_t current_packet_size; // Additive size of currently already received fragments uint16_t current_packet_size; // Additive size of currently already received fragments
mutex_t mu; // Used to synchronize transfer thread with reassembly thread
uint8_t *packet; // Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte uint8_t *packet; // Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte
lowpan_interval_list_t *interval_list_head; // Pointer to list of intervals of received packet fragments (if any) lowpan_interval_list_t *interval_list_head; // Pointer to list of intervals of received packet fragments (if any)
struct lowpan_reas_buf_t *next; // Pointer to next reassembly buffer (if any) struct lowpan_reas_buf_t *next; // Pointer to next reassembly buffer (if any)
@ -73,6 +73,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
ieee_802154_long_t *s_laddr, ieee_802154_long_t *s_laddr,
ieee_802154_long_t *d_laddr); ieee_802154_long_t *d_laddr);
uint8_t lowpan_context_len(); uint8_t lowpan_context_len();
void add_fifo_packet(lowpan_reas_buf_t *current_packet);
lowpan_context_t * lowpan_context_update( lowpan_context_t * lowpan_context_update(
uint8_t num, const ipv6_addr_t *prefix, uint8_t num, const ipv6_addr_t *prefix,
uint8_t length, uint8_t comp, uint8_t length, uint8_t comp,
@ -80,9 +81,11 @@ lowpan_context_t * lowpan_context_update(
lowpan_context_t * lowpan_context_get(); lowpan_context_t * lowpan_context_get();
lowpan_context_t * lowpan_context_lookup(ipv6_addr_t *addr); lowpan_context_t * lowpan_context_lookup(ipv6_addr_t *addr);
lowpan_context_t * lowpan_context_num_lookup(uint8_t num); lowpan_context_t * lowpan_context_num_lookup(uint8_t num);
lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf);
lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf); lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf);
void check_timeout(void); void check_timeout(void);
void lowpan_ipv6_set_dispatch(uint8_t *data); void lowpan_ipv6_set_dispatch(uint8_t *data);
void init_reas_bufs(lowpan_reas_buf_t *buf); void init_reas_bufs(lowpan_reas_buf_t *buf);
void printReasBuffers(void); void printReasBuffers(void);
void printFIFOBuffers(void);
#endif #endif