added states and event handling from tv

This commit is contained in:
Simon Stürz 2014-08-08 16:40:12 +02:00 committed by Michael Zanetti
parent 07ac559665
commit 202def72a7
9 changed files with 630 additions and 26 deletions

View File

@ -27,6 +27,16 @@ VendorId lgVendorId = VendorId("a9af9673-78db-4226-a16b-f34b304f7041");
DeviceClassId lgSmartTvDeviceClassId = DeviceClassId("1d41b5a8-74ff-4a12-b365-c7bbe610848f");
StateTypeId tvReachableStateTypeId = StateTypeId("b056c36b-df87-4177-8d5d-1e7c1e8cdc7a");
StateTypeId tv3DModeStateTypeId = StateTypeId("8ad3d77f-d340-495d-8c2a-5569a80e9d36");
StateTypeId tvVolumeLevelStateTypeId = StateTypeId("07d39a6e-7eab-42d0-851d-9f3bcd3bbb57");
StateTypeId tvMuteStateTypeId = StateTypeId("a6ac9061-3de7-403a-a646-790ca5d73764");
StateTypeId tvChannelTypeStateTypeId = StateTypeId("84c86670-77c7-4fc6-9e23-abca066e76aa");
StateTypeId tvChannelNameStateTypeId = StateTypeId("265dc5f7-3f4d-4002-a6fe-2a53986bcf1d");
StateTypeId tvChannelNumberStateTypeId = StateTypeId("881629a3-4ce2-42ba-8ce6-10d90c383799");
StateTypeId tvProgramNameStateTypeId = StateTypeId("3f53e52e-1ad7-40e7-8080-76908e720cac");
StateTypeId tvInputSourceIndexStateTypeId = StateTypeId("e895017a-139f-410c-bfb2-4d008104e164");
StateTypeId tvInputSourceLabelNameStateTypeId = StateTypeId("58b734ec-2269-4c57-99e1-e1eeee401053");
ActionTypeId commandVolumeUpActionTypeId = ActionTypeId("ac5d7dcd-dfe8-4a94-9ab9-21b3f804b39e");
ActionTypeId commandVolumeDownActionTypeId = ActionTypeId("62b17bec-f461-4ffa-93d1-67a9430d55e1");
@ -80,6 +90,7 @@ QList<DeviceClass> DevicePluginLgSmartTv::supportedDevices() const
paramTypes.append(ParamType("uuid", QVariant::String));
paramTypes.append(ParamType("model", QVariant::String));
paramTypes.append(ParamType("host address", QVariant::String));
paramTypes.append(ParamType("port", QVariant::Int));
paramTypes.append(ParamType("location", QVariant::String));
paramTypes.append(ParamType("manufacturer", QVariant::String));
paramTypes.append(ParamType("key", QVariant::String));
@ -95,6 +106,60 @@ QList<DeviceClass> DevicePluginLgSmartTv::supportedDevices() const
reachableState.setDefaultValue(false);
tvStates.append(reachableState);
StateType tv3DModeState(tv3DModeStateTypeId);
tv3DModeState.setName("3D Mode");
tv3DModeState.setType(QVariant::Bool);
tv3DModeState.setDefaultValue(false);
tvStates.append(tv3DModeState);
StateType tvVolumeLevelState(tvVolumeLevelStateTypeId);
tvVolumeLevelState.setName("volume level");
tvVolumeLevelState.setType(QVariant::Int);
tvVolumeLevelState.setDefaultValue(-1);
tvStates.append(tvVolumeLevelState);
StateType tvMuteState(tvMuteStateTypeId);
tvMuteState.setName("mute");
tvMuteState.setType(QVariant::Bool);
tvMuteState.setDefaultValue(false);
tvStates.append(tvMuteState);
StateType tvChannelTypeState(tvChannelTypeStateTypeId);
tvChannelTypeState.setName("channel type");
tvChannelTypeState.setType(QVariant::String);
tvChannelTypeState.setDefaultValue("");
tvStates.append(tvChannelTypeState);
StateType tvChannelNameState(tvChannelNameStateTypeId);
tvChannelNameState.setName("channel name");
tvChannelNameState.setType(QVariant::String);
tvChannelNameState.setDefaultValue("");
tvStates.append(tvChannelNameState);
StateType tvChannelNumberState(tvChannelNumberStateTypeId);
tvChannelNumberState.setName("channel number");
tvChannelNumberState.setType(QVariant::Int);
tvChannelNumberState.setDefaultValue(-1);
tvStates.append(tvChannelNumberState);
StateType tvProgramNameState(tvProgramNameStateTypeId);
tvProgramNameState.setName("program name");
tvProgramNameState.setType(QVariant::String);
tvProgramNameState.setDefaultValue("");
tvStates.append(tvProgramNameState);
StateType tvInputSourceIndexState(tvInputSourceIndexStateTypeId);
tvInputSourceIndexState.setName("input source index");
tvInputSourceIndexState.setType(QVariant::Int);
tvInputSourceIndexState.setDefaultValue(-1);
tvStates.append(tvInputSourceIndexState);
StateType tvInputSourceLabelNameState(tvInputSourceLabelNameStateTypeId);
tvInputSourceLabelNameState.setName("input source label");
tvInputSourceLabelNameState.setType(QVariant::String);
tvInputSourceLabelNameState.setDefaultValue("");
tvStates.append(tvInputSourceLabelNameState);
deviceClassLgSmartTv.setStateTypes(tvStates);
// Actions
@ -201,12 +266,16 @@ QPair<DeviceManager::DeviceSetupStatus, QString> DevicePluginLgSmartTv::setupDev
tvDevice->setUuid(device->paramValue("uuid").toString());
tvDevice->setModelName(device->paramValue("model").toString());
tvDevice->setHostAddress(QHostAddress(device->paramValue("host address").toString()));
tvDevice->setPort(device->paramValue("port").toInt());
tvDevice->setLocation(QUrl(device->paramValue("location").toString()));
tvDevice->setUuid(device->paramValue("manufacturer").toString());
// key if there is one...
tvDevice->setupEventHandler();
connect(tvDevice, &TvDevice::pairingFinished, this, &DevicePluginLgSmartTv::pairingFinished);
connect(tvDevice, &TvDevice::sendCommandFinished, this, &DevicePluginLgSmartTv::sendingCommandFinished);
connect(tvDevice, &TvDevice::statusChanged, this, &DevicePluginLgSmartTv::statusChanged);
tvDevice->requestPairing();
m_tvList.insert(tvDevice,device);
@ -308,6 +377,7 @@ void DevicePluginLgSmartTv::deviceRemoved(Device *device)
TvDevice *tvDevice= m_tvList.key(device);
qDebug() << "remove LG Smart Tv " << tvDevice->modelName();
m_tvList.remove(tvDevice);
tvDevice->deleteLater();
}
QString DevicePluginLgSmartTv::pluginName() const
@ -322,7 +392,9 @@ PluginId DevicePluginLgSmartTv::pluginId() const
void DevicePluginLgSmartTv::guhTimer()
{
foreach (TvDevice *tvDevice, m_tvList.keys()) {
tvDevice->refresh();
}
}
void DevicePluginLgSmartTv::discoveryDone(QList<TvDevice*> tvList)
@ -336,6 +408,7 @@ void DevicePluginLgSmartTv::discoveryDone(QList<TvDevice*> tvList)
params.append(Param("model", device->modelName()));
params.append(Param("host address", device->hostAddress().toString()));
params.append(Param("location", device->location().toString()));
params.append(Param("port", device->port()));
params.append(Param("manufacturer", device->manufacturer()));
params.append(Param("key", device->key()));
descriptor.setParams(params);
@ -351,6 +424,7 @@ void DevicePluginLgSmartTv::pairingFinished(const bool &success)
if(success){
emit deviceSetupFinished(device,DeviceManager::DeviceSetupStatusSuccess,QString(""));
tvDevice->refresh();
}else{
emit deviceSetupFinished(device,DeviceManager::DeviceSetupStatusFailure,QString("Could not pair with tv."));
}
@ -365,4 +439,21 @@ void DevicePluginLgSmartTv::sendingCommandFinished(const bool &success, const Ac
}
}
void DevicePluginLgSmartTv::statusChanged()
{
TvDevice *tvDevice = static_cast<TvDevice*>(sender());
Device *device = m_tvList.value(tvDevice);
device->setStateValue(tvReachableStateTypeId, tvDevice->reachable());
device->setStateValue(tv3DModeStateTypeId, tvDevice->is3DMode());
device->setStateValue(tvVolumeLevelStateTypeId, tvDevice->volumeLevel());
device->setStateValue(tvMuteStateTypeId, tvDevice->mute());
device->setStateValue(tvChannelTypeStateTypeId, tvDevice->channelType());
device->setStateValue(tvChannelNameStateTypeId, tvDevice->channelName());
device->setStateValue(tvChannelNumberStateTypeId, tvDevice->channelNumber());
device->setStateValue(tvProgramNameStateTypeId, tvDevice->programName());
device->setStateValue(tvInputSourceIndexStateTypeId, tvDevice->inputSourceIndex());
device->setStateValue(tvInputSourceLabelNameStateTypeId, tvDevice->inputSourceLabelName());
}

