[sys net destiny]

- fixed a bug where a retransmitted TCP ACK segment did not contain the
ACK flag

[sys net sixlowpan]
- changed sixlowpan architecture: IPV6 packets now always get stored in
sixlowpan (reassembly) buffer and are transmitted one after the other 
(FIFO) to IPV6 layer via a separate transfer thread
This commit is contained in:
Oliver 2012-02-13 23:31:17 +01:00
parent be14d20042
commit 8a886fae25
9 changed files with 192 additions and 154 deletions

View File

@ -188,7 +188,7 @@ void init_tcp_server(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);
}
}
}
@ -414,7 +414,7 @@ void send_packet(char *str){
void send_udp(char *str)
{
timex_t start, end, total;
float secs;
long secs;
int sock;
sockaddr6_t sa;
ipv6_addr_t ipaddr;
@ -449,9 +449,10 @@ void send_udp(char *str)
}
end = vtimer_now();
total = timex_sub(end, start);
secs = total.microseconds / 1000000;
printf("Start: %lu, End: %lu, Total: %lu\n", start.microseconds, end.microseconds, total.microseconds);
secs = total.microseconds / 1000000;
printf("Time: %f seconds, Bandwidth: %f byte/second\n", secs, (count*48)/secs);
printf("Time: %lu seconds, Bandwidth: %lu byte/second\n", secs, (count*48)/secs);
close(sock);
}

View File

