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++){
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,5 @@
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 ;

View File

@ -2,25 +2,136 @@
#include <string.h>
#include <vtimer.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/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;
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);
uint8_t state = rpl_init(TRANSCEIVER_CC1100, &std_addr);
if(state != SUCCESS){
printf("Error initializing RPL\n");
}
if(root == 0x0001){
rpl_init_root();
}
printf("RPL INIT FINISHED\n");
while(1);
uint8_t state;
switch (command) {
case 'r':
printf("INFO: Initialize as root on address \n");
ipv6_print_addr(&std_addr);
if (r_addr > 255) {
printf("ERROR: address not an 8 bit integer\n");
return;
}
state = rpl_init(TRANSCEIVER_CC1100, &std_addr);
if(state != SUCCESS){
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/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;
@ -125,7 +127,7 @@ void init_udp_server(void)
ssize_t recsize;
uint32_t fromlen;
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_port = HTONS(7654);
@ -146,6 +148,7 @@ void init_udp_server(void)
printf("recsize: %i\n ", recsize);
printf("datagram: %s\n", buffer_main);
}
close(sock);
}
void init_tcp_server(void)
@ -216,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);
}
@ -230,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,
@ -244,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);
@ -304,7 +311,7 @@ void send_tcp_bandwidth_test(char *str)
end = vtimer_now();
total = timex_sub(end, start);
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("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)
{
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)
{
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;
int bytes_sent;
int address, count;
uint8_t text[] = "abcdefghijklmnopqrstuvwxyz0123456789!-=$%&/()";
sscanf(str, "send_udp %i %i", &count, &address);
char text[] = "abcdefghijklmnopqrstuvwxyz0123456789!-=$%&/()";
sscanf(str, "send_udp %i %i %s", &count, &address, text);
sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (-1 == sock)
@ -461,7 +468,7 @@ void send_udp(char *str)
memcpy(&sa.sin6_addr, &ipaddr, 16);
sa.sin6_port = HTONS(7654);
ltc4150_start();
printf("Start power: %f\n", ltc4150_get_total_mAh());
printf("Start power: %f\n", ltc4150_get_total_Joule());
start = vtimer_now();
for (int i = 0; i < count; i++)
{
@ -470,11 +477,12 @@ void send_udp(char *str)
{
printf("Error sending packet!\n");
}
// hwtimer_wait(20*1000);
}
end = vtimer_now();
total = timex_sub(end, start);
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);
secs = total.microseconds / 1000000;
printf("Time: %lu seconds, Bandwidth: %lu byte/second\n", secs, (count*48)/secs);
@ -587,48 +595,56 @@ void ignore(char *addr) {
}
#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)
*
* 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".
* For every static route with N hops there are always N-2 nodes which are
* routing nodes and 2 head nodes (start and end).
* declare the nodes A to D as "static_routes" and assign them radio addresses in ascending or descending order
* without gaps (ie 2-3-4-5 is OK, 2-3-5-6 is NOT OK).
*
* A "head node" is a node receiving or sending packets of higher layers (i.e. layer 3 or higher)
* 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. */
* The variable which needs to be set in every node is static_route in sys/net/sixlowpan/sixlowpan.c. */
void static_routing (char *str)
{
if (static_route == 0)
{
static_route = 1;
printf("Static Routing: TRUE\n");
}
else
{
static_route = 0;
printf("Static Routing: FALSE\n");
}
}
void static_head (char *str)
void print_fragment_counter (char *str)
{
if (route_head == 0)
{
route_head = 1;
}
else
{
route_head = 0;
}
printf("Fragment Counter: %u\n", fragmentcounter);
}
void pfifo_buf (char *str)
{
printFIFOBuffers();
}
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[] = {
@ -655,7 +671,11 @@ const shell_command_t shell_commands[] = {
{"bootc", "", boot_client},
{"print_nbr_cache", "", show_nbr_cache},
{"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
{"ign", "ignore node", ignore},
#endif

View File

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

View File

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

View File

@ -13,6 +13,7 @@
#include "tcp.h"
#include "socket.h"
#include "vtimer.h"
#include "hwtimer.h"
#include "tcp_timer.h"
#include "tcp_hc.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)
{
// 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
return -1;
}
sixlowpan_send(&current_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), compressed_size, IPPROTO_TCP);
return 1;
#else
// 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;
}
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 rttvar = tcp_control->rttvar;
double rto = tcp_control->rto;
@ -603,7 +602,7 @@ void calculate_rto(tcp_cb_t *tcp_control, timex_t 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
{
@ -616,17 +615,12 @@ void calculate_rto(tcp_cb_t *tcp_control, timex_t current_time)
{
rto = SECOND;
}
// if (((rto > (SECOND-1)) && (rto < (SECOND+1))))
// {
// printf("RTO is correct!\n");
// }
tcp_control->srtt = srtt;
tcp_control->rttvar = rttvar;
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
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));
tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN]));
// Check if socket exists and is TCP socket
if (!isTCPSocket(s))
{
@ -722,8 +717,7 @@ int32_t send(int s, void *msg, uint64_t len, int flags)
}
// 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);
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)
{
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));
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
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);
}
msg_receive(&m_recv);
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;
}
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))
{
@ -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;
udp_hdr_t *udp_header;
uint8_t *payload;
getSocket(s)->recv_pid = thread_getpid();
msg_receive(&m_recv);
ipv6_header = ((ipv6_hdr_t*)m_recv.content.ptr);
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);
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);
from->sin6_family = AF_INET6;
from->sin6_flowinfo = 0;
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);
return udp_header->length;
return udp_header->length-UDP_HDR_LEN;
}
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))
{

View File

@ -14,8 +14,6 @@
#include "in.h"
#include "sys/net/sixlowpan/sixlowip.h"
#define TCP_HC
/*
* Types
*/
@ -195,10 +193,10 @@ int socket(int domain, int type, int protocol);
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);
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 sendto( int s, void *msg, uint64_t len, int flags, sockaddr6_t *to, uint32_t tolen);
int32_t send(int s, void *msg, uint64_t len, int flags);
int recv(int s, void *buf, uint64_t len, int flags);
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, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen);
int32_t send(int s, void *msg, uint32_t len, int flags);
int recv(int s, void *buf, uint32_t len, int flags);
int close(int s);
int bind(int s, sockaddr6_t *name, int namelen);
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);
return;
}
// TODO: Find better way of handling queued sockets ACK packets
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;
@ -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);
// Send packet
block_continue_thread();
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#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
else
{
block_continue_thread();
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
#endif

View File

@ -8,8 +8,6 @@
#ifndef TCP_H_
#define TCP_H_
#define TCP_HC
#define TCP_HDR_LEN 20
#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_ACK(a) a = ((a & 0x00) | TCP_FIN_ACK)
// TODO: Probably stack size too high
#define TCP_STACK_SIZE 3072
#define TCP_STACK_SIZE 1024
#include "sys/net/sixlowpan/sixlowip.h"

View File

@ -8,8 +8,6 @@
#ifndef TCP_HC_H_
#define TCP_HC_H_
#define TCP_HC
#include "tcp.h"
#include "sys/net/sixlowpan/sixlowip.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++;
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 2800
#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 3072
#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

@ -9,6 +9,7 @@
#include "sys/net/sixlowpan/sixlowmac.h"
#include "sys/net/sixlowpan/sixlowip.h"
#include "sys/net/sixlowpan/sixlowpan.h"
#include "sys/net/sixlowpan/sixlownd.h"
#include "sys/net/sixlowpan/sixlowerror.h"
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_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(){
@ -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]));
}
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){
@ -152,6 +159,7 @@ void send_DIO(ipv6_addr_t* destination){
icmp_buf->type = ICMP_RPL_CONTROL;
icmp_buf->code = ICMP_CODE_DIO;
icmp_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
rpl_dio_buf = get_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->reserved = 0;
rpl_dio_buf->dodagid = mydodag->dodag_id;
printf("Send DIO with DODAGID: \n");
ipv6_print_addr(&rpl_dio_buf->dodagid);
//printf("Send DIO with DODAGID: \n");
//ipv6_print_addr(&rpl_dio_buf->dodagid);
int opt_hdr_len = 0;
//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->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();
uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN;
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;
//TODO:dao_sequence handling
rpl_dao_buf->dao_sequence = 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);
//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++){
if(routing_table[i].used){
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=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));
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);
}
}
//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;
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){
@ -397,18 +441,22 @@ void recv_rpl_dio(void){
if(rpl_equal_id(&my_dodag->dodag_id, &dio_dodag.dodag_id)){
//Mein DODAG
if( dio_dodag.version > my_dodag->version){
printf("New Version of dodag\n");
if(RPL_COUNTER_GREATER_THAN(dio_dodag.version,my_dodag->version) ){
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;
}
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();
return;
}
@ -417,17 +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
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;
}
@ -437,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){
@ -492,10 +556,16 @@ void recv_rpl_dis(void){
}
void recv_rpl_dao(void){
printf("Receiving DAO\n");
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
if(my_dodag == NULL){
printf("[Error] got DAO without beeing part of a Dodag\n");
return;
}
ipv6_buf = get_ipv6_buf();
rpl_dao_buf = get_rpl_dao_buf();
int len = DAO_BASE_LEN;
uint8_t increment_seq = 0;
while(len < (ipv6_buf->length - ICMPV6_HDR_LEN) ){
rpl_opt_buf = get_rpl_opt_buf(len);
switch(rpl_opt_buf->type){
@ -513,7 +583,21 @@ void recv_rpl_dao(void){
break;
}
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;
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):{
@ -529,10 +613,14 @@ void recv_rpl_dao(void){
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){
uint8_t *p_ptr;
uint8_t *p_ptr;
/*if (next_header == IPPROTO_TCP)
{
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);
if(next_hop == NULL){
if(i_am_root){
//oops... entweder bin ich root und weiß nicht wohin mit dem paket, oder es ist kein
//preferred parent eingetragen, was nicht passieren sollte.
//oops... ich bin root und weiß nicht wohin mit dem paketn
printf("[Error] destination unknown\n");
return;
}
else{
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);
@ -596,12 +688,13 @@ 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){
//TODO: if no free entry, delete worst parent
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;
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"
#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,13 +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,7 +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;
//TODO: parents aus Liste löschen?
rpl_delete_all_parents();
}
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;
}
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->rank = rank;
parent->dodag = dodag;
//dtsn is set at the end of recv_dio function
parent->dtsn = 0;
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){
@ -128,21 +133,90 @@ rpl_parent_t *rpl_find_parent(ipv6_addr_t *address){
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();
//TODO:check if this was the preferred parent, find new parent, if it was last parent leave dodag
if(rpl_equal_id(&my_dodag->my_preferred_parent->addr,address)){
//set_new_preferred_parent
if( (my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr, &parent->addr) ){
my_dodag->my_preferred_parent = NULL;
}
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++){
if( parents[i].used && (rpl_equal_id(address, &parents[i].addr)) ){
memset(&parents[i], 0, sizeof(parents[i]));
if(parents[i].rank > max_rank){
worst = i;
max_rank = parents[i].rank;
}
}
if(worst == 0xFF){
//Fehler, keine parents -> sollte nicht passieren
return;
}
rpl_delete_parent(&parents[worst]);
}
void rpl_delete_all_parents(void){
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){
@ -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->my_preferred_parent = preferred_parent;
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;
start_trickle(my_dodag->dio_min, my_dodag->dio_interval_doubling, my_dodag->dio_redundancy);
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;
}
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(){
@ -197,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,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);
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
@ -68,6 +69,7 @@
#define DEFAULT_MIN_HOP_RANK_INCREASE 256
//DAO_DELAY is in seconds
#define DEFAULT_DAO_DELAY 1
#define RPL_DODAG_ID_LEN 16
//others
@ -78,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
@ -161,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;
@ -197,6 +209,7 @@ typedef struct rpl_dodag_t {
uint8_t version;
uint8_t grounded;
uint16_t my_rank;
uint8_t dao_seq;
uint16_t min_rank;
uint8_t joined;
rpl_parent_t *my_preferred_parent;
@ -217,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

@ -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;
// printArrayRange(payload, p_len, "Outgoing");
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){
msg_t m_recv_lowpan, m_send_lowpan;
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){
msg_receive(&m_recv_lowpan);
//ipv6_buf = get_ipv6_buf();
ipv6_buf = (struct ipv6_hdr_t*) m_recv_lowpan.content.ptr;
/* identifiy packet */
nextheader = &ipv6_buf->nextheader;
switch(*nextheader) {
case(PROTO_NUM_ICMPV6):{
/* checksum test*/
if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff){
printf("ERROR: wrong checksum\n");
}
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
icmpv6_demultiplex(icmp_buf);
break;
if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) && (ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15]))
{
memcpy(get_ipv6_buf_send(), get_ipv6_buf(), IPV6_HDR_LEN+ipv6_buf->length);
lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)get_ipv6_buf_send());
}
case(IPPROTO_TCP):
{
// printf("INFO: TCP Packet received.\n");
if (tcp_packet_handler_pid != 0)
{
m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
else
{
switch(*nextheader) {
case(PROTO_NUM_ICMPV6):{
/* checksum test*/
if(icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff){
printf("ERROR: wrong checksum\n");
}
else
{
printf("INFO: No TCP handler registered.\n");
}
break;
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
icmpv6_demultiplex(icmp_buf);
break;
}
case(IPPROTO_UDP):
{
// printf("INFO: UDP Packet received.\n");
if (udp_packet_handler_pid != 0)
case(IPPROTO_TCP):
{
m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
if (tcp_packet_handler_pid != 0)
{
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):
{
printf("INFO: Packet with no Header following the IPv6 Header received.\n");
break;
}
default:
break;
case(PROTO_NUM_NONE):
{
printf("INFO: Packet with no Header following the IPv6 Header received.\n");
break;
}
default:
break;
}
}
msg_reply(&m_recv_lowpan, &m_send_lowpan);
}

View File

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

View File

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

View File

@ -40,6 +40,8 @@ uint8_t comp_buf[512];
uint8_t byte_offset;
uint8_t first_frag = 0;
lowpan_reas_buf_t *head = NULL;
lowpan_reas_buf_t *packet_fifo = NULL;
mutex_t fifo_mutex;
unsigned int ip_process_pid;
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];
lowpan_context_t contexts[LOWPAN_CONTEXT_MAX];
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);
@ -79,15 +82,15 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data){
data = &comp_buf[0];
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
{
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]);
}
void printReasBuffers()
void printReasBuffers(void)
{
lowpan_reas_buf_t *temp_buffer;
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)
{
msg_t m_recv, m_send;
ipv6_hdr_t *ipv6_buf;
lowpan_reas_buf_t *current_buf, *temp_buf;
lowpan_reas_buf_t *current_buf;
long temp_time;
uint8_t gotosleep;
while (1)
{
temp_buf = NULL;
temp_time = LONG_MAX;
gotosleep = 1;
current_buf = head;
while(current_buf != NULL)
mutex_lock(&fifo_mutex);
current_buf = packet_fifo;
if (current_buf != NULL)
{
if ((current_buf->current_packet_size == current_buf->packet_size) &&
(current_buf->timestamp < temp_time))
{
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)
mutex_unlock(&fifo_mutex, 0);
if((current_buf->packet)[0] == LOWPAN_IPV6_DISPATCH)
{
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;
packet_length = temp_buf->packet_size - 1;
packet_length = current_buf->packet_size - 1;
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();
m_send.content.ptr = (char*) ipv6_buf;
msg_send_receive(&m_send, &m_recv, ip_process_pid);
}
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;
}
check_timeout();
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->packet_size = datagram_size;
new_buf->timestamp = rtc_time(NULL);
new_buf->timestamp = vtimer_now().microseconds;
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
{
mutex_lock(&temp_buf->mu);
temp_buf->next = new_buf;
mutex_unlock(&temp_buf->mu, 0);
}
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)
{
/* Found buffer for current packet fragment */
mutex_lock(&current_buf->mu);
current_buf->timestamp = rtc_time(NULL);
mutex_unlock(&current_buf->mu, 0);
current_buf->timestamp = vtimer_now().microseconds;
return 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;
}
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_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;
temp_buf = temp_buf->next;
}
mutex_lock(&my_buf->mu);
my_buf->next = current_buf->next;
mutex_unlock(&my_buf->mu, 0);
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);
mutex_lock(&current_buf->mu);
free(current_buf);
mutex_unlock(&current_buf->mu, 0);
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 */
memcpy(current_buf->packet+datagram_offset, data+hdr_length, frag_size);
mutex_lock(&current_buf->mu);
current_buf->current_packet_size += frag_size;
mutex_unlock(&current_buf->mu, 0);
if (thread_getstatus(transceiver_pid) == STATUS_SLEEPING)
if (current_buf->current_packet_size == current_buf->packet_size)
{
thread_wakeup(transfer_pid);
add_fifo_packet(current_buf);
if (thread_getstatus(transfer_pid) == STATUS_SLEEPING)
{
thread_wakeup(transfer_pid);
}
}
}
else
@ -469,24 +524,75 @@ void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t da
void check_timeout(void)
{
lowpan_reas_buf_t *temp_buf;
time_t cur_time;
lowpan_reas_buf_t *temp_buf, *smallest_time = NULL;
long cur_time;
int count = 0;
cur_time = rtc_time(NULL);
cur_time = vtimer_now().microseconds;
temp_buf = head;
while (temp_buf != NULL)
{
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);
}
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;
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,
@ -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_tag = 0;
check_timeout();
/* Fragmented Packet */
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);
/* Copy packet bytes into corresponding packet space area */
memcpy(current_buf->packet, data, length);
mutex_lock(&current_buf->mu);
current_buf->current_packet_size += length;
mutex_unlock(&current_buf->mu, 0);
if (thread_getstatus(transceiver_pid) == STATUS_SLEEPING)
add_fifo_packet(current_buf);
if (thread_getstatus(transfer_pid) == STATUS_SLEEPING)
{
thread_wakeup(transfer_pid);
}
@ -1283,7 +1390,6 @@ void init_reas_bufs(lowpan_reas_buf_t *buf) {
buf->packet = NULL;
buf->interval_list_head = NULL;
buf->next = NULL;
mutex_init(&buf->mu);
}
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 */
mutex_init(&lowpan_context_mutex);
/* init packet_fifo mutex */
mutex_init(&fifo_mutex);
local_address = r_addr;
/* init link-local address */
ipv6_set_ll_prefix(&lladdr);

View File

@ -23,7 +23,7 @@
#define LOWPAN_IPV6_DISPATCH 0x41
#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 "sixlowip.h"
@ -32,7 +32,8 @@
#include <time.h>
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 {
uint8_t num;
@ -55,7 +56,6 @@ typedef struct lowpan_reas_buf_t {
long timestamp; // Timestamp of last packet fragment
uint16_t packet_size; // Size of reassembled packet with possible IPHC header
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
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)
@ -73,6 +73,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
ieee_802154_long_t *s_laddr,
ieee_802154_long_t *d_laddr);
uint8_t lowpan_context_len();
void add_fifo_packet(lowpan_reas_buf_t *current_packet);
lowpan_context_t * lowpan_context_update(
uint8_t num, const ipv6_addr_t *prefix,
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_lookup(ipv6_addr_t *addr);
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);
void check_timeout(void);
void lowpan_ipv6_set_dispatch(uint8_t *data);
void init_reas_bufs(lowpan_reas_buf_t *buf);
void printReasBuffers(void);
void printFIFOBuffers(void);
#endif