View File

@ -55,6 +55,7 @@ private slots:
void discoveryDone(QList<TvDevice *> tvList);
void pairingFinished(const bool &success);
void sendingCommandFinished(const bool &success, const ActionId &actionId);
void statusChanged();
public slots:

View File

@ -2,16 +2,18 @@ include(../../plugins.pri)
TARGET = $$qtLibraryTarget(guh_devicepluginlgsmarttv)
QT+= network
QT+= network xml
SOURCES += \
devicepluginlgsmarttv.cpp \
tvdiscovery.cpp \
tvdevice.cpp
tvdevice.cpp \
tveventhandler.cpp
HEADERS += \
devicepluginlgsmarttv.h \
tvdiscovery.h \
tvdevice.h
tvdevice.h \
tveventhandler.h

View File

@ -1,3 +1,21 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "tvdevice.h"
TvDevice::TvDevice(QObject *parent) :
@ -5,7 +23,9 @@ TvDevice::TvDevice(QObject *parent) :
{
m_manager = new QNetworkAccessManager(this);
// TODO: make dynamic...displayPin setup
m_key = "539887";
m_pairingStatus = false;
m_reachable = false;
@ -32,6 +52,16 @@ QHostAddress TvDevice::hostAddress() const
return m_hostAddress;
}
void TvDevice::setPort(const int &port)
{
m_port = port;
}
int TvDevice::port() const
{
return m_port;
}
void TvDevice::setName(const QString &name)
{
m_name = name;
@ -102,12 +132,54 @@ bool TvDevice::paired() const
return m_pairingStatus;
}
bool TvDevice::is3DMode() const
{
return m_is3DMode;
}
int TvDevice::volumeLevel() const
{
return m_volumeLevel;
}
bool TvDevice::mute() const
{
return m_mute;
}
QString TvDevice::channelType() const
{
return m_channelType;
}
QString TvDevice::channelName() const
{
return m_channelName;
}
int TvDevice::channelNumber() const
{
return m_channelNumber;
}
QString TvDevice::programName() const
{
return m_programName;
}
int TvDevice::inputSourceIndex() const
{
return m_inputSourceIndex;
}
QString TvDevice::inputSourceLabelName() const
{
return m_inputSourceLabel;
}
void TvDevice::showPairingKey()
{
qDebug() << "request show pairing key on screen...";
qDebug() << "--------------------------------------------";
QString urlString = "http://" + m_hostAddress.toString() + ":8080/udap/api/pairing";
QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/pairing";
QNetworkRequest request;
request.setUrl(QUrl(urlString));
@ -125,7 +197,7 @@ void TvDevice::requestPairing()
emit pairingFinished(false);
}
QString urlString = "http://" + m_hostAddress.toString() +":8080/udap/api/pairing";
QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/pairing";
QNetworkRequest request;
request.setUrl(QUrl(urlString));
@ -137,6 +209,22 @@ void TvDevice::requestPairing()
m_requestPairingReplay = m_manager->post(request,data);
}
void TvDevice::endPairing()
{
QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/pairing";
QNetworkRequest request;
request.setUrl(QUrl(urlString));
request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/xml; charset=utf-8"));
request.setHeader(QNetworkRequest::UserAgentHeader,QVariant("UDAP/2.0 guh"));
request.setRawHeader("Connection", "Close");
QByteArray data = "<?xml version=\"1.0\" encoding=\"utf-8\"?><envelope><api type=\"pairing\"><name>byebye</name><port>8080</port></api></envelope>";
m_finishingPairingReplay = m_manager->post(request,data);
}
void TvDevice::sendCommand(TvDevice::RemoteKey key, ActionId actionId)
{
m_actionId = actionId;
@ -146,7 +234,7 @@ void TvDevice::sendCommand(TvDevice::RemoteKey key, ActionId actionId)
return;
}
QString urlString = "http://" + m_hostAddress.toString() +":8080/udap/api/command";
QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/command";
QByteArray data;
data.append("<?xml version=\"1.0\" encoding=\"utf-8\"?><envelope><api type=\"command\"><name>HandleKeyInput</name><value>");
@ -161,18 +249,113 @@ void TvDevice::sendCommand(TvDevice::RemoteKey key, ActionId actionId)
m_sendCommandReplay = m_manager->post(request,data);
}
void TvDevice::finishingPairing()
void TvDevice::setupEventHandler()
{
QString urlString = "http://" + m_hostAddress.toString() +":8080/udap/api/pairing";
//qDebug() << "set up event handler " << m_hostAddress.toString() << m_port;
m_eventHandler = new TvEventHandler(this,m_hostAddress,m_port);
connect(m_eventHandler, &TvEventHandler::eventOccured, this, &TvDevice::eventOccured);
}
void TvDevice::refresh()
{
if(paired()){
queryChannelInformation();
queryVolumeInformation();
}
}
void TvDevice::queryVolumeInformation()
{
QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/data?target=volume_info";
QNetworkRequest request;
request.setUrl(QUrl(urlString));
request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/xml; charset=utf-8"));
request.setHeader(QNetworkRequest::UserAgentHeader,QVariant("UDAP/2.0 guh"));
request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/xml"));
request.setHeader(QNetworkRequest::UserAgentHeader,QVariant("UDAP/2.0"));
request.setRawHeader("Connection", "Close");
QByteArray data = "<?xml version=\"1.0\" encoding=\"utf-8\"?><envelope><api type=\"pairing\"><name>byebye</name><port>8080</port></api></envelope>";
m_queryVolumeInformationReplay = m_manager->get(request);
}
m_finishingPairingReplay = m_manager->post(request,data);
void TvDevice::queryChannelInformation()
{
QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/data?target=cur_channel";
QNetworkRequest deviceRequest;
deviceRequest.setUrl(QUrl(urlString));
deviceRequest.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/xml"));
deviceRequest.setHeader(QNetworkRequest::UserAgentHeader,QVariant("UDAP/2.0"));
deviceRequest.setRawHeader("Connection", "Close");
m_queryChannelInformationReplay = m_manager->get(deviceRequest);
}
void TvDevice::parseVolumeInformation(const QByteArray &data)
{
//qDebug() << printXmlData(data);
QXmlStreamReader xml(data);
while(!xml.atEnd() && !xml.hasError()){
xml.readNext();
if(xml.name() == "mute"){
m_mute = QVariant(xml.readElementText()).toBool();
}
if(xml.name() == "level"){
m_volumeLevel = QVariant(xml.readElementText()).toInt();
}
}
emit statusChanged();
}
void TvDevice::parseChannelInformation(const QByteArray &data)
{
//qDebug() << printXmlData(data);
QXmlStreamReader xml(data);
while(!xml.atEnd() && !xml.hasError()){
xml.readNext();
if(xml.name() == "chtype"){
m_channelType = xml.readElementText();
}
if(xml.name() == "major"){
m_channelNumber = QVariant(xml.readElementText()).toInt();
}
if(xml.name() == "chname"){
m_channelName = xml.readElementText();
}
if(xml.name() == "progName"){
m_programName = xml.readElementText();
}
if(xml.name() == "inputSourceIdx"){
m_inputSourceIndex = QVariant(xml.readElementText()).toInt();
}
if(xml.name() == "labelName"){
m_inputSourceLabel = xml.readElementText();
}
}
emit statusChanged();
}
QString TvDevice::printXmlData(QByteArray data)
{
QString xmlOut;
QXmlStreamReader reader(data);
QXmlStreamWriter writer(&xmlOut);
writer.setAutoFormatting(true);
while (!reader.atEnd()) {
reader.readNext();
if (!reader.isWhitespace()) {
writer.writeCurrentToken(reader);
}
}
if(reader.hasError()){
qDebug() << "ERROR reading XML device information: " << reader.errorString();
qDebug() << "--------------------------------------------";
}
return xmlOut;
}
void TvDevice::replyFinished(QNetworkReply *reply)
@ -189,6 +372,7 @@ void TvDevice::replyFinished(QNetworkReply *reply)
if(status != 200){
qWarning() << "ERROR: could not request to show pairing key on screen " << status;
}
m_showKeyReplay->deleteLater();
}
if(reply == m_requestPairingReplay){
if(status != 200){
@ -198,7 +382,9 @@ void TvDevice::replyFinished(QNetworkReply *reply)
}else{
m_pairingStatus = true;
qDebug() << "successfully paired with tv " << m_modelName;
emit pairingFinished(true); }
emit pairingFinished(true);
}
m_requestPairingReplay->deleteLater();
}
if(reply == m_finishingPairingReplay){
@ -206,6 +392,7 @@ void TvDevice::replyFinished(QNetworkReply *reply)
m_pairingStatus = false;
qDebug() << "successfully unpaired from tv " << m_modelName;
}
m_finishingPairingReplay->deleteLater();
}
if(reply == m_sendCommandReplay){
@ -216,7 +403,59 @@ void TvDevice::replyFinished(QNetworkReply *reply)
m_pairingStatus = true;
qDebug() << "successfully sent command to tv " << m_modelName;
emit sendCommandFinished(true,m_actionId);
refresh();
}
m_sendCommandReplay->deleteLater();
}
if(reply == m_queryVolumeInformationReplay){
parseVolumeInformation(reply->readAll());
m_queryVolumeInformationReplay->deleteLater();
}
if(reply == m_queryChannelInformationReplay){
parseChannelInformation(reply->readAll());
m_queryChannelInformationReplay->deleteLater();
}
emit statusChanged();
}
void TvDevice::eventOccured(const QByteArray &data)
{
// if we got a channel changed event...
if(data.contains("ChannelChanged")){
parseChannelInformation(data);
return;
}
// qDebug() << "---------------------------------";
// qDebug() << printXmlData(data);
// if the tv suspends, it will send a byebye message, which means
// the pairing will be closed.
if(data.contains("api type=\"pairing\"") && data.contains("byebye")){
qDebug() << "--> tv ended pairing";
m_pairingStatus = false;
m_reachable = false;
emit statusChanged();
return;
}
// check if this is a 3DMode changed event
QXmlStreamReader xml(data);
while(!xml.atEnd() && !xml.hasError()){
xml.readNext();
if(xml.name() == "name"){
if(xml.readElementText() == "3DMode"){
xml.readNext();
if(xml.name() == "value"){
m_is3DMode = QVariant(xml.readElementText()).toBool();
}
}
}
}
emit statusChanged();
}

