Masterctrl/Sources/AvReceiver/AVReceiverDevice.cpp

388 lines
9.0 KiB
C++

#include "AVReceiverDevice.h"
#include "GlobalDefine.h"
#include "ProtocolDefs.h"
#include <QDataStream>
/**
Command syntax
@ SUBUNIT : FUNCNAME = Parameter [CR/LF]
[1] [2] [3] [4] [5] [6] [7]
[1] Start Delimiter (@) : The beginning of a command
[2] Sub Unit Name : Indicating whether the command is for System, any zones or
any internal input sources as iPod, Tuner, Sirius, and
Rhapsody etc
[3] Command Delimiter (:) : Sub Unit Name and Function name are separated by this
delimiter
[4] Function Name : Specifying actual operations, some of them are abbreviated
[5] Parameter Delimiter (=) : Separating the Function Name and its Parameter (Value)
[6] Parameter : Showing a parameter value of the command
[7] End Delimiter : The end of a command, Carriage
*/
CAVReceiverDevice::CAVReceiverDevice()
{
mReceiverSocket = new QTcpSocket;
mDisconnectTimer = new QTimer;
mStateRequestTimer = new QTimer;
mDisconnectTimer->setSingleShot(true);
mDisconnectTimer->stop();
mStateRequestTimer->setSingleShot(true);
mStateRequestTimer->setInterval(RECEIVER_STATE_UPDATE_TIMEOUT);
connect(mDisconnectTimer,SIGNAL(timeout()),this,SLOT(DisconnectTimerExpired()));
connect(mReceiverSocket,SIGNAL(connected()),this,SLOT(SocketConnected()));
connect(mReceiverSocket,SIGNAL(disconnected()),this,SLOT(SocketDisconnected()));
connect(mReceiverSocket,SIGNAL(readyRead()),this,SLOT(SocketRX()));
connect(mStateRequestTimer,SIGNAL(timeout()),this,SLOT(StateRequestTimerExpired()));
}
CAVReceiverDevice::~CAVReceiverDevice()
{
mReceiverSocket->disconnectFromHost();
mReceiverSocket->waitForDisconnected(100);
delete mReceiverSocket;
delete mDisconnectTimer;
delete mStateRequestTimer;
}
int CAVReceiverDevice::Start()
{
mStateRequestTimer->start();
return RET_OK;
}
int CAVReceiverDevice::ConnectToReceiver()
{
if(mReceiverSocket->state() != QAbstractSocket::ConnectedState)
{
mReceiverSocket->connectToHost("192.168.50.101",50000);
}
return RET_OK;
}
int CAVReceiverDevice::DisconnectReceiver()
{
if(mReceiverSocket->state() != QAbstractSocket::ConnectedState)
return RET_ERROR;
mReceiverSocket->disconnectFromHost();
return RET_OK;
}
int CAVReceiverDevice::AnalyseRxData(QByteArray data)
{
QString Data(data);
if(data == "\r\n")
{
// qDebug("AV Receiver: Heartbeat received");
return RET_OK;
}
QStringList Commands = Data.split("\r\n",QString::SkipEmptyParts);
for(int i = 0; i<Commands.size();i++)
{
QString Cmd = Commands.at(i);
Cmd.remove("@");
QString SubUnit = Cmd.left(Cmd.indexOf(QChar(':')));
Cmd.remove(SubUnit + ":");
QString Function = Cmd.left(Cmd.indexOf(QChar('=')));
Cmd.remove(Function + "=");
QString Param = Cmd.remove("\r\n");
UpdateReceiverStateParam(SubUnit,Function,Param);
// qDebug("Received SubUnit:[%s], Function:[%s], Param:[%s]",qPrintable(SubUnit),qPrintable(Function),qPrintable(Param));
}
return RET_OK;
}
int CAVReceiverDevice::UpdateReceiverStateParam(QString SubUnit, QString Fcn, QString Param)
{
static bool AllValid = false;
CAvReceiverMainStatus *UnitStatus = 0;
if(SubUnit == "MAIN")
{
UnitStatus = &mReceiverStatus;
}
else if(SubUnit == "ZONE2")
{
UnitStatus = &mZone2Status;
}
if(UnitStatus != 0)
{
if(Fcn == "PWR")
{
if(Param == "On")
{
UnitStatus->mMainPwrStatus = true;
}
else
UnitStatus->mMainPwrStatus = false;
}
if(Fcn == "SLEEP")
{
if(Param == "On")
{
UnitStatus->mMainSleepStatus = true;
}
else
{
UnitStatus->mMainSleepStatus = false;
}
}
else if(Fcn == "VOL")
{
bool OK;
float Vol = Param.toFloat(&OK);
if(OK)
{
UnitStatus->mMainVolume = Vol;
}
else
{
UnitStatus->mMainPwrStatus = 0xDEADBEEF;
}
}
else if(Fcn == "MUTE")
{
if(Param == "On")
{
UnitStatus->mIsMute = true;
}
else
{
UnitStatus->mIsMute = false;
}
}
else if (Fcn == "INP")
{
UnitStatus->mInput = Param;
}
else if (Fcn == "SOUNDPRG")
{
UnitStatus->mProgram = Param;
}
}
return RET_OK;
}
int CAVReceiverDevice::SendReceiverCommand(QString Command)
{
//Make sure the escape sequence is correct.
// Command.remove("\r");
// Command.remove("\n");
// Command.append("\r\n");
if(mReceiverSocket->state() == QAbstractSocket::ConnectedState)
{
mReceiverSocket->write(Command.toUtf8());
// qDebug("Sent command to receiver : %s",qPrintable(mPendingCommand));
}
else
{
mPendingCommand = Command;
ConnectToReceiver();
}
return RET_OK;
}
void CAVReceiverDevice::SocketConnected()
{
if(mPendingCommand.isEmpty() == false)
{
QByteArray data =mPendingCommand.toLatin1();
int ret = mReceiverSocket->write(data);
// qDebug("Sent command to receiver : %s",qPrintable(mPendingCommand));
mPendingCommand.clear();
return;
}
qDebug("Receiver Connected");
}
void CAVReceiverDevice::SocketDisconnected()
{
// qDebug("Receiver Disconnected");
}
void CAVReceiverDevice::SocketRX()
{
// qDebug("Receiver response:");
QByteArray Data = mReceiverSocket->readAll();
// qDebug("%s",qPrintable(Data));
AnalyseRxData(Data);
}
void CAVReceiverDevice::DisconnectTimerExpired()
{
DisconnectReceiver();
mDisconnectTimer->stop();
}
int CAVReceiverDevice::DisconnectReceiverDelayed(int Delay)
{
if(Delay > 5000)
{
Delay = 5000;
}
mDisconnectTimer->start(Delay);
return RET_OK;
}
void CAVReceiverDevice::StateRequestTimerExpired()
{
if(mReceiverSocket->state() != QAbstractSocket::ConnectedState)
{
SendReceiverCommand("@MAIN:BASIC=?\r\n@ZONE2:BASIC=?\r\n");
mStateRequestTimer->start(RECEIVER_STATE_UPDATE_TIMEOUT);
DisconnectReceiverDelayed(1000);
}
else
{
//A transaction is going on... wait and retry later
mStateRequestTimer->start(500);
}
}
////// Network Interface Implementation
int CAVReceiverDevice::SetZone2(bool OnOff)
{
QString Cmd = "@ZONE2:PWR=";
if(OnOff)
{
Cmd += "On\r\n";
}
else
Cmd += "Standby\r\n";
SendReceiverCommand(Cmd);
DisconnectReceiverDelayed();
return RET_OK;
}
int CAVReceiverDevice::SetMainZone(bool OnOff)
{
QString Cmd = "@MAIN:PWR=";
if(OnOff)
{
Cmd += "On\r\n";
}
else
Cmd += "Standby\r\n";
SendReceiverCommand(Cmd);
DisconnectReceiverDelayed();
return RET_OK;
}
int CAVReceiverDevice::SetSpeakers(int SpeakerA, int SpeakerB)
{
//First, speaker A.
if(SpeakerA != RECEIVER_DONT_CHANGE_SPK)
{
QString Cmd = "@MAIN:SPEAKERA=";
if(SpeakerA == RECEIVER_SET_SPK_ON)
{
Cmd += "On\r\n";
}
else if(SpeakerA == RECEIVER_SET_SPK_OFF)
{
Cmd += "Off\r\n";
}
else if(SpeakerA == RECEVIVER_TOGGLE_SPK)
{
// if(mReceiverStatus.mSpeakerAState == true)
// {
// Cmd += "Off";
// }
// else
// {
// Cmd += "On";
// }
}
else
{
qDebug("Got a SetSpeakers() command with invalid parameter for Speaker A. Weirds stuff!!");
}
SendReceiverCommand(Cmd);
}
//Then, speaker B.
if(SpeakerB != RECEIVER_DONT_CHANGE_SPK)
{
QString Cmd = "@MAIN:SPEAKERB=";
if(SpeakerB == RECEIVER_SET_SPK_ON)
{
Cmd += "On";
}
else if(SpeakerB == RECEIVER_SET_SPK_OFF)
{
Cmd += "Off";
}
else if(SpeakerB == RECEVIVER_TOGGLE_SPK)
{
// if(mReceiverStatus.mSpeakerAState == true)
// {
// Cmd += "Off";
// }
// else
// {
// Cmd += "On";
// }
}
else
{
qDebug("Got a SetSpeakers() command with invalid parameter for Speaker B. Weirds stuff!!");
}
SendReceiverCommand(Cmd);
}
DisconnectReceiverDelayed();
return RET_OK;
}
int CAVReceiverDevice::SendRawCommand(QString Cmd)
{
return SendReceiverCommand(Cmd);
DisconnectReceiverDelayed(2000);
}
QByteArray CAVReceiverDevice::GetReceiverStatus()
{
QByteArray StatusArray;
QDataStream Strm(&StatusArray,QIODevice::WriteOnly | QIODevice::Unbuffered);
Strm.device()->seek(0);
Strm << mReceiverStatus
<< mZone2Status ;
return StatusArray;
}