X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=rsdecoder.cpp;h=14527ca06cea226d9ad0dff1e1a458a0e82564a8;hb=a8e9b75339d48294145a9b102e43046a10b0bc36;hp=8a27896d8dedd70f2c3b8094e703a8c81eadd661;hpb=f873d7fa08ab2f48e5ca96a5b6d1b41724874b09;p=greproxy diff --git a/rsdecoder.cpp b/rsdecoder.cpp index 8a27896..14527ca 100644 --- a/rsdecoder.cpp +++ b/rsdecoder.cpp @@ -1,23 +1,20 @@ #include #include #include +#include #include #include "rsdecoder.h" #include "rs_parm.h" -extern "C" { -#include -} - #define RS_GROUP_HISTORY 3 using namespace std; RSDecoder::RSDecoder(Sender *sender) - : sender(sender) + : sender(sender), + rs(RS_PAYLOAD_SIZE, RS_GROUP_SIZE) { - rs = init_rs_char(RS_SYM_SIZE, RS_GF_POLY, 1, 1, RS_PARITY_SIZE, RS_PAD); } void RSDecoder::send_packet(uint16_t proto, const std::string &data, int incoming_seq) @@ -86,59 +83,49 @@ void RSDecoder::send_packet(uint16_t proto, const std::string &data, int incomin if (num_regular < RS_PAYLOAD_SIZE) { // Piece the data back into the different RS groups. vector padded_packets; - vector missing_packets; - for (int i = 0; i < RS_GROUP_SIZE; ++i) { - int packet_num = (i < RS_PAYLOAD_SIZE) ? rs_group * RS_PAYLOAD_SIZE + i : - rs_group * RS_PAYLOAD_SIZE - 1 - (i - RS_PAYLOAD_SIZE); + std::map shares; + for (const auto &packet_pair : group.packets) { + int packet_seq = packet_pair.first; + int share_num; string p; p.resize(max_length); - const auto it = group.packets.find(packet_num); - if (it == group.packets.end()) { - missing_packets.push_back(i); - } else { - const GREPacket &packet = it->second; + const GREPacket &packet = packet_pair.second; + if (packet_seq >= rs_group * RS_PAYLOAD_SIZE) { + // Regular packet. + share_num = packet_seq - rs_group * RS_PAYLOAD_SIZE; uint16_t proto_be = htons(packet.proto); memcpy(&p[0], &proto_be, sizeof(uint16_t)); uint16_t len_be = htons(packet.data.size()); memcpy(&p[2], &len_be, sizeof(uint16_t)); memcpy(&p[4], packet.data.data(), packet.data.size()); + } else { + // RS packet. + share_num = RS_PAYLOAD_SIZE + (rs_group * RS_PAYLOAD_SIZE - packet_seq - 1); + memcpy(&p[0], packet.data.data(), packet.data.size()); } padded_packets.push_back(p); - } - - // Now reconstruct the missing pieces. - unsigned char ch[RS_GROUP_SIZE]; - for (int i = 0; i < max_length; ++i) { - for (int j = 0; j < RS_GROUP_SIZE; ++j) { - ch[j] = padded_packets[j][i]; - } - int ret = decode_rs_char(rs, ch, &missing_packets[0], missing_packets.size()); - if (ret == -1) { - printf("Failed reconstruction!\n"); - // We might get more data later, so don't remove it. - return; - } - for (int j = 0; j < RS_GROUP_SIZE; ++j) { - padded_packets[j][i] = ch[j]; - } + shares[share_num] = reinterpret_cast(padded_packets.back().data()); } // Output all packets we didn't have before. They will come // out-of-order, which will be the job of the Reorderer to fix. - for (int i = 0; i < RS_PAYLOAD_SIZE; ++i) { - int packet_num = rs_group * RS_PAYLOAD_SIZE + i; - if (group.packets.count(packet_num) != 0) { + rs.decode(shares, max_length, [&](size_t share_num, size_t num_shares, const fecpp::byte data[], size_t len){ + if (shares.count(share_num)) { // Already had this packet. - continue; + return; } - const string &p = padded_packets[i]; + int packet_num = rs_group * RS_PAYLOAD_SIZE + share_num; uint16_t proto_be, len_be; - memcpy(&proto_be, &p[0], sizeof(uint16_t)); - memcpy(&len_be, &p[2], sizeof(uint16_t)); - string s(&p[4], &p[4 + ntohs(len_be)]); // TODO: security + memcpy(&proto_be, &data[0], sizeof(uint16_t)); + memcpy(&len_be, &data[2], sizeof(uint16_t)); + string s(&data[4], &data[4 + ntohs(len_be)]); // TODO: security sender->send_packet(ntohs(proto_be), s, packet_num); - printf("Reconstructed packet %d\n", packet_num); - } + const unsigned char *ptr = &data[4]; + printf("Reconstructed packet %d (proto=0x%04x len=%d, data=%02x %02x %02x %02x %02x %02x %02x %02x)\n", packet_num, + ntohs(proto_be), ntohs(len_be), + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]); + + }); } group.done = true;