From d7a6f4d08d87a833c353d555271854b102d81599 Mon Sep 17 00:00:00 2001 From: ezratl Date: Sat, 21 Dec 2019 18:37:35 -0500 Subject: [PATCH] Add command line option for python client --- src/core/Configuration.cpp | 6 ++++ src/core/Configuration.h | 10 ++++-- src/core/ScannerSM.cpp | 2 +- src/core/constants.h | 3 ++ src/piScan_backend.cpp | 8 +++-- src/scan/RadioSystem.cpp | 7 ---- src/scan/SystemList.cpp | 8 ++++- src/scan/SystemList.h | 2 +- src/server/ServerManager.cpp | 16 ++++++---- src/server/ServerManager.h | 8 ++++- src/server/SocketServer.cpp | 62 ++++++++++++++++++++++++++++++++++++ src/server/SocketServer.h | 13 ++++++-- src/sigproc/Demodulator.cpp | 6 ++-- 13 files changed, 123 insertions(+), 28 deletions(-) diff --git a/src/core/Configuration.cpp b/src/core/Configuration.cpp index b0d1593..9924375 100644 --- a/src/core/Configuration.cpp +++ b/src/core/Configuration.cpp @@ -76,6 +76,9 @@ void Configuration::loadConfig(){ _socketConfig.maxConnections = pt.get("config.socket.max_connections", MAX_TCP_CONNECTIONS); _socketConfig.tcpPort = pt.get("config.socket.port", DEFAULT_TCP_PORT); + _socketConfig.spawnLocalClient = pt.get("config.socket.use_gui", DEFAULT_SPAWN_CLIENT); + _socketConfig.pythonClient = pt.get("config.socket.client_path", DEFAULT_PY_CLIENT_LOCATION); + _socketConfig.pythonBinary = pt.get("config.socket.python_path", DEFAULT_PY_ENV_LOCATION); } @@ -115,6 +118,9 @@ void Configuration::saveConfig(){ pt.put("config.socket.port", _socketConfig.tcpPort); pt.put("config.socket.max_connections", _socketConfig.maxConnections); + pt.put("config.socket.use_gui", _socketConfig.spawnLocalClient); + pt.put("config.socket.client_path", _socketConfig.pythonClient); + pt.put("config.socket.python_path", _socketConfig.pythonBinary); write_json(path.c_str(), pt); } diff --git a/src/core/Configuration.h b/src/core/Configuration.h index f0bf826..421e7c4 100644 --- a/src/core/Configuration.h +++ b/src/core/Configuration.h @@ -34,14 +34,18 @@ struct GeneralConfig { int logfileVerbosity = DEFAULT_LOGFILE_VERBOSITY; }; -#define DEFAULT_TCP_PORT 1234 -#define MAX_TCP_CONNECTIONS 5 -#define DEFAULT_SPAWN_CLIENT false +#define DEFAULT_TCP_PORT 1234 +#define MAX_TCP_CONNECTIONS 5 +#define DEFAULT_SPAWN_CLIENT false +#define DEFAULT_PY_CLIENT_LOCATION "./" +#define DEFAULT_PY_ENV_LOCATION "python" struct SocketServerConfig { int tcpPort = DEFAULT_TCP_PORT; int maxConnections = MAX_TCP_CONNECTIONS; bool spawnLocalClient = DEFAULT_SPAWN_CLIENT; + std::string pythonClient = DEFAULT_PY_CLIENT_LOCATION; + std::string pythonBinary = DEFAULT_PY_ENV_LOCATION; }; #define DEFAULT_SQUELCH 0 diff --git a/src/core/ScannerSM.cpp b/src/core/ScannerSM.cpp index f1395cd..f3c7efe 100644 --- a/src/core/ScannerSM.cpp +++ b/src/core/ScannerSM.cpp @@ -87,7 +87,7 @@ void ScannerSM::ST_Load(EventData* data){ LOG_F(INFO, "Loaded %u systems", _systems.size()); //_currentSystem = _systems[0]; - _systems.sortBins(2000000); + _systems.sortBins(getTunerSampleRate()); // do not issue event - SM will wait until an event is generated before proceeding //InternalEvent(ST_SCAN); diff --git a/src/core/constants.h b/src/core/constants.h index 1f1ecc5..46d2e00 100644 --- a/src/core/constants.h +++ b/src/core/constants.h @@ -12,6 +12,9 @@ namespace piscan { +#define TUNER_RETUNE_TIME 225000 +#define DEMOD_BUFFER_TIME 7000 + enum ConnectionLevel { RECEIVE_ONLY = 0, VIEWER, FULL_CONTROL, }; diff --git a/src/piScan_backend.cpp b/src/piScan_backend.cpp index da04351..71f104e 100644 --- a/src/piScan_backend.cpp +++ b/src/piScan_backend.cpp @@ -392,11 +392,12 @@ int main(int argc, char **argv) { Configuration& config = Configuration::getConfig(); bool useDebugConsole = false; + bool spawnClient = false; int logVerbosity = config.getGeneralConfig().logfileVerbosity; int c; - while((c = getopt(argc,argv,"dp:f:")) != -1){ + while((c = getopt(argc,argv,"dp:f:l")) != -1){ switch(c){ case 'd': useDebugConsole = true; @@ -409,6 +410,9 @@ int main(int argc, char **argv) { if(optarg) logVerbosity = std::atoi(optarg); break; + case 'l': + spawnClient = true; + break; } } @@ -434,7 +438,7 @@ int main(int argc, char **argv) { { scanner.start(); - connectionManager.start(useDebugConsole); + connectionManager.start(useDebugConsole, spawnClient); demod.start(); /*while(sysRun){ diff --git a/src/scan/RadioSystem.cpp b/src/scan/RadioSystem.cpp index 1d348c2..c9bbfb5 100644 --- a/src/scan/RadioSystem.cpp +++ b/src/scan/RadioSystem.cpp @@ -68,7 +68,6 @@ EntryPtr RadioSystem::makeDCChannel(ptree& pt) { AnalogSystem::AnalogSystem(ptree pt, size_t index) : RadioSystem(pt.get(TAG_KEY, ""), pt.get(LOCKOUT_KEY, false)) { setSysIndex(index); - RAW_LOG_F(1, "New analog system\n\tTag: %s\n\tLockout: %i", tag().c_str(), lockedOut()); BOOST_FOREACH(ptree::value_type& v, pt.get_child(CHANNELS_KEY)){ ptree entryPT = v.second; @@ -84,12 +83,6 @@ AnalogSystem::AnalogSystem(ptree pt, size_t index) : RadioSystem(pt.get(TAG_KEY, if(entry == nullptr) continue; - RAW_LOG_F(1, "\t\tNew %s entry", type.c_str()); - RAW_LOG_F(1, "\t\tTag: %s", entry->tag().c_str()); - RAW_LOG_F(1, "\t\tFreq: %li", entry->freq()); - RAW_LOG_F(1, "\t\tLockout: %i", entry->isLockedOut()); - RAW_LOG_F(1, "\t\tDelay: %i", entry->delay()); - addEntry(entry); } } diff --git a/src/scan/SystemList.cpp b/src/scan/SystemList.cpp index af42263..f5788f6 100644 --- a/src/scan/SystemList.cpp +++ b/src/scan/SystemList.cpp @@ -12,6 +12,7 @@ #include "SystemList.h" #include "Configuration.h" #include "loguru.hpp" +#include "constants.h" using namespace piscan; using namespace std::experimental; @@ -117,7 +118,7 @@ EntryPtr SystemList::getNextEntry(){ } -void SystemList::sortBins(int bandwidth){ +void SystemList::sortBins(long long bandwidth){ LOG_F(1, "Sorting bandwidth chunks..."); size_t numEntries = 0; @@ -161,6 +162,11 @@ void SystemList::sortBins(int bandwidth){ RAW_LOG_F(1, binPrint.c_str()); binPrint = ""; } + + double totalTimeS = ((numEntries * DEMOD_BUFFER_TIME) + (_bins.size() * (TUNER_RETUNE_TIME + DEMOD_BUFFER_TIME))) / 1000000; + double totalChannels = numEntries + _bins.size(); + double avgScanRate = totalChannels / totalTimeS; + LOG_F(1, "Max average scan rate: %.1lf channels per second", avgScanRate); } void SystemList::merge(EntryPtr arr[], int l, int m, int r) diff --git a/src/scan/SystemList.h b/src/scan/SystemList.h index 81758ac..05bf77c 100644 --- a/src/scan/SystemList.h +++ b/src/scan/SystemList.h @@ -39,7 +39,7 @@ public: EntryPtr getNextEntry(); - void sortBins(int bandwidth); + void sortBins(long long bandwidth); private: class EntryBin: public std::vector{ diff --git a/src/server/ServerManager.cpp b/src/server/ServerManager.cpp index 85b3f79..ce08da7 100644 --- a/src/server/ServerManager.cpp +++ b/src/server/ServerManager.cpp @@ -37,10 +37,13 @@ ServerManager::ServerManager(boost::asio::io_service& io_service, MessageReceive } -void ServerManager::start(bool useDebugServer){ - if(useDebugServer) - _servers.push_back(new DebugServer(*this)); - _servers.push_back(new SocketServer(*this, _io_service)); +void ServerManager::start(bool useDebugServer, bool spawnLocalClient){ + if(useDebugServer){ + _debugServer = new DebugServer(*this); + _servers.push_back(_debugServer); + } + _sockServer = new SocketServer(*this, _io_service); + _servers.push_back(_sockServer); _run = true; _queueThread = std::thread(&ServerManager::_queueThreadFunc, this); @@ -48,8 +51,9 @@ void ServerManager::start(bool useDebugServer){ for(unsigned int i = 0; i < _servers.size(); i++) _servers[i]->start(); - //auto message = std::make_shared(SERVER_MAN, ControllerMessage::NOTIFY_READY); - //_centralQueue.giveMessage(message); + if(spawnLocalClient) + _sockServer->spawnLocalClient(); + LOG_F(1, "Connection Manager started"); notifyReady(); } diff --git a/src/server/ServerManager.h b/src/server/ServerManager.h index 292ad33..c5811ce 100644 --- a/src/server/ServerManager.h +++ b/src/server/ServerManager.h @@ -17,14 +17,18 @@ #include "request.h" #include "connection.h" #include "clientmessage.h" +#include "SocketServer.h" +#include "DebugServer.h" #include "BackendServer.h" #include "synchronize.h" + #define MAX_CONNECTIONS 5 namespace piscan { class Connection; +class SocketServer; class ServerManager : public MessageReceiver, public ServerInterface, public Synchronizable { public: @@ -34,7 +38,7 @@ public: delete _servers[i]; _queueThread.join(); }; - void start(bool useDebugServer); + void start(bool useDebugServer, bool spawnLocalClient); void stop(); void allowConnections(); void disconnectClients(); @@ -57,6 +61,8 @@ private: bool _allowConnections = false; bool _run = false; + DebugServer* _debugServer = nullptr; + SocketServer* _sockServer = nullptr; void _queueThreadFunc(void); void _handleMessage(std::shared_ptr message); diff --git a/src/server/SocketServer.cpp b/src/server/SocketServer.cpp index 29b2bf0..eb8e39b 100644 --- a/src/server/SocketServer.cpp +++ b/src/server/SocketServer.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include #include "SocketServer.h" #include "loguru.hpp" @@ -240,6 +242,9 @@ void SocketServer::start() { LOG_F(ERROR, "Exception caught: %s", e.what()); stop(); } + + if(config.spawnLocalClient) + _spawnPythonClient(); } void SocketServer::stop(){ @@ -247,6 +252,15 @@ void SocketServer::stop(){ LOG_F(INFO, "Stopping TCP server"); _acceptor.close(); } + + //if(_clientPid > 0) + // _stopPythonClient(); +} + +void SocketServer::spawnLocalClient(){ + SocketServerConfig& config = Configuration::getConfig().getSocketConfig(); + if(!config.spawnLocalClient) + _spawnPythonClient(); } void SocketServer::giveMessage(std::shared_ptr message){ @@ -278,3 +292,51 @@ void SocketServer::handle_accept(SocketConnection::pointer connection, start_accept(); } +void SocketServer::_spawnPythonClient(){ + LOG_F(INFO, "Creating local GUI client"); + + SocketServerConfig& config = Configuration::getConfig().getSocketConfig(); + std::string scriptPath = config.pythonClient; + std::string pythonPath = config.pythonBinary; + + const char* argv[16]; + argv[0] = pythonPath.c_str(); + argv[1] = "client.py"; + argv[2] = "-l"; + argv[3] = "-p"; + argv[4] = std::to_string(config.tcpPort).c_str(); + argv[5] = NULL; + + _clientPid = fork(); + + if(_clientPid == 0){ + //child process + LOG_F(1, "Python command: %s", argv[0]); + LOG_F(1, "Client path: %s", argv[1]); + + chdir(scriptPath.c_str()); + + execvp(argv[0], const_cast(argv)); + + LOG_F(ERROR, "Starting client failed: %s", strerror(errno)); + exit(0); + } + else if(_clientPid > 0){ + // parent + LOG_F(1, "Process creation success"); + signal(SIGCHLD, SIG_IGN); + } + else { + // fork failed + LOG_F(ERROR, "Failed to create local client"); + } +} + +void SocketServer::_stopPythonClient(){ + // send SIGINT to client + int status; + pid_t childPid = waitpid(_clientPid, &status, 0); + + if(childPid == -1) + LOG_F(ERROR, "waitpid failed"); +} diff --git a/src/server/SocketServer.h b/src/server/SocketServer.h index 59765c3..4062726 100644 --- a/src/server/SocketServer.h +++ b/src/server/SocketServer.h @@ -8,15 +8,17 @@ #ifndef SERVER_SOCKETSERVER_H_ #define SERVER_SOCKETSERVER_H_ +#include +#include +#include +#include + #include "BackendServer.h" #include "constants.h" #include "ServerManager.h" #include "request.pb.h" #include "Configuration.h" -#include -#include -#include using namespace boost::asio; using ip::tcp; @@ -75,16 +77,21 @@ public: void start(); void stop(); + void spawnLocalClient(); void giveMessage(std::shared_ptr message); private: tcp::acceptor _acceptor; uint16_t _listenPort = DEFAULT_TCP_PORT; int _activeConnections = 0; + pid_t _clientPid = 0; void start_accept(); void handle_accept(SocketConnection::pointer connection, const boost::system::error_code& err); + + void _spawnPythonClient(); + void _stopPythonClient(); }; } #endif /* SERVER_SOCKETSERVER_H_ */ diff --git a/src/sigproc/Demodulator.cpp b/src/sigproc/Demodulator.cpp index e6e7da8..3a497ce 100644 --- a/src/sigproc/Demodulator.cpp +++ b/src/sigproc/Demodulator.cpp @@ -10,7 +10,7 @@ #include "Demodulator.h" #include "loguru.hpp" -#define DEFAULT_SDR_SAMPLE_RATE 2048000 +#define DEFAULT_SDR_SAMPLE_RATE 1024000 #define INIT_FREQUENCY 100000000 #define NUM_RATES_DEFAULT 4 @@ -174,12 +174,12 @@ bool Demodulator::setFrequency(long long freq) { if(std::abs(_cubic->getFrequency() - freq) >= (_cubic->getSampleRate() / 2)){ _cubic->setFrequency(freq); //also arbitrary - usleep(225000); + usleep(TUNER_RETUNE_TIME); } _demodMgr.getCurrentModem()->setFrequency(freq); //this is totally arbitrary - usleep(7000); + usleep(DEMOD_BUFFER_TIME); _currentFreq = freq;