From 3148f1ea93e9c6a8e6c917d587d6dc986d07e4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sun, 11 Aug 2019 20:19:55 +0200 Subject: [PATCH] Integrate CLI in GUI --- cli/include/chiaki-cli.h | 3 +- cli/src/discover.c | 86 +++++++++++++++++++++++++++++----- cli/src/main.c | 23 ++++++++-- gui/CMakeLists.txt | 4 +- gui/include/discoverycmd.h | 25 ---------- gui/src/discoverycmd.cpp | 94 -------------------------------------- gui/src/main.cpp | 49 ++++++++++++++++---- 7 files changed, 136 insertions(+), 148 deletions(-) delete mode 100644 gui/include/discoverycmd.h delete mode 100644 gui/src/discoverycmd.cpp diff --git a/cli/include/chiaki-cli.h b/cli/include/chiaki-cli.h index 0f34104..0bd1e1b 100644 --- a/cli/include/chiaki-cli.h +++ b/cli/include/chiaki-cli.h @@ -19,12 +19,13 @@ #define CHIAKI_CHIAKI_CLI_H #include +#include #ifdef __cplusplus extern "C" { #endif -CHIAKI_EXPORT int chiaki_cli_cmd_discover(int argc, char *argv[]); +CHIAKI_EXPORT int chiaki_cli_cmd_discover(ChiakiLog *log, int argc, char *argv[]); #ifdef __cplusplus } diff --git a/cli/src/discover.c b/cli/src/discover.c index 76aaec8..c711221 100644 --- a/cli/src/discover.c +++ b/cli/src/discover.c @@ -17,20 +17,26 @@ #include +#include + #include +#include #include +#include static char doc[] = "Send a PS4 discovery request."; +#define ARG_KEY_HOST 'h' + static struct argp_option options[] = { - { "ip", 'i', "IP", 0, "IP to send discovery request to", 0 }, - { 0 } + { "host", ARG_KEY_HOST, "Host", 0, "Host to send discovery request to", 0 }, + { 0 } }; typedef struct arguments { - char *ip; + const char *host; } Arguments; static int parse_opt(int key, char *arg, struct argp_state *state) @@ -39,8 +45,8 @@ static int parse_opt(int key, char *arg, struct argp_state *state) switch(key) { - case 'i': - arguments->ip = arg; + case ARG_KEY_HOST: + arguments->host = arg; break; case ARGP_KEY_ARG: argp_usage(state); @@ -54,21 +60,77 @@ static int parse_opt(int key, char *arg, struct argp_state *state) static struct argp argp = { options, parse_opt, 0, doc, 0, 0, 0 }; -CHIAKI_EXPORT int chiaki_cli_cmd_discover(int argc, char *argv[]) +CHIAKI_EXPORT int chiaki_cli_cmd_discover(ChiakiLog *log, int argc, char *argv[]) { Arguments arguments = { 0 }; - error_t r = argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &arguments); - if(r != 0) + error_t argp_r = argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &arguments); + if(argp_r != 0) return 1; - if(!arguments.ip) + if(!arguments.host) { - fprintf(stderr, "ip for discovery is not set.\n"); + fprintf(stderr, "No host specified, see --help.\n"); return 1; } - // TODO - printf("run discovery\n"); + ChiakiDiscovery discovery; + ChiakiErrorCode err = chiaki_discovery_init(&discovery, log, AF_INET); // TODO: IPv6 + if(err != CHIAKI_ERR_SUCCESS) + { + CHIAKI_LOGE(log, "Discovery init failed"); + return 1; + } + + ChiakiDiscoveryThread thread; + err = chiaki_discovery_thread_start(&thread, &discovery); + if(err != CHIAKI_ERR_SUCCESS) + { + CHIAKI_LOGE(log, "Discovery thread init failed"); + chiaki_discovery_fini(&discovery); + return 1; + } + + struct addrinfo *host_addrinfos; + int r = getaddrinfo(arguments.host, NULL, NULL, &host_addrinfos); + if(r != 0) + { + CHIAKI_LOGE(log, "getaddrinfo failed"); + return 1; + } + + struct sockaddr *host_addr = NULL; + socklen_t host_addr_len = 0; + for(struct addrinfo *ai=host_addrinfos; ai; ai=ai->ai_next) + { + if(ai->ai_protocol != IPPROTO_UDP) + continue; + if(ai->ai_family != AF_INET) // TODO: IPv6 + continue; + + host_addr_len = ai->ai_addrlen; + host_addr = (struct sockaddr *)malloc(host_addr_len); + if(!host_addr) + break; + memcpy(host_addr, ai->ai_addr, host_addr_len); + } + freeaddrinfo(host_addrinfos); + + if(!host_addr) + { + CHIAKI_LOGE(log, "Failed to get addr for hostname"); + return 1; + } + + ((struct sockaddr_in *)host_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT); // TODO: IPv6 + + ChiakiDiscoveryPacket packet; + memset(&packet, 0, sizeof(packet)); + packet.cmd = CHIAKI_DISCOVERY_CMD_SRCH; + + chiaki_discovery_send(&discovery, &packet, host_addr, host_addr_len); + + while(1) + sleep(1); return 0; } \ No newline at end of file diff --git a/cli/src/main.c b/cli/src/main.c index 8e1f708..7395ba8 100644 --- a/cli/src/main.c +++ b/cli/src/main.c @@ -29,11 +29,19 @@ static const char doc[] = "Supported commands are:\n" " discover Discover Consoles.\n"; +#define ARG_KEY_VERBOSE 'v' + static struct argp_option options[] = { + { "verbose", ARG_KEY_VERBOSE, NULL, 0, "Verbose Logging", 0 }, { 0 } }; -static int call_subcmd(struct argp_state *state, const char *name, int (*subcmd)(int argc, char *argv[])) +typedef struct context +{ + ChiakiLog log; +} Context; + +static int call_subcmd(struct argp_state *state, const char *name, int (*subcmd)(ChiakiLog *log, int argc, char *argv[])) { if(state->next < 1 || state->argc < state->next) return 1; @@ -47,7 +55,7 @@ static int call_subcmd(struct argp_state *state, const char *name, int (*subcmd) return 1; snprintf(argv[0], l, "%s %s", state->name, name); - int r = subcmd(argc, argv); + int r = subcmd(state->input, argc, argv); free(argv[0]); return r; @@ -55,8 +63,13 @@ static int call_subcmd(struct argp_state *state, const char *name, int (*subcmd) static int parse_opt(int key, char *arg, struct argp_state *state) { + Context *ctx = state->input; + switch(key) { + case ARG_KEY_VERBOSE: + ctx->log.level_mask = CHIAKI_LOG_ALL; + break; case ARGP_KEY_ARG: if(strcmp(arg, "discover") == 0) exit(call_subcmd(state, "discover", chiaki_cli_cmd_discover)); @@ -74,7 +87,11 @@ static struct argp argp = { options, parse_opt, " [CMD-ARGS...]", doc, 0, 0 int main(int argc, char *argv[]) { - argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, NULL); + Context ctx; + chiaki_log_init(&ctx.log, CHIAKI_LOG_ALL & ~CHIAKI_LOG_VERBOSE, chiaki_log_cb_print, NULL); + + argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &ctx); + return 0; } diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 6c8a9e4..34d4d7f 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -19,8 +19,6 @@ add_executable(chiaki src/streamwindow.cpp include/videodecoder.h src/videodecoder.cpp - include/discoverycmd.h - src/discoverycmd.cpp include/mainwindow.h src/mainwindow.cpp include/dynamicgridwidget.h @@ -39,7 +37,7 @@ add_executable(chiaki src/avopenglframeuploader.cpp) target_include_directories(chiaki PRIVATE include) -target_link_libraries(chiaki chiaki-lib) +target_link_libraries(chiaki chiaki-lib chiaki-cli-lib) target_link_libraries(chiaki FFMPEG::avcodec) target_link_libraries(chiaki Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Multimedia Qt5::OpenGL) if(CHIAKI_GUI_ENABLE_QT_GAMEPAD) diff --git a/gui/include/discoverycmd.h b/gui/include/discoverycmd.h deleted file mode 100644 index 5451b8d..0000000 --- a/gui/include/discoverycmd.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of Chiaki. - * - * Chiaki is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Chiaki is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chiaki. If not, see . - */ - -#ifndef CHIAKI_DISCOVERYCMD_H -#define CHIAKI_DISCOVERYCMD_H - -#include - -int RunDiscoveryCmd(const QString &host); - -#endif //CHIAKI_DISCOVERYCMD_H diff --git a/gui/src/discoverycmd.cpp b/gui/src/discoverycmd.cpp deleted file mode 100644 index 2b2b6b2..0000000 --- a/gui/src/discoverycmd.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of Chiaki. - * - * Chiaki is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Chiaki is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chiaki. If not, see . - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include - - -int RunDiscoveryCmd(const QString &host) -{ - ChiakiLog log; - chiaki_log_init(&log, CHIAKI_LOG_ALL, chiaki_log_cb_print, NULL); - - ChiakiDiscovery discovery; - ChiakiErrorCode err = chiaki_discovery_init(&discovery, &log, AF_INET); // TODO: IPv6 - if(err != CHIAKI_ERR_SUCCESS) - { - CHIAKI_LOGE(&log, "Discovery init failed"); - return 1; - } - - ChiakiDiscoveryThread thread; - err = chiaki_discovery_thread_start(&thread, &discovery); - if(err != CHIAKI_ERR_SUCCESS) - { - CHIAKI_LOGE(&log, "Discovery thread init failed"); - chiaki_discovery_fini(&discovery); - return 1; - } - - struct addrinfo *host_addrinfos; - int r = getaddrinfo(host.toUtf8().constData(), NULL, NULL, &host_addrinfos); - if(r != 0) - { - CHIAKI_LOGE(&log, "getaddrinfo failed"); - return 1; - } - - struct sockaddr *host_addr = nullptr; - socklen_t host_addr_len = 0; - for(struct addrinfo *ai=host_addrinfos; ai; ai=ai->ai_next) - { - if(ai->ai_protocol != IPPROTO_UDP) - continue; - if(ai->ai_family != AF_INET) // TODO: IPv6 - continue; - - host_addr_len = ai->ai_addrlen; - host_addr = (struct sockaddr *)malloc(host_addr_len); - if(!host_addr) - break; - memcpy(host_addr, ai->ai_addr, host_addr_len); - } - freeaddrinfo(host_addrinfos); - - if(!host_addr) - CHIAKI_LOGE(&log, "Failed to get addr for hostname"); - else - { - ((struct sockaddr_in *)host_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT); // TODO: IPv6 - - ChiakiDiscoveryPacket packet; - memset(&packet, 0, sizeof(packet)); - packet.cmd = CHIAKI_DISCOVERY_CMD_SRCH; - - chiaki_discovery_send(&discovery, &packet, host_addr, host_addr_len); - } - - while(1) - sleep(1); - - return 0; -} \ No newline at end of file diff --git a/gui/src/main.cpp b/gui/src/main.cpp index 4e25dfc..e9f3b3f 100644 --- a/gui/src/main.cpp +++ b/gui/src/main.cpp @@ -1,10 +1,11 @@ #include #include -#include #include #include +#include + #include #include @@ -15,7 +16,16 @@ #include #include #include +#include +struct CLICommand +{ + int (*cmd)(ChiakiLog *log, int argc, char *argv[]); +}; + +static const QMap cli_commands = { + { "discover", { chiaki_cli_cmd_discover } } +}; int RunStream(QApplication &app, const StreamSessionConnectInfo &connect_info); int RunMain(QApplication &app); @@ -35,10 +45,15 @@ int main(int argc, char *argv[]) QApplication::setApplicationName("Chiaki"); QCommandLineParser parser; + parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments); parser.addHelpOption(); - parser.addPositionalArgument("command", "stream or discover"); - parser.addPositionalArgument("host", "Address to connect to"); + QStringList cmds; + cmds.append("stream"); + cmds.append(cli_commands.keys()); + + parser.addPositionalArgument("command", cmds.join(", ")); + parser.addPositionalArgument("host", "Address to connect to (when using the stream command)"); QCommandLineOption regist_key_option("registkey", "", "registkey"); parser.addOption(regist_key_option); @@ -62,13 +77,13 @@ int main(int argc, char *argv[]) if(args.length() == 0) return RunMain(app); - if(args.length() < 2) - parser.showHelp(1); - - QString host = args[1]; - if(args[0] == "stream") { + if(args.length() < 2) + parser.showHelp(1); + + QString host = args[1]; + StreamSessionConnectInfo connect_info; connect_info.log_level_mask = CHIAKI_LOG_ALL & ~CHIAKI_LOG_VERBOSE; @@ -87,11 +102,25 @@ int main(int argc, char *argv[]) if(connect_info.registkey.isEmpty() || connect_info.ostype.isEmpty() || connect_info.auth.isEmpty() || connect_info.morning.isEmpty() || connect_info.did.isEmpty()) parser.showHelp(1); + return RunStream(app, connect_info); } - else if(args[0] == "discover") + else if(cli_commands.contains(args[0])) { - return RunDiscoveryCmd(args[1]); + ChiakiLog log; + // TODO: add verbose arg + chiaki_log_init(&log, CHIAKI_LOG_ALL & ~CHIAKI_LOG_VERBOSE, chiaki_log_cb_print, nullptr); + + const auto &cmd = cli_commands[args[0]]; + int sub_argc = args.count(); + QVector sub_argv_b(sub_argc); + QVector sub_argv(sub_argc); + for(size_t i=0; i