diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 70b5072..73d61f7 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -12,7 +12,9 @@ add_executable(chiaki include/streamwindow.h src/streamwindow.cpp include/videodecoder.h - src/videodecoder.cpp) + src/videodecoder.cpp + include/discoverycmd.h + src/discoverycmd.cpp) target_include_directories(chiaki PRIVATE include) target_link_libraries(chiaki chiaki-lib) diff --git a/gui/include/discoverycmd.h b/gui/include/discoverycmd.h new file mode 100644 index 0000000..5451b8d --- /dev/null +++ b/gui/include/discoverycmd.h @@ -0,0 +1,25 @@ +/* + * 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 new file mode 100644 index 0000000..1701f3f --- /dev/null +++ b/gui/src/discoverycmd.cpp @@ -0,0 +1,93 @@ +/* + * 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; + + ChiakiDiscovery discovery; + ChiakiErrorCode err = chiaki_discovery_init(&discovery, &log, AF_INET); // TODO: IPv6 + if(err != CHIAKI_ERR_SUCCESS) + { + CHIAKI_LOGE(&log, "Discovery init failed\n"); + return 1; + } + + ChiakiDiscoveryThread thread; + err = chiaki_discovery_thread_start(&thread, &discovery); + if(err != CHIAKI_ERR_SUCCESS) + { + CHIAKI_LOGE(&log, "Discovery thread init failed\n"); + 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\n"); + 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\n"); + 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 5da505c..2948d07 100644 --- a/gui/src/main.cpp +++ b/gui/src/main.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -11,6 +12,66 @@ #include #include #include +#include + + +int RunStream(QApplication &app, const QString &host, const QString ®istkey, const QString &ostype, const QString &auth, const QString &morning, const QString &did); + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QApplication::setApplicationName("Chiaki"); + + QCommandLineParser parser; + parser.addHelpOption(); + + parser.addPositionalArgument("command", "Command"); + parser.addPositionalArgument("host", "Host"); + + QCommandLineOption regist_key_option("registkey"); + parser.addOption(regist_key_option); + + QCommandLineOption ostype_option("ostype", "Win10.0.0"); + parser.addOption(ostype_option); + + QCommandLineOption auth_option("auth"); + parser.addOption(auth_option); + + QCommandLineOption morning_option("morning"); + parser.addOption(morning_option); + + QCommandLineOption did_option("did"); + parser.addOption(did_option); + + + parser.process(app); + QStringList args = parser.positionalArguments(); + + if(args.length() < 2) + parser.showHelp(1); + + QString host = args[1]; + + if(args[0] == "stream") + { + QString registkey = parser.value(regist_key_option); + QString ostype = parser.value(ostype_option); + QString auth = parser.value(auth_option); + QString morning = parser.value(morning_option); + QString did = parser.value(did_option); + if(registkey.isEmpty() || ostype.isEmpty() || auth.isEmpty() || morning.isEmpty() || did.isEmpty()) + parser.showHelp(1); + return RunStream(app, host, registkey, ostype, auth, morning, did); + } + else if(args[0] == "discover") + { + return RunDiscoveryCmd(args[1]); + } + else + { + parser.showHelp(1); + } +} QAudioOutput *audio_out; @@ -38,28 +99,28 @@ void video_sample_cb(uint8_t *buf, size_t buf_size, void *user) } -int main(int argc, char *argv[]) +int RunStream(QApplication &app, const QString &host, const QString ®istkey, const QString &ostype, const QString &auth, const QString &morning, const QString &did) { - if(argc != 7) - { - printf("Usage: %s \n", argv[0]); - return 1; - } + QByteArray host_str = host.toUtf8(); + QByteArray registkey_str = registkey.toUtf8(); + QByteArray ostype_str = ostype.toUtf8(); ChiakiConnectInfo connect_info; - connect_info.host = argv[1]; - connect_info.regist_key = argv[2]; - connect_info.ostype = argv[3]; + connect_info.host = host_str.constData(); + connect_info.regist_key = registkey_str.constData(); + connect_info.ostype = ostype_str.constData(); - size_t auth_len = strlen(argv[4]); + QByteArray auth_str = auth.toUtf8(); + size_t auth_len = auth_str.length(); if(auth_len > sizeof(connect_info.auth)) auth_len = sizeof(connect_info.auth); - memcpy(connect_info.auth, argv[4], auth_len); + memcpy(connect_info.auth, auth_str.constData(), auth_len); if(auth_len < sizeof(connect_info.auth)) memset(connect_info.auth + auth_len, 0, sizeof(connect_info.auth) - auth_len); size_t morning_size = sizeof(connect_info.morning); - ChiakiErrorCode err = chiaki_base64_decode(argv[5], strlen(argv[5]), connect_info.morning, &morning_size); + QByteArray morning_str = morning.toUtf8(); + ChiakiErrorCode err = chiaki_base64_decode(morning_str.constData(), morning_str.length(), connect_info.morning, &morning_size); if(err != CHIAKI_ERR_SUCCESS || morning_size != sizeof(connect_info.morning)) { printf("morning invalid.\n"); @@ -67,16 +128,14 @@ int main(int argc, char *argv[]) } size_t did_size = sizeof(connect_info.did); - err = chiaki_base64_decode(argv[6], strlen(argv[6]), connect_info.did, &did_size); + QByteArray did_str = did.toUtf8(); + err = chiaki_base64_decode(did_str.constData(), did_str.length(), connect_info.did, &did_size); if(err != CHIAKI_ERR_SUCCESS || did_size != sizeof(connect_info.did)) { printf("did invalid.\n"); return 1; } - argc = 1; - QApplication app(argc, argv); - StreamWindow window; window.resize(640, 360); window.show(); @@ -136,6 +195,5 @@ int main(int argc, char *argv[]) delete audio_out; - - return ret; -} \ No newline at end of file + return 0; +}