[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:
parent
be14d20042
commit
8a886fae25
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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(¤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);
|
||||
// print_tcp_status(OUT_PACKET, temp_ipv6_header, current_tcp_packet, current_tcp_socket);
|
||||
switch_tcp_packet_byte_order(current_tcp_packet);
|
||||
sixlowpan_send(¤t_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, ¤t_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(¤t_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, ¤t_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(¤t_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;
|
||||
|
||||
@ -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(¤t_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(¤t_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);
|
||||
}
|
||||
|
||||
|
||||
@ -58,9 +58,8 @@ uint16_t compress_tcp_packet(socket_internal_t *current_socket, uint8_t *current
|
||||
tcp_cb_t *tcp_cb = ¤t_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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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(¤t_buf->s_laddr, s_laddr)) == 64) &&
|
||||
((ll_get_addr_match(¤t_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(¤t_buf->s_laddr, s_laddr)) == 64) &&
|
||||
((ll_get_addr_match(¤t_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(¤t_buf->mu);
|
||||
current_buf->timestamp = rtc_time(NULL);
|
||||
mutex_unlock(¤t_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(¤t_buf->mu);
|
||||
free(current_buf);
|
||||
mutex_unlock(¤t_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(¤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->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(¤t_buf->mu);
|
||||
current_buf->current_packet_size += length;
|
||||
mutex_unlock(¤t_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){
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user