Parse received datagrams.

This commit is contained in:
Andrius Štikonas 2015-01-25 19:39:15 +00:00
parent 1155180fa5
commit bdba0234b2
4 changed files with 82 additions and 27 deletions

View File

@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 2.8)
project(s20)
add_definitions(-std=gnu++11)
find_package(Qt5 REQUIRED Core Network)
add_executable(s20 main.cpp socket.cpp)
target_link_libraries(s20 Qt5::Core Qt5::Network)

View File

@ -37,24 +37,26 @@ int main(int argc, char *argv[])
std::vector<Socket> sockets;
readDiscoverDatagrams(udpSocketGet, sockets);
delete udpSocketGet;
listSockets(sockets);
char command;
unsigned int number = 1;
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::cin >> command;
switch(command)
switch (command)
{
case 'q':
cont = false;
break;
case 's':
std::cin >> number;
case 't':
sockets[number-1].toggle();
case 'q':
cont = false;
break;
case 's':
std::cin >> number;
case 't':
sockets[number-1].toggle();
listSockets(sockets);
}
}
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)
{
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;
}
}

View File

@ -18,6 +18,7 @@
#include "socket.h"
#include <algorithm>
#include <iostream>
#include <QThread>
Socket::Socket(QHostAddress IPaddress, QByteArray reply)
@ -26,28 +27,68 @@ Socket::Socket(QHostAddress IPaddress, QByteArray reply)
mac = reply.mid(7, 6);
rmac = mac;
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;
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");
powered = reply.right(1) == one;
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()
{
sendDatagram(datagram[Subscribe]); // TODO: process replies
QThread::msleep(100); // wait a little to make toggle reliable
sendDatagram(datagram[powered ? PowerOff : PowerOn]);
powered = !powered;
bool powerOld = powered;
while (powerOld == 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->connectToHost(ip, 10000);
udpSocketSend->write(datagram);
udpSocketSend->disconnectFromHost();
udpSocketSend->write(datagram[d]);
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;
}
}
}
}
}

View File

@ -30,10 +30,20 @@ public:
bool powered;
private:
void sendDatagram(QByteArray datagram);
enum Datagram {Subscribe, PowerOff, PowerOn, TableData, MaxCommands};
enum {Subscribe, PowerOff, PowerOn};
QByteArray datagram[3];
void sendDatagram(Datagram);
void readDatagrams(QUdpSocket *udpSocketGet, Datagram d);
QByteArray commandID[MaxCommands];
QByteArray datagram[MaxCommands];
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;
};