Compare commits
7 Commits
broken_som
...
3827733f08
Author | SHA1 | Date | |
---|---|---|---|
3827733f08 | |||
5400c13f88 | |||
8972386971 | |||
b27107af4c | |||
bcde244a3c | |||
e9f22bc9ae | |||
c09f2e6f8f |
@ -1,8 +1,9 @@
|
||||
#include "./ngcext.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
NGCEXTEventProvider::NGCEXTEventProvider(ToxEventProviderI& tep) : _tep(tep) {
|
||||
NGCEXTEventProvider::NGCEXTEventProvider(ToxI& t, ToxEventProviderI& tep) : _t(t), _tep(tep) {
|
||||
_tep.subscribe(this, Tox_Event_Type::TOX_EVENT_GROUP_CUSTOM_PACKET);
|
||||
_tep.subscribe(this, Tox_Event_Type::TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET);
|
||||
}
|
||||
@ -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(
|
||||
const uint32_t group_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);
|
||||
case NGCEXT_Event::FT1_MESSAGE:
|
||||
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:
|
||||
return false;
|
||||
}
|
||||
@ -299,6 +432,183 @@ bool NGCEXTEventProvider::handlePacket(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_ft1_request(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint32_t file_kind,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
) {
|
||||
// - 1 byte packet id
|
||||
// - 4 byte file_kind
|
||||
// - X bytes file_id
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_REQUEST));
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
pkg.push_back((file_kind>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < file_id_size; i++) {
|
||||
pkg.push_back(file_id[i]);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_ft1_init(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint32_t file_kind,
|
||||
uint64_t file_size,
|
||||
uint8_t transfer_id,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
) {
|
||||
// - 1 byte packet id
|
||||
// - 4 byte (file_kind)
|
||||
// - 8 bytes (data size)
|
||||
// - 1 byte (temporary_file_tf_id, for this peer only, technically just a prefix to distinguish between simultainious fts)
|
||||
// - X bytes (file_kind dependent id, differnt sizes)
|
||||
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_INIT));
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
pkg.push_back((file_kind>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(file_size); i++) {
|
||||
pkg.push_back((file_size>>(i*8)) & 0xff);
|
||||
}
|
||||
pkg.push_back(transfer_id);
|
||||
for (size_t i = 0; i < file_id_size; i++) {
|
||||
pkg.push_back(file_id[i]);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_ft1_init_ack(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id
|
||||
) {
|
||||
// - 1 byte packet id
|
||||
// - 1 byte transfer_id
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_INIT_ACK));
|
||||
pkg.push_back(transfer_id);
|
||||
|
||||
// - 2 bytes max_lossy_data_size
|
||||
const uint16_t max_lossy_data_size = _t.toxGroupMaxCustomLossyPacketLength() - 4;
|
||||
for (size_t i = 0; i < sizeof(uint16_t); i++) {
|
||||
pkg.push_back((max_lossy_data_size>>(i*8)) & 0xff);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_ft1_data(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id,
|
||||
uint16_t sequence_id,
|
||||
const uint8_t* data, size_t data_size
|
||||
) {
|
||||
assert(data_size > 0);
|
||||
|
||||
// TODO
|
||||
// check header_size+data_size <= max pkg size
|
||||
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.reserve(2048); // saves a ton of allocations
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_DATA));
|
||||
pkg.push_back(transfer_id);
|
||||
pkg.push_back(sequence_id & 0xff);
|
||||
pkg.push_back((sequence_id >> (1*8)) & 0xff);
|
||||
|
||||
// TODO: optimize
|
||||
for (size_t i = 0; i < data_size; i++) {
|
||||
pkg.push_back(data[i]);
|
||||
}
|
||||
|
||||
// lossy
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, false, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_ft1_data_ack(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id,
|
||||
const uint16_t* seq_ids, size_t seq_ids_size
|
||||
) {
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.reserve(1+1+2*32); // 32acks in a single pkg should be unlikely
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_DATA_ACK));
|
||||
pkg.push_back(transfer_id);
|
||||
|
||||
// TODO: optimize
|
||||
for (size_t i = 0; i < seq_ids_size; i++) {
|
||||
pkg.push_back(seq_ids[i] & 0xff);
|
||||
pkg.push_back((seq_ids[i] >> (1*8)) & 0xff);
|
||||
}
|
||||
|
||||
// lossy
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, false, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_all_ft1_message(
|
||||
uint32_t group_number,
|
||||
uint32_t message_id,
|
||||
uint32_t file_kind,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
) {
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_MESSAGE));
|
||||
|
||||
for (size_t i = 0; i < sizeof(message_id); i++) {
|
||||
pkg.push_back((message_id>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
pkg.push_back((file_kind>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < file_id_size; i++) {
|
||||
pkg.push_back(file_id[i]);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPacket(group_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PACKET_OK;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> build_pc1_announce(const uint8_t* id_data, size_t id_size) {
|
||||
// - 1 byte packet id
|
||||
// - X bytes (id, differnt sizes)
|
||||
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::PC1_ANNOUNCE));
|
||||
for (size_t i = 0; i < id_size; i++) {
|
||||
pkg.push_back(id_data[i]);
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_pc1_announce(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
const uint8_t* id_data, size_t id_size
|
||||
) {
|
||||
auto pkg = build_pc1_announce(id_data, id_size);
|
||||
|
||||
std::cout << "NEEP: sending PC1_ANNOUNCE s:" << pkg.size() - sizeof(NGCEXT_Event::PC1_ANNOUNCE) << "\n";
|
||||
|
||||
// lossless?
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::send_all_pc1_announce(
|
||||
uint32_t group_number,
|
||||
const uint8_t* id_data, size_t id_size
|
||||
) {
|
||||
auto pkg = build_pc1_announce(id_data, id_size);
|
||||
|
||||
std::cout << "NEEP: sending all PC1_ANNOUNCE s:" << pkg.size() - sizeof(NGCEXT_Event::PC1_ANNOUNCE) << "\n";
|
||||
|
||||
// lossless?
|
||||
return _t.toxGroupSendCustomPacket(group_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCEXTEventProvider::onToxEvent(const Tox_Event_Group_Custom_Packet* e) {
|
||||
const auto group_number = tox_event_group_custom_packet_get_group_number(e);
|
||||
const auto peer_number = tox_event_group_custom_packet_get_peer_id(e);
|
||||
|
@ -3,6 +3,7 @@
|
||||
// solanaceae port of tox_ngc_ext
|
||||
|
||||
#include <solanaceae/toxcore/tox_event_interface.hpp>
|
||||
#include <solanaceae/toxcore/tox_interface.hpp>
|
||||
#include <solanaceae/util/event_provider.hpp>
|
||||
|
||||
#include <solanaceae/toxcore/tox_key.hpp>
|
||||
@ -119,7 +120,6 @@ namespace Events {
|
||||
// - 4 byte (message_id)
|
||||
uint32_t message_id;
|
||||
|
||||
// request the other side to initiate a FT
|
||||
// - 4 byte (file_kind)
|
||||
uint32_t file_kind;
|
||||
|
||||
@ -127,6 +127,49 @@ namespace Events {
|
||||
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
|
||||
|
||||
enum class NGCEXT_Event : uint8_t {
|
||||
@ -186,11 +229,44 @@ enum class NGCEXT_Event : uint8_t {
|
||||
// send file as message
|
||||
// basically the opposite of request
|
||||
// contains file_kind and file_id (and timestamp?)
|
||||
// - 4 byte (message_id)
|
||||
// - 4 byte (file_kind)
|
||||
// - 4 bytes (message_id)
|
||||
// - 4 bytes (file_kind)
|
||||
// - X bytes (file_kind dependent id, differnt sizes)
|
||||
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
|
||||
};
|
||||
|
||||
@ -204,15 +280,19 @@ struct NGCEXTEventI {
|
||||
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_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>;
|
||||
|
||||
class NGCEXTEventProvider : public ToxEventI, public NGCEXTEventProviderI {
|
||||
ToxI& _t;
|
||||
ToxEventProviderI& _tep;
|
||||
|
||||
public:
|
||||
NGCEXTEventProvider(ToxEventProviderI& tep/*, ToxI& t*/);
|
||||
NGCEXTEventProvider(ToxI& t, ToxEventProviderI& tep);
|
||||
|
||||
protected:
|
||||
bool parse_hs1_request_last_ids(
|
||||
@ -269,6 +349,24 @@ class NGCEXTEventProvider : public ToxEventI, public NGCEXTEventProviderI {
|
||||
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(
|
||||
const uint32_t group_number,
|
||||
const uint32_t peer_number,
|
||||
@ -277,6 +375,57 @@ class NGCEXTEventProvider : public ToxEventI, public NGCEXTEventProviderI {
|
||||
const bool _private
|
||||
);
|
||||
|
||||
public: // send api
|
||||
bool send_ft1_request(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint32_t file_kind,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
);
|
||||
|
||||
bool send_ft1_init(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint32_t file_kind,
|
||||
uint64_t file_size,
|
||||
uint8_t transfer_id,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
);
|
||||
|
||||
bool send_ft1_init_ack(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id
|
||||
);
|
||||
|
||||
bool send_ft1_data(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id,
|
||||
uint16_t sequence_id,
|
||||
const uint8_t* data, size_t data_size
|
||||
);
|
||||
|
||||
bool send_ft1_data_ack(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id,
|
||||
const uint16_t* seq_ids, size_t seq_ids_size
|
||||
);
|
||||
|
||||
// TODO: add private version
|
||||
bool send_all_ft1_message(
|
||||
uint32_t group_number,
|
||||
uint32_t message_id,
|
||||
uint32_t file_kind,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
);
|
||||
|
||||
bool send_pc1_announce(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
const uint8_t* id_data, size_t id_size
|
||||
);
|
||||
|
||||
bool send_all_pc1_announce(
|
||||
uint32_t group_number,
|
||||
const uint8_t* id_data, size_t id_size
|
||||
);
|
||||
|
||||
protected:
|
||||
bool onToxEvent(const Tox_Event_Group_Custom_Packet* e) override;
|
||||
bool onToxEvent(const Tox_Event_Group_Custom_Private_Packet* e) override;
|
||||
|
@ -15,147 +15,6 @@
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
bool NGCFT1::sendPKG_FT1_REQUEST(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint32_t file_kind,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
) {
|
||||
// - 1 byte packet id
|
||||
// - 4 byte file_kind
|
||||
// - X bytes file_id
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_REQUEST));
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
pkg.push_back((file_kind>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < file_id_size; i++) {
|
||||
pkg.push_back(file_id[i]);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCFT1::sendPKG_FT1_INIT(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint32_t file_kind,
|
||||
uint64_t file_size,
|
||||
uint8_t transfer_id,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
) {
|
||||
// - 1 byte packet id
|
||||
// - 4 byte (file_kind)
|
||||
// - 8 bytes (data size)
|
||||
// - 1 byte (temporary_file_tf_id, for this peer only, technically just a prefix to distinguish between simultainious fts)
|
||||
// - X bytes (file_kind dependent id, differnt sizes)
|
||||
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_INIT));
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
pkg.push_back((file_kind>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(file_size); i++) {
|
||||
pkg.push_back((file_size>>(i*8)) & 0xff);
|
||||
}
|
||||
pkg.push_back(transfer_id);
|
||||
for (size_t i = 0; i < file_id_size; i++) {
|
||||
pkg.push_back(file_id[i]);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCFT1::sendPKG_FT1_INIT_ACK(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id
|
||||
) {
|
||||
// - 1 byte packet id
|
||||
// - 1 byte transfer_id
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_INIT_ACK));
|
||||
pkg.push_back(transfer_id);
|
||||
|
||||
// - 2 bytes max_lossy_data_size
|
||||
const uint16_t max_lossy_data_size = _t.toxGroupMaxCustomLossyPacketLength() - 4;
|
||||
for (size_t i = 0; i < sizeof(uint16_t); i++) {
|
||||
pkg.push_back((max_lossy_data_size>>(i*8)) & 0xff);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCFT1::sendPKG_FT1_DATA(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id,
|
||||
uint16_t sequence_id,
|
||||
const uint8_t* data, size_t data_size
|
||||
) {
|
||||
assert(data_size > 0);
|
||||
|
||||
// TODO
|
||||
// check header_size+data_size <= max pkg size
|
||||
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.reserve(2048); // saves a ton of allocations
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_DATA));
|
||||
pkg.push_back(transfer_id);
|
||||
pkg.push_back(sequence_id & 0xff);
|
||||
pkg.push_back((sequence_id >> (1*8)) & 0xff);
|
||||
|
||||
// TODO: optimize
|
||||
for (size_t i = 0; i < data_size; i++) {
|
||||
pkg.push_back(data[i]);
|
||||
}
|
||||
|
||||
// lossy
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, false, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCFT1::sendPKG_FT1_DATA_ACK(
|
||||
uint32_t group_number, uint32_t peer_number,
|
||||
uint8_t transfer_id,
|
||||
const uint16_t* seq_ids, size_t seq_ids_size
|
||||
) {
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.reserve(1+1+2*32); // 32acks in a single pkg should be unlikely
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_DATA_ACK));
|
||||
pkg.push_back(transfer_id);
|
||||
|
||||
// TODO: optimize
|
||||
for (size_t i = 0; i < seq_ids_size; i++) {
|
||||
pkg.push_back(seq_ids[i] & 0xff);
|
||||
pkg.push_back((seq_ids[i] >> (1*8)) & 0xff);
|
||||
}
|
||||
|
||||
// lossy
|
||||
return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, false, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK;
|
||||
}
|
||||
|
||||
bool NGCFT1::sendPKG_FT1_MESSAGE(
|
||||
uint32_t group_number,
|
||||
uint32_t message_id,
|
||||
uint32_t file_kind,
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
) {
|
||||
std::vector<uint8_t> pkg;
|
||||
pkg.push_back(static_cast<uint8_t>(NGCEXT_Event::FT1_MESSAGE));
|
||||
|
||||
for (size_t i = 0; i < sizeof(message_id); i++) {
|
||||
pkg.push_back((message_id>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
pkg.push_back((file_kind>>(i*8)) & 0xff);
|
||||
}
|
||||
for (size_t i = 0; i < file_id_size; i++) {
|
||||
pkg.push_back(file_id[i]);
|
||||
}
|
||||
|
||||
// lossless
|
||||
return _t.toxGroupSendCustomPacket(group_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PACKET_OK;
|
||||
}
|
||||
|
||||
void NGCFT1::updateSendTransfer(float time_delta, uint32_t group_number, uint32_t peer_number, Group::Peer& peer, size_t idx, std::set<CCAI::SeqIDType>& timeouts_set, int64_t& can_packet_size) {
|
||||
auto& tf_opt = peer.send_transfers.at(idx);
|
||||
assert(tf_opt.has_value());
|
||||
@ -181,7 +40,8 @@ void NGCFT1::updateSendTransfer(float time_delta, uint32_t group_number, uint32_
|
||||
} else {
|
||||
// timed out, resend
|
||||
std::cerr << "NGCFT1 warning: ft init timed out, resending\n";
|
||||
sendPKG_FT1_INIT(group_number, peer_number, tf.file_kind, tf.file_size, idx, tf.file_id.data(), tf.file_id.size());
|
||||
//sendPKG_FT1_INIT(group_number, peer_number, tf.file_kind, tf.file_size, idx, tf.file_id.data(), tf.file_id.size());
|
||||
_neep.send_ft1_init(group_number, peer_number, tf.file_kind, tf.file_size, idx, tf.file_id.data(), tf.file_id.size());
|
||||
tf.inits_sent++;
|
||||
tf.time_since_activity = 0.f;
|
||||
}
|
||||
@ -191,7 +51,7 @@ void NGCFT1::updateSendTransfer(float time_delta, uint32_t group_number, uint32_
|
||||
case State::FINISHING: // we still have unacked packets
|
||||
tf.ssb.for_each(time_delta, [&](uint16_t id, const std::vector<uint8_t>& data, float& time_since_activity) {
|
||||
if (can_packet_size >= data.size() && timeouts_set.count({idx, id})) {
|
||||
sendPKG_FT1_DATA(group_number, peer_number, idx, id, data.data(), data.size());
|
||||
_neep.send_ft1_data(group_number, peer_number, idx, id, data.data(), data.size());
|
||||
peer.cca->onLoss({idx, id}, false);
|
||||
time_since_activity = 0.f;
|
||||
timeouts_set.erase({idx, id});
|
||||
@ -241,7 +101,7 @@ void NGCFT1::updateSendTransfer(float time_delta, uint32_t group_number, uint32_
|
||||
tf.ssb.for_each(time_delta, [&](uint16_t id, const std::vector<uint8_t>& data, float& time_since_activity) {
|
||||
if (can_packet_size >= data.size() && time_since_activity >= peer.cca->getCurrentDelay() && timeouts_set.count({idx, id})) {
|
||||
// TODO: can fail
|
||||
sendPKG_FT1_DATA(group_number, peer_number, idx, id, data.data(), data.size());
|
||||
_neep.send_ft1_data(group_number, peer_number, idx, id, data.data(), data.size());
|
||||
peer.cca->onLoss({idx, id}, false);
|
||||
time_since_activity = 0.f;
|
||||
timeouts_set.erase({idx, id});
|
||||
@ -278,7 +138,7 @@ void NGCFT1::updateSendTransfer(float time_delta, uint32_t group_number, uint32_
|
||||
);
|
||||
|
||||
uint16_t seq_id = tf.ssb.add(std::move(new_data));
|
||||
const bool sent = sendPKG_FT1_DATA(group_number, peer_number, idx, seq_id, tf.ssb.entries.at(seq_id).data.data(), tf.ssb.entries.at(seq_id).data.size());
|
||||
const bool sent = _neep.send_ft1_data(group_number, peer_number, idx, seq_id, tf.ssb.entries.at(seq_id).data.data(), tf.ssb.entries.at(seq_id).data.size());
|
||||
if (sent) {
|
||||
peer.cca->onSent({idx, seq_id}, chunk_size);
|
||||
} else {
|
||||
@ -338,7 +198,7 @@ void NGCFT1::iteratePeer(float time_delta, uint32_t group_number, uint32_t peer_
|
||||
NGCFT1::NGCFT1(
|
||||
ToxI& t,
|
||||
ToxEventProviderI& tep,
|
||||
NGCEXTEventProviderI& neep
|
||||
NGCEXTEventProvider& neep
|
||||
) : _t(t), _tep(tep), _neep(neep)
|
||||
{
|
||||
_neep.subscribe(this, NGCEXT_Event::FT1_REQUEST);
|
||||
@ -392,7 +252,7 @@ void NGCFT1::NGC_FT1_send_request_private(
|
||||
const uint8_t* file_id, size_t file_id_size
|
||||
) {
|
||||
// TODO: error check
|
||||
sendPKG_FT1_REQUEST(group_number, peer_number, file_kind, file_id, file_id_size);
|
||||
_neep.send_ft1_request(group_number, peer_number, file_kind, file_id, file_id_size);
|
||||
}
|
||||
|
||||
bool NGCFT1::NGC_FT1_send_init_private(
|
||||
@ -433,7 +293,7 @@ bool NGCFT1::NGC_FT1_send_init_private(
|
||||
}
|
||||
|
||||
// TODO: check return value
|
||||
sendPKG_FT1_INIT(group_number, peer_number, file_kind, file_size, idx, file_id, file_id_size);
|
||||
_neep.send_ft1_init(group_number, peer_number, file_kind, file_size, idx, file_id, file_id_size);
|
||||
|
||||
peer.send_transfers[idx] = Group::Peer::SendTransfer{
|
||||
file_kind,
|
||||
@ -463,7 +323,7 @@ bool NGCFT1::NGC_FT1_send_message_public(
|
||||
message_id = randombytes_random();
|
||||
|
||||
// TODO: check return value
|
||||
return sendPKG_FT1_MESSAGE(group_number, message_id, file_kind, file_id, file_id_size);
|
||||
return _neep.send_all_ft1_message(group_number, message_id, file_kind, file_id, file_id_size);
|
||||
}
|
||||
|
||||
bool NGCFT1::onEvent(const Events::NGCEXT_ft1_request& e) {
|
||||
@ -506,7 +366,7 @@ bool NGCFT1::onEvent(const Events::NGCEXT_ft1_init& e) {
|
||||
return true; // return true?
|
||||
}
|
||||
|
||||
sendPKG_FT1_INIT_ACK(e.group_number, e.peer_number, e.transfer_id);
|
||||
_neep.send_ft1_init_ack(e.group_number, e.peer_number, e.transfer_id);
|
||||
|
||||
std::cout << "NGCFT1: accepted init\n";
|
||||
|
||||
@ -628,7 +488,7 @@ bool NGCFT1::onEvent(const Events::NGCEXT_ft1_data& e) {
|
||||
// TODO: check if this caps at max acks
|
||||
if (!ack_seq_ids.empty()) {
|
||||
// TODO: check return value
|
||||
sendPKG_FT1_DATA_ACK(e.group_number, e.peer_number, e.transfer_id, ack_seq_ids.data(), ack_seq_ids.size());
|
||||
_neep.send_ft1_data_ack(e.group_number, e.peer_number, e.transfer_id, ack_seq_ids.data(), ack_seq_ids.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,7 +131,7 @@ using NGCFT1EventProviderI = EventProviderI<NGCFT1EventI>;
|
||||
class NGCFT1 : public ToxEventI, public NGCEXTEventI, public NGCFT1EventProviderI {
|
||||
ToxI& _t;
|
||||
ToxEventProviderI& _tep;
|
||||
NGCEXTEventProviderI& _neep;
|
||||
NGCEXTEventProvider& _neep; // not the interface?
|
||||
|
||||
std::default_random_engine _rng{std::random_device{}()};
|
||||
|
||||
@ -201,13 +201,6 @@ class NGCFT1 : public ToxEventI, public NGCEXTEventI, public NGCFT1EventProvider
|
||||
std::map<uint32_t, Group> groups;
|
||||
|
||||
protected:
|
||||
bool sendPKG_FT1_REQUEST(uint32_t group_number, uint32_t peer_number, uint32_t file_kind, const uint8_t* file_id, size_t file_id_size);
|
||||
bool sendPKG_FT1_INIT(uint32_t group_number, uint32_t peer_number, uint32_t file_kind, uint64_t file_size, uint8_t transfer_id, const uint8_t* file_id, size_t file_id_size);
|
||||
bool sendPKG_FT1_INIT_ACK(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id);
|
||||
bool sendPKG_FT1_DATA(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, uint16_t sequence_id, const uint8_t* data, size_t data_size);
|
||||
bool sendPKG_FT1_DATA_ACK(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, const uint16_t* seq_ids, size_t seq_ids_size);
|
||||
bool sendPKG_FT1_MESSAGE(uint32_t group_number, uint32_t message_id, uint32_t file_kind, const uint8_t* file_id, size_t file_id_size);
|
||||
|
||||
void updateSendTransfer(float time_delta, uint32_t group_number, uint32_t peer_number, Group::Peer& peer, size_t idx, std::set<CCAI::SeqIDType>& timeouts_set, int64_t& can_packet_size);
|
||||
void iteratePeer(float time_delta, uint32_t group_number, uint32_t peer_number, Group::Peer& peer);
|
||||
|
||||
@ -215,7 +208,7 @@ class NGCFT1 : public ToxEventI, public NGCEXTEventI, public NGCFT1EventProvider
|
||||
NGCFT1(
|
||||
ToxI& t,
|
||||
ToxEventProviderI& tep,
|
||||
NGCEXTEventProviderI& neep
|
||||
NGCEXTEventProvider& neep
|
||||
);
|
||||
|
||||
float iterate(float delta);
|
||||
|
@ -18,7 +18,7 @@ struct SHA1Digest {
|
||||
bool operator==(const SHA1Digest& other) const { return data == other.data; }
|
||||
bool operator!=(const SHA1Digest& other) const { return data != other.data; }
|
||||
|
||||
size_t size(void) const { return data.size(); }
|
||||
constexpr size_t size(void) const { return data.size(); }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const SHA1Digest& v);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <filesystem>
|
||||
#include <mutex>
|
||||
#include <future>
|
||||
#include <vector>
|
||||
|
||||
namespace Message::Components {
|
||||
|
||||
@ -60,6 +61,7 @@ namespace Components {
|
||||
entt::dense_map<size_t, float> chunks;
|
||||
};
|
||||
|
||||
// TODO: once announce is shipped, remove the "Suspected"
|
||||
struct SuspectedParticipants {
|
||||
entt::dense_set<Contact3> participants;
|
||||
};
|
||||
@ -185,7 +187,6 @@ void SHA1_NGCFT1::updateMessages(ObjectHandle ce) {
|
||||
|
||||
std::optional<std::pair<uint32_t, uint32_t>> SHA1_NGCFT1::selectPeerForRequest(ObjectHandle ce) {
|
||||
// get a list of peers we can request this file from
|
||||
// TODO: randomly request from non SuspectedParticipants
|
||||
std::vector<std::pair<uint32_t, uint32_t>> tox_peers;
|
||||
for (const auto c : ce.get<Components::SuspectedParticipants>().participants) {
|
||||
// TODO: sort by con state?
|
||||
@ -200,10 +201,11 @@ std::optional<std::pair<uint32_t, uint32_t>> SHA1_NGCFT1::selectPeerForRequest(O
|
||||
}
|
||||
}
|
||||
|
||||
// 1 in 20 chance to ask random peer instead
|
||||
// 1 in 40 chance to ask random peer instead
|
||||
// TODO: config + tweak
|
||||
// TODO: save group in content to avoid the tox_peers list build
|
||||
if (tox_peers.empty() || (_rng()%20) == 0) {
|
||||
// TODO: remove once pc1_announce is shipped
|
||||
if (tox_peers.empty() || (_rng()%40) == 0) {
|
||||
// meh
|
||||
// HACK: determain group based on last tox_peers
|
||||
if (!tox_peers.empty()) {
|
||||
@ -250,13 +252,17 @@ SHA1_NGCFT1::SHA1_NGCFT1(
|
||||
Contact3Registry& cr,
|
||||
RegistryMessageModel& rmm,
|
||||
NGCFT1& nft,
|
||||
ToxContactModel2& tcm
|
||||
ToxContactModel2& tcm,
|
||||
ToxEventProviderI& tep,
|
||||
NGCEXTEventProvider& neep
|
||||
) :
|
||||
_os(os),
|
||||
_cr(cr),
|
||||
_rmm(rmm),
|
||||
_nft(nft),
|
||||
_tcm(tcm)
|
||||
_tcm(tcm),
|
||||
_tep(tep),
|
||||
_neep(neep)
|
||||
{
|
||||
// TODO: also create and destroy
|
||||
_rmm.subscribe(this, RegistryMessageModel_Event::message_updated);
|
||||
@ -274,6 +280,10 @@ SHA1_NGCFT1::SHA1_NGCFT1(
|
||||
//_rmm.subscribe(this, RegistryMessageModel_Event::message_destroy);
|
||||
|
||||
_rmm.subscribe(this, RegistryMessageModel_Event::send_file_path);
|
||||
|
||||
_tep.subscribe(this, Tox_Event_Type::TOX_EVENT_GROUP_PEER_EXIT);
|
||||
|
||||
_neep.subscribe(this, NGCEXT_Event::PC1_ANNOUNCE);
|
||||
}
|
||||
|
||||
void SHA1_NGCFT1::iterate(float delta) {
|
||||
@ -319,7 +329,7 @@ void SHA1_NGCFT1::iterate(float delta) {
|
||||
it->second.time_since_activity += delta;
|
||||
|
||||
// if we have not heard for 10sec, timeout
|
||||
if (it->second.time_since_activity >= 10.f) {
|
||||
if (it->second.time_since_activity >= 20.f) {
|
||||
std::cerr << "SHA1_NGCFT1 warning: receiving tansfer timed out " << "." << int(it->first) << "\n";
|
||||
// TODO: if info, requeue? or just keep the timer comp? - no, timer comp will continue ticking, even if loading
|
||||
//it->second.v
|
||||
@ -632,6 +642,34 @@ bool SHA1_NGCFT1::onEvent(const Message::Events::MessageUpdated& e) {
|
||||
|
||||
ce.emplace<Message::Components::Transfer::File>(std::move(file_impl));
|
||||
|
||||
// announce we are participating
|
||||
// since this is the first time, we publicly announce to all
|
||||
if (e.e.all_of<Message::Components::ContactFrom, Message::Components::ContactTo>()) {
|
||||
const auto c_f = e.e.get<Message::Components::ContactFrom>().c;
|
||||
const auto c_t = e.e.get<Message::Components::ContactTo>().c;
|
||||
|
||||
std::vector<uint8_t> announce_id;
|
||||
const uint32_t file_kind = static_cast<uint32_t>(NGCFT1_file_kind::HASH_SHA1_INFO);
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
announce_id.push_back((file_kind>>(i*8)) & 0xff);
|
||||
}
|
||||
assert(ce.all_of<Components::FT1InfoSHA1Hash>());
|
||||
const auto& info_hash = ce.get<Components::FT1InfoSHA1Hash>().hash;
|
||||
announce_id.insert(announce_id.cend(), info_hash.cbegin(), info_hash.cend());
|
||||
|
||||
if (_cr.all_of<Contact::Components::ToxGroupEphemeral>(c_t)) {
|
||||
// public
|
||||
const auto group_number = _cr.get<Contact::Components::ToxGroupEphemeral>(c_t).group_number;
|
||||
|
||||
_neep.send_all_pc1_announce(group_number, announce_id.data(), announce_id.size());
|
||||
} else if (_cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(c_f)) {
|
||||
// private ?
|
||||
const auto [group_number, peer_number] = _cr.get<Contact::Components::ToxGroupPeerEphemeral>(c_f);
|
||||
|
||||
_neep.send_pc1_announce(group_number, peer_number, announce_id.data(), announce_id.size());
|
||||
}
|
||||
}
|
||||
|
||||
ce.remove<Message::Components::Transfer::TagPaused>();
|
||||
|
||||
// should?
|
||||
@ -1058,6 +1096,7 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_message& e) {
|
||||
|
||||
Message3Registry& reg = *reg_ptr;
|
||||
// TODO: check for existence, hs or other syncing mechanics might have sent it already (or like, it arrived 2x or whatever)
|
||||
// TODO: use the message dup test provided via rmm
|
||||
auto new_msg_e = reg.create();
|
||||
|
||||
{ // contact
|
||||
@ -1426,3 +1465,73 @@ bool SHA1_NGCFT1::sendFilePath(const Contact3 c, std::string_view file_name, std
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHA1_NGCFT1::onToxEvent(const Tox_Event_Group_Peer_Exit* e) {
|
||||
const auto group_number = tox_event_group_peer_exit_get_group_number(e);
|
||||
const auto peer_number = tox_event_group_peer_exit_get_peer_id(e);
|
||||
|
||||
// peer disconnected
|
||||
// - remove from all participantions
|
||||
|
||||
auto ch = _tcm.getContactGroupPeer(group_number, peer_number);
|
||||
if (!static_cast<bool>(ch)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& [_, h] : _info_to_content) {
|
||||
if (!h.all_of<Components::SuspectedParticipants>()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
h.get<Components::SuspectedParticipants>().participants.erase(ch);
|
||||
}
|
||||
|
||||
// - clear queues
|
||||
|
||||
for (auto it = _queue_requested_chunk.begin(); it != _queue_requested_chunk.end();) {
|
||||
if (group_number == std::get<0>(*it) && peer_number == std::get<1>(*it)) {
|
||||
it = _queue_requested_chunk.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHA1_NGCFT1::onEvent(const Events::NGCEXT_pc1_announce& e) {
|
||||
std::cerr << "SHA1_NGCFT1: PC1_ANNOUNCE s:" << e.id.size() << "\n";
|
||||
// id is file_kind + id
|
||||
uint32_t file_kind = 0u;
|
||||
|
||||
static_assert(SHA1Digest{}.size() == 20);
|
||||
if (e.id.size() != sizeof(file_kind) + 20) {
|
||||
// not for us
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||
file_kind |= uint32_t(e.id[i]) << (i*8);
|
||||
}
|
||||
|
||||
SHA1Digest hash{e.id.data()+sizeof(file_kind), 20};
|
||||
|
||||
// if have use hash(-info) for file, add to participants
|
||||
std::cout << "SHA1_NGCFT1: got ParticipationChatter1 announce from " << e.group_number << ":" << e.peer_number << " for " << hash << "\n";
|
||||
|
||||
auto itc_it = _info_to_content.find(hash);
|
||||
if (itc_it == _info_to_content.end()) {
|
||||
// we are not interested and dont track this
|
||||
return false;
|
||||
}
|
||||
|
||||
// add them to participants
|
||||
auto ce = itc_it->second;
|
||||
const auto c = _tcm.getContactGroupPeer(e.group_number, e.peer_number);
|
||||
const auto [_, was_new] = ce.get_or_emplace<Components::SuspectedParticipants>().participants.emplace(c);
|
||||
if (was_new) {
|
||||
std::cout << "SHA1_NGCFT1: and we where interested!\n";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,15 @@
|
||||
#include <mutex>
|
||||
#include <list>
|
||||
|
||||
class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI {
|
||||
class SHA1_NGCFT1 : public ToxEventI, public RegistryMessageModelEventI, public NGCFT1EventI, public NGCEXTEventI {
|
||||
ObjectStore2& _os;
|
||||
// TODO: backend abstraction
|
||||
Contact3Registry& _cr;
|
||||
RegistryMessageModel& _rmm;
|
||||
NGCFT1& _nft;
|
||||
ToxContactModel2& _tcm;
|
||||
ToxEventProviderI& _tep;
|
||||
NGCEXTEventProvider& _neep;
|
||||
|
||||
std::minstd_rand _rng {1337*11};
|
||||
|
||||
@ -122,7 +124,9 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI {
|
||||
Contact3Registry& cr,
|
||||
RegistryMessageModel& rmm,
|
||||
NGCFT1& nft,
|
||||
ToxContactModel2& tcm
|
||||
ToxContactModel2& tcm,
|
||||
ToxEventProviderI& tep,
|
||||
NGCEXTEventProvider& neep
|
||||
);
|
||||
|
||||
void iterate(float delta);
|
||||
@ -140,5 +144,9 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI {
|
||||
bool onEvent(const Events::NGCFT1_recv_message&) override;
|
||||
|
||||
bool sendFilePath(const Contact3 c, std::string_view file_name, std::string_view file_path) override;
|
||||
|
||||
bool onToxEvent(const Tox_Event_Group_Peer_Exit* e) override;
|
||||
|
||||
bool onEvent(const Events::NGCEXT_pc1_announce&) override;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user