2015-01-14 00:50:55 +00:00
/*************************************************************************
* Copyright ( C ) 2015 by Andrius Š tikonas < andrius @ stikonas . eu > *
* *
* 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 < http : //www.gnu.org/licenses/>.*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "socket.h"
2015-01-14 13:55:28 +00:00
# include <algorithm>
2015-01-25 19:39:15 +00:00
# include <iostream>
2015-02-03 01:24:47 +00:00
# include <QThread>
# include <QUdpSocket>
2015-01-14 13:55:28 +00:00
2015-01-31 15:28:34 +00:00
Socket : : Socket ( QHostAddress IPaddress , QByteArray reply )
2015-01-14 00:50:55 +00:00
{
ip = IPaddress ;
2015-01-31 15:28:34 +00:00
mac = reply . mid ( 7 , 6 ) ;
2015-01-14 13:55:28 +00:00
rmac = mac ;
2015-01-31 15:28:34 +00:00
std : : reverse ( rmac . begin ( ) , rmac . end ( ) ) ;
2015-01-14 13:55:28 +00:00
2015-01-31 15:28:34 +00:00
powered = reply . right ( 1 ) = = one ;
// 68:64:00:06:71:61 initial detection ??
// 68:64:00:1e:63:6c:ac:cf:23:35:f5:8c:20:20:20:20:20:20:38:38:38:38:38:38:20:20:20:20:20:20 // to 42.121.111.208
2015-01-25 19:39:15 +00:00
2015-01-31 15:28:34 +00:00
commandID [ Subscribe ] = QByteArray : : fromHex ( " 63 6c " ) ;
commandID [ PowerOn ] = QByteArray : : fromHex ( " 73 66 " ) ;
2015-01-25 19:39:15 +00:00
commandID [ PowerOff ] = commandID [ PowerOn ] ;
2015-01-31 15:28:34 +00:00
commandID [ TableData ] = QByteArray : : fromHex ( " 72 74 " ) ;
2015-01-26 00:55:20 +00:00
commandID [ SocketData ] = commandID [ TableData ] ;
commandID [ TimingData ] = commandID [ TableData ] ;
2015-01-31 15:28:34 +00:00
commandID [ WriteSocketData ] = QByteArray : : fromHex ( " 74 6d " ) ;
2015-01-25 19:39:15 +00:00
// 2 hex bytes are the total length of the message
2015-01-31 15:28:34 +00:00
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 + QByteArray : : fromHex ( " 01 00 00 " ) + zeros ;
2015-02-03 01:24:47 +00:00
udpSocket = new QUdpSocket ( ) ;
udpSocket - > connectToHost ( ip , 10000 ) ;
2015-02-01 01:42:45 +00:00
2015-02-03 01:24:47 +00:00
subscribed = false ;
2015-02-01 01:42:45 +00:00
subscribeTimer = new QTimer ( this ) ;
2015-02-03 01:24:47 +00:00
subscribeTimer - > setInterval ( 200 ) ; // increase later, debug
subscribeTimer - > setSingleShot ( false ) ;
2015-02-01 01:42:45 +00:00
connect ( subscribeTimer , & QTimer : : timeout , this , & Socket : : subscribe ) ;
subscribeTimer - > start ( ) ;
}
Socket : : ~ Socket ( )
{
delete subscribeTimer ;
2015-02-03 01:24:47 +00:00
delete udpSocket ;
2015-02-01 01:42:45 +00:00
}
void Socket : : subscribe ( )
{
2015-02-03 01:24:47 +00:00
qWarning ( ) < < " subscribing " ;
2015-02-01 01:42:45 +00:00
sendDatagram ( Subscribe ) ;
2015-01-14 13:55:28 +00:00
}
2015-01-26 00:55:20 +00:00
void Socket : : toggle ( )
2015-01-14 13:55:28 +00:00
{
2015-02-03 01:24:47 +00:00
sendDatagram ( powered ? PowerOff : PowerOn ) ;
2015-01-14 13:55:28 +00:00
}
2015-02-03 01:24:47 +00:00
void Socket : : changeSocketName ( QString newName )
2015-01-31 15:28:34 +00:00
{
2015-02-03 01:24:47 +00:00
QByteArray name = newName . toLatin1 ( ) . leftJustified ( 16 , ' ' , true ) ;
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 " ) /* record number = 1*/ + versionID + mac + twenties + rmac + twenties + remotePassword + name + 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 " ) ;
2015-01-31 15:28:34 +00:00
sendDatagram ( WriteSocketData ) ;
}
2015-01-26 00:55:20 +00:00
void Socket : : tableData ( )
{
2015-01-31 15:28:34 +00:00
sendDatagram ( TableData ) ;
datagram [ SocketData ] = magicKey + QByteArray : : fromHex ( " 00 1d " ) + commandID [ SocketData ] + mac + twenties + zeros + QByteArray : : fromHex ( " 04 00 00 " ) + zeros ;
datagram [ TimingData ] = magicKey + QByteArray : : fromHex ( " 00 1d " ) + commandID [ TimingData ] + mac + twenties + zeros + QByteArray : : fromHex ( " 03 00 00 " ) + zeros ;
// table number + 00 + version number
sendDatagram ( SocketData ) ;
sendDatagram ( TimingData ) ;
2015-01-26 00:55:20 +00:00
}
2015-01-31 15:28:34 +00:00
void Socket : : sendDatagram ( Datagram d )
2015-01-14 13:55:28 +00:00
{
2015-02-03 01:24:47 +00:00
qWarning ( ) < < " sending datagram " < < d < < " subscribed = " < < subscribed ;
2015-02-01 01:42:45 +00:00
udpSocket - > write ( datagram [ d ] ) ;
2015-01-31 15:28:34 +00:00
}
2015-01-25 19:39:15 +00:00
2015-01-31 15:28:34 +00:00
bool Socket : : parseReply ( QByteArray reply )
{
2015-02-03 01:24:47 +00:00
qWarning ( ) < < " parsing datagram " ;
2015-01-31 15:28:34 +00:00
if ( reply . left ( 2 ) ! = magicKey )
2015-02-01 01:42:45 +00:00
{
2015-01-31 15:28:34 +00:00
return false ;
2015-02-01 01:42:45 +00:00
}
2015-01-31 15:28:34 +00:00
QByteArray id = reply . mid ( 4 , 2 ) ;
unsigned int datagram = std : : distance ( commandID , std : : find ( commandID , commandID + MaxCommands , id ) ) ; // match commandID with enum
if ( datagram = = 3 ) // determine the table number
{
unsigned int table = reply [ reply . indexOf ( zeros ) + 4 ] ; // Table number immediately follows zeros
switch ( table )
{
case 1 :
datagram = TableData ;
2015-02-03 01:24:47 +00:00
qWarning ( ) < < " got Table " ;
2015-01-31 15:28:34 +00:00
break ;
case 3 :
datagram = TimingData ;
2015-02-03 01:24:47 +00:00
qWarning ( ) < < " got Timing " ;
2015-01-31 15:28:34 +00:00
break ;
case 4 :
datagram = SocketData ;
2015-02-03 01:24:47 +00:00
qWarning ( ) < < " got Socket " ;
2015-01-31 15:28:34 +00:00
break ;
default :
return false ;
2015-01-25 19:39:15 +00:00
}
}
2015-02-01 01:42:45 +00:00
// std::cout << reply.toHex().toStdString() << " " << datagram << std::endl; // for debugging purposes only
2015-01-31 15:28:34 +00:00
switch ( datagram )
{
case Subscribe :
2015-02-03 01:24:47 +00:00
subscribed = true ;
subscribeTimer - > setInterval ( 2 * 60 * 1000 ) ; // 2min
qWarning ( ) < < " got Subscribe " ;
2015-01-31 15:28:34 +00:00
case PowerOff :
case PowerOn :
2015-02-01 01:42:45 +00:00
{
bool poweredOld = powered ;
2015-01-31 15:28:34 +00:00
powered = reply . right ( 1 ) = = one ;
2015-02-01 01:42:45 +00:00
if ( powered ! = poweredOld )
Q_EMIT stateChanged ( ) ;
2015-01-31 15:28:34 +00:00
break ;
2015-02-01 01:42:45 +00:00
}
2015-01-31 15:28:34 +00:00
case TableData :
2015-02-03 01:24:47 +00:00
// qWarning() << "got TableData";
2015-01-31 15:28:34 +00:00
// FIXME: order might be swapped;
socketTableVersion = reply . mid ( reply . indexOf ( QByteArray : : fromHex ( " 000100000600 " ) ) + 6 , 2 ) ;
// 000100000600
break ;
case SocketData :
2015-02-03 01:24:47 +00:00
// qWarning() << "got SocketData";
2015-01-31 15:28:34 +00:00
remotePassword = reply . mid ( reply . indexOf ( rmac + twenties ) + 12 , 12 ) ;
name = reply . mid ( reply . indexOf ( rmac + twenties ) + 24 , 16 ) ;
2015-02-03 01:24:47 +00:00
versionID = reply . mid ( reply . indexOf ( rmac + twenties ) - 14 , 2 ) ;
2015-02-01 01:42:45 +00:00
Q_EMIT stateChanged ( ) ;
2015-01-31 15:28:34 +00:00
break ;
case TimingData :
2015-02-03 01:24:47 +00:00
// qWarning() << "got TimingData";
2015-01-31 15:28:34 +00:00
break ;
2015-02-01 01:42:45 +00:00
case WriteSocketData :
2015-02-03 01:24:47 +00:00
sendDatagram ( SocketData ) ;
// Q_EMIT stateChanged();
2015-02-01 01:42:45 +00:00
break ;
2015-01-31 15:28:34 +00:00
default :
return false ;
}
return true ;
2015-01-14 13:55:28 +00:00
}
2015-01-31 15:28:34 +00:00
2015-02-01 01:42:45 +00:00
QByteArray Socket : : fromIP ( unsigned char a , unsigned char b , unsigned char c , unsigned char d )
2015-01-31 15:28:34 +00:00
{
2015-02-01 01:42:45 +00:00
return QByteArray : : number ( a ) + QByteArray : : number ( b ) + QByteArray : : number ( c ) + QByteArray : : number ( d ) ;
}