#include #include #include #include #include #include #include #include "qcommandlineparser.h" #include "mainclass.h" #include "gpiomanager.h" #include "randommanager.h" MainClass::MainClass(QObject *parent) : QObject(parent) , m_input(nullptr) , m_device(Gpio) , m_address(QHostAddress::Any) , m_port(39415) , m_verbose(false) , m_lastTime(0) { } void MainClass::main() { getOpts(); InputManager* input = nullptr; if (m_device == Gpio) input = new GpioManager(this); else if (m_device == Random) input = new RandomManager(this); if (!input->init(m_channels)) { std::cerr << "Failed to initialize device" << std::endl; exit(1); return; } auto server = new ServerManager(this); if (!server->init(m_address, m_port)) { std::cerr << "Failed to bind socket" << std::endl; exit(2); return; } m_input = new InputBusiness(input, m_channels, server); m_timer = new QTimer(this); m_timer->setSingleShot(false); m_timer->setInterval(0); connect(m_timer, SIGNAL(timeout()), this, SLOT(maySend())); m_timer->start(); } void MainClass::maySend() { struct timeval time; gettimeofday(&time, NULL); if (time.tv_usec - m_lastTime < 100) usleep(100 - (time.tv_usec - m_lastTime)); gettimeofday(&time, NULL); m_lastTime = time.tv_usec; auto values = m_input->readAndSend(time.tv_usec); if (m_verbose) { std::cout << time.tv_usec << ":"; foreach (auto value, values) { std::cout << " " << value.toInt(); } std::cout << std::endl; } } void MainClass::getOpts() { QCommandLineParser parser; parser.setApplicationDescription("Server for GPIO monitoring"); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption device((QStringList() << "d" << "device"), "device to use [gpio|rand]", "DEVICE", "gpio"); parser.addOption(device); QCommandLineOption channel((QStringList() << "c" << "channel"), "channel to monitor", "CHANNEL"); parser.addOption(channel); QCommandLineOption address((QStringList() << "a" << "address"), "address to bind socket", "ADDRESS", m_address.toString()); parser.addOption(address); QCommandLineOption port((QStringList() << "p" << "port"), "port to bind socket [1-65535]", "PORT", QString::number(m_port)); parser.addOption(port); QCommandLineOption verbose((QStringList() << "verbose"), "enable verbose mode"); parser.addOption(verbose); parser.process(*qApp); auto dev = parser.value(device); if (dev == "gpio") m_device = Gpio; else if (dev == "rand" || dev == "random") m_device = Random; else { std::cerr << "Invalid device" << std::endl; parser.showHelp(EX_USAGE); } foreach (auto channel, parser.values(channel)) m_channels.append(channel); if (m_channels.empty()) { std::cerr << "At least one channel is required" << std::endl; parser.showHelp(EX_USAGE); } m_address = parser.value(address); if (m_address.isNull()) { std::cerr << "Invalid address" << std::endl; parser.showHelp(EX_USAGE); } bool ok = false; m_port = parser.value(port).toInt(&ok); if (!ok || m_port <= 0 || m_port > 653535) { std::cerr << "Invalid port" << std::endl; parser.showHelp(EX_USAGE); } m_verbose = parser.isSet(verbose); }