From e858f23fc1f2ab4457f0da2db225498bcaab8e1c Mon Sep 17 00:00:00 2001 From: Green Sky Date: Thu, 12 Jan 2023 02:36:29 +0100 Subject: [PATCH] works --- ngc_ext_common.hpp | 2 + ngc_ft1.cpp | 7 +++- ngc_ft1.h | 3 +- ngc_hs1.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++---- ngc_hs1.hpp | 9 ++++- 5 files changed, 106 insertions(+), 12 deletions(-) diff --git a/ngc_ext_common.hpp b/ngc_ext_common.hpp index c5f9c63..8384530 100644 --- a/ngc_ext_common.hpp +++ b/ngc_ext_common.hpp @@ -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(); } diff --git a/ngc_ft1.cpp b/ngc_ft1.cpp index b6e5054..1dea265 100644 --- a/ngc_ft1.cpp +++ b/ngc_ft1.cpp @@ -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; } diff --git a/ngc_ft1.h b/ngc_ft1.h index e8e7351..d353455 100644 --- a/ngc_ft1.h +++ b/ngc_ft1.h @@ -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 diff --git a/ngc_hs1.cpp b/ngc_hs1.cpp index 6d34e22..c614435 100644 --- a/ngc_hs1.cpp +++ b/ngc_hs1.cpp @@ -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(transfer.recv_buffer.front()), std::string(reinterpret_cast(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; } diff --git a/ngc_hs1.hpp b/ngc_hs1.hpp index 725efe2..36ae442 100644 --- a/ngc_hs1.hpp +++ b/ngc_hs1.hpp @@ -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 recv_buffer; // message gets dumped into here + size_t file_size {0}; }; // key: peer_number + transfer_id std::map, FileTransfers> transfers; + struct Sending { + _PeerKey msg_peer; + uint32_t msg_id; + }; + std::map, Sending> sending; }; std::map<_GroupKey, Group> history;