diff --git a/include/config.h b/include/config.h index db4eda5..0b3fa44 100644 --- a/include/config.h +++ b/include/config.h @@ -6,9 +6,12 @@ #define UDT_VERSION 4 +#define MIN_DATA_SIZE (8 * sizeof(uint32_t)) #define MAX_DATA_SIZE 1024 #define MAX_PACKET_SIZE (4 * sizeof(uint32_t) + MAX_DATA_SIZE) +#define MAX_LOSS_SIZE 100 + /* comment the following definition to turn off debuf */ #define DEBUG 1 diff --git a/include/losslist.h b/include/losslist.h new file mode 100644 index 0000000..6a312c5 --- /dev/null +++ b/include/losslist.h @@ -0,0 +1,7 @@ +#ifndef LOSSLIST_H_OFAY39Z2 +#define LOSSLIST_H_OFAY39Z2 + +int loss_list_add (uint32_t); +int loss_list_remove (uint32_t); + +#endif /* end of include guard: LOSSLIST_H_OFAY39Z2 */ diff --git a/include/packet.h b/include/packet.h index 0c4b0c7..788938a 100644 --- a/include/packet.h +++ b/include/packet.h @@ -33,6 +33,12 @@ #define packet_get_type(PACKET) \ ((PACKET).header._head0 & PACKET_MASK_TYPE) +#define packet_get_seqnum(PACKET) \ + ((PACKET).header._head0 & PACKET_MASK_SEQ) + +#define packet_get_order(PACKET) \ + ((PACKET).header._head1 & 0x20000000) + #define packet_clear_header(PACKET) \ ((PACKET).header._head0 &= 0x00000000); \ ((PACKET).header._head1 &= 0x00000000); \ diff --git a/src/losslist.c b/src/losslist.c new file mode 100644 index 0000000..ba39a0d --- /dev/null +++ b/src/losslist.c @@ -0,0 +1,43 @@ +#include + +#include "losslist.h" +#include "config.h" + +static uint32_t loss_list[MAX_LOSS_SIZE]; +static int last = 0; + +int loss_list_getindex(uint32_t); + +/* TODO: Optimize this to not use O(n) time */ + +int loss_list_add(uint32_t seqnum) +{ + if (last >= MAX_LOSS_SIZE) return -1; + if (loss_list_getindex(seqnum) == -1) return -1; + + loss_list[last] = seqnum; + last++; + return 0; +} + +int loss_list_remove(uint32_t seqnum) +{ + int i; + i = loss_list_getindex(seqnum); + if (i == -1) return -1; + + for (; i < MAX_LOSS_SIZE - 1; ++i) { + loss_list[i] = loss_list[i + 1]; + } + + last--; + return 0; +} + +int loss_list_getindex(uint32_t seqnum) +{ + for (int i = 0; i < MAX_LOSS_SIZE; ++i) { + if (loss_list[i] == seqnum) return i; + } + return -1; +} diff --git a/src/packet.c b/src/packet.c index e1e63ea..e686258 100644 --- a/src/packet.c +++ b/src/packet.c @@ -9,6 +9,9 @@ #include "util.h" extern conn_t connection; +int last_packet = 0; + +#define loss_list_add(NUM) void packet_deserialize(packet_t *packet) { @@ -128,16 +131,47 @@ void packet_parse(packet_t packet) if (packet.header._head1 & 0x80000000 && packet.header._head1 & 0x40000000) /* solo packet */ + { + console_log_mod("%x: solo\n", packet_get_seqnum(packet)); recv_buffer_write(packet.data, PACKET_DATA_SIZE); - - else if (packet.header._head1 & 0x40000000) /* last packet */ - recv_buffer_write(packet.data, PACKET_DATA_SIZE); + } else if (packet.header._head1 & 0x80000000) /* first packet */ + { + console_log_mod("%x: first\n", packet_get_seqnum(packet)); + if (packet_get_order(packet)) + last_packet = packet_get_seqnum(packet); recv_buffer_write(packet.data, -1); + } else /* middle packet */ - recv_buffer_write(packet.data, -1); + { + if (packet_get_order(packet)) { + uint32_t seqnum = packet_get_seqnum(packet); + if (seqnum == last_packet + 1) { + console_log_mod("%x: correct\n", seqnum); + + if (packet.header._head1 & 0x40000000) /* last packet */ + recv_buffer_write(packet.data, PACKET_DATA_SIZE); + else + recv_buffer_write(packet.data, -1); + + last_packet++; + } else { + console_log_mod("%x: loss\n", seqnum); + uint32_t num = last_packet; + while (num < seqnum) { + packet_clear_header(packet); + packet_set_ctrl(packet); + packet_set_type(packet, PACKET_TYPE_NAK); + packet_new(&packet, (char *) &num, sizeof(uint32_t)); + send_packet_buffer_write(&packet); + loss_list_add(num); + num++; + } + } + } + } } return; }