diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index 395c554f..434e9ca8 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -184,6 +184,7 @@ DeviceManager::DeviceManager(QObject *parent) : m_upnpDiscovery = new UpnpDiscovery(this); connect(m_upnpDiscovery, &UpnpDiscovery::discoveryFinished, this, &DeviceManager::upnpDiscoveryFinished); + connect(m_upnpDiscovery, &UpnpDiscovery::upnpNotify, this, &DeviceManager::upnpNotifyReceived); } /*! Destructor of the DeviceManager. Each loaded \l{DevicePlugin} will be deleted. */ @@ -941,6 +942,15 @@ void DeviceManager::upnpDiscoveryFinished(const QList &dev } } +void DeviceManager::upnpNotifyReceived(const QByteArray ¬ifyData) +{ + foreach (DevicePlugin *devicePlugin, m_devicePlugins) { + if (devicePlugin->requiredHardware().testFlag(HardwareResourceUpnpDisovery)) { + devicePlugin->upnpNotifyReceived(notifyData); + } + } +} + void DeviceManager::timerEvent() { foreach (Device *device, m_configuredDevices) { diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index 35ae2d31..bb11f0f9 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -132,6 +132,7 @@ private slots: void radio433SignalReceived(QList rawData); void upnpDiscoveryFinished(const QList &deviceDescriptorList, const PluginId &pluginId); + void upnpNotifyReceived(const QByteArray ¬ifyData); void timerEvent(); private: diff --git a/libguh/hardware/upnpdiscovery/upnpdiscovery.cpp b/libguh/hardware/upnpdiscovery/upnpdiscovery.cpp index 33c44486..bb249358 100644 --- a/libguh/hardware/upnpdiscovery/upnpdiscovery.cpp +++ b/libguh/hardware/upnpdiscovery/upnpdiscovery.cpp @@ -28,13 +28,13 @@ UpnpDiscovery::UpnpDiscovery(QObject *parent) : setSocketOption(QAbstractSocket::MulticastTtlOption,QVariant(1)); setSocketOption(QAbstractSocket::MulticastLoopbackOption,QVariant(1)); - if(!bind(QHostAddress::AnyIPv4,m_port,QUdpSocket::ShareAddress)){ - qWarning() << "ERROR: UPnP discovery could not bind to port " << m_port; + if(!bind(QHostAddress::AnyIPv4, m_port, QUdpSocket::ShareAddress)){ + qWarning() << "ERROR: UPnP discovery could not bind to port" << m_port; return; } if(!joinMulticastGroup(m_host)){ - qWarning() << "ERROR: UPnP discovery could not join multicast group " << m_host; + qWarning() << "ERROR: UPnP discovery could not join multicast group" << m_host; return; } @@ -53,7 +53,7 @@ UpnpDiscovery::UpnpDiscovery(QObject *parent) : connect(this,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error(QAbstractSocket::SocketError))); connect(this, &UpnpDiscovery::readyRead, this, &UpnpDiscovery::readData); - qDebug() << "--> Successfully created UPnPDiscovery."; + qDebug() << "--> UPnP discovery created successfully."; } bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString &userAgent, const PluginId &pluginId) @@ -65,6 +65,11 @@ bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString & reply->deleteLater(); } + if(state() != BoundState){ + qDebug() << "ERROR: UPnP not bound to port 1900"; + return false; + } + m_searchTarget = searchTarget; m_userAgent = userAgent; m_pluginId = pluginId; @@ -76,7 +81,8 @@ bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString & "ST: " + m_searchTarget.toUtf8() + "\r\n" "USR-AGENT: " + m_userAgent.toUtf8() + "\r\n\r\n"); - writeDatagram(ssdpSearchMessage,m_host,m_port); + qDebug() << "--> UPnP discovery called."; + writeDatagram(ssdpSearchMessage, m_host, m_port); m_timer->start(3000); return true; @@ -110,19 +116,25 @@ void UpnpDiscovery::readData() data.resize(pendingDatagramSize()); readDatagram(data.data(), data.size(), &hostAddress); } -// qDebug() << "-----------------------"; + +// qDebug() << "======================"; // qDebug() << data; + if (data.contains("NOTIFY")) { + emit upnpNotify(data); + return; + } + // if the data contains the HTTP OK header... - if(data.contains("HTTP/1.1 200 OK")){ + if (data.contains("HTTP/1.1 200 OK")) { const QStringList lines = QString(data).split("\r\n"); - foreach( const QString& line, lines){ + foreach (const QString& line, lines) { int separatorIndex = line.indexOf(':'); QString key = line.left(separatorIndex).toUpper(); QString value = line.mid(separatorIndex+1).trimmed(); // get location - if(key.contains("LOCATION")){ + if (key.contains("LOCATION")) { location = QUrl(value); } } @@ -147,45 +159,48 @@ void UpnpDiscovery::replyFinished(QNetworkReply *reply) // parse XML data QXmlStreamReader xml(data); - while(!xml.atEnd() && !xml.hasError()){ + while (!xml.atEnd() && !xml.hasError()) { xml.readNext(); - if(xml.isStartDocument()){ + if (xml.isStartDocument()) { continue; } - if(xml.isStartElement()){ - if(xml.name().toString() == "device"){ - while(!xml.atEnd()){ - if(xml.name() == "deviceType" && xml.isStartElement()){ + if (xml.isStartElement()) { + if (xml.name().toString() == "device") { + while (!xml.atEnd()) { + if (xml.name() == "deviceType" && xml.isStartElement()) { upnpDeviceDescriptor.setDeviceType(xml.readElementText()); } - if(xml.name() == "friendlyName" && xml.isStartElement()){ + if (xml.name() == "friendlyName" && xml.isStartElement()) { upnpDeviceDescriptor.setFriendlyName(xml.readElementText()); } - if(xml.name() == "manufacturer" && xml.isStartElement()){ + if (xml.name() == "manufacturer" && xml.isStartElement()) { upnpDeviceDescriptor.setManufacturer(xml.readElementText()); } - if(xml.name() == "manufacturerURL" && xml.isStartElement()){ + if (xml.name() == "manufacturerURL" && xml.isStartElement()) { upnpDeviceDescriptor.setManufacturerURL(QUrl(xml.readElementText())); } - if(xml.name() == "modelDescription" && xml.isStartElement()){ + if (xml.name() == "modelDescription" && xml.isStartElement()) { upnpDeviceDescriptor.setModelDescription(xml.readElementText()); } - if(xml.name() == "modelName" && xml.isStartElement()){ + if (xml.name() == "modelName" && xml.isStartElement()) { upnpDeviceDescriptor.setModelName(xml.readElementText()); } - if(xml.name() == "modelNumber" && xml.isStartElement()){ + if (xml.name() == "modelNumber" && xml.isStartElement()) { upnpDeviceDescriptor.setModelNumber(xml.readElementText()); } - if(xml.name() == "modelURL" && xml.isStartElement()){ + if (xml.name() == "modelURL" && xml.isStartElement()) { upnpDeviceDescriptor.setModelURL(QUrl(xml.readElementText())); } - if(xml.name() == "serialNumber" && xml.isStartElement()){ + if (xml.name() == "serialNumber" && xml.isStartElement()) { upnpDeviceDescriptor.setSerialNumber(xml.readElementText()); } - if(xml.name() == "UDN" && xml.isStartElement()){ + if (xml.name() == "UDN" && xml.isStartElement()) { upnpDeviceDescriptor.setUuid(xml.readElementText()); } - if(xml.name() == "UPC" && xml.isStartElement()){ + if (xml.name() == "uuid" && xml.isStartElement()) { + upnpDeviceDescriptor.setUuid(xml.readElementText()); + } + if (xml.name() == "UPC" && xml.isStartElement()) { upnpDeviceDescriptor.setUpc(xml.readElementText()); } xml.readNext(); @@ -198,11 +213,11 @@ void UpnpDiscovery::replyFinished(QNetworkReply *reply) // check if we allready have the device in the list bool isAlreadyInList = false; foreach (UpnpDeviceDescriptor deviceDescriptor, m_deviceList) { - if(deviceDescriptor.uuid() == upnpDeviceDescriptor.uuid()){ + if (deviceDescriptor.uuid() == upnpDeviceDescriptor.uuid()) { isAlreadyInList = true; } } - if(!isAlreadyInList){ + if (!isAlreadyInList) { m_deviceList.append(upnpDeviceDescriptor); } break; diff --git a/libguh/hardware/upnpdiscovery/upnpdiscovery.h b/libguh/hardware/upnpdiscovery/upnpdiscovery.h index bcc66d42..716f907c 100644 --- a/libguh/hardware/upnpdiscovery/upnpdiscovery.h +++ b/libguh/hardware/upnpdiscovery/upnpdiscovery.h @@ -58,6 +58,7 @@ private: signals: void discoveryFinished(const QList &deviceDescriptorList, const PluginId & pluginId); + void upnpNotify(const QByteArray ¬ifyMessage); private slots: void error(QAbstractSocket::SocketError error); diff --git a/libguh/plugin/deviceplugin.cpp b/libguh/plugin/deviceplugin.cpp index 3f9cd950..c94a4e73 100644 --- a/libguh/plugin/deviceplugin.cpp +++ b/libguh/plugin/deviceplugin.cpp @@ -525,7 +525,7 @@ bool DevicePlugin::transmitData(int delay, QList rawData, int repetitions) void DevicePlugin::upnpDiscover(QString searchTarget, QString userAgent) { - if(requiredHardware() == DeviceManager::HardwareResourceUpnpDisovery){ + if(requiredHardware().testFlag(DeviceManager::HardwareResourceUpnpDisovery)){ deviceManager()->m_upnpDiscovery->discoverDevices(searchTarget, userAgent, pluginId()); } } diff --git a/libguh/plugin/deviceplugin.h b/libguh/plugin/deviceplugin.h index 3cb82552..5d06d4e1 100644 --- a/libguh/plugin/deviceplugin.h +++ b/libguh/plugin/deviceplugin.h @@ -62,6 +62,7 @@ public: virtual void radioData(const QList &rawData) {Q_UNUSED(rawData)} virtual void guhTimer() {} virtual void upnpDiscoveryFinished(const QList &upnpDeviceDescriptorList) {Q_UNUSED(upnpDeviceDescriptorList)} + virtual void upnpNotifyReceived(const QByteArray ¬ifyData) {Q_UNUSED(notifyData)} // Configuration virtual QList configurationDescription() const; diff --git a/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.cpp b/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.cpp index e43259f5..77fd154a 100644 --- a/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.cpp +++ b/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.cpp @@ -16,28 +16,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/*! - \page lgsmarttv.html - \title LG Smart Tv - - \ingroup plugins - \ingroup network - - This plugin allows to interact with \l{http://www.lg.com/us/experience-tvs/smart-tv}{LG Smart Tv's} - with the \l{http://developer.lgappstv.com/TV_HELP/index.jsp?topic=%2Flge.tvsdk.references.book%2Fhtml%2FUDAP%2FUDAP%2FLG+UDAP+2+0+Protocol+Specifications.htm}{LG UDAP 2.0 Protocol Specifications}. - - \chapter Plugin properties - Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses} - and \l{Vendor}{Vendors} of this \l{DevicePlugin}. - - Each \l{DeviceClass} has a list of \l{ParamType}{paramTypes}, \l{ActionType}{actionTypes}, \l{StateType}{stateTypes} - and \l{EventType}{eventTypes}. The \l{DeviceClass::CreateMethod}{createMethods} parameter describes how the \l{Device} - will be created in the system. A device can have more than one \l{DeviceClass::CreateMethod}{CreateMethod}. - The \l{DeviceClass::SetupMethod}{setupMethod} describes the setup method of the \l{Device}. - The detailed implementation of each \l{DeviceClass} can be found in the source code. - - \quotefile plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.json -*/ #include "devicepluginlgsmarttv.h" @@ -47,42 +25,71 @@ #include +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"); +ActionTypeId commandMuteActionTypeId = ActionTypeId("1aa9d7f0-0f66-4b90-bb72-f6b7b2118221"); +ActionTypeId commandUnmuteActionTypeId = ActionTypeId("b7e31999-ba67-443d-8e5c-ec104af987bd"); +ActionTypeId commandChannelUpActionTypeId = ActionTypeId("acd1f6a0-2cfa-4665-9607-cf94245ec5a3"); +ActionTypeId commandChannelDownActionTypeId = ActionTypeId("6ea66772-0e6d-40b1-978c-a01fb53871dd"); +ActionTypeId commandPowerOffActionTypeId = ActionTypeId("cbe41134-ff11-4916-815b-3ac289c64090"); +ActionTypeId commandArrowUpActionTypeId = ActionTypeId("57c483b4-4ddf-4470-828c-8d8767e7a923"); +ActionTypeId commandArrowDownActionTypeId = ActionTypeId("614cf1af-5cf7-4bb2-885c-4414078d8899"); +ActionTypeId commandArrowLeftActionTypeId = ActionTypeId("916394dd-7833-4875-8d7a-49d7d24ceeb2"); +ActionTypeId commandArrowRightActionTypeId = ActionTypeId("01e3df1e-638b-4e14-ba85-660267766062"); +ActionTypeId commandOkActionTypeId = ActionTypeId("257dfa59-0d38-4e18-a3fc-213809fdb12f"); +ActionTypeId commandBackActionTypeId = ActionTypeId("ce4184b3-6b8e-4fc3-a4cb-7b8ec72f2ce9"); +ActionTypeId commandHomeActionTypeId = ActionTypeId("33f941c1-f5fc-4449-b6e3-93eafca493e0"); +ActionTypeId commandInputSourceActionTypeId = ActionTypeId("9a6e5111-95d3-49ac-8056-249e704b1509"); +ActionTypeId commandExitActionTypeId = ActionTypeId("d76efdb8-056e-4b39-a839-2ef6d6001b00"); +ActionTypeId commandInfoActionTypeId = ActionTypeId("9c1290d5-3135-4124-a576-fc7522cffdcf"); +ActionTypeId commandMyAppsActionTypeId = ActionTypeId("47d65cac-fe75-4c36-9dee-9862c1c1130e"); +ActionTypeId commandProgramListActionTypeId = ActionTypeId("9aa3a97e-505d-4906-9764-14b6dc4e31e8"); + DevicePluginLgSmartTv::DevicePluginLgSmartTv() { - m_discovery = new TvDiscovery(this); - - connect(m_discovery,SIGNAL(discoveryDone(QList)),this,SLOT(discoveryDone(QList))); } DeviceManager::DeviceError DevicePluginLgSmartTv::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) { - qDebug() << "should discover devices with params:" << params; - + Q_UNUSED(params); if(deviceClassId != lgSmartTvDeviceClassId){ return DeviceManager::DeviceErrorDeviceClassNotFound; } - - m_discovery->discover(3000); - + upnpDiscover("udap:rootservice","UDAP/2.0"); return DeviceManager::DeviceErrorAsync; } DeviceManager::DeviceSetupStatus DevicePluginLgSmartTv::setupDevice(Device *device) { - device->setName("LG Smart Tv (" + device->paramValue("model").toString() + ")"); - TvDevice *tvDevice = new TvDevice(this); - tvDevice->setName(device->paramValue("name").toString()); - 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()); + UpnpDeviceDescriptor upnpDeviceDescriptor; + upnpDeviceDescriptor.setFriendlyName(device->paramValue("name").toString()); + upnpDeviceDescriptor.setUuid(device->paramValue("uuid").toString()); + upnpDeviceDescriptor.setModelName(device->paramValue("model").toString()); + upnpDeviceDescriptor.setHostAddress(QHostAddress(device->paramValue("host address").toString())); + upnpDeviceDescriptor.setPort(device->paramValue("port").toInt()); + upnpDeviceDescriptor.setLocation(QUrl(device->paramValue("location").toString())); + upnpDeviceDescriptor.setManufacturer(device->paramValue("manufacturer").toString()); // key if there is one... + TvDevice *tvDevice = new TvDevice(this, upnpDeviceDescriptor); + // TODO: make dynamic...displayPin setup!!! + tvDevice->setKey("539887"); tvDevice->setupEventHandler(); connect(tvDevice, &TvDevice::pairingFinished, this, &DevicePluginLgSmartTv::pairingFinished); @@ -90,55 +97,55 @@ DeviceManager::DeviceSetupStatus DevicePluginLgSmartTv::setupDevice(Device *devi connect(tvDevice, &TvDevice::statusChanged, this, &DevicePluginLgSmartTv::statusChanged); tvDevice->requestPairing(); - m_tvList.insert(tvDevice,device); + m_tvList.insert(tvDevice, device); return DeviceManager::DeviceSetupStatusAsync; } DeviceManager::HardwareResources DevicePluginLgSmartTv::requiredHardware() const { - return DeviceManager::HardwareResourceTimer; + return DeviceManager::HardwareResourceTimer | DeviceManager::HardwareResourceUpnpDisovery; } DeviceManager::DeviceError DevicePluginLgSmartTv::executeAction(Device *device, const Action &action) { TvDevice * tvDevice = m_tvList.key(device); - if(action.actionTypeId() == commandVolumeUpActionTypeId){ + if (action.actionTypeId() == commandVolumeUpActionTypeId) { tvDevice->sendCommand(TvDevice::VolUp, action.id()); - } else if(action.actionTypeId() == commandVolumeDownActionTypeId){ + } else if(action.actionTypeId() == commandVolumeDownActionTypeId) { tvDevice->sendCommand(TvDevice::VolDown, action.id()); - } else if(action.actionTypeId() == commandMuteActionTypeId){ + } else if(action.actionTypeId() == commandMuteActionTypeId) { tvDevice->sendCommand(TvDevice::Mute, action.id()); - } else if(action.actionTypeId() == commandChannelUpActionTypeId){ + } else if(action.actionTypeId() == commandChannelUpActionTypeId) { tvDevice->sendCommand(TvDevice::ChannelUp, action.id()); - } else if(action.actionTypeId() == commandChannelDownActionTypeId){ + } else if(action.actionTypeId() == commandChannelDownActionTypeId) { tvDevice->sendCommand(TvDevice::ChannelDown, action.id()); - } else if(action.actionTypeId() == commandPowerOffActionTypeId){ + } else if(action.actionTypeId() == commandPowerOffActionTypeId) { tvDevice->sendCommand(TvDevice::Power, action.id()); - } else if(action.actionTypeId() == commandArrowUpActionTypeId){ + } else if(action.actionTypeId() == commandArrowUpActionTypeId) { tvDevice->sendCommand(TvDevice::Up, action.id()); - } else if(action.actionTypeId() == commandArrowDownActionTypeId){ + } else if(action.actionTypeId() == commandArrowDownActionTypeId) { tvDevice->sendCommand(TvDevice::Down, action.id()); - } else if(action.actionTypeId() == commandArrowLeftActionTypeId){ + } else if(action.actionTypeId() == commandArrowLeftActionTypeId) { tvDevice->sendCommand(TvDevice::Left, action.id()); - } else if(action.actionTypeId() == commandArrowRightActionTypeId){ + } else if(action.actionTypeId() == commandArrowRightActionTypeId) { tvDevice->sendCommand(TvDevice::Right, action.id()); - } else if(action.actionTypeId() == commandOkActionTypeId){ + } else if(action.actionTypeId() == commandOkActionTypeId) { tvDevice->sendCommand(TvDevice::Ok, action.id()); - } else if(action.actionTypeId() == commandBackActionTypeId){ + } else if(action.actionTypeId() == commandBackActionTypeId) { tvDevice->sendCommand(TvDevice::Back, action.id()); - } else if(action.actionTypeId() == commandHomeActionTypeId){ + } else if(action.actionTypeId() == commandHomeActionTypeId) { tvDevice->sendCommand(TvDevice::Home, action.id()); - } else if(action.actionTypeId() == commandInputSourceActionTypeId){ + } else if(action.actionTypeId() == commandInputSourceActionTypeId) { tvDevice->sendCommand(TvDevice::ExternalInput, action.id()); - } else if(action.actionTypeId() == commandExitActionTypeId){ + } else if(action.actionTypeId() == commandExitActionTypeId) { tvDevice->sendCommand(TvDevice::Exit, action.id()); - } else if(action.actionTypeId() == commandInfoActionTypeId){ + } else if(action.actionTypeId() == commandInfoActionTypeId) { tvDevice->sendCommand(TvDevice::Info, action.id()); - } else if(action.actionTypeId() == commandMyAppsActionTypeId){ + } else if(action.actionTypeId() == commandMyAppsActionTypeId) { tvDevice->sendCommand(TvDevice::MyApps, action.id()); - } else if(action.actionTypeId() == commandProgramListActionTypeId){ + } else if(action.actionTypeId() == commandProgramListActionTypeId) { tvDevice->sendCommand(TvDevice::ProgramList, action.id()); } else { return DeviceManager::DeviceErrorActionTypeNotFound; @@ -146,6 +153,33 @@ DeviceManager::DeviceError DevicePluginLgSmartTv::executeAction(Device *device, return DeviceManager::DeviceErrorAsync; } +void DevicePluginLgSmartTv::upnpDiscoveryFinished(const QList &upnpDeviceDescriptorList) +{ + QList deviceDescriptors; + foreach (UpnpDeviceDescriptor upnpDeviceDescriptor, upnpDeviceDescriptorList) { + DeviceDescriptor descriptor(lgSmartTvDeviceClassId, "Lg Smart Tv", upnpDeviceDescriptor.modelName()); + ParamList params; + params.append(Param("name", upnpDeviceDescriptor.friendlyName())); + params.append(Param("uuid", upnpDeviceDescriptor.uuid())); + params.append(Param("model", upnpDeviceDescriptor.modelName())); + params.append(Param("host address", upnpDeviceDescriptor.hostAddress().toString())); + params.append(Param("location", upnpDeviceDescriptor.hostAddress().toString())); + params.append(Param("port", upnpDeviceDescriptor.port())); + params.append(Param("manufacturer", upnpDeviceDescriptor.manufacturer())); + params.append(Param("key", "539887")); + descriptor.setParams(params); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(lgSmartTvDeviceClassId, deviceDescriptors); +} + +void DevicePluginLgSmartTv::upnpNotifyReceived(const QByteArray ¬ifyData) +{ + Q_UNUSED(notifyData); +// qDebug() << "######################################"; +// qDebug() << notifyData; +} + void DevicePluginLgSmartTv::deviceRemoved(Device *device) { if (!m_tvList.values().contains(device)) { @@ -153,7 +187,7 @@ void DevicePluginLgSmartTv::deviceRemoved(Device *device) } TvDevice *tvDevice= m_tvList.key(device); - qDebug() << "remove LG Smart Tv " << tvDevice->modelName(); + qDebug() << "remove LG SmartTv " << tvDevice->modelName(); m_tvList.remove(tvDevice); tvDevice->deleteLater(); } @@ -165,45 +199,35 @@ void DevicePluginLgSmartTv::guhTimer() } } -void DevicePluginLgSmartTv::discoveryDone(QList tvList) -{ - QList deviceDescriptors; - foreach (TvDevice *device, tvList) { - DeviceDescriptor descriptor(lgSmartTvDeviceClassId, "Lg Smart Tv", device->modelName()); - ParamList params; - params.append(Param("name", device->name())); - params.append(Param("uuid", device->uuid())); - 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); - deviceDescriptors.append(descriptor); - } - emit devicesDiscovered(lgSmartTvDeviceClassId, deviceDescriptors); -} void DevicePluginLgSmartTv::pairingFinished(const bool &success) { TvDevice *tvDevice = static_cast(sender()); Device *device = m_tvList.value(tvDevice); - if(success){ - emit deviceSetupFinished(device,DeviceManager::DeviceSetupStatusSuccess); + // check if we allready set up this device... + foreach (Device *configuredDevice, deviceManager()->findConfiguredDevices(lgSmartTvDeviceClassId)) { + if (configuredDevice->paramValue("uuid").toString() == device->paramValue("uuid").toString()) { + tvDevice->refresh(); + return; + } + } + + // ...otherwise emit deviceSetupFinished with appropriate DeviceError + if (success) { + emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess); tvDevice->refresh(); - }else{ - emit deviceSetupFinished(device,DeviceManager::DeviceSetupStatusFailure); + } else { + emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure); } } void DevicePluginLgSmartTv::sendingCommandFinished(const bool &success, const ActionId &actionId) { - if(success){ - emit actionExecutionFinished(actionId,DeviceManager::DeviceErrorNoError); - }else{ - emit actionExecutionFinished(actionId,DeviceManager::DeviceErrorHardwareFailure); + if (success) { + emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError); + } else { + emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorActionTypeNotFound); } } @@ -212,7 +236,7 @@ void DevicePluginLgSmartTv::statusChanged() TvDevice *tvDevice = static_cast(sender()); Device *device = m_tvList.value(tvDevice); - device->setStateValue(tvReachableStateTypeId, tvDevice->reachable()); + device->setStateValue(tvReachableStateTypeId, tvDevice->isReachable()); device->setStateValue(tv3DModeStateTypeId, tvDevice->is3DMode()); device->setStateValue(tvVolumeLevelStateTypeId, tvDevice->volumeLevel()); device->setStateValue(tvMuteStateTypeId, tvDevice->mute()); @@ -223,5 +247,3 @@ void DevicePluginLgSmartTv::statusChanged() device->setStateValue(tvInputSourceIndexStateTypeId, tvDevice->inputSourceIndex()); device->setStateValue(tvInputSourceLabelNameStateTypeId, tvDevice->inputSourceLabelName()); } - - diff --git a/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.h b/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.h index 32787ee8..0d7ea40b 100644 --- a/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.h +++ b/plugins/deviceplugins/lgsmarttv/devicepluginlgsmarttv.h @@ -19,8 +19,9 @@ #ifndef DEVICEPLUGINLGSMARTTV_H #define DEVICEPLUGINLGSMARTTV_H +#include "hardware/upnpdiscovery/upnpdevicedescriptor.h" #include "plugin/deviceplugin.h" -#include "tvdiscovery.h" +#include "tvdevice.h" class DevicePluginLgSmartTv : public DevicePlugin { @@ -32,12 +33,13 @@ class DevicePluginLgSmartTv : public DevicePlugin public: explicit DevicePluginLgSmartTv(); - TvDiscovery *m_discovery; DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; DeviceManager::HardwareResources requiredHardware() const override; DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; + void upnpDiscoveryFinished(const QList &upnpDeviceDescriptorList) override; + void upnpNotifyReceived(const QByteArray ¬ifyData); void deviceRemoved(Device *device) override; @@ -46,14 +48,10 @@ public: QHash m_tvList; private slots: - void discoveryDone(QList tvList); void pairingFinished(const bool &success); void sendingCommandFinished(const bool &success, const ActionId &actionId); void statusChanged(); -public slots: - - }; #endif // DEVICEPLUGINLGSMARTTV_H diff --git a/plugins/deviceplugins/lgsmarttv/lgsmarttv.pro b/plugins/deviceplugins/lgsmarttv/lgsmarttv.pro index f52adbda..bcde3a02 100644 --- a/plugins/deviceplugins/lgsmarttv/lgsmarttv.pro +++ b/plugins/deviceplugins/lgsmarttv/lgsmarttv.pro @@ -6,13 +6,11 @@ QT+= network xml SOURCES += \ devicepluginlgsmarttv.cpp \ - tvdiscovery.cpp \ tvdevice.cpp \ tveventhandler.cpp HEADERS += \ devicepluginlgsmarttv.h \ - tvdiscovery.h \ tvdevice.h \ tveventhandler.h diff --git a/plugins/deviceplugins/lgsmarttv/tvdevice.cpp b/plugins/deviceplugins/lgsmarttv/tvdevice.cpp index 5699b51a..b02d85a7 100644 --- a/plugins/deviceplugins/lgsmarttv/tvdevice.cpp +++ b/plugins/deviceplugins/lgsmarttv/tvdevice.cpp @@ -18,100 +18,18 @@ #include "tvdevice.h" -TvDevice::TvDevice(QObject *parent) : - QObject(parent) +TvDevice::TvDevice(QObject *parent, UpnpDeviceDescriptor upnpDeviceDescriptor) : + UpnpDevice(parent, upnpDeviceDescriptor) { m_manager = new QNetworkAccessManager(this); - // TODO: make dynamic...displayPin setup - m_key = "539887"; - + m_key = "0"; m_pairingStatus = false; m_reachable = false; connect(m_manager, &QNetworkAccessManager::finished, this, &TvDevice::replyFinished); } -void TvDevice::setLocation(const QUrl &location) -{ - m_location = location; -} - -QUrl TvDevice::location() const -{ - return m_location; -} - -void TvDevice::setHostAddress(const QHostAddress &hostAddress) -{ - m_hostAddress = hostAddress; -} - -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; -} - -QString TvDevice::name() const -{ - return m_name; -} - -void TvDevice::setModelName(const QString &modelName) -{ - m_modelName = modelName; -} - -QString TvDevice::modelName() const -{ - return m_modelName; -} - -void TvDevice::setManufacturer(const QString &manufacturer) -{ - m_manufacturer = manufacturer; -} - -QString TvDevice::manufacturer() const -{ - return m_manufacturer; -} - -void TvDevice::setDeviceType(const QString &deviceType) -{ - m_deviceType = deviceType; -} - -QString TvDevice::deviceType() const -{ - return m_deviceType; -} - -void TvDevice::setUuid(const QString &uuid) -{ - m_uuid = uuid; -} - -QString TvDevice::uuid() const -{ - return m_uuid; -} - void TvDevice::setKey(const QString &key) { m_key = key; @@ -122,7 +40,7 @@ QString TvDevice::key() const return m_key; } -bool TvDevice::reachable() const +bool TvDevice::isReachable() const { return m_reachable; } @@ -179,12 +97,12 @@ QString TvDevice::inputSourceLabelName() const void TvDevice::showPairingKey() { - QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/pairing"; + QString urlString = "http://" + hostAddress().toString() + ":" + QString::number(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.setHeader(QNetworkRequest::UserAgentHeader,QVariant("UDAP/2.0")); QByteArray data = " showKey"; @@ -197,7 +115,7 @@ void TvDevice::requestPairing() emit pairingFinished(false); } - QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/pairing"; + QString urlString = "http://" + hostAddress().toString() + ":" + QString::number(port()) + "/udap/api/pairing"; QNetworkRequest request; request.setUrl(QUrl(urlString)); @@ -211,7 +129,7 @@ void TvDevice::requestPairing() void TvDevice::endPairing() { - QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/pairing"; + QString urlString = "http://" + hostAddress().toString() + ":" + QString::number(port()) + "/udap/api/pairing"; QNetworkRequest request; request.setUrl(QUrl(urlString)); @@ -229,12 +147,12 @@ void TvDevice::sendCommand(TvDevice::RemoteKey key, ActionId actionId) { m_actionId = actionId; - if(!m_pairingStatus){ + if(!m_pairingStatus) { requestPairing(); return; } - QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/command"; + QString urlString = "http://" + hostAddress().toString() + ":" + QString::number(port()) + "/udap/api/command"; QByteArray data; data.append("HandleKeyInput"); @@ -252,21 +170,23 @@ void TvDevice::sendCommand(TvDevice::RemoteKey key, ActionId actionId) void TvDevice::setupEventHandler() { //qDebug() << "set up event handler " << m_hostAddress.toString() << m_port; - m_eventHandler = new TvEventHandler(this,m_hostAddress,m_port); + m_eventHandler = new TvEventHandler(this,hostAddress(),port()); connect(m_eventHandler, &TvEventHandler::eventOccured, this, &TvDevice::eventOccured); } void TvDevice::refresh() { - if(paired()){ + if(paired()) { queryChannelInformation(); queryVolumeInformation(); + }else{ + requestPairing(); } } void TvDevice::queryVolumeInformation() { - QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/data?target=volume_info"; + QString urlString = "http://" + hostAddress().toString() + ":" + QString::number(port()) + "/udap/api/data?target=volume_info"; QNetworkRequest request; request.setUrl(QUrl(urlString)); @@ -279,7 +199,7 @@ void TvDevice::queryVolumeInformation() void TvDevice::queryChannelInformation() { - QString urlString = "http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/udap/api/data?target=cur_channel"; + QString urlString = "http://" + hostAddress().toString() + ":" + QString::number(port()) + "/udap/api/data?target=cur_channel"; QNetworkRequest deviceRequest; deviceRequest.setUrl(QUrl(urlString)); @@ -295,13 +215,13 @@ void TvDevice::parseVolumeInformation(const QByteArray &data) //qDebug() << printXmlData(data); QXmlStreamReader xml(data); - while(!xml.atEnd() && !xml.hasError()){ + while(!xml.atEnd() && !xml.hasError()) { xml.readNext(); - if(xml.name() == "mute"){ + if(xml.name() == "mute") { m_mute = QVariant(xml.readElementText()).toBool(); } - if(xml.name() == "level"){ + if(xml.name() == "level") { m_volumeLevel = QVariant(xml.readElementText()).toInt(); } } @@ -313,25 +233,25 @@ void TvDevice::parseChannelInformation(const QByteArray &data) //qDebug() << printXmlData(data); QXmlStreamReader xml(data); - while(!xml.atEnd() && !xml.hasError()){ + while(!xml.atEnd() && !xml.hasError()) { xml.readNext(); - if(xml.name() == "chtype"){ + if(xml.name() == "chtype") { m_channelType = xml.readElementText(); } - if(xml.name() == "major"){ + if(xml.name() == "major") { m_channelNumber = QVariant(xml.readElementText()).toInt(); } - if(xml.name() == "chname"){ + if(xml.name() == "chname") { m_channelName = xml.readElementText(); } - if(xml.name() == "progName"){ + if(xml.name() == "progName") { m_programName = xml.readElementText(); } - if(xml.name() == "inputSourceIdx"){ + if(xml.name() == "inputSourceIdx") { m_inputSourceIndex = QVariant(xml.readElementText()).toInt(); } - if(xml.name() == "labelName"){ + if(xml.name() == "labelName") { m_inputSourceLabel = xml.readElementText(); } } @@ -347,11 +267,11 @@ QString TvDevice::printXmlData(QByteArray data) while (!reader.atEnd()) { reader.readNext(); - if (!reader.isWhitespace()) { + if(!reader.isWhitespace()) { writer.writeCurrentToken(reader); } } - if(reader.hasError()){ + if(reader.hasError()) { qDebug() << "ERROR reading XML device information: " << reader.errorString(); qDebug() << "--------------------------------------------"; } @@ -362,56 +282,56 @@ void TvDevice::replyFinished(QNetworkReply *reply) { int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if(status != 200){ + if(status != 200) { m_reachable = false; - }else{ + } else { m_reachable = true; } - if(reply == m_showKeyReplay){ - if(status != 200){ - qWarning() << "ERROR: could not request to show pairing key on screen " << status; + if(reply == m_showKeyReplay) { + 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){ + if(reply == m_requestPairingReplay) { + if(status != 200) { m_pairingStatus = false; emit pairingFinished(false); - qWarning() << "ERROR: could not pair with device" << status; - }else{ + //qWarning() << "ERROR: could not pair with device" << status; + } else { m_pairingStatus = true; - qDebug() << "successfully paired with tv " << m_modelName; + //qDebug() << "successfully paired with tv " << modelName(); emit pairingFinished(true); } m_requestPairingReplay->deleteLater(); } - if(reply == m_finishingPairingReplay){ - if(status == 200){ + if(reply == m_finishingPairingReplay) { + if(status == 200) { m_pairingStatus = false; - qDebug() << "successfully unpaired from tv " << m_modelName; + //qDebug() << "successfully unpaired from tv " << modelName(); } m_finishingPairingReplay->deleteLater(); } - if(reply == m_sendCommandReplay){ - if(status != 200){ + if(reply == m_sendCommandReplay) { + if (status != 200) { emit sendCommandFinished(false,m_actionId); qWarning() << "ERROR: could not send comand" << status; - }else{ + } else { m_pairingStatus = true; - qDebug() << "successfully sent command to tv " << m_modelName; + //qDebug() << "successfully sent command to tv " << modelName(); emit sendCommandFinished(true,m_actionId); refresh(); } m_sendCommandReplay->deleteLater(); } - if(reply == m_queryVolumeInformationReplay){ + if(reply == m_queryVolumeInformationReplay) { parseVolumeInformation(reply->readAll()); m_queryVolumeInformationReplay->deleteLater(); } - if(reply == m_queryChannelInformationReplay){ + if(reply == m_queryChannelInformationReplay) { parseChannelInformation(reply->readAll()); m_queryChannelInformationReplay->deleteLater(); } @@ -422,17 +342,14 @@ void TvDevice::replyFinished(QNetworkReply *reply) void TvDevice::eventOccured(const QByteArray &data) { // if we got a channel changed event... - if(data.contains("ChannelChanged")){ + 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")){ + if(data.contains("api type=\"pairing\"") && data.contains("byebye")) { qDebug() << "--> tv ended pairing"; m_pairingStatus = false; m_reachable = false; @@ -443,13 +360,13 @@ void TvDevice::eventOccured(const QByteArray &data) // check if this is a 3DMode changed event QXmlStreamReader xml(data); - while(!xml.atEnd() && !xml.hasError()){ + while(!xml.atEnd() && !xml.hasError()) { xml.readNext(); - if(xml.name() == "name"){ - if(xml.readElementText() == "3DMode"){ + if(xml.name() == "name") { + if(xml.readElementText() == "3DMode") { xml.readNext(); - if(xml.name() == "value"){ + if(xml.name() == "value") { m_is3DMode = QVariant(xml.readElementText()).toBool(); } } @@ -458,4 +375,3 @@ void TvDevice::eventOccured(const QByteArray &data) emit statusChanged(); } - diff --git a/plugins/deviceplugins/lgsmarttv/tvdevice.h b/plugins/deviceplugins/lgsmarttv/tvdevice.h index 84c85862..c4950d11 100644 --- a/plugins/deviceplugins/lgsmarttv/tvdevice.h +++ b/plugins/deviceplugins/lgsmarttv/tvdevice.h @@ -33,12 +33,13 @@ #include "plugin/deviceplugin.h" #include "tveventhandler.h" +#include "hardware/upnpdiscovery/upnpdevice.h" -class TvDevice : public QObject +class TvDevice : public UpnpDevice { Q_OBJECT public: - explicit TvDevice(QObject *parent = 0); + explicit TvDevice(QObject *parent = 0, UpnpDeviceDescriptor upnpDeviceDescriptor = UpnpDeviceDescriptor()); enum RemoteKey{ Power = 1, @@ -110,37 +111,13 @@ public: }; // 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; - - void setModelName(const QString &modelName); - QString modelName() const; - - void setManufacturer(const QString &manufacturer); - QString manufacturer() const; - - void setDeviceType(const QString &deviceType); - QString deviceType() const; - - void setUuid(const QString &uuid); - QString uuid() const; - void setKey(const QString &key); QString key() const; bool paired() const; // States - bool reachable() const; + bool isReachable() const; bool is3DMode() const; int volumeLevel() const; bool mute() const; @@ -160,14 +137,6 @@ public: void refresh(); private: - QUrl m_location; - QHostAddress m_hostAddress; - int m_port; - QString m_name; - QString m_modelName; - QString m_manufacturer; - QString m_deviceType; - QString m_uuid; QString m_key; bool m_pairingStatus; @@ -210,8 +179,6 @@ private slots: void replyFinished(QNetworkReply *reply); void eventOccured(const QByteArray &data); -public slots: - }; #endif // TVDEVICE_H diff --git a/plugins/deviceplugins/lgsmarttv/tvdiscovery.cpp b/plugins/deviceplugins/lgsmarttv/tvdiscovery.cpp deleted file mode 100644 index e435517f..00000000 --- a/plugins/deviceplugins/lgsmarttv/tvdiscovery.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * 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 . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "tvdiscovery.h" - -TvDiscovery::TvDiscovery(QObject *parent) : - QUdpSocket(parent) -{ - m_timeout = new QTimer(this); - m_timeout->setSingleShot(true); - connect(m_timeout,SIGNAL(timeout()),this,SLOT(discoverTimeout())); - - m_manager = new QNetworkAccessManager(this); - connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); - - m_port = 1900; - m_host = QHostAddress("239.255.255.250"); - setSocketOption(QAbstractSocket::MulticastTtlOption,QVariant(1)); - setSocketOption(QAbstractSocket::MulticastLoopbackOption,QVariant(1)); - bind(QHostAddress::AnyIPv4,m_port,QUdpSocket::ShareAddress); - joinMulticastGroup(m_host); - connect(this,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error(QAbstractSocket::SocketError))); - connect(this,SIGNAL(readyRead()),this,SLOT(readData())); -} - -bool TvDiscovery::checkXmlData(QByteArray data) -{ - QByteArray 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 false; - } - m_deviceInformationData = xmlOut; - return true; -} - -QString TvDiscovery::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 TvDiscovery::error(QAbstractSocket::SocketError error) -{ - qWarning() << errorString() << error; -} - -void TvDiscovery::readData() -{ - QByteArray data; - QHostAddress sender; - quint16 udpPort; - - // read the answere from the multicast - while (hasPendingDatagrams()) { - data.resize(pendingDatagramSize()); - readDatagram(data.data(), data.size(), &sender, &udpPort); - } - - if(data.size() > 0){ - if(data.contains("HTTP/1.1 200 OK")){ - const QStringList lines = QString(data).split("\r\n"); - - QUrl location; - QString uuid; - QString server; - - foreach( const QString& line, lines){ - int separatorIndex = line.indexOf(':'); - QString key = line.left(separatorIndex).toUpper(); - QString value = line.mid(separatorIndex+1).trimmed(); - - // get location - if(key.contains("LOCATION")){ - location = QUrl(value); - } - - // get server info - if(key.contains("SERVER")){ - // check if it is a LG Smart Tv with UDAP/2.0 protocoll - if(value.contains("UDAP/2.0")){ - server = value; - } - } - - // get uuid - if(key.contains("USN")){ - int startIndex = value.indexOf(":"); - int endIndex = value.indexOf("::"); - uuid = value.mid(startIndex +1 ,(endIndex - startIndex)-1); - } - - if(!location.isEmpty() && !uuid.isEmpty() && !server.isEmpty()){ - foreach (TvDevice *device, m_tvList) { - if(device->uuid() == uuid){ - return; - } - } - TvDevice *device = new TvDevice(this); - device->setLocation(location); - device->setHostAddress(sender); - device->setUuid(uuid); - - m_tvList.append(device); - requestDeviceInformation(device); - } - } - } - } -} - -void TvDiscovery::discoverTimeout() -{ - emit discoveryDone(m_tvList); -} - -void TvDiscovery::requestDeviceInformation(TvDevice *device) -{ - - QNetworkRequest deviceRequest; - deviceRequest.setUrl(device->location()); - deviceRequest.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/xml")); - deviceRequest.setHeader(QNetworkRequest::UserAgentHeader,QVariant("UDAP/2.0")); - - m_deviceInformationReplay = m_manager->get(deviceRequest); -} - -void TvDiscovery::replyFinished(QNetworkReply *reply) -{ - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - QByteArray data; - - switch (status) { - case(200): - data = reply->readAll(); - if(checkXmlData(data)){ - parseDeviceInformation(data); - } - break; - case(400): - qDebug() << "ERROR: 400 Bad request. The event format is not valid or it has an incorrect value."; - qDebug() << "--------------------------------------------"; - return; - case(401): - qDebug() << "ERROR: 401 Unauthorized. An event is sent when a Host and a Controller are not paired."; - qDebug() << "--------------------------------------------"; - return; - case(404): - qDebug() << "ERROR: 404 Not Found. The POST path of an event is incorrect."; - qDebug() << "--------------------------------------------"; - return; - case(500): - qDebug() << "ERROR: 500 Internal Server Error. Event Execution Failure."; - qDebug() << "--------------------------------------------"; - return; - default: - return; - } -} - -void TvDiscovery::parseDeviceInformation(QByteArray data) -{ - - QXmlStreamReader xml(data); - - QString name; - QString uuid; - QString modelName; - QString deviceType; - QString manufacturer; - int port; - - qDebug() << printXmlData(data); - - while(!xml.atEnd() && !xml.hasError()){ - xml.readNext(); - - if(xml.isStartDocument()){ - continue; - } - if(xml.isStartElement()){ - if(xml.name() == "envelope"){ - continue; - } - //check if we have device part of message - if(xml.name() == "device"){ - // seems to be device information - while(!xml.atEnd()){ - if(xml.name() == "deviceType" && xml.isStartElement()){ - deviceType = xml.readElementText(); - } - if(xml.name() == "modelName" && xml.isStartElement()){ - modelName = xml.readElementText(); - } - if(xml.name() == "friendlyName" && xml.isStartElement()){ - name = xml.readElementText(); - } - if(xml.name() == "manufacturer" && xml.isStartElement()){ - manufacturer = xml.readElementText(); - } - 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){ - device->setName(name); - device->setModelName(modelName); - device->setDeviceType(deviceType); - device->setManufacturer(manufacturer); - device->setPort(port); - - qDebug() << "--> fetched TV information..."; - qDebug() << "name: " << device->name(); - qDebug() << "model name: " << device->modelName(); - 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() << "--------------------------------------------"; - } - } -} - - -void TvDiscovery::discover(int timeout) -{ - QString searchMessage("M-SEARCH * HTTP/1.1\r\n" - "HOST:239.255.255.250:1900\r\n" - "MAN:\"ssdp:discover\"\r\n" - "MX:2\r\n" - "ST:udap:rootservice\r\n" - "USER-AGENT: UDAP/2.0 \r\n\r\n"); - - m_tvList.clear(); - writeDatagram(searchMessage.toUtf8(),m_host,m_port); - m_timeout->start(timeout); -} diff --git a/plugins/deviceplugins/lgsmarttv/tvdiscovery.h b/plugins/deviceplugins/lgsmarttv/tvdiscovery.h deleted file mode 100644 index bd35b76c..00000000 --- a/plugins/deviceplugins/lgsmarttv/tvdiscovery.h +++ /dev/null @@ -1,72 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * 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 . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef TVDISCOVERY_H -#define TVDISCOVERY_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tvdevice.h" - -class TvDiscovery : public QUdpSocket -{ - Q_OBJECT -public: - explicit TvDiscovery(QObject *parent = 0); - -private: - QHostAddress m_host; - qint16 m_port; - - QTimer *m_timeout; - QList m_tvList; - - QNetworkAccessManager *m_manager; - QNetworkReply *m_deviceInformationReplay; - - QByteArray m_deviceInformationData; - bool checkXmlData(QByteArray data); - QString printXmlData(QByteArray data); - -signals: - void discoveryDone(const QList deviceList); - -private slots: - void error(QAbstractSocket::SocketError error); - void readData(); - void discoverTimeout(); - - void requestDeviceInformation(TvDevice *device); - void replyFinished(QNetworkReply *reply); - void parseDeviceInformation(QByteArray data); - -public slots: - void discover(int timeout); - -}; - -#endif // TVDISCOVERY_H diff --git a/plugins/deviceplugins/philipshue/devicepluginphilipshue.cpp b/plugins/deviceplugins/philipshue/devicepluginphilipshue.cpp index 7648f3ca..f0e0b004 100644 --- a/plugins/deviceplugins/philipshue/devicepluginphilipshue.cpp +++ b/plugins/deviceplugins/philipshue/devicepluginphilipshue.cpp @@ -51,14 +51,29 @@ #include #include -DevicePluginPhilipsHue::DevicePluginPhilipsHue(): - m_discovery(new Discovery(this)) -{ - connect(m_discovery, &Discovery::discoveryDone, this, &DevicePluginPhilipsHue::discoveryDone); +VendorId hueVendorId = VendorId(""); - m_bridge = new HueBridgeConnection(this); - connect(m_bridge, &HueBridgeConnection::createUserFinished, this, &DevicePluginPhilipsHue::createUserFinished); - connect(m_bridge, &HueBridgeConnection::getFinished, this, &DevicePluginPhilipsHue::getFinished); +DeviceClassId hueDeviceClassId = DeviceClassId("d8f4c397-e05e-47c1-8917-8e72d4d0d47c"); + +StateTypeId hueColorStateTypeId = StateTypeId("d25423e7-b924-4b20-80b6-77eecc65d089"); +ActionTypeId hueSetColorActionTypeId = ActionTypeId("29cc299a-818b-47b2-817f-c5a6361545e4"); + +StateTypeId huePowerStateTypeId = StateTypeId("6ac64eee-f356-4ae4-bc85-8c1244d12b02"); +ActionTypeId hueSetPowerActionTypeId = ActionTypeId("7782d91e-d73a-4321-8828-da768e2f6827"); + +StateTypeId hueBrightnessStateTypeId = StateTypeId("411f489c-4bc9-42f7-b47d-b0581dc0c29e"); +ActionTypeId hueSetBrightnessActionTypeId = ActionTypeId("3bc95552-cba0-4222-abd5-9b668132e442"); + +StateTypeId hueReachableStateTypeId = StateTypeId("15794d26-fde8-4a61-8f83-d7830534975f"); + +DevicePluginPhilipsHue::DevicePluginPhilipsHue() + //:m_discovery(new Discovery(this)) +{ +// connect(m_discovery, &Discovery::discoveryDone, this, &DevicePluginPhilipsHue::discoveryDone); + +// m_bridge = new HueBridgeConnection(this); +// connect(m_bridge, &HueBridgeConnection::createUserFinished, this, &DevicePluginPhilipsHue::createUserFinished); +// connect(m_bridge, &HueBridgeConnection::getFinished, this, &DevicePluginPhilipsHue::getFinished); } DeviceManager::HardwareResources DevicePluginPhilipsHue::requiredHardware() const diff --git a/plugins/deviceplugins/wemo/devicepluginwemo.cpp b/plugins/deviceplugins/wemo/devicepluginwemo.cpp index c3ddd864..82cbb9f6 100644 --- a/plugins/deviceplugins/wemo/devicepluginwemo.cpp +++ b/plugins/deviceplugins/wemo/devicepluginwemo.cpp @@ -53,9 +53,9 @@ DevicePluginWemo::DevicePluginWemo() { - m_discovery = new WemoDiscovery(this); +// m_discovery = new WemoDiscovery(this); - connect(m_discovery,SIGNAL(discoveryDone(QList)),this,SLOT(discoveryDone(QList))); +// connect(m_discovery,SIGNAL(discoveryDone(QList)),this,SLOT(discoveryDone(QList))); } DeviceManager::DeviceError DevicePluginWemo::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)