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:
commit
b81b7d6429
@ -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);
|
||||
}
|
||||
|
@ -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 ;
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -8,8 +8,6 @@
|
||||
#ifndef DESTINY_H_
|
||||
#define DESTINY_H_
|
||||
|
||||
#define TCP_HC
|
||||
|
||||
void init_transport_layer(void);
|
||||
|
||||
#endif /* DESTINY_H_ */
|
||||
|
@ -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(¤t_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(¤t_tcp_socket->tcp_control, vtimer_now());
|
||||
calculate_rto(¤t_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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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, ¤t_buf->s_laddr, ¤t_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(¤t_buf->mu);
|
||||
current_buf->timestamp = rtc_time(NULL);
|
||||
mutex_unlock(¤t_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(¤t_buf->mu);
|
||||
free(current_buf);
|
||||
mutex_unlock(¤t_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(¤t_buf->mu);
|
||||
current_buf->current_packet_size += frag_size;
|
||||
mutex_unlock(¤t_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(¤t_buf->mu);
|
||||
current_buf->current_packet_size += length;
|
||||
mutex_unlock(¤t_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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user