diff --git a/sys/net/sixlowpan/Jamfile b/sys/net/sixlowpan/Jamfile index ea75100514..0304f037e7 100644 --- a/sys/net/sixlowpan/Jamfile +++ b/sys/net/sixlowpan/Jamfile @@ -2,7 +2,7 @@ SubDir TOP sys net sixlowpan ; # HDRS += $(TOP)/sys/net/sixlowpan/ ; -Module 6lowpan : sixlowpan.c sixlowip.c sixlowmac.c sixlownd.c sixlowborder.c ieee802154_frame.c serialnumber.c semaphore.c ; +Module 6lowpan : sixlowpan.c sixlowip.c sixlowmac.c sixlownd.c sixlowborder.c ieee802154_frame.c serialnumber.c semaphore.c flowcontrol.c ; UseModule vtimer ; UseModule transceiver ; diff --git a/sys/net/sixlowpan/flowcontrol.c b/sys/net/sixlowpan/flowcontrol.c new file mode 100644 index 0000000000..9e28ea7050 --- /dev/null +++ b/sys/net/sixlowpan/flowcontrol.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include + +#include "semaphore.h" +#include "bordermultiplex.h" + +flowcontrol_stat_t slwin_stat; +sem_t connection_established; +int16_t synack_seqnum = -1; + + +ipv6_addr_t init_threeway_handshake() { + border_syn_packet_t *syn; + msg_t m; + m.content.ptr = NULL; + msg_send(&m,border_get_serial_reader(),1); + while(1) { + msg_receive(&m); + + syn = (border_syn_packet_t *)m.content.ptr; + border_conf_header_t *synack = (border_conf_header_t *)get_serial_out_buffer(0); + ipv6_addr_t addr; + memcpy(&addr, &(syn->addr), sizeof (ipv6_addr_t)); + + slwin_stat.next_exp = syn->next_seq_num; + slwin_stat.last_frame = syn->next_exp - 1; + slwin_stat.last_ack = slwin_stat.last_frame; + + synack->reserved = 0; + synack->type = BORDER_PACKET_CONF_TYPE; + synack->conftype = BORDER_CONF_SYNACK; + + flowcontrol_send_over_uart((border_packet_t *)synack,sizeof (border_conf_header_t)); + + synack_seqnum = synack->seq_num; + + return addr; + } +} + +ipv6_addr_t flowcontrol_init() { + int i; + + slwin_stat.send_win_not_full = sem_init(BORDER_SWS); + for(i = 0; i < BORDER_SWS; i++) { + slwin_stat.send_win[i].frame_len = 0; + } + memset(&slwin_stat.send_win,0, sizeof(struct send_slot) * BORDER_SWS); + + for(i = 0; i < BORDER_RWS; i++) { + slwin_stat.recv_win[i].received = 0; + slwin_stat.recv_win[i].frame_len = 0; + } + memset(&slwin_stat.recv_win,0, sizeof(struct recv_slot) * BORDER_RWS); + + return init_threeway_handshake(); +} + +int set_timeout(vtimer_t *timeout, long useconds, void *args); + +void timeout_callback (void *args) { + uint8_t seq_num = *((uint8_t *)args); + struct send_slot *slot = &(slwin_stat.send_win[seq_num % BORDER_SWS]); + + if (seq_num == ((border_packet_t *)(slot->frame))->seq_num) { + writepacket(slot->frame,slot->frame_len); + + if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, args) != 0) { + printf("ERROR: Error invoking timeout timer\n"); + return; + } + } else { + return; + } +} + +int set_timeout(vtimer_t *timeout, long useconds, void *args) { + timex_t interval; + interval.seconds = useconds / 1000000; + interval.nanoseconds = (useconds % 1000000) * 1000; + + return vtimer_set_cb(timeout, interval, timeout_callback, args); +} + +static int in_window(uint8_t seq_num, uint8_t min, uint8_t max) { + uint8_t pos = seq_num - min; + uint8_t maxpos = max - min + 1; + return pos < maxpos; +} + +void flowcontrol_send_over_uart(border_packet_t *packet, int len) { + struct send_slot *slot; + uint8_t args[] = {packet->seq_num}; + + sem_wait(&(slwin_stat.send_win_not_full)); + packet->seq_num = ++slwin_stat.last_frame; + slot = &(slwin_stat.send_win[packet->seq_num % BORDER_SWS]); + memcpy(slot->frame, (uint8_t *)packet, len); + slot->frame_len = len; + if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)args) != 0) { + printf("ERROR: Error invoking timeout timer\n"); + return; + } + writepacket((uint8_t *)packet, len); +} + +void send_ack(uint8_t seq_num) { + border_packet_t *packet = (border_packet_t *)get_serial_out_buffer(0); + packet->reserved = 0; + packet->type = BORDER_PACKET_ACK_TYPE; + packet->seq_num = seq_num; + writepacket((uint8_t *)packet, sizeof (border_packet_t)); +} + +void flowcontrol_deliver_from_uart(border_packet_t *packet, int len) { + if (packet->type == BORDER_PACKET_ACK_TYPE) { + if (in_window(packet->seq_num, slwin_stat.last_ack+1, slwin_stat.last_frame)) { + if (synack_seqnum == packet->seq_num) { + synack_seqnum = -1; + sem_signal(&connection_established); + } + do { + struct send_slot *slot; + slot = &(slwin_stat.send_win[++slwin_stat.last_ack % BORDER_SWS]); + vtimer_remove(&slot->timeout); + memset(&slot->frame,0,BORDER_BUFFER_SIZE); + sem_signal(&slwin_stat.send_win_not_full); + } while (slwin_stat.last_ack != packet->seq_num); + } + } else { + struct recv_slot *slot; + + slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]); + if ( !in_window(packet->seq_num, + slwin_stat.next_exp, + slwin_stat.next_exp + BORDER_RWS - 1)) { + return; + } + + memcpy(slot->frame, (uint8_t *)packet, len); + slot->received = 1; + + if (packet->seq_num == slwin_stat.next_exp) { + while (slot->received) { + demultiplex((border_packet_t *)slot->frame, slot->frame_len); + memset(&slot->frame,0,BORDER_BUFFER_SIZE); + slot->received = 0; + slot = &slwin_stat.recv_win[++(slwin_stat.next_exp) % BORDER_RWS]; + } + } + + send_ack(slwin_stat.next_exp - 1); + } +} diff --git a/sys/net/sixlowpan/flowcontrol.h b/sys/net/sixlowpan/flowcontrol.h new file mode 100644 index 0000000000..a016268992 --- /dev/null +++ b/sys/net/sixlowpan/flowcontrol.h @@ -0,0 +1,55 @@ +#ifndef FLOWCONTROL_H +#define FLOWCONTROL_H + +#include +#include + +#include "semaphore.h" +#include "sixlowip.h" +#include "bordermultiplex.h" + +/* packet types for flowcontrol */ +#define BORDER_PACKET_ACK_TYPE 1 + +/* configuration types for flowcontrol */ +#define BORDER_CONF_SYN 0 +#define BORDER_CONF_SYNACK 1 + +#define BORDER_SWS 8 +#define BORDER_RWS 8 +#define BORDER_SL_TIMEOUT 500 // microseconds, maybe smaller + +typedef struct flowcontrol_stat_t { + /* Sender state */ + uint8_t last_ack; + uint8_t last_frame; + sem_t send_win_not_full; + struct send_slot { + vtimer_t timeout; + uint8_t frame[BORDER_BUFFER_SIZE]; + size_t frame_len; + } send_win[BORDER_SWS]; + + /* Receiver state */ + uint8_t next_exp; + struct recv_slot { + int8_t received; + uint8_t frame[BORDER_BUFFER_SIZE]; + size_t frame_len; + } recv_win[BORDER_RWS]; +} flowcontrol_stat_t; + +typedef struct __attribute__ ((packed)) border_syn_packet_t { + uint8_t reserved; + uint8_t type; + uint8_t next_seq_num; + uint8_t conftype; + uint8_t next_exp; + ipv6_addr_t addr; +} border_syn_packet_t; + +ipv6_addr_t flowcontrol_init(); +void flowcontrol_send_over_uart(border_packet_t *packet, int len); +void flowcontrol_deliver_from_uart(border_packet_t *packet, int len); + +#endif /* FLOWCONTROL_H*/ diff --git a/sys/net/sixlowpan/sixlowborder.c b/sys/net/sixlowpan/sixlowborder.c index d8526e48af..d20c22a20e 100644 --- a/sys/net/sixlowpan/sixlowborder.c +++ b/sys/net/sixlowpan/sixlowborder.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -9,6 +8,7 @@ #include #include #include "ieee802154_frame.h" +#include "flowcontrol.h" #include "sixlowborder.h" #include "sixlowip.h" #include "sixlownd.h" @@ -30,64 +30,11 @@ uint16_t serial_reader_pid; uint8_t serial_out_buf[BORDER_BUFFER_SIZE]; uint8_t serial_in_buf[BORDER_BUFFER_SIZE]; -flowcontrol_stat_t slwin_stat; -sem_t connection_established; -int16_t synack_seqnum = -1; -int readpacket(uint8_t *packet_buf, int size); - void serial_reader_f(void); -void flowcontrol_deliver_from_uart(border_packet_t *packet, int len); - -void slwin_init() { - int i; - - slwin_stat.send_win_not_full = sem_init(BORDER_SWS); - for(i = 0; i < BORDER_SWS; i++) { - slwin_stat.send_win[i].frame_len = 0; - } - memset(&slwin_stat.send_win,0, sizeof(struct send_slot) * BORDER_SWS); - - for(i = 0; i < BORDER_RWS; i++) { - slwin_stat.recv_win[i].received = 0; - slwin_stat.recv_win[i].frame_len = 0; - } - memset(&slwin_stat.recv_win,0, sizeof(struct recv_slot) * BORDER_RWS); -} - -ipv6_addr_t init_threeway_handshake() { - border_syn_packet_t *syn; - msg_t m; - m.content.ptr = NULL; - msg_send(&m,serial_reader_pid,1); - while(1) { - msg_receive(&m); - - syn = (border_syn_packet_t *)m.content.ptr; - border_conf_header_t *synack = (border_conf_header_t *)get_serial_out_buffer(0); - ipv6_addr_t addr; - memcpy(&addr, &(syn->addr), sizeof (ipv6_addr_t)); - - slwin_stat.next_exp = syn->next_seq_num; - slwin_stat.last_frame = syn->next_exp - 1; - slwin_stat.last_ack = slwin_stat.last_frame; - - synack->reserved = 0; - synack->type = BORDER_PACKET_CONF_TYPE; - synack->conftype = BORDER_CONF_SYNACK; - - flowcontrol_send_over_uart((border_packet_t *)synack,sizeof (border_conf_header_t)); - - synack_seqnum = synack->seq_num; - - return addr; - } -} uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_addr) { ipv6_addr_t addr; - slwin_init(); - serial_reader_pid = thread_create( serial_reader_stack, READER_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, @@ -96,7 +43,7 @@ uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_ad if (border_router_addr == NULL) { border_router_addr = &addr; - addr = init_threeway_handshake(); + addr = flowcontrol_init(); } /* only allow addresses generated accoding to @@ -270,38 +217,6 @@ void serial_reader_f(void) { } } -int set_timeout(vtimer_t *timeout, long useconds, void *args); - -void timeout_callback (void *args) { - uint8_t seq_num = *((uint8_t *)args); - struct send_slot *slot = &(slwin_stat.send_win[seq_num % BORDER_SWS]); - - if (seq_num == ((border_packet_t *)(slot->frame))->seq_num) { - writepacket(slot->frame,slot->frame_len); - - if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, args) != 0) { - printf("ERROR: Error invoking timeout timer\n"); - return; - } - } else { - return; - } -} - -int set_timeout(vtimer_t *timeout, long useconds, void *args) { - timex_t interval; - interval.seconds = useconds / 1000000; - interval.nanoseconds = (useconds % 1000000) * 1000; - - return vtimer_set_cb(timeout, interval, timeout_callback, args); -} - -static int in_window(uint8_t seq_num, uint8_t min, uint8_t max) { - uint8_t pos = seq_num - min; - uint8_t maxpos = max - min + 1; - return pos < maxpos; -} - void demultiplex(border_packet_t *packet, int len) { switch (packet->type) { case (BORDER_PACKET_RAW_TYPE):{ @@ -359,71 +274,6 @@ void demultiplex(border_packet_t *packet, int len) { } } -void border_send_ack(uint8_t seq_num) { - border_packet_t *packet = (border_packet_t *)get_serial_out_buffer(0); - packet->reserved = 0; - packet->type = BORDER_PACKET_ACK_TYPE; - packet->seq_num = seq_num; - writepacket((uint8_t *)packet, sizeof (border_packet_t)); -} - -void flowcontrol_deliver_from_uart(border_packet_t *packet, int len) { - if (packet->type == BORDER_PACKET_ACK_TYPE) { - if (in_window(packet->seq_num, slwin_stat.last_ack+1, slwin_stat.last_frame)) { - if (synack_seqnum == packet->seq_num) { - synack_seqnum = -1; - sem_signal(&connection_established); - } - do { - struct send_slot *slot; - slot = &(slwin_stat.send_win[++slwin_stat.last_ack % BORDER_SWS]); - vtimer_remove(&slot->timeout); - memset(&slot->frame,0,BORDER_BUFFER_SIZE); - sem_signal(&slwin_stat.send_win_not_full); - } while (slwin_stat.last_ack != packet->seq_num); - } - } else { - struct recv_slot *slot; - - slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]); - if ( !in_window(packet->seq_num, - slwin_stat.next_exp, - slwin_stat.next_exp + BORDER_RWS - 1)) { - return; - } - - memcpy(slot->frame, (uint8_t *)packet, len); - slot->received = 1; - - if (packet->seq_num == slwin_stat.next_exp) { - while (slot->received) { - demultiplex((border_packet_t *)slot->frame, slot->frame_len); - memset(&slot->frame,0,BORDER_BUFFER_SIZE); - slot->received = 0; - slot = &slwin_stat.recv_win[++(slwin_stat.next_exp) % BORDER_RWS]; - } - } - - border_send_ack(slwin_stat.next_exp - 1); - } -} - -void flowcontrol_send_over_uart(border_packet_t *packet, int len) { - struct send_slot *slot; - uint8_t args[] = {packet->seq_num}; - - sem_wait(&(slwin_stat.send_win_not_full)); - packet->seq_num = ++slwin_stat.last_frame; - slot = &(slwin_stat.send_win[packet->seq_num % BORDER_SWS]); - memcpy(slot->frame, (uint8_t *)packet, len); - slot->frame_len = len; - if (set_timeout(&slot->timeout, BORDER_SL_TIMEOUT, (void *)args) != 0) { - printf("ERROR: Error invoking timeout timer\n"); - return; - } - writepacket((uint8_t *)packet, len); -} - void multiplex_send_ipv6_over_uart(struct ipv6_hdr_t *packet) { border_l3_header_t *serial_buf; diff --git a/sys/net/sixlowpan/sixlowborder.h b/sys/net/sixlowpan/sixlowborder.h index 8e93072835..353c90a801 100644 --- a/sys/net/sixlowpan/sixlowborder.h +++ b/sys/net/sixlowpan/sixlowborder.h @@ -5,27 +5,17 @@ #include #include -#include #include "sixlowip.h" #include "sixlowpan.h" #include "sixlownd.h" #include "semaphore.h" -#define BORDER_SWS 8 -#define BORDER_RWS 8 -#define BORDER_SL_TIMEOUT 500 // microseconds, maybe smaller - -#define BORDER_HEADER_LENGTH 2 - /* packet types of uart-packets */ #define BORDER_PACKET_RAW_TYPE 0 -#define BORDER_PACKET_ACK_TYPE 1 #define BORDER_PACKET_CONF_TYPE 2 #define BORDER_PACKET_L3_TYPE 3 /* configuration types */ -#define BORDER_CONF_SYN 0 -#define BORDER_CONF_SYNACK 1 #define BORDER_CONF_CONTEXT 2 #define BORDER_CONF_IPADDR 3 @@ -52,15 +42,6 @@ typedef struct __attribute__ ((packed)) border_conf_header_t { uint8_t conftype; } border_conf_header_t; -typedef struct __attribute__ ((packed)) border_syn_packet_t { - uint8_t reserved; - uint8_t type; - uint8_t next_seq_num; - uint8_t conftype; - uint8_t next_exp; - ipv6_addr_t addr; -} border_syn_packet_t; - typedef struct __attribute__ ((packed)) border_addr_packet_t { uint8_t reserved; uint8_t type; @@ -85,34 +66,18 @@ typedef struct __attribute__ ((packed)) border_context_packet_t { #define BORDER_BUFFER_SIZE (sizeof (border_l3_header_t) + MTU) -typedef struct flowcontrol_stat_t { - /* Sender state */ - uint8_t last_ack; - uint8_t last_frame; - sem_t send_win_not_full; - struct send_slot { - vtimer_t timeout; - uint8_t frame[BORDER_BUFFER_SIZE]; - size_t frame_len; - } send_win[BORDER_SWS]; - - /* Receiver state */ - uint8_t next_exp; - struct recv_slot { - int8_t received; - uint8_t frame[BORDER_BUFFER_SIZE]; - size_t frame_len; - } recv_win[BORDER_RWS]; -} flowcontrol_stat_t; uint16_t border_get_serial_reader(); uint8_t *get_serial_out_buffer(int offset); uint8_t *get_serial_in_buffer(int offset); uint8_t border_initialize(transceiver_type_t trans,ipv6_addr_t *border_router_addr); +void demultiplex(border_packet_t *packet, int len); void multiplex_send_ipv6_over_uart(struct ipv6_hdr_t *packet); void multiplex_send_addr_over_uart(ipv6_addr_t *addr); -void flowcontrol_send_over_uart(border_packet_t *packet, int len); void border_send_ipv6_over_lowpan(struct ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag); void border_process_lowpan(void); +int readpacket(uint8_t *packet_buf, int size); +int writepacket(uint8_t *packet_buf, size_t size); + #endif /* SIXLOWBORDER_H*/