Parse received datagrams.
This commit is contained in:
parent
1155180fa5
commit
bdba0234b2
|
@ -1,6 +1,8 @@
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
project(s20)
|
project(s20)
|
||||||
|
|
||||||
|
add_definitions(-std=gnu++11)
|
||||||
|
|
||||||
find_package(Qt5 REQUIRED Core Network)
|
find_package(Qt5 REQUIRED Core Network)
|
||||||
add_executable(s20 main.cpp socket.cpp)
|
add_executable(s20 main.cpp socket.cpp)
|
||||||
target_link_libraries(s20 Qt5::Core Qt5::Network)
|
target_link_libraries(s20 Qt5::Core Qt5::Network)
|
||||||
|
|
22
main.cpp
22
main.cpp
|
@ -37,24 +37,26 @@ int main(int argc, char *argv[])
|
||||||
std::vector<Socket> sockets;
|
std::vector<Socket> sockets;
|
||||||
|
|
||||||
readDiscoverDatagrams(udpSocketGet, sockets);
|
readDiscoverDatagrams(udpSocketGet, sockets);
|
||||||
|
delete udpSocketGet;
|
||||||
listSockets(sockets);
|
listSockets(sockets);
|
||||||
|
|
||||||
char command;
|
char command;
|
||||||
unsigned int number = 1;
|
unsigned int number = 1;
|
||||||
bool cont=true;
|
bool cont=true;
|
||||||
while(cont)
|
while (cont)
|
||||||
{
|
{
|
||||||
std::cout << "s - pick another socket (default is 1)\nt - toggle power state\nq - quit" << std::endl;
|
std::cout << "s - pick another socket (default is 1)\nt - toggle power state\nq - quit" << std::endl;
|
||||||
std::cin >> command;
|
std::cin >> command;
|
||||||
switch(command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case 'q':
|
case 'q':
|
||||||
cont = false;
|
cont = false;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
std::cin >> number;
|
std::cin >> number;
|
||||||
case 't':
|
case 't':
|
||||||
sockets[number-1].toggle();
|
sockets[number-1].toggle();
|
||||||
|
listSockets(sockets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -64,6 +66,6 @@ void listSockets(std::vector<Socket> const &sockets)
|
||||||
{
|
{
|
||||||
for (std::vector<Socket>::const_iterator i = sockets.begin() ; i != sockets.end(); ++i)
|
for (std::vector<Socket>::const_iterator i = sockets.begin() ; i != sockets.end(); ++i)
|
||||||
{
|
{
|
||||||
std::cout << "IP Address: " << i->ip.toString().toStdString() << "\t MAC Address: " << i->mac.toHex().toStdString() << "\t Powered: " << i->powered << 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
67
socket.cpp
67
socket.cpp
|
@ -18,6 +18,7 @@
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
Socket::Socket(QHostAddress IPaddress, QByteArray reply)
|
Socket::Socket(QHostAddress IPaddress, QByteArray reply)
|
||||||
|
@ -26,28 +27,68 @@ Socket::Socket(QHostAddress IPaddress, QByteArray reply)
|
||||||
mac = reply.mid(7, 6);
|
mac = reply.mid(7, 6);
|
||||||
rmac = mac;
|
rmac = mac;
|
||||||
std::reverse(rmac.begin(), rmac.end());
|
std::reverse(rmac.begin(), rmac.end());
|
||||||
powered = reply.right(1) == QByteArray::fromHex("01");
|
|
||||||
QByteArray twenties = QByteArray::fromHex("20 20 20 20 20 20");
|
|
||||||
QByteArray zeros = QByteArray::fromHex("00 00 00 00");
|
|
||||||
|
|
||||||
datagram[Subscribe] = QByteArray::fromHex("68 64 00 1e 63 6c") + mac + twenties + rmac + twenties;
|
powered = reply.right(1) == one;
|
||||||
datagram[PowerOn] = QByteArray::fromHex("68 64 00 17 64 63") + mac + twenties + zeros + QByteArray::fromHex("01");
|
|
||||||
datagram[PowerOff] = QByteArray::fromHex("68 64 00 17 64 63") + mac + twenties + zeros + QByteArray::fromHex("00");
|
commandID[Subscribe] = QByteArray::fromHex("63 6c");
|
||||||
|
commandID[PowerOn] = QByteArray::fromHex("73 66");
|
||||||
|
commandID[PowerOff] = commandID[PowerOn];
|
||||||
|
commandID[TableData] = QByteArray::fromHex("72 74");
|
||||||
|
|
||||||
|
// 2 hex bytes are the total length of the message
|
||||||
|
datagram[Subscribe] = magicKey + QByteArray::fromHex("00 1e") + commandID[Subscribe] + mac + twenties + rmac + twenties;
|
||||||
|
datagram[PowerOn] = magicKey + QByteArray::fromHex("00 17 64 63") + mac + twenties + zeros + one;
|
||||||
|
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 + one + zeros + zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Socket::toggle()
|
bool Socket::toggle()
|
||||||
{
|
{
|
||||||
sendDatagram(datagram[Subscribe]); // TODO: process replies
|
bool powerOld = powered;
|
||||||
QThread::msleep(100); // wait a little to make toggle reliable
|
while (powerOld == powered)
|
||||||
sendDatagram(datagram[powered ? PowerOff : PowerOn]);
|
{
|
||||||
powered = !powered;
|
sendDatagram(Subscribe);
|
||||||
|
sendDatagram(powerOld ? PowerOff : PowerOn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket::sendDatagram(QByteArray datagram)
|
void Socket::sendDatagram(Datagram d)
|
||||||
{
|
{
|
||||||
|
udpSocketGet = new QUdpSocket();
|
||||||
|
udpSocketGet->bind(QHostAddress::Any, 10000);
|
||||||
|
|
||||||
udpSocketSend = new QUdpSocket();
|
udpSocketSend = new QUdpSocket();
|
||||||
udpSocketSend->connectToHost(ip, 10000);
|
udpSocketSend->connectToHost(ip, 10000);
|
||||||
udpSocketSend->write(datagram);
|
udpSocketSend->write(datagram[d]);
|
||||||
udpSocketSend->disconnectFromHost();
|
|
||||||
delete udpSocketSend;
|
delete udpSocketSend;
|
||||||
|
readDatagrams(udpSocketGet, d);
|
||||||
|
delete udpSocketGet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Socket::readDatagrams(QUdpSocket *udpSocketGet, Datagram d)
|
||||||
|
{
|
||||||
|
while (udpSocketGet->waitForReadyRead(300)) // 300ms
|
||||||
|
{
|
||||||
|
while (udpSocketGet->hasPendingDatagrams())
|
||||||
|
{
|
||||||
|
QByteArray datagramGet;
|
||||||
|
datagramGet.resize(udpSocketGet->pendingDatagramSize());
|
||||||
|
QHostAddress sender;
|
||||||
|
quint16 senderPort;
|
||||||
|
|
||||||
|
udpSocketGet->readDatagram(datagramGet.data(), datagramGet.size(), &sender, &senderPort);
|
||||||
|
|
||||||
|
if (datagramGet.left(2) == magicKey && datagramGet.mid(4,2) == commandID[d])
|
||||||
|
{
|
||||||
|
std::cout << datagramGet.toHex().toStdString() << std::endl;
|
||||||
|
switch (d)
|
||||||
|
{
|
||||||
|
case Subscribe:
|
||||||
|
case PowerOff:
|
||||||
|
case PowerOn:
|
||||||
|
powered = datagramGet.right(1) == one;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
18
socket.h
18
socket.h
|
@ -30,10 +30,20 @@ public:
|
||||||
bool powered;
|
bool powered;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendDatagram(QByteArray datagram);
|
enum Datagram {Subscribe, PowerOff, PowerOn, TableData, MaxCommands};
|
||||||
|
|
||||||
enum {Subscribe, PowerOff, PowerOn};
|
void sendDatagram(Datagram);
|
||||||
QByteArray datagram[3];
|
void readDatagrams(QUdpSocket *udpSocketGet, Datagram d);
|
||||||
|
|
||||||
|
QByteArray commandID[MaxCommands];
|
||||||
|
QByteArray datagram[MaxCommands];
|
||||||
QByteArray rmac; // Reveresed mac
|
QByteArray rmac; // Reveresed mac
|
||||||
QUdpSocket *udpSocketSend;
|
|
||||||
|
const QByteArray magicKey = QByteArray::fromHex("68 64"); // recognize datagrams from the socket
|
||||||
|
const QByteArray twenties = QByteArray::fromHex("20 20 20 20 20 20"); // mac address padding
|
||||||
|
const QByteArray zeros = QByteArray::fromHex("00 00 00 00");
|
||||||
|
const QByteArray zero = QByteArray::fromHex("00");
|
||||||
|
const QByteArray one = QByteArray::fromHex("01");
|
||||||
|
|
||||||
|
QUdpSocket *udpSocketSend, *udpSocketGet;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue