From 11fecd089ee0871fc549710f0a07da70f5fdaf7b Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 26 Dec 2011 02:59:58 +0100 Subject: [PATCH] - Added dynamic 6LoWPAN fragment buffer for reassembly of multiple fragments at the same time - Introduced thread message wrappers for identifying the correct function - Several bugfixes --- projects/tlayer/Jamfile | 2 +- projects/tlayer/main.c | 11 +- sys/net/destiny/destiny.c | 4 +- sys/net/destiny/socket.c | 80 ++++--- sys/net/destiny/tcp.c | 17 +- sys/net/destiny/tcp.h | 2 +- sys/net/destiny/udp.c | 19 +- sys/net/destiny/udp.h | 3 +- sys/net/net_help/msg_help.h | 20 +- sys/net/sixlowpan/sixlowip.c | 14 +- sys/net/sixlowpan/sixlowip.h | 7 +- sys/net/sixlowpan/sixlowmac.h | 3 +- sys/net/sixlowpan/sixlowpan.c | 433 ++++++++++++++++++++++++++-------- sys/net/sixlowpan/sixlowpan.h | 25 +- sys/transceiver.c | 5 + 15 files changed, 467 insertions(+), 178 deletions(-) diff --git a/projects/tlayer/Jamfile b/projects/tlayer/Jamfile index cc0f7ae152..c120ede364 100644 --- a/projects/tlayer/Jamfile +++ b/projects/tlayer/Jamfile @@ -12,4 +12,4 @@ UseModule shell ; UseModule ps ; UseModule 6lowpan ; UseModule vtimer ; -#UseModule net_help ; +UseModule rtc ; diff --git a/projects/tlayer/main.c b/projects/tlayer/main.c index 533820a854..85abe963b0 100644 --- a/projects/tlayer/main.c +++ b/projects/tlayer/main.c @@ -206,7 +206,7 @@ void send_tcp(char *str) { msg_t send_msg; sscanf(str, "send_tcp %s", current_message.tcp_string_msg); - + printf("1Send Content: %s\n", current_message.tcp_string_msg); send_msg.content.value = 1; msg_send(&send_msg, tcp_cht_pid, 0); } @@ -402,13 +402,19 @@ void shows(char *str) print_sockets(); } +void showReas(char *str) + { + printReasBuffers(); + } + const shell_command_t shell_commands[] = { {"init", "", init}, {"addr", "", get_r_address}, {"set_chann", "", set_radio_chann}, {"boot", "", bootstrapping}, {"ip", "", ip}, - {"shows", "", shows}, + {"shows", "Show Sockets", shows}, + {"show_reas", "Show reassembly Buffers", showReas}, {"context", "", context}, {"init_tl", "", init_tl}, {"init_udp_server_thread", "", init_udp_server_thread}, @@ -422,7 +428,6 @@ const shell_command_t shell_commands[] = { int main(void) { printf("6LoWPAN Transport Layers\n"); - printf("RANDMAX: %i\n", RAND_MAX); posix_open(uart0_handler_pid, 0); init_tl(NULL); shell_t shell; diff --git a/sys/net/destiny/destiny.c b/sys/net/destiny/destiny.c index ef7bf799eb..ac2cd733b5 100644 --- a/sys/net/destiny/destiny.c +++ b/sys/net/destiny/destiny.c @@ -20,9 +20,9 @@ void init_transport_layer(void) // UDP int udp_thread_pid = thread_create(udp_stack_buffer, UDP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, udp_packet_handler, "udp_packet_handler"); - set_udp_packet_handler_pid(udp_thread_pid, buffer_udp); + set_udp_packet_handler_pid(udp_thread_pid); // TCP int tcp_thread_pid = thread_create(tcp_stack_buffer, TCP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, tcp_packet_handler, "tcp_packet_handler"); - set_tcp_packet_handler_pid(tcp_thread_pid, buffer_tcp); + set_tcp_packet_handler_pid(tcp_thread_pid); } diff --git a/sys/net/destiny/socket.c b/sys/net/destiny/socket.c index 0f39296e75..e90ac3314d 100644 --- a/sys/net/destiny/socket.c +++ b/sys/net/destiny/socket.c @@ -17,21 +17,43 @@ void print_tcp_flags (tcp_hdr_t *tcp_header) { printf("FLAGS: "); - if ((tcp_header->reserved_flags & TCP_ACK) > 0) + switch(tcp_header->reserved_flags) { - printf("ACK "); - } - if ((tcp_header->reserved_flags & TCP_RST) > 0) - { - printf("RST "); - } - if ((tcp_header->reserved_flags & TCP_SYN) > 0) - { - printf("SYN "); - } - if ((tcp_header->reserved_flags & TCP_FIN) > 0) - { - printf("FIN "); + case TCP_ACK: + { + printf("ACK "); + break; + } + case TCP_RST: + { + printf("RST "); + break; + } + case TCP_SYN: + { + printf("SYN "); + break; + } + case TCP_FIN: + { + printf("FIN "); + break; + } + case TCP_URG_PSH: + { + printf("URG PSH "); + break; + } + case TCP_SYN_ACK: + { + printf("SYN ACK "); + break; + } + case TCP_FIN_ACK: + { + printf("FIN ACK "); + break; + } } printf("\n\n"); } @@ -384,10 +406,10 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen, uint8_t tcp_client_ sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), TCP_HDR_LEN, IPPROTO_TCP); // wait for SYN ACK - msg_receive(&msg_from_server); + net_msg_receive(&msg_from_server, FID_SOCKET_CONNECT); // Read packet content - tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(buffer_tcp+IPV6_HDR_LEN)); + tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(msg_from_server.content.ptr)); // Check for consistency if (check_tcp_consistency(current_tcp_socket, tcp_header) == -1) @@ -409,7 +431,7 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen, uint8_t tcp_client_ current_tcp_packet->checksum = ~tcp_csum(temp_ipv6_header, current_tcp_packet); sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), TCP_HDR_LEN, IPPROTO_TCP); - msg_reply(&msg_from_server, &msg_reply_fin); + net_msg_reply(&msg_from_server, &msg_reply_fin, FID_TCP_SYN_ACK); return 0; } @@ -534,9 +556,9 @@ int32_t recvfrom(int s, void *buf, uint64_t len, int flags, sockaddr6_t *from, u udp_hdr_t *udp_header; uint8_t *payload; net_msg_receive(&m_recv, FID_RECV_FROM); - ipv6_header = ((ipv6_hdr_t*)&buffer_udp); - udp_header = ((udp_hdr_t*)(&buffer_udp[IPV6_HDR_LEN])); - payload = &buffer_udp[IPV6_HDR_LEN+UDP_HDR_LEN]; + 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); @@ -726,7 +748,7 @@ int handle_new_tcp_connection(socket_t *current_queued_socket, socket_internal_t int new_socket; msg_t msg_recv_client_ack, msg_send_client_ack; socket_internal_t *current_new_socket; - uint8_t send_buffer[BUFFER_SIZE]; + uint8_t send_buffer[BUFFER_SIZE], consistency; ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); tcp_hdr_t *syn_ack_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); @@ -747,22 +769,22 @@ int handle_new_tcp_connection(socket_t *current_queued_socket, socket_internal_t syn_ack_packet->checksum = ~tcp_csum(temp_ipv6_header, syn_ack_packet); - printf("BEFORE SENDING SYN ACK PACKET!\n"); sixlowpan_send(¤t_queued_socket->foreign_address.sin6_addr, (uint8_t*)(syn_ack_packet), TCP_HDR_LEN, IPPROTO_TCP); // wait for ACK from Client - msg_receive(&msg_recv_client_ack); + net_msg_receive(&msg_recv_client_ack, FID_SOCKET_HANDLE_NEW_TCP_CON); - ipv6_hdr_t *ipv6_header; tcp_hdr_t *tcp_header; - ipv6_header = ((ipv6_hdr_t*)(buffer_tcp)); - tcp_header = ((tcp_hdr_t*)(buffer_tcp+IPV6_HDR_LEN)); + tcp_header = ((tcp_hdr_t*)(msg_recv_client_ack.content.ptr)); // Check for consistency - if (check_tcp_consistency(current_queued_socket, tcp_header) != PACKET_OK) + consistency = check_tcp_consistency(current_queued_socket, tcp_header); + if (consistency != PACKET_OK) { - printf("TCP packets not consistent!\n"); + printf("TCP packets not consistent, Error Code: %i!\n", consistency); + printf("TCP ACK NR: %li, Local TCP Status SEQ: %li, TCP SEQ NR: %li, FOREIGN TCP STATUS SEQ: %li\n", tcp_header->ack_nr, current_queued_socket->local_tcp_status.seq_nr+1, + tcp_header->seq_nr, current_queued_socket->foreign_tcp_status.seq_nr); } // Got ack, connection established, refresh local and foreign tcp socket status @@ -773,7 +795,7 @@ int handle_new_tcp_connection(socket_t *current_queued_socket, socket_internal_t server_socket->in_socket.local_tcp_status.state = LISTEN; // 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); + net_msg_reply(&msg_recv_client_ack, &msg_send_client_ack, FID_TCP_ACK); new_socket = socket(current_queued_socket->domain, current_queued_socket->type, current_queued_socket->protocol); current_new_socket = getSocket(new_socket); diff --git a/sys/net/destiny/tcp.c b/sys/net/destiny/tcp.c index 0c3edad0f5..afacf162b2 100644 --- a/sys/net/destiny/tcp.c +++ b/sys/net/destiny/tcp.c @@ -67,13 +67,12 @@ uint8_t handle_payload(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_in else { memcpy(tcp_socket->tcp_input_buffer, payload, tcp_payload_len); - tcp_socket->in_socket.local_tcp_status.window = tcp_socket->in_socket.local_tcp_status.window - tcp_payload_len; acknowledged_bytes = tcp_payload_len; tcp_socket->tcp_input_buffer_end = tcp_socket->tcp_input_buffer_end + tcp_payload_len; } - net_msg_send(&m_send_tcp, tcp_socket->pid, 0, FID_RECV); + net_msg_send(&m_send_tcp, tcp_socket->pid, 1, FID_RECV); return acknowledged_bytes; } @@ -83,7 +82,8 @@ void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socke if (getWaitingConnectionSocket(tcp_socket->socket_id)->local_tcp_status.state == SYN_RCVD) { - msg_send_receive(&m_send_tcp, &m_recv_tcp, tcp_socket->pid); + m_send_tcp.content.ptr = (char*)tcp_header; + net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->pid, FID_SOCKET_HANDLE_NEW_TCP_CON, FID_TCP_ACK); } printf("GOT REGULAR ACK FOR DATA!\n"); } @@ -121,7 +121,8 @@ void handle_tcp_syn_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, s msg_t m_recv_tcp, m_send_tcp; if (tcp_socket->in_socket.local_tcp_status.state == SYN_SENT) { - msg_send_receive(&m_send_tcp, &m_recv_tcp, tcp_socket->pid); + m_send_tcp.content.ptr = (char*) tcp_header; + net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->pid, FID_SOCKET_CONNECT, FID_TCP_SYN_ACK); } else { @@ -191,9 +192,11 @@ void tcp_packet_handler (void) while (1) { net_msg_receive(&m_recv_ip, FID_TCP_PH); - ipv6_header = ((ipv6_hdr_t*)&buffer_tcp); - tcp_header = ((tcp_hdr_t*)(&buffer_tcp[IPV6_HDR_LEN])); - payload = &buffer_tcp[IPV6_HDR_LEN+TCP_HDR_LEN]; + + ipv6_header = ((ipv6_hdr_t*)m_recv_ip.content.ptr); + tcp_header = ((tcp_hdr_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); + payload = (uint8_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN + TCP_HDR_LEN); + chksum = tcp_csum(ipv6_header, tcp_header); printf("Checksum is %x!\n", chksum); print_tcp_status(INC_PACKET, ipv6_header, tcp_header); diff --git a/sys/net/destiny/tcp.h b/sys/net/destiny/tcp.h index 4e235210ef..cd38162089 100644 --- a/sys/net/destiny/tcp.h +++ b/sys/net/destiny/tcp.h @@ -90,7 +90,7 @@ typedef struct __attribute__ ((packed)) tcp_h_t } tcp_hdr_t; -uint8_t buffer_tcp[BUFFER_SIZE]; +// uint8_t buffer_tcp[BUFFER_SIZE]; char tcp_stack_buffer[TCP_STACK_SIZE]; void tcp_packet_handler (void); diff --git a/sys/net/destiny/udp.c b/sys/net/destiny/udp.c index 84bd0a023d..47affb96bf 100644 --- a/sys/net/destiny/udp.c +++ b/sys/net/destiny/udp.c @@ -6,22 +6,12 @@ #include "udp.h" #include "msg.h" #include "sys/net/sixlowpan/sixlowip.h" +#include "sys/net/sixlowpan/sixlowpan.h" #include "socket.h" #include "in.h" #include "sys/net/net_help/net_help.h" #include "sys/net/net_help/msg_help.h" -void printArrayRange_udp(uint8_t *array, uint16_t len) - { - int i = 0; - printf("-------------MEMORY-------------\n"); - for (i = 0; i < len; i++) - { - printf("%#x ", *(array+i)); - } - printf("-------------MEMORY-------------\n"); - } - uint16_t udp_csum(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header) { uint16_t sum; @@ -45,9 +35,9 @@ void udp_packet_handler(void) while (1) { net_msg_receive(&m_recv_ip, FID_UDP_PH); - ipv6_header = ((ipv6_hdr_t*)&buffer_udp); - udp_header = ((udp_hdr_t*)(&buffer_udp[IPV6_HDR_LEN])); - payload = &buffer_udp[IPV6_HDR_LEN+UDP_HDR_LEN]; + ipv6_header = ((ipv6_hdr_t*)m_recv_ip.content.ptr); + udp_header = ((udp_hdr_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); + payload = (uint8_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN); chksum = udp_csum(ipv6_header, udp_header); @@ -56,6 +46,7 @@ void udp_packet_handler(void) udp_socket = get_udp_socket(ipv6_header, udp_header); if (udp_socket != NULL) { + m_send_udp.content.ptr = (char*)ipv6_header; net_msg_send_recv(&m_send_udp, &m_recv_udp, udp_socket->pid, FID_RECV_FROM, FID_UDP_PH); } else diff --git a/sys/net/destiny/udp.h b/sys/net/destiny/udp.h index 7f70873520..b6c059dc3d 100644 --- a/sys/net/destiny/udp.h +++ b/sys/net/destiny/udp.h @@ -23,11 +23,10 @@ typedef struct __attribute__ ((packed)) udp_h_t{ uint16_t checksum; } udp_hdr_t; -uint8_t buffer_udp[BUFFER_SIZE]; +// uint8_t buffer_udp[BUFFER_SIZE]; char udp_stack_buffer[UDP_STACK_SIZE]; uint16_t udp_csum(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header); void udp_packet_handler(void); -void printArrayRange_udp(uint8_t *array, uint16_t len); #endif /* UDP_H_ */ diff --git a/sys/net/net_help/msg_help.h b/sys/net/net_help/msg_help.h index 00a70e85bb..b36b555312 100644 --- a/sys/net/net_help/msg_help.h +++ b/sys/net/net_help/msg_help.h @@ -9,19 +9,23 @@ #define MSG_HELP_H_ // Function IDs -#define FID_SIXLOWIP_TCP 0 -#define FID_SIXLOWIP_UDP 1 -#define FID_TCP_PH 2 -#define FID_UDP_PH 3 -#define FID_H_PAYLOAD 4 -#define FID_RECV 5 -#define FID_RECV_FROM 6 - +#define FID_SIXLOWIP_TCP 0 +#define FID_SIXLOWIP_UDP 1 +#define FID_TCP_PH 2 +#define FID_UDP_PH 3 +#define FID_H_PAYLOAD 4 +#define FID_RECV 5 +#define FID_RECV_FROM 6 +#define FID_TCP_SYN_ACK 7 +#define FID_SOCKET_CONNECT 8 +#define FID_SOCKET_HANDLE_NEW_TCP_CON 9 +#define FID_TCP_ACK 10 int net_msg_receive(msg_t *m, uint16_t function_id); int net_msg_reply(msg_t *m, msg_t *reply, uint16_t function_id); int net_msg_send(msg_t *m, unsigned int pid, bool block, uint16_t function_id); +/* Target Function ID: function_id_m, Source Function ID: function_id_reply */ int net_msg_send_recv(msg_t *m, msg_t *reply, unsigned int pid, uint16_t function_id_m, uint16_t function_id_reply); #endif /* MSG_HELP_H_ */ diff --git a/sys/net/sixlowpan/sixlowip.c b/sys/net/sixlowpan/sixlowip.c index 9eae43088d..d05913f20d 100644 --- a/sys/net/sixlowpan/sixlowip.c +++ b/sys/net/sixlowpan/sixlowip.c @@ -22,8 +22,8 @@ iface_t iface; uint8_t iface_addr_list_count = 0; int udp_packet_handler_pid = 0; int tcp_packet_handler_pid = 0; -uint8_t *udp_packet_buffer; -uint8_t *tcp_packet_buffer; +//uint8_t *udp_packet_buffer; +//uint8_t *tcp_packet_buffer; //mutex_t buf_mutex; @@ -135,7 +135,7 @@ void ipv6_process(void){ if (tcp_packet_handler_pid != 0) { - memcpy(tcp_packet_buffer, (char*) ipv6_buf, IPV6_HDR_LEN+ipv6_buf->length); + m_send.content.ptr = (char*) ipv6_buf; net_msg_send_recv(&m_send, &m_recv, tcp_packet_handler_pid, FID_TCP_PH, FID_SIXLOWIP_TCP); } else @@ -150,7 +150,7 @@ void ipv6_process(void){ if (udp_packet_handler_pid != 0) { - memcpy(udp_packet_buffer, (char*) ipv6_buf, IPV6_HDR_LEN+ipv6_buf->length); + m_send.content.ptr = (char*) ipv6_buf; net_msg_send_recv(&m_send, &m_recv, udp_packet_handler_pid, FID_UDP_PH, FID_SIXLOWIP_UDP); } else @@ -457,14 +457,12 @@ uint8_t ipv6_is_router(void) { return 0; } -void set_tcp_packet_handler_pid(int pid, uint8_t *buf) +void set_tcp_packet_handler_pid(int pid) { tcp_packet_handler_pid = pid; - tcp_packet_buffer = buf; } -void set_udp_packet_handler_pid(int pid, uint8_t *buf) +void set_udp_packet_handler_pid(int pid) { udp_packet_handler_pid = pid; - udp_packet_buffer = buf; } diff --git a/sys/net/sixlowpan/sixlowip.h b/sys/net/sixlowpan/sixlowip.h index 9a82d713cd..e143997b48 100644 --- a/sys/net/sixlowpan/sixlowip.h +++ b/sys/net/sixlowpan/sixlowip.h @@ -125,9 +125,6 @@ typedef struct __attribute__ ((packed)) iface_t { extern iface_t iface; -//#define HTONS(a) (uint16_t)((((uint16_t) (a)) << 8) | (((uint16_t) (a)) >> 8)) - - /* function prototypes */ struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len); struct ipv6_hdr_t* get_ipv6_buf(void); @@ -164,6 +161,6 @@ void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix); uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr); uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr); uint8_t ipv6_next_hdr_unrec(uint8_t next_hdr); -void set_tcp_packet_handler_pid(int pid, uint8_t *buffer); -void set_udp_packet_handler_pid(int pid, uint8_t *buffer); +void set_tcp_packet_handler_pid(int pid); +void set_udp_packet_handler_pid(int pid); #endif /* SIXLOWIP_H*/ diff --git a/sys/net/sixlowpan/sixlowmac.h b/sys/net/sixlowpan/sixlowmac.h index 798bf3ea4d..1cdfaf3d94 100644 --- a/sys/net/sixlowpan/sixlowmac.h +++ b/sys/net/sixlowpan/sixlowmac.h @@ -9,7 +9,7 @@ #include "radio/radio.h" #include -#define RADIO_STACK_SIZE 2048 +#define RADIO_STACK_SIZE 3072 #define RADIO_RCV_BUF_SIZE 64 #define RADIO_SND_BUF_SIZE 100 #define RADIO_SENDING_DELAY 1000 @@ -22,6 +22,5 @@ void init_802154_long_addr(ieee_802154_long_t *laddr); void init_802154_short_addr(ieee_802154_short_t *saddr); void sixlowmac_init(transceiver_type_t type); ieee_802154_long_t* mac_get_eui(ipv6_addr_t *ipaddr); -// void send(void); #endif /* SIXLOWMAC_H*/ diff --git a/sys/net/sixlowpan/sixlowpan.c b/sys/net/sixlowpan/sixlowpan.c index 3985eaa7a3..d711e2f396 100644 --- a/sys/net/sixlowpan/sixlowpan.c +++ b/sys/net/sixlowpan/sixlowpan.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include "msg.h" #include "sixlowmac.h" #include "sixlowpan.h" @@ -33,6 +35,7 @@ uint8_t reas_buf[512]; uint8_t comp_buf[512]; uint8_t byte_offset; uint8_t first_frag = 0; +lowpan_reas_buf_t *head = NULL; unsigned int ip_process_pid; unsigned int nd_nbr_cache_rem_pid = 0; @@ -135,6 +138,268 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data){ tag++; } +void printArrayRange(uint8_t *array, uint16_t len, char *str) + { + int i = 0; + printf("-------------%s-------------\n", str); + for (i = 0; i < len; i++) + { + printf("%#x ", *(array+i)); + } + printf("\n--------------------------\n"); + } + +void printLongLocalAddr(ieee_802154_long_t *saddr) + { + char text[9]; + text[8] = '\0'; + memcpy(text, saddr, 8); + printf("Short Local Address: %s\n", text); + } + +void printReasBuffers() + { + lowpan_reas_buf_t *temp_buffer; + lowpan_interval_list_t *temp_interval; + temp_buffer = head; + + 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; + } + } + +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++){ + /* if bytes are equal add 8 */ + if(src->uint8[i] == dst->uint8[i]){ + val += 8; + } else { + xor = src->uint8[i] ^ dst->uint8[i]; + /* while bits from byte equal add 1 */ + for(int j = 0; j < 8; j++){ + if((xor & 0x80) == 0){ + val++; + xor = xor << 1; + } else { + break; + } + } + } + } + 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 *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; + } + + /* Allocate new memory for a new packet to be reassembled */ + new_buf = malloc(sizeof(lowpan_reas_buf_t)); + + if (new_buf != NULL) + { + 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); + + if ((current_buf == NULL) && (temp_buf == NULL)) + { + head = new_buf; + } + else + { + temp_buf->next = new_buf; + } + return new_buf; + } + else + { + return NULL; + } + } + else + { + return NULL; + } + } + +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 */ + /* 0: Interval 1 and 2 are not overlapping or the same */ + + if (((start1 < start2) && (start2 <= end1)) || + ((start2 < start1) && (start1 <= end2)) || + ((start1 == start2) && (end1 == end2))) + { + return 1; + } + else + { + return 0; + } + } + +uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf, uint8_t datagram_offset, uint8_t frag_size) + { + /* 0: Error, discard fragment */ + /* 1: Finished correctly */ + lowpan_interval_list_t *temp_interval = NULL, *current_interval = NULL, *new_interval = NULL; + current_interval = current_buf->interval_list_head; + while (current_interval != NULL) + { + if (isInInterval(current_interval->start, current_interval->end, datagram_offset, datagram_offset+frag_size) == 1) + { + /* Interval is overlapping or the same as one of a previous fragment, discard fragment */ + return 0; + } + temp_interval = current_interval; + current_interval = current_interval->next; + } + new_interval = malloc(sizeof(lowpan_interval_list_t)); + + if (new_interval != NULL) + { + new_interval->start = datagram_offset; + new_interval->end = datagram_offset+frag_size-1; + new_interval->next = NULL; + if ((current_interval == NULL) && (temp_interval == NULL)) + { + current_buf->interval_list_head = new_interval; + } + else + { + temp_interval->next = new_interval; + } + return 1; + } + + return 0; + } + +void collect_garbage(lowpan_reas_buf_t *current_buf) + { + lowpan_interval_list_t *temp_list, *current_list; + lowpan_reas_buf_t *temp_buf, *my_buf; + + 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; + } + + temp_buf = head; + my_buf = temp_buf; + + if (head == current_buf) + { + head = current_buf->next; + } + 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); + } + +void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset, uint16_t datagram_size, + uint16_t datagram_tag, ieee_802154_long_t *s_laddr, ieee_802154_long_t *d_laddr, + 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) + { + 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); + } + } + else + { + /* No memory left or duplicate */ + if (current_buf == NULL) + { + printf("ERROR: no memory left!\n"); + } + else + { + printf("ERROR: duplicate fragment!\n"); + } + } + } + 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 */ @@ -144,102 +409,68 @@ 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 first 5-bit*/ - switch(data[0] & 0xf8) { - /* first fragment */ - case(0xc0):{ - first_frag = 1; - datagram_offset = 0; - /* get 11-bit from first 2 byte*/ - datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff; - /* get 16-bit datagram tag */ - datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]); - /* discard fragment header */ - hdr_length += 4; - /* set global variable frag_size to size of decompr. packet*/ - frag_size = datagram_size; - /* check dispatch byte */ - switch(data[hdr_length]) { - case(LOWPAN_IPV6_DISPATCH):{ - break; - } - default: - break; - } - memcpy(reas_buf, data + hdr_length, length - 4); - break; - } - /* subsequent fragment */ - case(0xe0):{ - if(first_frag == 0){ - printf("ERROR: first fragment not received\n"); - break; - } + /* Fragmented Packet */ + if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) + { + /* get 11-bit from first 2 byte*/ + datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff; - /* get 11-bit from first 2 byte*/ - datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff; - /* get 16-bit datagram tag */ - datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]); - /* get 8-bit datagram offset */ - datagram_offset = data[4]; - /* discard framentation header */ - hdr_length += 5; - - frag_size = length - hdr_length; - byte_offset = datagram_offset * 8; - if((frag_size % 8) != 0){ - if((byte_offset + frag_size) != datagram_size){ - printf("ERROR: received invalid fragment\n"); - return; - } - } - memcpy(reas_buf + byte_offset, data + hdr_length, frag_size); - if((byte_offset + frag_size) == datagram_size){ - if(reas_buf[0] == LOWPAN_IPV6_DISPATCH) { - /* mutex lock here */ - // mutex_lock(&buf_mutex); - ipv6_buf = get_ipv6_buf(); - memcpy(ipv6_buf, reas_buf + 1, datagram_size - 1); - m.content.ptr = (char*) ipv6_buf; - packet_length = datagram_size - 1; - msg_send(&m,ip_process_pid, 1); - } else if((reas_buf[0] & 0xe0) == LOWPAN_IPHC_DISPATCH) { - /* mutex lock */ - // mutex_lock(&buf_mutex); - lowpan_iphc_decoding(reas_buf, 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"); - } - } - break; - } - default:{ - if(data[0] == LOWPAN_IPV6_DISPATCH){ - /* mutex lock here */ - // mutex_lock(&buf_mutex); - 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); - break; - } else if((data[0] & 0xe0) == LOWPAN_IPHC_DISPATCH){ - /* mutex lock here */ - // mutex_lock(&buf_mutex); - 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); - break; - } else { - printf("ERROR: packet with unknown dispatch received\n"); - break; - } - } - } + /* get 16-bit datagram tag */ + datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]); + + switch(data[0] & 0xf8) + { + /* First Fragment */ + case(0xc0): + { + datagram_offset = 0; + hdr_length += 4; + break; + } + /* Subsequent Fragment */ + case(0xe0): + { + datagram_offset = data[4]; + hdr_length += 5; + break; + } + } + frag_size = length - hdr_length; + byte_offset = datagram_offset * 8; + + if((frag_size % 8) != 0) + { + if((byte_offset + frag_size) != datagram_size) + { + printf("ERROR: received invalid fragment\n"); + return; + } + } + handle_packet_fragment(data, byte_offset, datagram_size, datagram_tag, s_laddr, d_laddr, hdr_length, frag_size); + } + /* Regular Packet */ + else + { + if(data[0] == LOWPAN_IPV6_DISPATCH) + { + 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"); + } + } } void lowpan_ipv6_set_dispatch(uint8_t *data){ @@ -953,6 +1184,18 @@ void lowpan_context_auto_remove(void) { } } +void init_reas_bufs(lowpan_reas_buf_t *buf) { + memset(&buf->s_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); + memset(&buf->d_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN); + buf->ident_no = 0; + buf->timestamp = 0; + buf->packet_size = 0; + buf->current_packet_size = 0; + buf->packet = NULL; + buf->interval_list_head = NULL; + buf->next = NULL; +} + void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border){ ipv6_addr_t tmp; /* init mac-layer and radio transceiver */ diff --git a/sys/net/sixlowpan/sixlowpan.h b/sys/net/sixlowpan/sixlowpan.h index 171961d1e5..47e626de75 100644 --- a/sys/net/sixlowpan/sixlowpan.h +++ b/sys/net/sixlowpan/sixlowpan.h @@ -1,7 +1,7 @@ #ifndef SIXLOWPAN_H #define SIXLOWPAN_H -#define IP_PROCESS_STACKSIZE 2048 +#define IP_PROCESS_STACKSIZE 3072 #define NC_STACKSIZE 512 #define CON_STACKSIZE 512 @@ -26,6 +26,7 @@ #include "sixlowip.h" #include #include +#include extern mutex_t lowpan_context_mutex; @@ -37,6 +38,26 @@ typedef struct lowpan_context_t { uint16_t lifetime; } lowpan_context_t; +typedef struct lowpan_interval_list_t { + uint8_t start; + uint8_t end; + struct lowpan_interval_list_t *next; +} lowpan_interval_list_t; + +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 + 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) +} lowpan_reas_buf_t; + +extern lowpan_reas_buf_t *head; + void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border); void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix, uint8_t r_addr); void lowpan_init(ieee_802154_long_t *addr, uint8_t *data); @@ -55,4 +76,6 @@ 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); void lowpan_ipv6_set_dispatch(uint8_t *data); +void init_reas_bufs(lowpan_reas_buf_t *buf); +void printReasBuffers(void); #endif diff --git a/sys/transceiver.c b/sys/transceiver.c index b3ddecc3bc..a41e6b1e8c 100644 --- a/sys/transceiver.c +++ b/sys/transceiver.c @@ -62,6 +62,11 @@ static void switch_to_rx(transceiver_type_t t); /* Transceiver init */ void transceiver_init(transceiver_type_t t) { uint8_t i; + + /* Initializing transceiver buffer and data buffer */ + memset(transceiver_buffer, 0, TRANSCEIVER_BUFFER_SIZE); + memset(data_buffer, 0, TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE); + for (i = 0; i < TRANSCEIVER_MAX_REGISTERED; i++) { reg[i].transceivers = TRANSCEIVER_NONE; reg[i].pid = 0;