@ -17,9 +17,6 @@
#include "sys/net/net_help/net_help.h"
#include "sys/net/net_help/msg_help.h"
//msg_t socket_msg_queue[IP_PKT_RECV_BUF_SIZE];
//msg_t send_msg_queue[SEND_MSG_BUF_SIZE];
void printf_tcp_context(tcp_hc_context_t *current_tcp_context)
{
printf("Context: %u\n", current_tcp_context->context_id);
@ -157,17 +154,11 @@ bool exists_socket(uint8_t socket)
void close_socket(socket_internal_t *current_socket)
{
// printf("Closing Socket %i with size %i!\n", current_socket->socket_id, sizeof(socket_internal_t));
memset(current_socket, 0, sizeof(socket_internal_t));
}
bool isUDPSocket(uint8_t s)
{
// printf("Socket_exists: %s, domain: %u, type: %u, protocol: %u\n", exists_socket(s)?"true":"false",
// getSocket(s)->socket_values.domain, getSocket(s)->socket_values.type, getSocket(s)->socket_values.protocol);
// printf("Domain_match: %s, type_macht: %s, protocol_match: %s\n", (getSocket(s)->socket_values.domain == PF_INET6)?"true":"false",
// (getSocket(s)->socket_values.type == SOCK_DGRAM)?"true":"false",
// (getSocket(s)->socket_values.protocol == IPPROTO_UDP)?"true":"false");
if ( (exists_socket(s)) &&
(getSocket(s)->socket_values.domain == PF_INET6) &&
(getSocket(s)->socket_values.type == SOCK_DGRAM) &&
@ -398,7 +389,6 @@ int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, i
uint8_t header_length = TCP_HDR_LEN/4;
if (IS_TCP_SYN(flags) || IS_TCP_SYN_ACK(flags))
{
printf("Sending with MSS Option! flags: %u\n", flags);
tcp_mss_option_t current_mss_option;
header_length += sizeof(tcp_mss_option_t)/4;
@ -423,17 +413,18 @@ int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, i
uint16_t compressed_size;
compressed_size = compress_tcp_packet(current_socket, (uint8_t *) current_tcp_packet, temp_ipv6_header, flags, payload_length);
// printArrayRange(((uint8_t *)temp_ipv6_header), IPV6_HDR_LEN+compressed_size, "Outgoing2");
if (compressed_size == 0)
{
// 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);
// print_tcp_status(OUT_PACKET, temp_ipv6_header, current_tcp_packet, current_tcp_socket);
switch_tcp_packet_byte_order(current_tcp_packet);
sixlowpan_send(&current_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), header_length*4+payload_length, IPPROTO_TCP);
return 1;
@ -493,11 +484,11 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
current_tcp_socket->tcp_control.tcp_context.context_id = global_context_counter;
mutex_unlock(&global_context_counter_mutex, 0);
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
// Remember TCP Context for possible TCP_RETRY
tcp_hc_context_t saved_tcp_context;
memcpy(&saved_tcp_context, &current_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t));
printf("Context ID in Connect(): %u\n", current_tcp_socket->tcp_control.tcp_context.context_id);
#endif
set_tcp_cb(&current_tcp_socket->tcp_control, 0, STATIC_WINDOW, current_tcp_socket->tcp_control.send_iss, current_tcp_socket->tcp_control.send_iss, 0);
@ -564,8 +555,8 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
current_tcp_socket->tcp_control.no_of_retries = 0;
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
// Remember TCP Context for possible TCP_RETRY
tcp_hc_context_t saved_tcp_context;
memcpy(&saved_tcp_context, &current_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t));
#endif
@ -642,7 +633,6 @@ int32_t send(int s, void *msg, uint64_t len, int flags)
while (recv_msg.type != TCP_ACK)
{
// Add packet data
// printf("Send Window: %u, MSS: %u\n", current_tcp_socket->tcp_control.send_wnd, current_tcp_socket->tcp_control.mss);
if (current_tcp_socket->tcp_control.send_wnd > current_tcp_socket->tcp_control.mss)
{
// Window size > Maximum Segment Size
@ -679,7 +669,6 @@ int32_t send(int s, void *msg, uint64_t len, int flags)
current_tcp_socket->tcp_control.send_nxt += sent_bytes;
current_tcp_socket->tcp_control.send_wnd -= sent_bytes;
// printf("Sent bytes: %li\n", sent_bytes);
if (send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, 0, sent_bytes) != 1)
{
// Error while sending tcp data
@ -696,13 +685,11 @@ 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();
// printf("Waiting for Message in send()!\n");
net_msg_receive(&recv_msg);
switch (recv_msg.type)
{
case TCP_ACK:
{
// printf("Got ACK in send()!\n");
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))
{
@ -710,7 +697,6 @@ int32_t send(int s, void *msg, uint64_t len, int flags)
current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr;
current_tcp_socket->tcp_control.send_wnd = tcp_header->window;
// Got ACK for every sent byte
// printf("Everything sent, returning!\n");
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
@ -792,7 +778,6 @@ int recv(int s, void *buf, uint64_t len, int flags)
uint8_t read_bytes;
msg_t m_recv, m_send;
socket_internal_t *current_int_tcp_socket;
// msg_init_queue(socket_msg_queue, IP_PKT_RECV_BUF_SIZE);
// Check if socket exists
if (!isTCPSocket(s))
{
@ -926,6 +911,9 @@ int close(int s)
// Refresh local TCP socket information
current_socket->socket_values.tcp_control.send_una++;
current_socket->socket_values.tcp_control.state = FIN_WAIT_1;
#ifdef TCP_HC
current_socket->socket_values.tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
send_tcp(current_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN, 0);
msg_receive(&m_recv);
@ -1080,6 +1068,7 @@ int handle_new_tcp_connection(socket_internal_t *current_queued_int_socket, sock
current_queued_int_socket->recv_pid = thread_getpid();
#ifdef TCP_HC
current_queued_int_socket->socket_values.tcp_control.tcp_context.hc_type = FULL_HEADER;
memcpy(&current_queued_int_socket->socket_values.tcp_control.tcp_context.context_id,
&server_socket->socket_values.tcp_control.tcp_context.context_id, sizeof(server_socket->socket_values.tcp_control.tcp_context.context_id));
#endif
@ -1136,8 +1125,12 @@ int handle_new_tcp_connection(socket_internal_t *current_queued_int_socket, sock
// send a reply to the TCP handler after processing every information from the TCP ACK packet
msg_reply(&msg_recv_client_ack, &msg_send_client_ack);
// Reset PID to an unlikely value
current_queued_int_socket->recv_pid = 255;
// Waiting for Clients ACK waiting period to time out
vtimer_usleep(TCP_SYN_INITIAL_TIMEOUT/2);
print_sockets();
return current_queued_int_socket->socket_id;

View File

@ -51,14 +51,9 @@ uint16_t tcp_csum(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header)
uint16_t sum;
uint16_t len = ipv6_header->length;
// printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN + tcp_header->dataOffset_reserved, "Incoming_TCP");
sum = len + IPPROTO_TCP;
// printf("sum1: %u\n", sum);
sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t));
// printf("sum2: %u\n", sum);
sum = csum(sum, (uint8_t *)tcp_header, len);
// printf("sum3: %u\n", sum);
return (sum == 0) ? 0xffff : HTONS(sum);
}
@ -123,7 +118,6 @@ void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socke
{
if (check_tcp_consistency(&tcp_socket->socket_values, tcp_header) == PACKET_OK)
{
// printf("Packet consistency OK!\n");
m_send_tcp.content.ptr = (char*)tcp_header;
net_msg_send(&m_send_tcp, tcp_socket->send_pid, 0, TCP_ACK);
return;
@ -188,6 +182,10 @@ void handle_tcp_fin_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socke
set_tcp_cb(&current_tcp_socket->tcp_control, tcp_header->seq_nr+1, current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr,
tcp_header->ack_nr, tcp_header->window);
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
if (current_tcp_socket->tcp_control.state == FIN_WAIT_1)
{
current_tcp_socket->tcp_control.state = CLOSING;
@ -216,6 +214,10 @@ void handle_tcp_fin_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, s
set_tcp_cb(&current_tcp_socket->tcp_control, tcp_header->seq_nr+1, current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr,
tcp_header->ack_nr, tcp_header->window);
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
msg_send(&m_send, tcp_socket->send_pid, 0);
@ -259,7 +261,7 @@ void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
{
block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = MOSTLY_COMPRESSED_HEADER;
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
#endif
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
}
@ -281,7 +283,6 @@ void tcp_packet_handler (void)
ipv6_header = ((ipv6_hdr_t*)m_recv_ip.content.ptr);
tcp_header = ((tcp_hdr_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN));
// printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN+ipv6_header->length, "Incoming");
#ifdef TCP_HC
tcp_socket = decompress_tcp_packet(ipv6_header);
#else
@ -292,9 +293,6 @@ void tcp_packet_handler (void)
payload = (uint8_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN + tcp_header->dataOffset_reserved*4);
// print_tcp_status(INC_PACKET, ipv6_header, tcp_header, &tcp_socket->socket_values);
if ((chksum == 0xffff) && (tcp_socket != NULL))
{
#ifdef TCP_HC
@ -355,7 +353,7 @@ void tcp_packet_handler (void)
else
{
printf("Wrong checksum (%x) or no corresponding socket found!\n", chksum);
// printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN+ipv6_header->length, "Incoming");
printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN+ipv6_header->length, "Incoming");
print_tcp_status(INC_PACKET, ipv6_header, tcp_header, &tcp_socket->socket_values);
}

View File

@ -58,9 +58,8 @@ uint16_t compress_tcp_packet(socket_internal_t *current_socket, uint8_t *current
tcp_cb_t *tcp_cb = &current_tcp_socket->tcp_control;
tcp_hdr_t full_tcp_header;
uint16_t packet_size = 0;
// printArrayRange(((uint8_t *)temp_ipv6_header), IPV6_HDR_LEN+temp_ipv6_header->length, "Outgoing");
// Connection establisment phase, use FULL_HEADER TCP
if (tcp_cb->state != ESTABLISHED)
if (tcp_context->hc_type == FULL_HEADER)
{
// draft-aayadi-6lowpan-tcphc-01: 5.1 Full header TCP segment. Establishing Connection
@ -80,11 +79,8 @@ uint16_t compress_tcp_packet(socket_internal_t *current_socket, uint8_t *current
// Update the tcp context fields
update_tcp_hc_context(false, current_socket, (tcp_hdr_t *)(current_tcp_packet+3));
// print_tcp_status(OUT_PACKET, temp_ipv6_header, (tcp_hdr_t *)(current_tcp_packet+3), current_tcp_socket);
// Convert TCP packet to network byte order
switch_tcp_packet_byte_order((tcp_hdr_t *)(current_tcp_packet+3));
// printArrayRange(((uint8_t *)temp_ipv6_header), IPV6_HDR_LEN+temp_ipv6_header->length, "Outgoing1");
return packet_size;
}
@ -163,9 +159,7 @@ uint16_t compress_tcp_packet(socket_internal_t *current_socket, uint8_t *current
if ((IS_TCP_ACK(full_tcp_header.reserved_flags) &&
(tcp_cb->tcp_context.ack_snd == full_tcp_header.ack_nr)))
{
// printf("TCP Context Ack Send: %lu, Current TCP Packet Ack: %lu\n", tcp_cb->tcp_context.ack_snd, ((tcp_hdr_t*)current_tcp_packet)->ack_nr);
tcp_context->ack_snd = tcp_context->seq_rcv;
// printf("TCP Context Ack Send: %lu, TCP Context Seq Recv: %lu\n", tcp_cb->tcp_context.ack_snd, tcp_context->seq_rcv);
}
if (full_tcp_header.ack_nr == tcp_context->ack_snd)
{
@ -276,9 +270,6 @@ uint16_t compress_tcp_packet(socket_internal_t *current_socket, uint8_t *current
packet_size += payload_length;
update_tcp_hc_context(false, current_socket, &full_tcp_header);
// print_tcp_status(OUT_PACKET, temp_ipv6_header, &full_tcp_header, current_tcp_socket);
// printf("packet Size2: %u\n", packet_size);
return packet_size;
}
@ -373,11 +364,7 @@ uint16_t compress_tcp_packet(socket_internal_t *current_socket, uint8_t *current
// Adding TCP payload length to TCP_HC header length
packet_size += payload_length;
// printf("packet Size2: %u\n", packet_size);
update_tcp_hc_context(false, current_socket, &full_tcp_header);
// print_tcp_status(OUT_PACKET, temp_ipv6_header, &full_tcp_header, current_tcp_socket);
// printArrayRange(((uint8_t *)temp_ipv6_header), IPV6_HDR_LEN+temp_ipv6_header->length, "Outgoing3");
return packet_size;
}
return 0;
@ -389,7 +376,7 @@ socket_internal_t *decompress_tcp_packet(ipv6_hdr_t *temp_ipv6_header)
uint16_t tcp_hc_header;
socket_internal_t *current_socket = NULL;
uint16_t packet_size = 0;
// printArrayRange(((uint8_t *)temp_ipv6_header), IPV6_HDR_LEN+temp_ipv6_header->length, "Incoming");
// Full header TCP segment
if (*(((uint8_t *)temp_ipv6_header)+IPV6_HDR_LEN) == 0x01)
{
@ -604,7 +591,6 @@ socket_internal_t *decompress_tcp_packet(ipv6_hdr_t *temp_ipv6_header)
// Set IPV6 header length
temp_ipv6_header->length = temp_ipv6_header->length - packet_size + TCP_HDR_LEN;
// printArrayRange(((uint8_t *)temp_ipv6_header), IPV6_HDR_LEN+temp_ipv6_header->length, "Incoming");
return current_socket;
}
}

View File

@ -13,6 +13,7 @@
#include "destiny.h"
#include "socket.h"
#include "net_help/msg_help.h"
#include "sys/net/sixlowpan/sixlowpan.h"
void handle_synchro_timeout(socket_internal_t *current_socket)
{
@ -66,6 +67,7 @@ void handle_established(socket_internal_t *current_socket)
else if (timex_sub(vtimer_now(), current_socket->socket_values.tcp_control.last_packet_time).microseconds >
current_timeout)
{
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: %lu\n", current_socket->socket_values.tcp_control.no_of_retries,

View File

@ -14,7 +14,7 @@
#define TCP_SYN_TIMEOUT 24*SECONDS
#define TCP_MAX_SYN_RETRIES 3
#define TCP_ACK_TIMEOUT 3*SECONDS // still static, should be calculated via RTT
#define TCP_ACK_MAX_TIMEOUT 90*SECONDS
#define TCP_ACK_MAX_TIMEOUT 30*SECONDS // TODO: Set back to 90 Seconds
#define TCP_NOT_DEFINED 0
#define TCP_RETRY 1

View File

@ -80,6 +80,8 @@ 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);
}
@ -129,9 +131,8 @@ int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) {
}
void ipv6_process(void){
msg_t m_recv_lowpan;
msg_t m_recv_lowpan, m_send_lowpan;
msg_t m_recv, m_send;
msg_init_queue(msg_queue, IP_PKT_RECV_BUF_SIZE);
while(1){
msg_receive(&m_recv_lowpan);
@ -190,6 +191,7 @@ void ipv6_process(void){
default:
break;
}
msg_reply(&m_recv_lowpan, &m_send_lowpan);
}
}

View File

@ -1,11 +1,13 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <vtimer.h>
#include <timex.h>
#include <debug.h>
#include <thread.h>
#include <mutex.h>
#include <hwtimer.h>
#include <rtc.h>
#include <lpc2387-rtc.h>
#include "msg.h"
@ -42,6 +44,7 @@ lowpan_reas_buf_t *head = NULL;
unsigned int ip_process_pid;
unsigned int nd_nbr_cache_rem_pid = 0;
unsigned int contexts_rem_pid = 0;
unsigned int transfer_pid = 0;
iface_t iface;
ipv6_addr_t lladdr;
@ -52,6 +55,7 @@ mutex_t lowpan_context_mutex;
char ip_process_buf[IP_PROCESS_STACKSIZE];
char nc_buf[NC_STACKSIZE];
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;
@ -70,16 +74,10 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data){
mcast = 1;
}
//#ifdef LOWPAN_IPHC
lowpan_iphc_encoding(&laddr, ipv6_buf);
data = &comp_buf[0];
packet_length = comp_len;
//#endif
//#ifndef LOWPAN_IPHC
// lowpan_ipv6_set_dispatch(data);
//#endif
/* check if packet needs to be fragmented */
if(packet_length + header_size > PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN){
uint8_t fragbuf[packet_length + header_size];
@ -143,10 +141,10 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data){
void printLongLocalAddr(ieee_802154_long_t *saddr)
{
char text[9];
text[8] = '\0';
memcpy(text, saddr, 8);
printf("Short Local Address: %s\n", text);
printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
((uint8_t *)saddr)[0], ((uint8_t *)saddr)[1], ((uint8_t *)saddr)[2],
((uint8_t *)saddr)[3], ((uint8_t *)saddr)[4], ((uint8_t *)saddr)[5],
((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]);
}
void printReasBuffers()
@ -171,6 +169,66 @@ void printReasBuffers()
}
}
void lowpan_transfer(void)
{
msg_t m_recv, m_send;
ipv6_hdr_t *ipv6_buf;
lowpan_reas_buf_t *current_buf, *temp_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)
{
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)
{
ipv6_buf = get_ipv6_buf();
memcpy(ipv6_buf, (temp_buf->packet)+1, temp_buf->packet_size - 1);
m_send.content.ptr = (char*) ipv6_buf;
packet_length = temp_buf->packet_size - 1;
msg_send_receive(&m_send, &m_recv, ip_process_pid);
}
else if(((temp_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);
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");
}
collect_garbage(temp_buf);
gotosleep = 0;
}
check_timeout();
if (gotosleep == 1)
{
vtimer_usleep(1000);
}
}
}
uint8_t ll_get_addr_match(ieee_802154_long_t *src, ieee_802154_long_t *dst){
uint8_t val = 0, xor;
for(int i = 0; i < 8; i++){
@ -193,24 +251,10 @@ uint8_t ll_get_addr_match(ieee_802154_long_t *src, ieee_802154_long_t *dst){
return val;
}
lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr)
lowpan_reas_buf_t *new_packet_buffer(uint16_t datagram_size, uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr,
lowpan_reas_buf_t *current_buf, lowpan_reas_buf_t *temp_buf)
{
lowpan_reas_buf_t *current_buf = NULL, *new_buf = NULL, *temp_buf = NULL;
current_buf = head;
while (current_buf != NULL)
{
if (((ll_get_addr_match(&current_buf->s_laddr, s_laddr)) == 64) &&
((ll_get_addr_match(&current_buf->d_laddr, d_laddr)) == 64) &&
(current_buf->packet_size == datagram_size) &&
(current_buf->ident_no == datagram_tag))
{
/* Found buffer for current packet fragment */
current_buf->timestamp = rtc_time(NULL);
return current_buf;
}
temp_buf = current_buf;
current_buf = current_buf->next;
}
lowpan_reas_buf_t *new_buf = NULL;
/* Allocate new memory for a new packet to be reassembled */
new_buf = malloc(sizeof(lowpan_reas_buf_t));
@ -220,11 +264,11 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, uint16_t datagram
init_reas_bufs(new_buf);
new_buf->packet = malloc(datagram_size);
//printf("Malloc Packet Size: %i, Pointer: %p\n", );
if(new_buf->packet != NULL)
{
memcpy(&new_buf->s_laddr, s_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN);
memcpy(&new_buf->d_laddr, d_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN);
new_buf->ident_no = datagram_tag;
new_buf->packet_size = datagram_size;
new_buf->timestamp = rtc_time(NULL);
@ -235,7 +279,9 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, uint16_t datagram
}
else
{
mutex_lock(&temp_buf->mu);
temp_buf->next = new_buf;
mutex_unlock(&temp_buf->mu, 0);
}
return new_buf;
}
@ -250,6 +296,31 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, uint16_t datagram
}
}
lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size, uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr)
{
lowpan_reas_buf_t *current_buf = NULL, *temp_buf = NULL;
current_buf = head;
while (current_buf != NULL)
{
if (((ll_get_addr_match(&current_buf->s_laddr, s_laddr)) == 64) &&
((ll_get_addr_match(&current_buf->d_laddr, d_laddr)) == 64) &&
(current_buf->packet_size == datagram_size) &&
(current_buf->ident_no == datagram_tag) &&
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);
return current_buf;
}
temp_buf = current_buf;
current_buf = current_buf->next;
}
return new_packet_buffer(datagram_size, datagram_tag, s_laddr, d_laddr, current_buf, temp_buf);
}
uint8_t isInInterval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2)
{
/* 1: Interval 1 and 2 are the same or overlapping */
@ -307,7 +378,28 @@ uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf, uint8_t data
lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf)
{
lowpan_interval_list_t *temp_list, *current_list;
lowpan_reas_buf_t *temp_buf, *my_buf;
lowpan_reas_buf_t *temp_buf, *my_buf, *return_buf;
temp_buf = head;
my_buf = temp_buf;
if (head == current_buf)
{
head = current_buf->next;
return_buf = head;
}
else
{
while (temp_buf != 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;
}
current_list = current_buf->interval_list_head;
temp_list = current_list;
@ -319,28 +411,13 @@ lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf)
current_list = temp_list;
}
temp_buf = head;
my_buf = temp_buf;
free(current_buf->packet);
if (head == current_buf)
{
head = current_buf->next;
free(current_buf->packet);
free(current_buf);
return head;
}
else
{
while (temp_buf != current_buf)
{
my_buf = temp_buf;
temp_buf = temp_buf->next;
}
my_buf->next = current_buf->next;
free(current_buf->packet);
free(current_buf);
return my_buf->next;
}
mutex_lock(&current_buf->mu);
free(current_buf);
mutex_unlock(&current_buf->mu, 0);
return return_buf;
}
void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t datagram_size,
@ -348,37 +425,19 @@ void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t da
uint8_t hdr_length, uint8_t frag_size)
{
lowpan_reas_buf_t *current_buf;
msg_t m;
/* Is there already a reassembly buffer for this packet fragment? */
current_buf = get_packet_frag_buf(datagram_size, datagram_tag, s_laddr, d_laddr);
if ((current_buf != NULL) && (handle_packet_frag_interval(current_buf, datagram_offset, frag_size) == 1))
{
/* Copy fragment bytes into corresponding packet space area */
memcpy(current_buf->packet+datagram_offset, data+hdr_length, frag_size);
current_buf->current_packet_size += frag_size;
if (current_buf->current_packet_size == datagram_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->packet[0] == LOWPAN_IPV6_DISPATCH)
{
ipv6_buf = get_ipv6_buf();
memcpy(ipv6_buf, current_buf->packet + 1, datagram_size - 1);
m.content.ptr = (char*) ipv6_buf;
packet_length = datagram_size - 1;
msg_send(&m,ip_process_pid, 1);
}
else if((current_buf->packet[0] & 0xe0) == LOWPAN_IPHC_DISPATCH)
{
lowpan_iphc_decoding(current_buf->packet, datagram_size, s_laddr, d_laddr);
ipv6_buf = get_ipv6_buf();
m.content.ptr = (char*) ipv6_buf;
msg_send(&m,ip_process_pid, 1);
}
else
{
printf("ERROR: packet with unknown dispatch received\n");
}
collect_garbage(current_buf);
thread_wakeup(transfer_pid);
}
}
else
@ -420,7 +479,6 @@ void check_timeout(void)
void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
ieee_802154_long_t *d_laddr){
/* check if packet is fragmented */
msg_t m;
uint8_t hdr_length = 0;
uint8_t datagram_offset = 0;
uint16_t datagram_size = 0;
@ -468,27 +526,18 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
/* Regular Packet */
else
{
if(data[0] == LOWPAN_IPV6_DISPATCH)
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)
{
ipv6_buf = get_ipv6_buf();
memcpy(ipv6_buf, data + 1, length - 1);
m.content.ptr = (char*) ipv6_buf;
packet_length = length - 1;
msg_send(&m,ip_process_pid, 1);
}
else if((data[0] & 0xe0) == LOWPAN_IPHC_DISPATCH)
{
lowpan_iphc_decoding(data, length, s_laddr, d_laddr);
ipv6_buf = get_ipv6_buf();
m.content.ptr = (char*) ipv6_buf;
msg_send(&m,ip_process_pid, 1);
}
else
{
printf("ERROR: packet with unknown dispatch received\n");
thread_wakeup(transfer_pid);
}
}
check_timeout();
}
void lowpan_ipv6_set_dispatch(uint8_t *data){
@ -1221,12 +1270,12 @@ 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){
ipv6_addr_t tmp;
/* init mac-layer and radio transceiver */
// vtimer_init();
sixlowmac_init(trans);
rtc_init();
@ -1273,6 +1322,9 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){
contexts_rem_pid = thread_create(con_buf, CON_STACKSIZE,
PRIORITY_MAIN+1, CREATE_STACKTEST,
lowpan_context_auto_remove, "lowpan_context_rem");
transfer_pid = thread_create(lowpan_transfer_buf, LOWPAN_TRANSFER_BUF_STACKSIZE,
PRIORITY_MAIN-1, CREATE_STACKTEST,
lowpan_transfer, "lowpan_transfer");
}
void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, uint8_t r_addr){

View File

@ -1,9 +1,10 @@
#ifndef SIXLOWPAN_H
#define SIXLOWPAN_H
#define IP_PROCESS_STACKSIZE 3072
#define NC_STACKSIZE 512
#define CON_STACKSIZE 512
#define IP_PROCESS_STACKSIZE 3072
#define NC_STACKSIZE 512
#define CON_STACKSIZE 512
#define LOWPAN_TRANSFER_BUF_STACKSIZE 512
/* fragment size in bytes*/
#define FRAG_PART_ONE_HDR_LEN 4
@ -50,9 +51,10 @@ typedef struct lowpan_reas_buf_t {
ieee_802154_long_t s_laddr; // Source Address
ieee_802154_long_t d_laddr; // Destination Address
uint16_t ident_no; // Identification Number
time_t timestamp; // Timestamp of last packet fragment
uint8_t packet_size; // Size of reassembled packet with possible IPHC header
uint8_t current_packet_size; // Additive size of currently already received fragments
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)
@ -77,6 +79,8 @@ 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(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);