states + refactoring

This commit is contained in:
Green Sky 2023-01-14 23:18:10 +01:00
parent 490d892262
commit 8970512160
No known key found for this signature in database
10 changed files with 230 additions and 48 deletions

View File

@ -18,6 +18,11 @@ add_executable(tox_ngc_ft1_tool
./tox_client.hpp
./tox_client.cpp
./state.hpp
./send_states/sha1_start.hpp
./send_states/sha1_start.cpp
)
target_compile_features(tox_ngc_ft1_tool PUBLIC cxx_std_17)

View File

@ -11,6 +11,8 @@ CommandLine::CommandLine(int argc, char** argv) {
for (int i = 1; i < argc; i++) {
std::string_view arg_sv{argv[i]};
#define PRINT_HELP_AND_BAIL printHelp(); _should_exit = true; return;
if (arg_sv == "-v") {
version = true;
_should_exit = true;
@ -22,59 +24,68 @@ CommandLine::CommandLine(int argc, char** argv) {
_should_exit = true;
} else if (arg_sv == "-G") {
if (i+1 >= argc) {
std::cerr << "-G missing <chat_id> parameter!\n\n";
printHelp();
_should_exit = true;
return;
std::cerr << "ERROR: -G missing <chat_id> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
chat_id = argv[++i];
} else if (arg_sv == "-F") {
if (i+1 >= argc) {
std::cerr << "-F missing <path> parameter!\n\n";
printHelp();
_should_exit = true;
return;
std::cerr << "ERROR: -F missing <path> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
profile_path = argv[++i];
} else if (arg_sv == "-N") {
if (i+1 >= argc) {
std::cerr << "-N missing <self_name> parameter!\n\n";
printHelp();
_should_exit = true;
return;
std::cerr << "ERROR: -N missing <self_name> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
self_name = argv[++i];
} else if (arg_sv == "-a") {
if (i+1 >= argc) {
std::cerr << "ERROR: -a missing <transfer_variant> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
std::string_view tv_sv{argv[++i]};
if (tv_sv == "id1") {
transfer_variant = TransferE::ID;
} else if (tv_sv == "sha1_single") {
transfer_variant = TransferE::SHA1_SINGLE;
} else if (tv_sv == "sha1_info") {
transfer_variant = TransferE::SHA1_INFO;
} else {
std::cerr << "ERROR: invalid <transfer_variant> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
} else if (arg_sv == "-f") {
if (i+1 >= argc) {
std::cerr << "-f missing <path> parameter!\n\n";
printHelp();
_should_exit = true;
return;
std::cerr << "ERROR: -f missing <path> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
send_path = argv[++i];
} else if (arg_sv == "-d") {
if (i+1 >= argc) {
std::cerr << "-d missing <path> parameter!\n\n";
printHelp();
_should_exit = true;
return;
std::cerr << "ERROR: -d missing <path> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
receive_dump_dir = argv[++i];
} else if (arg_sv == "-D") {
if (i+1 >= argc) {
std::cerr << "-D missing <id/hash> parameter!\n\n";
printHelp();
_should_exit = true;
return;
std::cerr << "ERROR: -D missing <id/hash> parameter!\n\n";
PRINT_HELP_AND_BAIL;
}
receive_id = argv[++i];
} else {
std::cerr << "unknown parameter '" << arg_sv << "' !\n\n";
printHelp();
_should_exit = true;
std::cerr << "ERROR: unknown parameter '" << arg_sv << "' !\n\n";
PRINT_HELP_AND_BAIL;
}
}
if (transfer_variant == TransferE::INVALID) {
std::cerr << "ERROR: transfer_variant not set!\n\n";
PRINT_HELP_AND_BAIL;
}
}
void CommandLine::printHelp(void) {
@ -95,7 +106,7 @@ void CommandLine::printHelp(void) {
<< " if profile exists load, otherwise create new\n"
<< "\n"
<< " transfer variant:\n"
<< " -a id1/sha128_single/sha128_info/sha256_single/sha256_info\n"
<< " -a id1/sha1_single/sha1_info/sha2_single/sha2_info\n"
<< "\n"
<< " send:\n"
<< " -f send_this_file.zip\n"

View File

@ -17,7 +17,7 @@
// if profile exists load, otherwise create new
//
// transfer variant:
// -a id1/sha128_single/sha128_info/sha256_single/sha256_info
// -a id1/sha1_single/sha1_info/sha2_single/sha2_info
//
// send:
// -f send_this_file.zip
@ -26,6 +26,15 @@
// -d dump/everything/in/this/dir
// -D <id/hash> (what to dl)
enum class TransferE {
INVALID,
ID,
SHA1_SINGLE, // a single chunk (no filename is transfered)
SHA1_INFO,
//...
};
struct CommandLine {
std::string exe;
@ -46,8 +55,8 @@ struct CommandLine {
std::string self_name {"tox_ngc_tf1_tool"};
// transfer variant:
// -a id1/sha128_single/sha128_info/sha256_single/sha256_info
// some enum?
// -a id1/sha1_single/sha1_info/sha2_single/sha2_info
TransferE transfer_variant {TransferE::INVALID};
// send:
// -f send_this_file.zip

View File

@ -23,8 +23,7 @@ int main(int argc, char** argv) {
std::cout << "tox id: " << client.getOwnAddress() << "\n";
while (true) {
client.iterate();
while (client.iterate()) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}

View File

@ -0,0 +1,48 @@
#include "./sha1_start.hpp"
#include "../tox_client.hpp"
namespace SendStates {
SHA1Start::SHA1Start(ToxClient& tcl, const CommandLine& cl) : StateI(tcl) {
}
bool SHA1Start::iterate(void) {
_tcl._tox;
return false;
}
std::unique_ptr<StateI> SHA1Start::nextState(void) {
return nullptr;
}
// sha1_info
void SHA1Start::onFT1ReceiveRequestSHA1Info(uint32_t, uint32_t, const uint8_t*, size_t) {
}
bool SHA1Start::onFT1ReceiveInitSHA1Info(uint32_t, uint32_t, const uint8_t*, size_t, const uint8_t, const size_t) {
return false;
}
void SHA1Start::onFT1ReceiveDataSHA1Info(uint32_t, uint32_t, uint8_t, size_t, const uint8_t*, size_t) {
}
void SHA1Start::onFT1SendDataSHA1Info(uint32_t, uint32_t, uint8_t, size_t, uint8_t*, size_t) {
}
// sha1_chunk
void SHA1Start::onFT1ReceiveRequestSHA1Chunk(uint32_t, uint32_t, const uint8_t*, size_t) {
}
bool SHA1Start::onFT1ReceiveInitSHA1Chunk(uint32_t, uint32_t, const uint8_t*, size_t, const uint8_t, const size_t) {
return false;
}
void SHA1Start::onFT1ReceiveDataSHA1Chunk(uint32_t, uint32_t, uint8_t, size_t, const uint8_t*, size_t) {
}
void SHA1Start::onFT1SendDataSHA1Chunk(uint32_t, uint32_t, uint8_t, size_t, uint8_t*, size_t) {
}
} // SendStates

View File

@ -0,0 +1,34 @@
#pragma once
#include "../state.hpp"
#include "../command_line.hpp"
namespace SendStates {
// we are hashing the given file
// does not react to any ft events
struct SHA1Start final : public StateI {
public: // general interface
SHA1Start(ToxClient& tcl, const CommandLine& cl);
~SHA1Start(void) override = default;
bool iterate(void) override;
std::unique_ptr<StateI> nextState(void) override;
public: // callbacks
// sha1_info
void onFT1ReceiveRequestSHA1Info(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size) override;
bool onFT1ReceiveInitSHA1Info(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size) override;
void onFT1ReceiveDataSHA1Info(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size) override;
void onFT1SendDataSHA1Info(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) override;
// sha1_chunk
void onFT1ReceiveRequestSHA1Chunk(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size) override;
bool onFT1ReceiveInitSHA1Chunk(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size) override;
void onFT1ReceiveDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size) override;
void onFT1SendDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) override;
};
} // SendStates

34
src/state.hpp Normal file
View File

@ -0,0 +1,34 @@
#pragma once
#include <memory>
// fwd
struct ToxClient;
struct StateI {
public: // general interface
StateI(ToxClient& tcl) : _tcl(tcl) {}
virtual ~StateI(void) = default;
// returns true if we should call nextState()
virtual bool iterate(void) = 0;
// returns the new state (transition)
virtual std::unique_ptr<StateI> nextState(void) = 0;
public: // callbacks
// sha1_info
virtual void onFT1ReceiveRequestSHA1Info(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size) = 0;
virtual bool onFT1ReceiveInitSHA1Info(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size) = 0;
virtual void onFT1ReceiveDataSHA1Info(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size) = 0;
virtual void onFT1SendDataSHA1Info(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) = 0;
// sha1_chunk
virtual void onFT1ReceiveRequestSHA1Chunk(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size) = 0;
virtual bool onFT1ReceiveInitSHA1Chunk(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size) = 0;
virtual void onFT1ReceiveDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size) = 0;
virtual void onFT1SendDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) = 0;
protected:
ToxClient& _tcl;
};

View File

@ -48,36 +48,36 @@ void group_self_join_cb(Tox*, uint32_t group_number, void *user_data) {
// ==================== sha1_info ====================
void ft1_recv_request_sha1_info_cb(Tox*, uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, void* user_data) {
static_cast<ToxClient*>(user_data)->onFT1ReceiveRequestSHA1Info(group_number, peer_number, file_id, file_id_size);
static_cast<ToxClient*>(user_data)->getState().onFT1ReceiveRequestSHA1Info(group_number, peer_number, file_id, file_id_size);
}
bool ft1_recv_init_sha1_info_cb(Tox*, uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size, void* user_data) {
return static_cast<ToxClient*>(user_data)->onFT1ReceiveInitSHA1Info(group_number, peer_number, file_id, file_id_size, transfer_id, file_size);
return static_cast<ToxClient*>(user_data)->getState().onFT1ReceiveInitSHA1Info(group_number, peer_number, file_id, file_id_size, transfer_id, file_size);
}
void ft1_recv_data_sha1_info_cb(Tox*, uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size, void* user_data) {
static_cast<ToxClient*>(user_data)->onFT1ReceiveDataSHA1Info(group_number, peer_number, transfer_id, data_offset, data, data_size);
static_cast<ToxClient*>(user_data)->getState().onFT1ReceiveDataSHA1Info(group_number, peer_number, transfer_id, data_offset, data, data_size);
}
void ft1_send_data_sha1_info_cb(Tox*, uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size, void* user_data) {
static_cast<ToxClient*>(user_data)->onFT1SendDataSHA1Info(group_number, peer_number, transfer_id, data_offset, data, data_size);
static_cast<ToxClient*>(user_data)->getState().onFT1SendDataSHA1Info(group_number, peer_number, transfer_id, data_offset, data, data_size);
}
// ==================== sha1_chunk ====================
void ft1_recv_request_sha1_chunk_cb(Tox*, uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, void* user_data) {
static_cast<ToxClient*>(user_data)->onFT1ReceiveRequestSHA1Chunk(group_number, peer_number, file_id, file_id_size);
static_cast<ToxClient*>(user_data)->getState().onFT1ReceiveRequestSHA1Chunk(group_number, peer_number, file_id, file_id_size);
}
bool ft1_recv_init_sha1_chunk_cb(Tox*, uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size, void* user_data) {
return static_cast<ToxClient*>(user_data)->onFT1ReceiveInitSHA1Chunk(group_number, peer_number, file_id, file_id_size, transfer_id, file_size);
return static_cast<ToxClient*>(user_data)->getState().onFT1ReceiveInitSHA1Chunk(group_number, peer_number, file_id, file_id_size, transfer_id, file_size);
}
void ft1_recv_data_sha1_chunk_cb(Tox*, uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size, void* user_data) {
static_cast<ToxClient*>(user_data)->onFT1ReceiveDataSHA1Chunk(group_number, peer_number, transfer_id, data_offset, data, data_size);
static_cast<ToxClient*>(user_data)->getState().onFT1ReceiveDataSHA1Chunk(group_number, peer_number, transfer_id, data_offset, data, data_size);
}
void ft1_send_data_sha1_chunk_cb(Tox*, uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size, void* user_data) {
static_cast<ToxClient*>(user_data)->onFT1SendDataSHA1Chunk(group_number, peer_number, transfer_id, data_offset, data, data_size);
static_cast<ToxClient*>(user_data)->getState().onFT1SendDataSHA1Chunk(group_number, peer_number, transfer_id, data_offset, data, data_size);
}

View File

@ -2,11 +2,9 @@
#include "./tox_utils.hpp"
#include "./tox_callbacks.hpp"
#include "ngc_ext.h"
#include "ngc_ft1.h"
#include <sodium.h>
#include "send_states/sha1_start.hpp"
#include <memory>
#include <sodium.h>
#include <vector>
@ -123,6 +121,14 @@ ToxClient::ToxClient(const CommandLine& cl) :
NGC_FT1_register_callback_recv_data(_ft1_ctx, NGC_FT1_file_kind::HASH_SHA1_CHUNK, ft1_recv_data_sha1_chunk_cb, this);
NGC_FT1_register_callback_send_data(_ft1_ctx, NGC_FT1_file_kind::HASH_SHA1_CHUNK, ft1_send_data_sha1_chunk_cb, this);
{ // state factory // TODO: extract
// sender
if (!cl.send_path.empty()) {
_state = std::make_unique<SendStates::SHA1Start>(*this, cl);
} else { // receiver
}
}
// dht bootstrap
{
struct DHT_node {
@ -163,13 +169,24 @@ ToxClient::~ToxClient(void) {
tox_kill(_tox);
}
void ToxClient::iterate(void) {
bool ToxClient::iterate(void) {
tox_iterate(_tox, this);
NGC_FT1_iterate(_tox, _ft1_ctx);
if (_state->iterate()) {
_state = _state->nextState();
if (!_state) {
// exit program
return false;
}
}
if (_tox_profile_dirty) {
saveToxProfile();
}
return true;
}
std::string ToxClient::getOwnAddress(void) const {
@ -230,6 +247,13 @@ void ToxClient::onToxGroupSelfJoin(uint32_t group_number) {
_tox_profile_dirty = true;
}
StateI& ToxClient::getState(void) {
assert(_state.get());
return *_state.get();
}
#if 0
// sha1_info
void ToxClient::onFT1ReceiveRequestSHA1Info(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size) {
}
@ -257,6 +281,7 @@ void ToxClient::onFT1ReceiveDataSHA1Chunk(uint32_t group_number, uint32_t peer_n
void ToxClient::onFT1SendDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) {
}
#endif
void ToxClient::saveToxProfile(void) {
if (_tox_profile_path.empty()) {

View File

@ -2,19 +2,28 @@
#include "./command_line.hpp"
#include <string_view>
#include "./state.hpp"
#include <memory>
#include <tox/tox.h>
#include <ngc_ext.h>
#include <ngc_ft1.h>
#include <string>
#include <string_view>
// fwd
namespace SendStates {
struct SHA1Start;
}
struct ToxClient {
public:
ToxClient(const CommandLine& cl);
~ToxClient(void);
void iterate(void);
// returns false when we shoul stop the program
bool iterate(void);
void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; }
@ -31,6 +40,8 @@ struct ToxClient {
void onToxGroupSelfJoin(uint32_t group_number);
public: // FT1 callbacks
StateI& getState(void); // public accessor for callbacks
#if 0
// sha1_info
void onFT1ReceiveRequestSHA1Info(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size);
bool onFT1ReceiveInitSHA1Info(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size);
@ -42,6 +53,7 @@ struct ToxClient {
bool onFT1ReceiveInitSHA1Chunk(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size);
void onFT1ReceiveDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size);
void onFT1SendDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size);
#endif
private:
void saveToxProfile(void);
@ -55,5 +67,10 @@ struct ToxClient {
std::string _tox_profile_path;
bool _tox_profile_dirty {false}; // set in callbacks
std::unique_ptr<StateI> _state;
// TODO: this is a hack, make better?
friend SendStates::SHA1Start;
};