ngcext: parse ft1_have, ft1_bitset, pc1_announce
This commit is contained in:
parent
0eb30246a8
commit
c09f2e6f8f
@ -1,5 +1,6 @@
|
|||||||
#include "./ngcext.hpp"
|
#include "./ngcext.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
NGCEXTEventProvider::NGCEXTEventProvider(ToxEventProviderI& tep) : _tep(tep) {
|
NGCEXTEventProvider::NGCEXTEventProvider(ToxEventProviderI& tep) : _tep(tep) {
|
||||||
@ -261,6 +262,132 @@ bool NGCEXTEventProvider::parse_ft1_init_ack_v2(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NGCEXTEventProvider::parse_ft1_have(
|
||||||
|
uint32_t group_number, uint32_t peer_number,
|
||||||
|
const uint8_t* data, size_t data_size,
|
||||||
|
bool _private
|
||||||
|
) {
|
||||||
|
if (!_private) {
|
||||||
|
std::cerr << "NGCEXT: ft1_have cant be public\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Events::NGCEXT_ft1_have e;
|
||||||
|
e.group_number = group_number;
|
||||||
|
e.peer_number = peer_number;
|
||||||
|
size_t curser = 0;
|
||||||
|
|
||||||
|
// - 4 byte (file_kind)
|
||||||
|
e.file_kind = 0u;
|
||||||
|
_DATA_HAVE(sizeof(e.file_kind), std::cerr << "NGCEXT: packet too small, missing file_kind\n"; return false)
|
||||||
|
for (size_t i = 0; i < sizeof(e.file_kind); i++, curser++) {
|
||||||
|
e.file_kind |= uint32_t(data[curser]) << (i*8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - X bytes (file_kind dependent id, differnt sizes)
|
||||||
|
uint16_t file_id_size = 0u;
|
||||||
|
_DATA_HAVE(sizeof(file_id_size), std::cerr << "NGCEXT: packet too small, missing file_id_size\n"; return false)
|
||||||
|
for (size_t i = 0; i < sizeof(file_id_size); i++, curser++) {
|
||||||
|
file_id_size |= uint32_t(data[curser]) << (i*8);
|
||||||
|
}
|
||||||
|
|
||||||
|
_DATA_HAVE(file_id_size, std::cerr << "NGCEXT: packet too small, missing file_id, or file_id_size too large\n"; return false)
|
||||||
|
|
||||||
|
e.file_id = {data+curser, data+curser+file_id_size};
|
||||||
|
curser += file_id_size;
|
||||||
|
|
||||||
|
// - array [
|
||||||
|
// - 4 bytes (chunk index)
|
||||||
|
// - ]
|
||||||
|
while (curser < data_size) {
|
||||||
|
_DATA_HAVE(sizeof(uint32_t), std::cerr << "NGCEXT: packet too small, broken chunk index\n"; return false)
|
||||||
|
uint32_t chunk_index = 0u;
|
||||||
|
for (size_t i = 0; i < sizeof(chunk_index); i++, curser++) {
|
||||||
|
chunk_index |= uint32_t(data[curser]) << (i*8);
|
||||||
|
}
|
||||||
|
e.chunks.push_back(chunk_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dispatch(
|
||||||
|
NGCEXT_Event::FT1_HAVE,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NGCEXTEventProvider::parse_ft1_bitset(
|
||||||
|
uint32_t group_number, uint32_t peer_number,
|
||||||
|
const uint8_t* data, size_t data_size,
|
||||||
|
bool _private
|
||||||
|
) {
|
||||||
|
if (!_private) {
|
||||||
|
std::cerr << "NGCEXT: ft1_bitset cant be public\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Events::NGCEXT_ft1_bitset e;
|
||||||
|
e.group_number = group_number;
|
||||||
|
e.peer_number = peer_number;
|
||||||
|
size_t curser = 0;
|
||||||
|
|
||||||
|
// - 4 byte (file_kind)
|
||||||
|
e.file_kind = 0u;
|
||||||
|
_DATA_HAVE(sizeof(e.file_kind), std::cerr << "NGCEXT: packet too small, missing file_kind\n"; return false)
|
||||||
|
for (size_t i = 0; i < sizeof(e.file_kind); i++, curser++) {
|
||||||
|
e.file_kind |= uint32_t(data[curser]) << (i*8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - X bytes (file_kind dependent id, differnt sizes)
|
||||||
|
uint16_t file_id_size = 0u;
|
||||||
|
_DATA_HAVE(sizeof(file_id_size), std::cerr << "NGCEXT: packet too small, missing file_id_size\n"; return false)
|
||||||
|
for (size_t i = 0; i < sizeof(file_id_size); i++, curser++) {
|
||||||
|
file_id_size |= uint32_t(data[curser]) << (i*8);
|
||||||
|
}
|
||||||
|
|
||||||
|
_DATA_HAVE(file_id_size, std::cerr << "NGCEXT: packet too small, missing file_id, or file_id_size too large\n"; return false)
|
||||||
|
|
||||||
|
e.file_id = {data+curser, data+curser+file_id_size};
|
||||||
|
curser += file_id_size;
|
||||||
|
|
||||||
|
e.start_chunk = 0u;
|
||||||
|
_DATA_HAVE(sizeof(e.start_chunk), std::cerr << "NGCEXT: packet too small, missing start_chunk\n"; return false)
|
||||||
|
for (size_t i = 0; i < sizeof(e.start_chunk); i++, curser++) {
|
||||||
|
e.start_chunk |= uint32_t(data[curser]) << (i*8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - X bytes
|
||||||
|
// - array [
|
||||||
|
// - 1 bit (have chunk)
|
||||||
|
// - ] (filled up with zero)
|
||||||
|
// high to low?
|
||||||
|
// simply rest of file packet
|
||||||
|
e.chunk_bitset = {data+curser, data+curser+(data_size-curser)};
|
||||||
|
|
||||||
|
return dispatch(
|
||||||
|
NGCEXT_Event::FT1_BITSET,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NGCEXTEventProvider::parse_pc1_announce(
|
||||||
|
uint32_t group_number, uint32_t peer_number,
|
||||||
|
const uint8_t* data, size_t data_size,
|
||||||
|
bool _private
|
||||||
|
) {
|
||||||
|
// can be public
|
||||||
|
Events::NGCEXT_pc1_announce e;
|
||||||
|
e.group_number = group_number;
|
||||||
|
e.peer_number = peer_number;
|
||||||
|
size_t curser = 0;
|
||||||
|
|
||||||
|
// - X bytes (id, differnt sizes)
|
||||||
|
e.id = {data+curser, data+curser+(data_size-curser)};
|
||||||
|
|
||||||
|
return dispatch(
|
||||||
|
NGCEXT_Event::PC1_ANNOUNCE,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bool NGCEXTEventProvider::handlePacket(
|
bool NGCEXTEventProvider::handlePacket(
|
||||||
const uint32_t group_number,
|
const uint32_t group_number,
|
||||||
const uint32_t peer_number,
|
const uint32_t peer_number,
|
||||||
@ -292,6 +419,12 @@ bool NGCEXTEventProvider::handlePacket(
|
|||||||
return parse_ft1_data_ack(group_number, peer_number, data+1, data_size-1, _private);
|
return parse_ft1_data_ack(group_number, peer_number, data+1, data_size-1, _private);
|
||||||
case NGCEXT_Event::FT1_MESSAGE:
|
case NGCEXT_Event::FT1_MESSAGE:
|
||||||
return parse_ft1_message(group_number, peer_number, data+1, data_size-1, _private);
|
return parse_ft1_message(group_number, peer_number, data+1, data_size-1, _private);
|
||||||
|
case NGCEXT_Event::FT1_HAVE:
|
||||||
|
return parse_ft1_have(group_number, peer_number, data+1, data_size-1, _private);
|
||||||
|
case NGCEXT_Event::FT1_BITSET:
|
||||||
|
return parse_ft1_bitset(group_number, peer_number, data+1, data_size-1, _private);
|
||||||
|
case NGCEXT_Event::PC1_ANNOUNCE:
|
||||||
|
return parse_pc1_announce(group_number, peer_number, data+1, data_size-1, _private);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,6 @@ namespace Events {
|
|||||||
// - 4 byte (message_id)
|
// - 4 byte (message_id)
|
||||||
uint32_t message_id;
|
uint32_t message_id;
|
||||||
|
|
||||||
// request the other side to initiate a FT
|
|
||||||
// - 4 byte (file_kind)
|
// - 4 byte (file_kind)
|
||||||
uint32_t file_kind;
|
uint32_t file_kind;
|
||||||
|
|
||||||
@ -127,6 +126,49 @@ namespace Events {
|
|||||||
std::vector<uint8_t> file_id;
|
std::vector<uint8_t> file_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NGCEXT_ft1_have {
|
||||||
|
uint32_t group_number;
|
||||||
|
uint32_t peer_number;
|
||||||
|
|
||||||
|
// - 4 byte (file_kind)
|
||||||
|
uint32_t file_kind;
|
||||||
|
|
||||||
|
// - X bytes (file_kind dependent id, differnt sizes)
|
||||||
|
std::vector<uint8_t> file_id;
|
||||||
|
|
||||||
|
// - array [
|
||||||
|
// - 4 bytes (chunk index)
|
||||||
|
// - ]
|
||||||
|
std::vector<uint32_t> chunks;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NGCEXT_ft1_bitset {
|
||||||
|
uint32_t group_number;
|
||||||
|
uint32_t peer_number;
|
||||||
|
|
||||||
|
// - 4 byte (file_kind)
|
||||||
|
uint32_t file_kind;
|
||||||
|
|
||||||
|
// - X bytes (file_kind dependent id, differnt sizes)
|
||||||
|
std::vector<uint8_t> file_id;
|
||||||
|
|
||||||
|
uint32_t start_chunk;
|
||||||
|
|
||||||
|
// - array [
|
||||||
|
// - 1 bit (have chunk)
|
||||||
|
// - ] (filled up with zero)
|
||||||
|
// high to low?
|
||||||
|
std::vector<uint8_t> chunk_bitset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NGCEXT_pc1_announce {
|
||||||
|
uint32_t group_number;
|
||||||
|
uint32_t peer_number;
|
||||||
|
|
||||||
|
// - X bytes (id, differnt sizes)
|
||||||
|
std::vector<uint8_t> id;
|
||||||
|
};
|
||||||
|
|
||||||
} // Events
|
} // Events
|
||||||
|
|
||||||
enum class NGCEXT_Event : uint8_t {
|
enum class NGCEXT_Event : uint8_t {
|
||||||
@ -186,11 +228,44 @@ enum class NGCEXT_Event : uint8_t {
|
|||||||
// send file as message
|
// send file as message
|
||||||
// basically the opposite of request
|
// basically the opposite of request
|
||||||
// contains file_kind and file_id (and timestamp?)
|
// contains file_kind and file_id (and timestamp?)
|
||||||
// - 4 byte (message_id)
|
// - 4 bytes (message_id)
|
||||||
// - 4 byte (file_kind)
|
// - 4 bytes (file_kind)
|
||||||
// - X bytes (file_kind dependent id, differnt sizes)
|
// - X bytes (file_kind dependent id, differnt sizes)
|
||||||
FT1_MESSAGE,
|
FT1_MESSAGE,
|
||||||
|
|
||||||
|
// announce you have specified chunks, for given info
|
||||||
|
// this is info/chunk specific
|
||||||
|
// bundle these together to reduce overhead (like maybe every 16, max 1min)
|
||||||
|
// - 4 bytes (file_kind)
|
||||||
|
// - X bytes (file_kind dependent id, differnt sizes)
|
||||||
|
// - array [
|
||||||
|
// - 4 bytes (chunk index)
|
||||||
|
// - ]
|
||||||
|
FT1_HAVE,
|
||||||
|
|
||||||
|
// tell the other peer which chunks, for a given info you have
|
||||||
|
// compressed down to a bitset (in parts)
|
||||||
|
// supposed to only be sent once on participation announcement, when mutual interest
|
||||||
|
// it is always assumed by the other side, that you dont have the chunk, until told otherwise,
|
||||||
|
// so you can be smart about what you send.
|
||||||
|
// - 4 bytes (file_kind)
|
||||||
|
// - X bytes (file_kind dependent id, differnt sizes)
|
||||||
|
// - 4 bytes (first chunk index in bitset)
|
||||||
|
// - array [
|
||||||
|
// - 1 bit (have chunk)
|
||||||
|
// - ] (filled up with zero)
|
||||||
|
FT1_BITSET,
|
||||||
|
|
||||||
|
// TODO: FT1_IDONTHAVE, tell a peer you no longer have said chunk
|
||||||
|
// TODO: FT1_REJECT, tell a peer you wont fulfil the request
|
||||||
|
|
||||||
|
// tell another peer that you are participating in X
|
||||||
|
// you can reply with PC1_ANNOUNCE, to let the other side know, you too are participating in X
|
||||||
|
// you should NOT announce often, since this hits peers that not participate
|
||||||
|
// ft1 uses fk+id
|
||||||
|
// - x bytes (id, different sizes)
|
||||||
|
PC1_ANNOUNCE = 0x80 | 32u,
|
||||||
|
|
||||||
MAX
|
MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -204,6 +279,9 @@ struct NGCEXTEventI {
|
|||||||
virtual bool onEvent(const Events::NGCEXT_ft1_data&) { return false; }
|
virtual bool onEvent(const Events::NGCEXT_ft1_data&) { return false; }
|
||||||
virtual bool onEvent(const Events::NGCEXT_ft1_data_ack&) { return false; }
|
virtual bool onEvent(const Events::NGCEXT_ft1_data_ack&) { return false; }
|
||||||
virtual bool onEvent(const Events::NGCEXT_ft1_message&) { return false; }
|
virtual bool onEvent(const Events::NGCEXT_ft1_message&) { return false; }
|
||||||
|
virtual bool onEvent(const Events::NGCEXT_ft1_have&) { return false; }
|
||||||
|
virtual bool onEvent(const Events::NGCEXT_ft1_bitset&) { return false; }
|
||||||
|
virtual bool onEvent(const Events::NGCEXT_pc1_announce&) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
using NGCEXTEventProviderI = EventProviderI<NGCEXTEventI>;
|
using NGCEXTEventProviderI = EventProviderI<NGCEXTEventI>;
|
||||||
@ -269,6 +347,24 @@ class NGCEXTEventProvider : public ToxEventI, public NGCEXTEventProviderI {
|
|||||||
bool _private
|
bool _private
|
||||||
);
|
);
|
||||||
|
|
||||||
|
bool parse_ft1_have(
|
||||||
|
uint32_t group_number, uint32_t peer_number,
|
||||||
|
const uint8_t* data, size_t data_size,
|
||||||
|
bool _private
|
||||||
|
);
|
||||||
|
|
||||||
|
bool parse_ft1_bitset(
|
||||||
|
uint32_t group_number, uint32_t peer_number,
|
||||||
|
const uint8_t* data, size_t data_size,
|
||||||
|
bool _private
|
||||||
|
);
|
||||||
|
|
||||||
|
bool parse_pc1_announce(
|
||||||
|
uint32_t group_number, uint32_t peer_number,
|
||||||
|
const uint8_t* data, size_t data_size,
|
||||||
|
bool _private
|
||||||
|
);
|
||||||
|
|
||||||
bool handlePacket(
|
bool handlePacket(
|
||||||
const uint32_t group_number,
|
const uint32_t group_number,
|
||||||
const uint32_t peer_number,
|
const uint32_t peer_number,
|
||||||
|
Loading…
Reference in New Issue
Block a user