View File

@ -1,3 +1,21 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef TVDEVICE_H
#define TVDEVICE_H
@ -9,10 +27,12 @@
#include <QNetworkRequest>
#include <QUrl>
#include <QXmlStreamReader>
#include <QXmlReader>
#include <QXmlStreamWriter>
#include <QXmlStreamAttributes>
#include "plugin/deviceplugin.h"
#include "tveventhandler.h"
class TvDevice : public QObject
{
@ -89,12 +109,16 @@ public:
MyApps = 417
};
// propertys
void setLocation(const QUrl &location);
QUrl location() const;
void setHostAddress(const QHostAddress &hostAddress);
QHostAddress hostAddress() const;
void setPort(const int &port);
int port() const;
void setName(const QString &name);
QString name() const;
@ -113,16 +137,32 @@ public:
void setKey(const QString &key);
QString key() const;
bool reachable() const;
bool paired() const;
// States
bool reachable() const;
bool is3DMode() const;
int volumeLevel() const;
bool mute() const;
QString channelType() const;
QString channelName() const;
int channelNumber() const;
QString programName() const;
int inputSourceIndex() const;
QString inputSourceLabelName() const;
// public actions
void showPairingKey();
void requestPairing();
void endPairing();
void sendCommand(TvDevice::RemoteKey key, ActionId actionId);
void setupEventHandler();
void refresh();
private:
QUrl m_location;
QHostAddress m_hostAddress;
int m_port;
QString m_name;
QString m_modelName;
QString m_manufacturer;
@ -130,7 +170,18 @@ private:
QString m_uuid;
QString m_key;
bool m_pairingStatus;
// States
bool m_is3DMode;
bool m_reachable;
int m_volumeLevel;
bool m_mute;
QString m_channelType;
QString m_channelName;
int m_channelNumber;
QString m_programName;
int m_inputSourceIndex;
QString m_inputSourceLabel;
ActionId m_actionId;
@ -139,8 +190,16 @@ private:
QNetworkReply *m_requestPairingReplay;
QNetworkReply *m_finishingPairingReplay;
QNetworkReply *m_sendCommandReplay;
QNetworkReply *m_queryVolumeInformationReplay;
QNetworkReply *m_queryChannelInformationReplay;
void finishingPairing();
TvEventHandler *m_eventHandler;
QString printXmlData(QByteArray data);
void queryVolumeInformation();
void queryChannelInformation();
void parseVolumeInformation(const QByteArray &data);
void parseChannelInformation(const QByteArray &data);
signals:
void pairingFinished(const bool &success);
@ -149,7 +208,7 @@ signals:
private slots:
void replyFinished(QNetworkReply *reply);
void eventOccured(const QByteArray &data);
public slots:

