diff --git a/README.md b/README.md index 9226a18..a157e50 100644 --- a/README.md +++ b/README.md @@ -36,5 +36,12 @@ $ tox_ngc_ft1_tool -U disable udp -P proxy_host proxy_port -p tox_port (bind tox to that port) + + FT1: + --ft_ack_per_packet + --ft_init_retry_timeout_after + --ft_sending_resend_without_ack_after + --ft_sending_give_up_after + --ft_packet_window_size ``` diff --git a/external/tox_ngc_ft1/tox_ngc_ft1 b/external/tox_ngc_ft1/tox_ngc_ft1 index 5bb4349..ae9e272 160000 --- a/external/tox_ngc_ft1/tox_ngc_ft1 +++ b/external/tox_ngc_ft1/tox_ngc_ft1 @@ -1 +1 @@ -Subproject commit 5bb4349e27fda14a9e99fe17d6f59de66a00d410 +Subproject commit ae9e2729d20ff5134e718a3603459b218aebf077 diff --git a/src/command_line.cpp b/src/command_line.cpp index bc6cacb..0d2d8fb 100644 --- a/src/command_line.cpp +++ b/src/command_line.cpp @@ -3,118 +3,133 @@ #include #include #include +#include + +struct CLParser { + const size_t argc; + const char*const* argv; + size_t& i; + + bool error {false}; + +bool parseFlag(std::string_view arg_sv, bool& flag) { + std::string_view arg0_sv{argv[i]}; + + if (arg0_sv != arg_sv) { + return false; + } + + flag = true; + + return true; +} + +template +static void visit(FN&& fn, Arg0&& arg0, Args&& ...args) { + fn(arg0); + (fn(args),...); +} + +template +bool parseParam(std::string_view arg_sv, Arg0& arg0, Args& ...args) { + std::string_view arg0_sv{argv[i]}; + + if (arg0_sv != arg_sv) { + return false; + } + + if (argc < 1+1+sizeof...(args)) { + std::cerr << "ERROR: " << arg_sv << " not enough parameters!\n\n"; + error = true; + return true; + } + + visit([this](auto& arg) { + if (error) return; + + std::string_view argX_sv{argv[++i]}; + + using T = std::decay_t; + if constexpr (std::is_same_v) { + arg = argX_sv; + } else if constexpr (std::is_integral_v) { + auto res = std::from_chars(argX_sv.data(), argX_sv.data()+argX_sv.size(), arg); + if (res.ptr != argX_sv.data() + argX_sv.size()) { + std::cerr << "ERROR: invalid parameter!\n\n"; + error = true; + //PRINT_HELP_AND_BAIL; + } + } else if constexpr (std::is_same_v) { + // HACK: wait for more charconv <.< + std::string tmp_str {argX_sv}; + arg = std::stof(tmp_str); + } else { + assert(false && "invalid parameter type"); + } + }, arg0, args...); + + return true; +} + +}; CommandLine::CommandLine(int argc, char** argv) { assert(argc > 0); exe = argv[0]; - for (int i = 1; i < argc; i++) { - std::string_view arg_sv{argv[i]}; + for (size_t i = 1; i < size_t(argc); i++) { + CLParser parser{size_t(argc), argv, i}; + std::string_view arg_sv{argv[i]}; // alt #define PRINT_HELP_AND_BAIL printHelp(); _should_exit = true; return; - if (arg_sv == "-v") { - version = true; + if (parser.parseFlag("-v", version)) { _should_exit = true; - } else if (arg_sv == "-V") { - verbose = true; + } else if (parser.parseFlag("-V", verbose)) { } else if (arg_sv == "-h") { help = true; printHelp(); _should_exit = true; - } else if (arg_sv == "-G") { - if (i+1 >= argc) { - std::cerr << "ERROR: -G missing parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - chat_id = argv[++i]; - } else if (arg_sv == "-F") { - if (i+1 >= argc) { - std::cerr << "ERROR: -F missing parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - profile_path = argv[++i]; - } else if (arg_sv == "-N") { - if (i+1 >= argc) { - std::cerr << "ERROR: -N missing 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 parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - std::string_view tv_sv{argv[++i]}; - - if (tv_sv == "id1") { + } else if (parser.parseParam("-G", chat_id)) { + } else if (parser.parseParam("-F", profile_path)) { + } else if (parser.parseParam("-N", self_name)) { + } else if (std::string tv; parser.parseParam("-a", tv)) { + if (tv == "id1") { transfer_variant = TransferE::ID; - } else if (tv_sv == "sha1_single") { + } else if (tv == "sha1_single") { transfer_variant = TransferE::SHA1_SINGLE; - } else if (tv_sv == "sha1_info") { + } else if (tv == "sha1_info") { transfer_variant = TransferE::SHA1_INFO; } else { std::cerr << "ERROR: invalid parameter!\n\n"; PRINT_HELP_AND_BAIL; } - - } else if (arg_sv == "-f") { - if (i+1 >= argc) { - std::cerr << "ERROR: -f missing parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - send_path = argv[++i]; - } else if (arg_sv == "-d") { - if (i+1 >= argc) { - std::cerr << "ERROR: -d missing parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - receive_dump_dir = argv[++i]; - } else if (arg_sv == "-D") { - if (i+1 >= argc) { - std::cerr << "ERROR: -D missing parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - receive_id = argv[++i]; - } else if (arg_sv == "-L") { - tox_disable_local_discovery = true; - } else if (arg_sv == "-U") { - tox_disable_udp = true; - } else if (arg_sv == "-P") { - if (i+2 >= argc) { - std::cerr << "ERROR: -P missing and/or parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - - std::string_view host_sv{argv[++i]}; - std::string_view port_sv{argv[++i]}; - - proxy_host = host_sv; - - auto res = std::from_chars(port_sv.data(), port_sv.data()+port_sv.size(), proxy_port); - if (res.ptr != port_sv.data()+port_sv.size()) { - std::cerr << "ERROR: invalid !\n\n"; - PRINT_HELP_AND_BAIL; - } + } else if (parser.parseParam("-f", send_path)) { + } else if (parser.parseParam("-d", receive_dump_dir)) { + std::cout << "CL going to write to '" << receive_dump_dir << "'\n"; + } else if (parser.parseParam("-D", receive_id)) { + } else if (parser.parseFlag("-L", tox_disable_local_discovery)) { + std::cout << "CL disabled local discovery\n"; + } else if (parser.parseFlag("-U", tox_disable_udp)) { + std::cout << "CL disabled udp\n"; + } else if (parser.parseParam("-P", proxy_host, proxy_port)) { std::cout << "CL set proxy to " << proxy_host << proxy_port << "\n"; - } else if (arg_sv == "-p") { - if (i+1 >= argc) { - std::cerr << "ERROR: -p missing parameter!\n\n"; - PRINT_HELP_AND_BAIL; - } - - std::string_view port_sv{argv[++i]}; - auto res = std::from_chars(port_sv.data(), port_sv.data()+port_sv.size(), tox_port); - if (res.ptr != port_sv.data()+port_sv.size()) { - std::cerr << "ERROR: invalid !\n\n"; - PRINT_HELP_AND_BAIL; - } + } else if (parser.parseParam("-p", tox_port)) { std::cout << "CL set tox_port to " << tox_port << "\n"; + } else if (parser.parseParam("--ft_ack_per_packet", ft_acks_per_packet)) { + } else if (parser.parseParam("--ft_init_retry_timeout_after", ft_init_retry_timeout_after)) { + } else if (parser.parseParam("--ft_sending_resend_without_ack_after", ft_sending_resend_without_ack_after)) { + } else if (parser.parseParam("--ft_sending_give_up_after", ft_sending_give_up_after)) { + } else if (parser.parseParam("--ft_packet_window_size", ft_packet_window_size)) { } else { std::cerr << "ERROR: unknown parameter '" << arg_sv << "' !\n\n"; PRINT_HELP_AND_BAIL; } + + if (parser.error) { + PRINT_HELP_AND_BAIL; + } } if (transfer_variant == TransferE::INVALID) { @@ -158,8 +173,12 @@ void CommandLine::printHelp(void) { << " -p tox_port (bind tox to that port)\n" << "\n" << " FT1:\n" - << " TODO\n" - << "\n" + << " --ft_ack_per_packet\n" + << " --ft_init_retry_timeout_after\n" + << " --ft_sending_resend_without_ack_after\n" + << " --ft_sending_give_up_after\n" + << " --ft_packet_window_size\n" + << " transfer logic:\n" << " TODO\n" ; diff --git a/src/command_line.hpp b/src/command_line.hpp index 9eb531e..1586b54 100644 --- a/src/command_line.hpp +++ b/src/command_line.hpp @@ -55,11 +55,19 @@ struct CommandLine { // -p port (start and end is set to the same port) uint16_t tox_port {0}; - // ---- TODO ---- - // advanced FT1: - // -w packet_window_size - // TODO: all them timeouts + // --ft_ack_per_packet + size_t ft_acks_per_packet {5}; + // --ft_init_retry_timeout_after + float ft_init_retry_timeout_after {10.f}; + // --ft_sending_resend_without_ack_after + float ft_sending_resend_without_ack_after {5.f}; + // --ft_sending_give_up_after + float ft_sending_give_up_after {30.f}; + // --ft_packet_window_size + size_t ft_packet_window_size {5}; + + // ---- TODO ---- // advaced dl: // -I max_incoming_transfers (default 16) diff --git a/src/states/receive_start_sha1.cpp b/src/states/receive_start_sha1.cpp index 04d5b62..25c988f 100644 --- a/src/states/receive_start_sha1.cpp +++ b/src/states/receive_start_sha1.cpp @@ -108,7 +108,7 @@ std::unique_ptr ReceiveStartSHA1::nextState(void) { } } - std::cout << "ReceiveStartSHA1 have " << tmp_have_count << "/" << sha1_info.chunks.size() << "chunks (" << float(tmp_have_count)/sha1_info.chunks.size() << "%)\n"; + std::cout << "ReceiveStartSHA1 have " << tmp_have_count << "/" << sha1_info.chunks.size() << " chunks (" << float(tmp_have_count)/sha1_info.chunks.size() << "%)\n"; } std::cout << "ReceiveStartSHA1 switching state to SHA1\n"; diff --git a/src/tox_client.cpp b/src/tox_client.cpp index 0a88c59..b2bbaea 100644 --- a/src/tox_client.cpp +++ b/src/tox_client.cpp @@ -5,9 +5,6 @@ #include "./states/send_start_sha1.hpp" #include "./states/receive_start_sha1.hpp" -#include "ngc_ft1.h" -#include "tox/tox.h" -#include "toxcore/tox.h" #include #include @@ -124,6 +121,11 @@ ToxClient::ToxClient(const CommandLine& cl) : _ext_ctx = NGC_EXT_new(); NGC_FT1_options ft1_options {}; + ft1_options.acks_per_packet = 5; + ft1_options.init_retry_timeout_after = 10.f; + ft1_options.sending_resend_without_ack_after = 5.f; + ft1_options.sending_give_up_after = 30.f; + ft1_options.packet_window_size = 10; _ft1_ctx = NGC_FT1_new(&ft1_options); NGC_FT1_register_ext(_ft1_ctx, _ext_ctx); @@ -195,11 +197,13 @@ ToxClient::~ToxClient(void) { } bool ToxClient::iterate(void) { - tox_iterate(_tox, this); - NGC_FT1_iterate(_tox, _ft1_ctx); - // HACK: hardcoded 5ms sleep in main - if (_state->iterate(0.005f)) { + float time_delta {0.005f}; + + tox_iterate(_tox, this); + NGC_FT1_iterate(_tox, _ft1_ctx, time_delta); + + if (_state->iterate(time_delta)) { _state = _state->nextState(); if (!_state) {