From 748ad8cb9109888a19138ab510f80e88f514128c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 31 Jan 2015 18:12:20 +0000 Subject: [PATCH] Move input handling to another thread and enable event loop. --- CMakeLists.txt | 2 +- consolereader.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++ consolereader.h | 38 ++++++++++++++++++++++ discover.h | 6 ++-- main.cpp | 55 ++++++-------------------------- socket.cpp | 3 -- socket.h | 5 +++ 7 files changed, 136 insertions(+), 53 deletions(-) create mode 100644 consolereader.cpp create mode 100644 consolereader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d6bcda..5bd9c81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,5 +4,5 @@ project(s20) add_definitions(-std=gnu++11) find_package(Qt5 REQUIRED Core Network) -add_executable(s20 main.cpp socket.cpp) +add_executable(s20 main.cpp socket.cpp consolereader.cpp) target_link_libraries(s20 Qt5::Core Qt5::Network) diff --git a/consolereader.cpp b/consolereader.cpp new file mode 100644 index 0000000..851775a --- /dev/null +++ b/consolereader.cpp @@ -0,0 +1,80 @@ +/************************************************************************* + * Copyright (C) 2015 by Andrius Štikonas * + * * + * This program 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. * + * * + * This program 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 this program. If not, see .* + *************************************************************************/ + +#include + +#include "consolereader.h" + +ConsoleReader::ConsoleReader(std::vector *sockets_vector) +{ + sockets = sockets_vector; +} + +ConsoleReader::~ConsoleReader() +{ + // +} + +void ConsoleReader::run() +{ + char command; + unsigned int number = 0; + bool cont = true; + + while (cont) + { + listSockets(); + std::cout << "d - update table data\nn - change socket name\ns - pick another socket (default is 1)\np - toggle power state\nq - quit" << std::endl; + std::cin >> command; + switch (command) + { + case 'd': + (*sockets)[number].tableData(); + break; + case 'n': +// std::cout << "Enter new name (max 16 characters)" << std::endl; +// string name; +// std::cin >> name; + (*sockets)[number].changeSocketName(); + break; + case 'p': + (*sockets)[number].toggle(); + break; + case 'q': + cont = false; + emit(QCoreApplication::quit()); + break; + case 's': + std::cin >> number; + --number; // count from 0 + break; + default: + std::cout << "Invalid command" << std::endl; + } + } +} + +void ConsoleReader::listSockets() +{ + for (std::vector::const_iterator i = sockets->begin() ; i != sockets->end(); ++i) + { + std::cout << "___________________________________________________________________________\n" << std::endl; + std::cout << "IP Address: " << i->ip.toString().toStdString() << "\t MAC Address: " << i->mac.toHex().toStdString() << "\t Power: " << (i->powered ? "On" : "Off") << std::endl; + std::cout << "Socket Name: " << i->name.toStdString() << "\t Remote Password: " << i->remotePassword.toStdString() << std::endl; + } + std::cout << "___________________________________________________________________________\n" << std::endl; +} diff --git a/consolereader.h b/consolereader.h new file mode 100644 index 0000000..7f34e9b --- /dev/null +++ b/consolereader.h @@ -0,0 +1,38 @@ +/************************************************************************* + * Copyright (C) 2015 by Andrius Štikonas * + * * + * This program 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. * + * * + * This program 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 this program. If not, see .* + *************************************************************************/ + +#ifndef CONSOLEREADER_H +#define CONSOLEREADER_H + +#include +#include + +#include "socket.h" + +class ConsoleReader : public QThread +{ +public: + ConsoleReader(std::vector *sockets_vector); + ~ConsoleReader(); + void run (); + +private: + void listSockets(); + std::vector *sockets; +}; + +#endif /* CONSOLEREADER_H */ diff --git a/discover.h b/discover.h index c32a769..d62f92a 100644 --- a/discover.h +++ b/discover.h @@ -19,7 +19,7 @@ QByteArray discover = QByteArray::fromHex("68 64 00 06 71 61"); -void readDiscoverDatagrams(QUdpSocket *udpSocketGet, std::vector &sockets) +void readDiscoverDatagrams(QUdpSocket *udpSocketGet, std::vector *sockets) { while (udpSocketGet->waitForReadyRead(500)) // 500ms { @@ -35,7 +35,7 @@ void readDiscoverDatagrams(QUdpSocket *udpSocketGet, std::vector &socket if (datagramGet != discover && datagramGet.left(2) == QByteArray::fromHex("68 64")) { bool duplicate = false; - for(std::vector::const_iterator i = sockets.begin() ; i != sockets.end(); ++i) + for(std::vector::const_iterator i = sockets->begin() ; i != sockets->end(); ++i) { if (i->ip == sender) duplicate = true; @@ -43,7 +43,7 @@ void readDiscoverDatagrams(QUdpSocket *udpSocketGet, std::vector &socket if(!duplicate) { const Socket socket(sender, datagramGet); - sockets.push_back(socket); + sockets->push_back(socket); } } } diff --git a/main.cpp b/main.cpp index 586169c..c552021 100644 --- a/main.cpp +++ b/main.cpp @@ -18,13 +18,15 @@ #include #include +#include "consolereader.h" #include "discover.h" -void readDiscoverDatagrams(QUdpSocket *udpSocketGet, std::vector &sockets); void listSockets(std::vector const &sockets); int main(int argc, char *argv[]) { + QCoreApplication app(argc, argv); + QUdpSocket *udpSocketSend = new QUdpSocket(); QUdpSocket *udpSocketGet = new QUdpSocket(); @@ -34,54 +36,15 @@ int main(int argc, char *argv[]) udpSocketSend->write(discover); udpSocketSend->disconnectFromHost(); delete udpSocketSend; - std::vector sockets; + std::vector *sockets = new std::vector; readDiscoverDatagrams(udpSocketGet, sockets); delete udpSocketGet; - char command; - unsigned int number = 0; - bool cont=true; - while (cont) - { - listSockets(sockets); - std::cout << "d - update table data\nn - change socket name\ns - pick another socket (default is 1)\np - toggle power state\nq - quit" << std::endl; - std::cin >> command; - switch (command) - { - case 'd': - sockets[number].tableData(); - break; - case 'n': -// std::cout << "Enter new name (max 16 characters)" << std::endl; -// string name; -// std::cin >> name; - sockets[number].changeSocketName(); - break; - case 'p': - sockets[number].toggle(); - break; - case 'q': - cont = false; - break; - case 's': - std::cin >> number; - --number; // count from 0 - break; - default: - std::cout << "Invalid command" << std::endl; - } - } - return 0; -} + ConsoleReader reader(sockets); + reader.start(); -void listSockets(std::vector const &sockets) -{ - for (std::vector::const_iterator i = sockets.begin() ; i != sockets.end(); ++i) - { - std::cout << "___________________________________________________________________________\n" << std::endl; - std::cout << "IP Address: " << i->ip.toString().toStdString() << "\t MAC Address: " << i->mac.toHex().toStdString() << "\t Power: " << (i->powered ? "On" : "Off") << std::endl; - std::cout << "Socket Name: " << i->name.toStdString() << "\t Remote Password: " << i->remotePassword.toStdString() << std::endl; - } - std::cout << "___________________________________________________________________________\n" << std::endl; + int exitCode = app.exec(); + reader.wait(); + return exitCode; } diff --git a/socket.cpp b/socket.cpp index 6a7838f..440679e 100644 --- a/socket.cpp +++ b/socket.cpp @@ -19,7 +19,6 @@ #include #include -#include Socket::Socket ( QHostAddress IPaddress, QByteArray reply ) { @@ -46,8 +45,6 @@ Socket::Socket ( QHostAddress IPaddress, QByteArray reply ) datagram[PowerOff] = magicKey + QByteArray::fromHex ( "00 17 64 63" ) + mac + twenties + zeros + zero; datagram[TableData] = magicKey + QByteArray::fromHex ( "00 1d" ) + commandID[TableData] + mac + twenties + zeros + QByteArray::fromHex ( "01 00 00" ) + zeros; - tableData(); - datagram[WriteSocketData] = magicKey + QByteArray::fromHex ( "00 a5" ) + commandID[WriteSocketData] + mac + twenties + zeros + QByteArray::fromHex ( "04:00:01")/*table number and unknown*/ + QByteArray::fromHex("8a:00") /* record length = 138 bytes*/ + QByteArray::fromHex (":01:00:43:25" ) + mac + twenties + rmac + twenties + QByteArray::fromHex ( "38:38:38:38:38:38:20:20:20:20:20:20" ) + QByteArray ( "Heater " ) + QByteArray::fromHex ( "04:00:20:00:00:00:14:00:00:00:05:00:00:00:10:27") + fromIP(42,121,111,208) + QByteArray::fromHex("10:27") + "vicenter.orvibo.com" + " " + twenties + twenties + twenties + fromIP(192,168,1,212) + QByteArray::fromHex ( "c0:a8:01:01:ff:ff:ff:00:01:01:00:08:00:ff:00:00" ); } diff --git a/socket.h b/socket.h index bea08b6..3900463 100644 --- a/socket.h +++ b/socket.h @@ -15,6 +15,9 @@ * along with this program. If not, see .* *************************************************************************/ +#ifndef SOCKET_H +#define SOCKET_H + #include #include #include @@ -53,3 +56,5 @@ private: QUdpSocket *udpSocketSend, *udpSocketGet; }; + +#endif /* SOCKET_H */