View File

@ -1,3 +1,21 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "tvdiscovery.h"
TvDiscovery::TvDiscovery(QObject *parent) :
@ -124,11 +142,6 @@ void TvDiscovery::readData()
device->setHostAddress(sender);
device->setUuid(uuid);
// qDebug() << "--> UPnP searcher discovered a TV...";
// qDebug() << "location: " << location.toString();
// qDebug() << "ip: " << sender.toString();
// qDebug() << "uuid: " << uuid;
// qDebug() << "--------------------------------------------";
m_tvList.append(device);
requestDeviceInformation(device);
}
@ -196,6 +209,9 @@ void TvDiscovery::parseDeviceInformation(QByteArray data)
QString modelName;
QString deviceType;
QString manufacturer;
int port;
qDebug() << printXmlData(data);
while(!xml.atEnd() && !xml.hasError()){
xml.readNext();
@ -226,12 +242,17 @@ void TvDiscovery::parseDeviceInformation(QByteArray data)
if(xml.name() == "uuid" && xml.isStartElement()){
uuid = xml.readElementText();
}
//check if we have port part of message
if(xml.name() == "port"){
port = xml.readElementText().toInt();
}
xml.readNext();
}
}
}
}
foreach (TvDevice *device, m_tvList) {
// find our device with this uuid
if(device->uuid() == uuid){
@ -239,6 +260,7 @@ void TvDiscovery::parseDeviceInformation(QByteArray data)
device->setModelName(modelName);
device->setDeviceType(deviceType);
device->setManufacturer(manufacturer);
device->setPort(port);
qDebug() << "--> fetched TV information...";
qDebug() << "name: " << device->name();
@ -246,6 +268,7 @@ void TvDiscovery::parseDeviceInformation(QByteArray data)
qDebug() << "device type: " << device->deviceType();
qDebug() << "manufacturer: " << device->manufacturer();
qDebug() << "address: " << device->hostAddress().toString();
qDebug() << "port: " << device->port();
qDebug() << "location: " << device->location().toString();
qDebug() << "uuid: " << device->uuid();
qDebug() << "--------------------------------------------";
@ -253,6 +276,7 @@ void TvDiscovery::parseDeviceInformation(QByteArray data)
}
}
void TvDiscovery::discover(int timeout)
{
QString searchMessage("M-SEARCH * HTTP/1.1\r\n"

View File

@ -1,3 +1,21 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef TVDISCOVERY_H
#define TVDISCOVERY_H

View File

@ -0,0 +1,108 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "tveventhandler.h"
TvEventHandler::TvEventHandler(QObject *parent, QHostAddress host, int port) :
QTcpServer(parent),m_host(host),m_port(port)
{
listen(QHostAddress::AnyIPv4,m_port);
m_disabled = false;
m_expectingData = false;
//TODO: handle ip address change (dhcp) notification from the tv!
}
void TvEventHandler::incomingConnection(qintptr socket)
{
if(m_disabled){
return;
}
QTcpSocket* tcpSocket = new QTcpSocket(this);
connect(tcpSocket, &QTcpSocket::readyRead, this, &TvEventHandler::readClient);
connect(tcpSocket, &QTcpSocket::disconnected, this, &TvEventHandler::discardClient);
tcpSocket->setSocketDescriptor(socket);
//qDebug() << "incomming connection" << s->peerAddress().toString() << s->peerName();
}
void TvEventHandler::readClient()
{
if(m_disabled){
return;
}
QTcpSocket* socket = (QTcpSocket*)sender();
// reject everything, except the tv
if(socket->peerAddress() != m_host){
qWarning() << "reject connection from " << socket->peerAddress().toString();
socket->close();
if (socket->state() == QTcpSocket::UnconnectedState) {
delete socket;
}
return;
}
// the tv sends first the header (POST /udap/api/.... HTTP/1.1)
// in the scond package the tv sends the information (xml format)
while(!socket->atEnd()){
QByteArray data = socket->readAll();
// check if we got information
if(data.startsWith("<?xml") && m_expectingData){
m_expectingData = false;
// Answere with OK
QTextStream textStream(socket);
textStream.setAutoDetectUnicode(true);
textStream << "HTTP/1.0 200 OK\r\n"
"Content-Type: text/html; charset=\"utf-8\"\r\n"
"User-Agent: UDAP/2.0 guh\r\n"
<< "Date: " << QDateTime::currentDateTime().toString() << "\n";
emit eventOccured(data);
}
// check if we got header
if (data.startsWith("POST") && !m_expectingData) {
m_expectingData = true;
// QStringList tokens = QString(data).split(QRegExp("[ \r\n][ \r\n]*"));
// qDebug() << "==================================";
// qDebug() << "event occured" << "http://" << m_host.toString() << ":" << m_port << tokens[1];
}
}
}
void TvEventHandler::discardClient()
{
QTcpSocket* socket = (QTcpSocket*)sender();
socket->deleteLater();
}
void TvEventHandler::enable()
{
m_disabled = false;
}
void TvEventHandler::disable()
{
m_disabled = true;
}

View File

@ -0,0 +1,62 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef TVEVENTHANDLER_H
#define TVEVENTHANDLER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
#include <QDateTime>
#include <QTextStream>
#include <QRegExp>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
class TvEventHandler : public QTcpServer
{
Q_OBJECT
public:
explicit TvEventHandler(QObject *parent = 0, QHostAddress host = QHostAddress(), int port = 8080);
void incomingConnection(qintptr socket) override;
private:
QHostAddress m_host;
int m_port;
bool m_disabled;
bool m_expectingData;
QNetworkAccessManager *m_manager;
signals:
void eventOccured(const QByteArray &path);
void byebyeEvent();
private slots:
void readClient();
void discardClient();
public slots:
void enable();
void disable();
};
#endif // TVEVENTHANDLER_H