This commit is contained in:
Green Sky 2023-01-12 02:36:29 +01:00
parent dbcf2777c0
commit e858f23fc1
No known key found for this signature in database
5 changed files with 106 additions and 12 deletions

View File

@ -87,6 +87,7 @@ struct _GroupKey {
_GroupKey(void) = default;
_GroupKey(const _GroupKey& other) : data(other.data) {}
_GroupKey(_GroupKey&&) = delete;
_GroupKey& operator=(const _GroupKey& other) { data = other.data; return *this; }
bool operator<(const _GroupKey& rhs) const;
bool operator==(const _GroupKey& rhs) const;
size_t size(void) const { return data.size(); }
@ -98,6 +99,7 @@ struct _PeerKey {
_PeerKey(void) = default;
_PeerKey(const _PeerKey& other) : data(other.data) {}
_PeerKey(_PeerKey&&) = delete;
_PeerKey& operator=(const _PeerKey& other) { data = other.data; return *this; }
bool operator<(const _PeerKey& rhs) const;
bool operator==(const _PeerKey& rhs) const;
size_t size(void) const { return data.size(); }

View File

@ -365,7 +365,8 @@ bool NGC_FT1_send_init_private(
uint32_t group_number, uint32_t peer_number,
NGC_FT1_file_kind file_kind,
const uint8_t* file_id, size_t file_id_size,
size_t file_size
size_t file_size,
uint8_t* transfer_id
) {
//fprintf(stderr, "TODO: init ft for %08X\n", msg_id);
fprintf(stderr, "FT: init ft\n");
@ -412,6 +413,10 @@ bool NGC_FT1_send_init_private(
0,
};
if (transfer_id != nullptr) {
*transfer_id = idx;
}
return true;
}

View File

@ -81,7 +81,8 @@ bool NGC_FT1_send_init_private(
uint32_t group_number, uint32_t peer_number,
NGC_FT1_file_kind file_kind,
const uint8_t* file_id, size_t file_id_size,
size_t file_size
size_t file_size,
uint8_t* transfer_id
);
// return true to accept, false to deny

View File

@ -147,6 +147,18 @@ static void _iterate_group(Tox *tox, NGC_EXT_CTX* ngc_ext_ctx, uint32_t group_nu
} else {
auto& group = ngc_hs1_ctx->history[g_id];
// check if transfers have timed out
for (auto it = group.transfers.begin(); it != group.transfers.end();) {
it->second.time_since_ft_activity += time_delta;
if (it->second.time_since_ft_activity >= ngc_hs1_ctx->options.ft_activity_timeout) {
// timed out
fprintf(stderr, "HS: !!! ft timed out (%08X)\n", it->first.first);
it = group.transfers.erase(it);
} else {
it++;
}
}
// for each peer
for (auto& [peer_key, peer] : group.peers) {
//fprintf(stderr, " p: %X%X%X%X\n", key.data.data()[0], key.data.data()[1], key.data.data()[2], key.data.data()[3]);
@ -311,7 +323,6 @@ bool NGC_HS1_shim_group_send_message(
return ret;
}
// record own msg
void NGC_HS1_record_own_message(
const Tox *tox,
@ -423,13 +434,20 @@ void _handle_HS1_ft_recv_request(
const auto& msg = peer.dict.at(msg_id);
size_t file_size = 1 + msg.text.size();
uint8_t transfer_id {0};
NGC_FT1_send_init_private(
tox, ngc_ext_ctx,
group_number, peer_number,
NGC_HS1_MESSAGE_BY_ID,
file_id, file_id_size,
file_size
file_size,
&transfer_id
);
//TODO: can fail
ngc_ext_ctx->ngc_hs1_ctx->history[group_id].sending[std::make_pair(peer_number, transfer_id)] = {peer_key, msg_id};
}
bool _handle_HS1_ft_recv_init(
@ -483,10 +501,19 @@ bool _handle_HS1_ft_recv_init(
// TODO: if allready acked but got init again, they did not get the ack
// TODO: more?
// move from pending to transfers
group.transfers[std::make_pair(peer_number, transfer_id)] = {
peer_key,
msg_id,
0.f,
{}, // empty buffer
file_size,
};
pending.at(msg_id).time_since_ft_activity = 0.f;
//pending.at(msg_id).transfer_acked;
//group.transfers
// TODO: keep the pending until later?
//pending.erase(msg_id);
return true; // accept
}
@ -507,7 +534,6 @@ void _handle_HS1_ft_recv_data(
auto& group = ngc_ext_ctx->ngc_hs1_ctx->history[g_id];
//auto& pending = group.peers[peer_key].pending;
// get based on transfer_id
if (!group.transfers.count(std::make_pair(peer_number, transfer_id))) {
if (data_offset != 0) {
@ -516,11 +542,32 @@ void _handle_HS1_ft_recv_data(
}
// new transfer?
fprintf(stderr, "HS: !! got transfer from %d tid:%d\n", peer_number, transfer_id);
fprintf(stderr, "HS: !! got new transfer from %d tid:%d\n", peer_number, transfer_id);
}
fprintf(stderr, "HS: recv_data from %d tid:%d\n", peer_number, transfer_id);
auto& transfer = group.transfers.at(std::make_pair(peer_number, transfer_id));
transfer.time_since_ft_activity = 0.f;
// TODO: also timer for pending?
// TODO: optimize
for (size_t i = 0; i < data_size; i++) {
transfer.recv_buffer.push_back(data[i]);
}
// add data to tmp buffer
// TODO: data done?
if (data_offset + data_size == transfer.file_size) {
fprintf(stderr, "HS: transfer done %d:%d\n", peer_number, transfer_id);
transfer.recv_buffer.push_back('\0');
fprintf(stderr, " message was %s\n", transfer.recv_buffer.data()+1);
auto& peer = group.peers[transfer.msg_peer];
peer.pending.erase(transfer.msg_id);
peer.append(transfer.msg_id, static_cast<Tox_Message_Type>(transfer.recv_buffer.front()), std::string(reinterpret_cast<const char*>(transfer.recv_buffer.data()+1)));
group.transfers.erase(std::make_pair(peer_number, transfer_id));
}
}
void _handle_HS1_ft_send_data(
@ -532,6 +579,40 @@ void _handle_HS1_ft_send_data(
size_t data_offset, uint8_t* data, size_t data_size
) {
// get group id
_GroupKey g_id{};
{ // TODO: error
tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr);
}
auto& group = ngc_ext_ctx->ngc_hs1_ctx->history[g_id];
if (!group.sending.count(std::make_pair(peer_number, transfer_id))) {
fprintf(stderr, "HS: error, unknown sending transfer %d:%d\n", peer_number, transfer_id);
return;
}
// map peer_number and transfer_id to peer_key and message_id
const auto& [msg_peer, msg_id] = group.sending.at(std::make_pair(peer_number, transfer_id));
// get msg
const auto& message = group.peers.at(msg_peer).dict.at(msg_id);
size_t i = 0;
if (data_offset == 0) {
// serl type
data[i++] = message.type;
}
for (; i < data_size; i++) {
data[i] = message.text.at((data_offset+i)-1);
}
if (data_offset + data_size == 1 + message.text.size()) {
// done
fprintf(stderr, "HS: done %d:%d\n", peer_number, transfer_id);
group.sending.erase(std::make_pair(peer_number, transfer_id));
}
}
#define _HS1_HAVE(x, error) if ((length - curser) < (x)) { error; }

View File

@ -54,15 +54,20 @@ struct NGC_HS1 {
std::map<_PeerKey, Peer> peers;
struct FileTransfers {
//uint32_t peer_number; // the peer we requested the message from
float time_since_ft_activity {0.f};
_PeerKey msg_peer;
uint32_t msg_id;
float time_since_ft_activity {0.f};
std::vector<uint8_t> recv_buffer; // message gets dumped into here
size_t file_size {0};
};
// key: peer_number + transfer_id
std::map<std::pair<uint32_t, uint8_t>, FileTransfers> transfers;
struct Sending {
_PeerKey msg_peer;
uint32_t msg_id;
};
std::map<std::pair<uint32_t, uint8_t>, Sending> sending;
};
std::map<_GroupKey, Group> history;