3 #include <netinet/in.h>
6 #include <sys/select.h>
7 #include <sys/socket.h>
12 #include "reorderer.h"
13 #include "rsencoder.h"
20 RSEncoder::RSEncoder(Sender *sender)
23 rs = init_rs_char(RS_SYM_SIZE, RS_GF_POLY, 1, 1, RS_PARITY_SIZE, RS_PAD);
26 void RSEncoder::send_packet(uint16_t proto, const std::string &data, int incoming_seq)
28 if (!packet_history.empty() &&
29 incoming_seq <= packet_history.back().seq) {
30 // Reorderer should have done this for us.
33 if (!packet_history.empty() &&
34 incoming_seq / RS_PAYLOAD_SIZE !=
35 packet_history.back().seq / RS_PAYLOAD_SIZE) {
36 // Received an unfinished group.
37 packet_history.clear();
39 sender->send_packet(proto, data, incoming_seq);
40 packet_history.emplace_back(GREPacket{incoming_seq, proto, data});
41 if (packet_history.size() == RS_PAYLOAD_SIZE) {
46 void RSEncoder::finish_group()
48 // Our RS packets need to have the same max length as the longest one.
50 for (int i = 0; i < packet_history.size(); ++i) {
51 max_length = max<int>(max_length, packet_history[i].data.size());
54 vector<string> padded_packets;
55 for (int i = 0; i < packet_history.size(); ++i) {
57 p.resize(max_length + 4);
58 memset(&p[0], 0, max_length + 4);
59 uint16_t proto_be = htons(packet_history[i].proto);
60 memcpy(&p[0], &proto_be, sizeof(uint16_t));
61 uint16_t len_be = htons(packet_history[i].data.size());
62 memcpy(&p[2], &len_be, sizeof(uint16_t));
63 memcpy(&p[4], packet_history[i].data.data(), packet_history[i].data.size());
64 padded_packets.push_back(p);
67 // Now construct RS packets.
68 vector<string> rs_packets;
69 for (int i = 0; i < RS_PARITY_SIZE; ++i) {
71 p.resize(max_length + 4);
72 memset(&p[0], 0, max_length + 4);
73 rs_packets.push_back(p);
76 data.resize(RS_PAYLOAD_SIZE);
77 parity.resize(RS_PARITY_SIZE);
78 for (int i = 0; i < max_length + 4; ++i) {
79 for (int j = 0; j < packet_history.size(); ++j) {
80 data[j] = packet_history[j].data[i];
83 reinterpret_cast<unsigned char *>(&data[0]),
84 reinterpret_cast<unsigned char *>(&parity[0]));
85 for (int j = 0; j < RS_PARITY_SIZE; ++j) {
86 rs_packets[j][i] = parity[j];
90 // Actually send the RS packets.
91 int start_seq = packet_history[0].seq - 1;
92 for (int i = 0; i < RS_PARITY_SIZE; ++i) {
93 sender->send_packet(0xffff, rs_packets[i], start_seq - i);
96 packet_history.clear();