herqq-1.0.0/0000755000000000000000000000000011543637460011337 5ustar rootrootherqq-1.0.0/hupnp/0000755000000000000000000000000011543640160012460 5ustar rootrootherqq-1.0.0/hupnp/src/0000755000000000000000000000000011543640126013251 5ustar rootrootherqq-1.0.0/hupnp/src/devicehosting/0000755000000000000000000000000011543637460016113 5ustar rootrootherqq-1.0.0/hupnp/src/devicehosting/devicehost/0000755000000000000000000000000011543637460020250 5ustar rootrootherqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost.cpp0000644000000000000000000004054711543637310023265 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicehost.h" #include "hdevicehost_p.h" #include "hevent_notifier_p.h" #include "hpresence_announcer_p.h" #include "hdevicehost_configuration.h" #include "hserverdevicecontroller_p.h" #include "hdevicehost_http_server_p.h" #include "hdevicehost_ssdp_handler_p.h" #include "hdevicehost_runtimestatus_p.h" #include "hdevicehost_dataretriever_p.h" #include "hservermodel_creator_p.h" #include "../../general/hlogger_p.h" #include "../../utils/hsysutils_p.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HServerDeviceController ******************************************************************************/ HServerDeviceController::HServerDeviceController( HServerDevice* device, qint32 deviceTimeoutInSecs, QObject* parent) : QObject(parent), m_statusNotifier(new QTimer(this)), m_deviceStatus(new HDeviceStatus()), m_device(device) { Q_ASSERT(m_device); //m_device->setParent(this); m_statusNotifier->setInterval(deviceTimeoutInSecs * 1000); bool ok = connect( m_statusNotifier.data(), SIGNAL(timeout()), this, SLOT(timeout_())); Q_ASSERT(ok); Q_UNUSED(ok) } HServerDeviceController::~HServerDeviceController() { } qint32 HServerDeviceController::deviceTimeoutInSecs() const { return m_statusNotifier->interval() / 1000; } void HServerDeviceController::timeout_() { HLOG(H_AT, H_FUN); m_timedout = true; stopStatusNotifier(); emit statusTimeout(this); } void HServerDeviceController::startStatusNotifier() { HLOG(H_AT, H_FUN); m_statusNotifier->start(); m_timedout = false; } void HServerDeviceController::stopStatusNotifier() { HLOG(H_AT, H_FUN); m_statusNotifier->stop(); } bool HServerDeviceController::isTimedout() const { return m_timedout; } /******************************************************************************* * HDeviceHostPrivate ******************************************************************************/ HDeviceHostPrivate::HDeviceHostPrivate() : QObject(), m_loggingIdentifier( QString("__DEVICE HOST %1__: ").arg( QUuid::createUuid().toString()).toLocal8Bit()), m_config (), m_ssdps (), m_httpServer (0), m_eventNotifier (0), m_presenceAnnouncer(0), m_runtimeStatus (0), q_ptr(0), m_lastError(HDeviceHost::UndefinedError), m_initialized(false), m_deviceStorage(m_loggingIdentifier), m_nam(0) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); srand(time(0)); } HDeviceHostPrivate::~HDeviceHostPrivate() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); } void HDeviceHostPrivate::announcementTimedout( HServerDeviceController* controller) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QList announcements; m_presenceAnnouncer->createAnnouncementMessagesForRootDevice( controller->m_device, controller->deviceTimeoutInSecs(), &announcements); m_presenceAnnouncer->sendAnnouncements(announcements); controller->startStatusNotifier(); } bool HDeviceHostPrivate::createRootDevice(const HDeviceConfiguration* deviceconfig) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QString baseDir = extractBaseUrl(deviceconfig->pathToDeviceDescription()); DeviceHostDataRetriever dataRetriever(m_loggingIdentifier, baseDir); QString deviceDescr; if (!dataRetriever.retrieveDeviceDescription( deviceconfig->pathToDeviceDescription(), &deviceDescr)) { m_lastError = HDeviceHost::InvalidConfigurationError; m_lastErrorDescription = dataRetriever.lastError(); return false; } HServerModelCreationArgs creatorParams(m_config->deviceModelCreator()); creatorParams.m_deviceDescription = deviceDescr; creatorParams.m_deviceLocations = m_httpServer->rootUrls(); creatorParams.setDeviceDescriptionPostfix(deviceDescriptionPostFix()); creatorParams.setInfoProvider(m_config->deviceModelInfoProvider()); creatorParams.m_serviceDescriptionFetcher = ServiceDescriptionFetcher( &dataRetriever, &DeviceHostDataRetriever::retrieveServiceDescription); creatorParams.m_deviceTimeoutInSecs = deviceconfig->cacheControlMaxAge() / 2; // this timeout value instructs the device host to re-announce the // device presence well before the advertised cache-control value // expires. creatorParams.m_iconFetcher = IconFetcher(&dataRetriever, &DeviceHostDataRetriever::retrieveIcon); creatorParams.m_loggingIdentifier = m_loggingIdentifier; HServerModelCreator creator(creatorParams); QScopedPointer rootDevice(creator.createRootDevice()); if (!rootDevice) { m_lastErrorDescription = creator.lastErrorDescription(); switch (creator.lastError()) { case HServerModelCreator::UndefinedTypeError: case HServerModelCreator::InvalidDeviceDescription: m_lastError = HDeviceHost::InvalidDeviceDescriptionError; break; case HServerModelCreator::UnimplementedAction: case HServerModelCreator::InvalidServiceDescription: m_lastError = HDeviceHost::InvalidServiceDescriptionError; break; default: m_lastError = HDeviceHost::UndefinedError; break; } return false; } Q_ASSERT(rootDevice); HServerDeviceController* controller = new HServerDeviceController( rootDevice.data(), creatorParams.m_deviceTimeoutInSecs, this); if (!m_deviceStorage.addRootDevice(rootDevice.data(), controller)) { delete controller; m_lastError = HDeviceHost::ResourceConflict; m_lastErrorDescription = m_deviceStorage.lastError(); return false; } rootDevice->setParent(this); connectSelfToServiceSignals(rootDevice.take()); return true; } bool HDeviceHostPrivate::createRootDevices() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QList diParams = m_config->deviceConfigurations(); foreach(const HDeviceConfiguration* deviceconfig, diParams) { if (!createRootDevice(deviceconfig)) { return false; } } return true; } void HDeviceHostPrivate::connectSelfToServiceSignals(HServerDevice* device) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HServerServices services(device->services()); for(qint32 i = 0; i < services.size(); ++i) { HServerService* service = services.at(i); bool ok = connect( service, SIGNAL(stateChanged(const Herqq::Upnp::HServerService*)), m_eventNotifier.data(), SLOT(stateChanged(const Herqq::Upnp::HServerService*))); Q_ASSERT(ok); Q_UNUSED(ok) } HServerDevices devices(device->embeddedDevices()); for(qint32 i = 0; i < devices.size(); ++i) { connectSelfToServiceSignals(devices.at(i)); } } void HDeviceHostPrivate::startNotifiers(HServerDeviceController* controller) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(controller); bool ok = connect( controller, SIGNAL(statusTimeout(HServerDeviceController*)), this, SLOT(announcementTimedout(HServerDeviceController*))); Q_ASSERT(ok); Q_UNUSED(ok) controller->startStatusNotifier(); } void HDeviceHostPrivate::startNotifiers() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QList controllers = m_deviceStorage.controllers(); foreach(HServerDeviceController* controller, controllers) { startNotifiers(controller); } } void HDeviceHostPrivate::stopNotifiers() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QList controllers = m_deviceStorage.controllers(); foreach(HServerDeviceController* controller, controllers) { controller->stopStatusNotifier(); } } /******************************************************************************* * HDeviceHost *******************************************************************************/ HDeviceHost::HDeviceHost(QObject* parent) : QObject(parent), h_ptr(new HDeviceHostPrivate()) { h_ptr->setParent(this); h_ptr->q_ptr = this; h_ptr->m_runtimeStatus.reset(new HDeviceHostRuntimeStatus()); h_ptr->m_runtimeStatus->h_ptr->m_deviceHost = this; } HDeviceHost::~HDeviceHost() { quit(); delete h_ptr; } bool HDeviceHost::doInit() { // default implementation does nothing return true; } void HDeviceHost::doQuit() { // default implementation does nothing } bool HDeviceHost::acceptSubscription( HServerService* /*targetService*/, const HEndpoint& /*source*/, bool /*renewal*/) { return true; } const HDeviceHostConfiguration* HDeviceHost::configuration() const { return h_ptr->m_config.data(); } const HDeviceHostRuntimeStatus* HDeviceHost::runtimeStatus() const { return h_ptr->m_runtimeStatus.data(); } void HDeviceHost::setError(DeviceHostError error, const QString& errorStr) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); h_ptr->m_lastError = error; h_ptr->m_lastErrorDescription = errorStr; } bool HDeviceHost::init(const HDeviceHostConfiguration& config) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); Q_ASSERT_X( thread() == QThread::currentThread(), H_AT, "The device host has to be initialized in the thread in which " "it is currently located."); if (h_ptr->m_initialized) { setError(AlreadyInitializedError, "The device host is already initialized"); return false; } if (!config.isValid()) { setError(InvalidConfigurationError, "The provided configuration is not valid"); return false; } bool ok = false; HLOG_INFO("DeviceHost Initializing."); h_ptr->m_config.reset(config.clone()); h_ptr->m_eventNotifier.reset( new HEventNotifier( h_ptr->m_loggingIdentifier, *h_ptr->m_config, this)); h_ptr->m_httpServer.reset( new HDeviceHostHttpServer( h_ptr->m_loggingIdentifier, HDeviceHostPrivate::deviceDescriptionPostFix(), h_ptr->m_deviceStorage, *h_ptr->m_eventNotifier, this)); QList addrs = config.networkAddressesToUse(); if (!h_ptr->m_httpServer->init(convertHostAddressesToEndpoints(addrs))) { setError(CommunicationsError, "Failed to initialize HTTP server"); goto err; } else { if (!h_ptr->createRootDevices()) { goto err; } foreach(const QHostAddress& ha, addrs) { HDeviceHostSsdpHandler* ssdp = new HDeviceHostSsdpHandler( h_ptr->m_loggingIdentifier, h_ptr->m_deviceStorage, this); h_ptr->m_ssdps.append(ssdp); if (!ssdp->init(ha)) { setError(CommunicationsError, "Failed to initialize SSDP"); goto err; } } h_ptr->m_presenceAnnouncer.reset( new PresenceAnnouncer( h_ptr->m_ssdps, h_ptr->m_config->individualAdvertisementCount())); // allow the derived classes to perform their initialization routines // before the hosted devices are announced to the network and timers // are started. In addition, at this time no HTTP or SSDP requests // are served. ok = doInit(); // continue only if the derived class succeeded in initializing itself } if (ok) { h_ptr->m_presenceAnnouncer->announce( h_ptr->m_deviceStorage.controllers()); h_ptr->startNotifiers(); h_ptr->m_initialized = true; HLOG_INFO("DeviceHost initialized."); return true; } err: quit(); HLOG_WARN("DeviceHost initialization failed"); return false; } HDeviceHost::DeviceHostError HDeviceHost::error() const { return h_ptr->m_lastError; } QString HDeviceHost::errorDescription() const { return h_ptr->m_lastErrorDescription; } void HDeviceHost::quit() { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); Q_ASSERT_X( thread() == QThread::currentThread(), H_AT, "The device host has to be shutdown in the thread in which it is " "currently located."); if (!h_ptr->m_initialized) { return; } HLOG_INFO("Shutting down."); h_ptr->stopNotifiers(); h_ptr->m_presenceAnnouncer->announce( h_ptr->m_deviceStorage.controllers()); h_ptr->m_httpServer->close(); h_ptr->m_initialized = false; doQuit(); h_ptr->m_presenceAnnouncer.reset(0); qDeleteAll(h_ptr->m_ssdps); h_ptr->m_ssdps.clear(); h_ptr->m_httpServer.reset(0); h_ptr->m_eventNotifier.reset(0); h_ptr->m_config.reset(0); h_ptr->m_deviceStorage.clear(); HLOG_INFO("Shut down."); } bool HDeviceHost::isStarted() const { return h_ptr->m_initialized; } bool HDeviceHost::add(const HDeviceConfiguration& configuration) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotStarted, "The device host is not started"); return false; } else if (!configuration.isValid()) { setError(InvalidConfigurationError, "The provided configuration is not valid"); return false; } bool b = h_ptr->createRootDevice(&configuration); if (b) { HServerDeviceController* newController = h_ptr->m_deviceStorage.controllers().last(); h_ptr->m_config->add(configuration); h_ptr->m_presenceAnnouncer->announce(newController); h_ptr->startNotifiers(newController); } return b; } HServerDevices HDeviceHost::rootDevices() const { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { HLOG_WARN("The device host is not started"); return HServerDevices(); } return h_ptr->m_deviceStorage.rootDevices(); } HServerDevice* HDeviceHost::device(const HUdn& udn, TargetDeviceType dts) const { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { HLOG_WARN("The device host is not started"); return 0; } return h_ptr->m_deviceStorage.searchDeviceByUdn(udn, dts); } /******************************************************************************* * HDeviceHostRuntimeStatusPrivate ******************************************************************************/ HDeviceHostRuntimeStatusPrivate::HDeviceHostRuntimeStatusPrivate() : m_deviceHost(0) { } /******************************************************************************* * HDeviceHostRuntimeStatus ******************************************************************************/ HDeviceHostRuntimeStatus::HDeviceHostRuntimeStatus() : h_ptr(new HDeviceHostRuntimeStatusPrivate()) { } HDeviceHostRuntimeStatus::~HDeviceHostRuntimeStatus() { delete h_ptr; } QList HDeviceHostRuntimeStatus::ssdpEndpoints() const { Q_ASSERT(h_ptr->m_deviceHost); QList retVal; foreach(HDeviceHostSsdpHandler* ssdp, h_ptr->m_deviceHost->h_ptr->m_ssdps) { retVal.append(ssdp->unicastEndpoint()); } return retVal; } QList HDeviceHostRuntimeStatus::httpEndpoints() const { Q_ASSERT(h_ptr->m_deviceHost); return h_ptr->m_deviceHost->h_ptr->m_httpServer->endpoints(); } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hevent_notifier_p.h0000644000000000000000000000474211543637310024131 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HEVENT_NOTIFIER_P_H_ #define HEVENT_NOTIFIER_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../../http/hhttp_p.h" #include "../../general/hupnp_fwd.h" #include "../../general/hupnp_defs.h" #include #include #include namespace Herqq { namespace Upnp { class HSid; class HTimeout; class HMessagingInfo; class HSubscribeRequest; class HUnsubscribeRequest; class HServiceEventSubscriber; // // Internal class used to notify event subscribers of events. // class HEventNotifier : public QObject { Q_OBJECT H_DISABLE_COPY(HEventNotifier) private: // attributes const QByteArray m_loggingIdentifier; // prefix for logging QList m_subscribers; HDeviceHostConfiguration& m_configuration; private: // methods HTimeout getSubscriptionTimeout(const HSubscribeRequest&); private Q_SLOTS: void stateChanged(const Herqq::Upnp::HServerService* source); public: HEventNotifier( const QByteArray& loggingIdentifier, HDeviceHostConfiguration&, QObject* parent); virtual ~HEventNotifier(); StatusCode addSubscriber(HServerService*, const HSubscribeRequest&, HSid*); bool removeSubscriber(const HUnsubscribeRequest&); StatusCode renewSubscription(const HSubscribeRequest&, HSid*); HServiceEventSubscriber* remoteClient(const HSid&) const; void initialNotify(HServiceEventSubscriber*, HMessagingInfo*); }; } } #endif /* HEVENT_NOTIFIER_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hserverdevicecontroller_p.h0000644000000000000000000000434511543637310025702 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERDEVICECONTROLLER_P_H_ #define HSERVERDEVICECONTROLLER_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include #include class QTimer; namespace Herqq { namespace Upnp { class HServerDevice; class HEventNotifier; // // This is an internal class that provides features HDeviceHost requires // in its operations // class H_UPNP_CORE_EXPORT HServerDeviceController : public QObject { Q_OBJECT H_DISABLE_COPY(HServerDeviceController) private: bool m_timedout; QScopedPointer m_statusNotifier; QScopedPointer m_deviceStatus; private Q_SLOTS: void timeout_(); public: HServerDevice* m_device; qint32 m_configId; public: HServerDeviceController( HServerDevice* device, qint32 deviceTimeoutInSecs, QObject* parent = 0); virtual ~HServerDeviceController(); qint32 deviceTimeoutInSecs() const; inline HDeviceStatus* deviceStatus() const { return m_deviceStatus.data(); } void startStatusNotifier(); void stopStatusNotifier(); bool isTimedout() const; Q_SIGNALS: void statusTimeout(HServerDeviceController* source); }; } } #endif /* HSERVERDEVICECONTROLLER_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_configuration_p.h0000644000000000000000000000456211543637310026175 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_CONFIGURATION_P_H_ #define HDEVICEHOST_CONFIGURATION_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hdevicehost_configuration.h" #include #include #include #include namespace Herqq { namespace Upnp { // // Implementation details of HDeviceConfiguration class // class H_UPNP_CORE_EXPORT HDeviceConfigurationPrivate { H_DISABLE_COPY(HDeviceConfigurationPrivate) public: // attributes QString m_pathToDeviceDescriptor; qint32 m_cacheControlMaxAgeInSecs; public: // methods HDeviceConfigurationPrivate(); ~HDeviceConfigurationPrivate(); }; // // // class H_UPNP_CORE_EXPORT HDeviceHostConfigurationPrivate { H_DISABLE_COPY(HDeviceHostConfigurationPrivate) public: QList m_collection; // configurations for each device to be hosted. qint32 m_individualAdvertisementCount; // how many times each announcement / advertisement is sent qint32 m_subscriptionExpirationTimeout; QList m_networkAddresses; QScopedPointer m_deviceCreator; QScopedPointer m_infoProvider; HDeviceHostConfigurationPrivate(); }; } } #endif /* HDEVICEHOST_CONFIGURATION_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hservermodel_creator_p.cpp0000644000000000000000000004561711543637310025520 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hservermodel_creator_p.h" #include "../../dataelements/hudn.h" #include "../../dataelements/hserviceid.h" #include "../../dataelements/hdeviceinfo.h" #include "../../general/hupnp_global_p.h" #include "../../general/hupnp_datatypes_p.h" #include "../../devicemodel/hdevicemodel_infoprovider.h" #include "../../devicemodel/server/hserverservice.h" #include "../../devicemodel/server/hserverservice_p.h" #include "../../devicemodel/server/hserverdevice_p.h" #include "../../devicemodel/server/hdevicemodelcreator.h" #include "../../devicemodel/server/hdefault_serverdevice_p.h" #include "../../devicemodel/server/hdefault_serveraction_p.h" #include "../../devicemodel/server/hdefault_serverstatevariable_p.h" #include "../../devicemodel/hactionarguments.h" #include "../../devicemodel/hactions_setupdata.h" #include "../../devicemodel/hdevices_setupdata.h" #include "../../devicemodel/hservices_setupdata.h" #include "../../devicemodel/hstatevariables_setupdata.h" #include "../../general/hlogger_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HServerModelCreationArgs ******************************************************************************/ HServerModelCreationArgs::HServerModelCreationArgs( HDeviceModelCreator* creator) : m_deviceModelCreator(creator), m_infoProvider(0), m_ddPostFix() { } HServerModelCreationArgs::~HServerModelCreationArgs() { } HServerModelCreationArgs::HServerModelCreationArgs( const HServerModelCreationArgs& other) : HModelCreationArgs(other), m_deviceModelCreator(other.m_deviceModelCreator), m_infoProvider(other.m_infoProvider), m_ddPostFix(other.m_ddPostFix) { } HServerModelCreationArgs& HServerModelCreationArgs::operator=( const HServerModelCreationArgs& other) { Q_ASSERT(this != &other); HModelCreationArgs::operator=(other); m_deviceModelCreator = other.m_deviceModelCreator; m_infoProvider = other.m_infoProvider; m_ddPostFix = other.m_ddPostFix; return *this; } /******************************************************************************* * HServerModelCreator ******************************************************************************/ HServerModelCreator::HServerModelCreator( const HServerModelCreationArgs& creationParameters) : m_creationParameters(new HServerModelCreationArgs(creationParameters)), m_docParser(creationParameters.m_loggingIdentifier, StrictChecks), m_lastErrorDescription() { Q_ASSERT(creationParameters.m_serviceDescriptionFetcher); Q_ASSERT(creationParameters.m_deviceLocations.size() > 0); Q_ASSERT(creationParameters.m_iconFetcher); Q_ASSERT(!creationParameters.m_loggingIdentifier.isEmpty()); Q_ASSERT(!creationParameters.deviceDescriptionPostfix().isEmpty()); } HStateVariablesSetupData HServerModelCreator::getStateVariablesSetupData( HServerService* service) { if (m_creationParameters->infoProvider()) { return m_creationParameters->infoProvider()->stateVariablesSetupData( service->info(), service->parentDevice()->info()); } return HStateVariablesSetupData(); } HActionsSetupData HServerModelCreator::getActionsSetupData( HServerService* service) { if (m_creationParameters->infoProvider()) { return m_creationParameters->infoProvider()->actionsSetupData( service->info(), service->parentDevice()->info()); } return HActionsSetupData(); } HServicesSetupData HServerModelCreator::getServicesSetupData( HServerDevice* device) { if (m_creationParameters->infoProvider()) { return m_creationParameters->infoProvider()->servicesSetupData( device->info()); } return HServicesSetupData(); } HDevicesSetupData HServerModelCreator::getDevicesSetupData( HServerDevice* device) { if (m_creationParameters->infoProvider()) { return m_creationParameters->infoProvider()->embedddedDevicesSetupData( device->info()); } return HDevicesSetupData(); } bool HServerModelCreator::parseStateVariables( HServerService* service, QDomElement stateVariableElement) { HStateVariablesSetupData stateVariablesSetup = getStateVariablesSetupData(service); while(!stateVariableElement.isNull()) { HStateVariableInfo svInfo; if (!m_docParser.parseStateVariable(stateVariableElement, &svInfo)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } QString name = svInfo.name(); HStateVariableInfo setupData = stateVariablesSetup.get(name); if (!setupData.isValid() && stateVariablesSetup.defaultInclusionPolicy() == HStateVariablesSetupData::Deny) { m_lastError = InvalidServiceDescription; m_lastErrorDescription = QString( "Implementation of service [%1] does not support state variable" "[%2]").arg(service->info().serviceId().toString(), name); return false; } HDeviceValidator validator; if (!validator.validate(stateVariablesSetup.get(name), svInfo)) { m_lastError = InvalidServiceDescription; m_lastErrorDescription = QString("Service [%1] validation error: %2").arg( service->info().serviceId().toString(), validator.lastErrorDescription()); return false; } HDefaultServerStateVariable* sv = new HDefaultServerStateVariable(svInfo, service); service->h_ptr->addStateVariable(sv); bool ok = QObject::connect( sv, SIGNAL(valueChanged( Herqq::Upnp::HServerStateVariable*, const Herqq::Upnp::HStateVariableEvent&)), service, SLOT(notifyListeners())); Q_ASSERT(ok); Q_UNUSED(ok) stateVariableElement = stateVariableElement.nextSiblingElement("stateVariable"); stateVariablesSetup.remove(name); } if (!stateVariablesSetup.isEmpty()) { foreach(const QString& name, stateVariablesSetup.names()) { HStateVariableInfo svSetup = stateVariablesSetup.get(name); if (svSetup.inclusionRequirement() == InclusionMandatory && svSetup.version() <= service->info().serviceType().version()) { m_lastError = InvalidServiceDescription; m_lastErrorDescription = QString( "Service description is missing a mandatory state variable " "[%1]").arg(name); return false; } } } return true; } bool HServerModelCreator::parseActions( HServerService* service, QDomElement actionElement, const HStateVariableInfos& svInfos) { HActionsSetupData actionsSetupData = getActionsSetupData(service); QHash actionInvokes = service->createActionInvokes(); while(!actionElement.isNull()) { HActionInfo actionInfo; if (!m_docParser.parseActionInfo( actionElement, svInfos, &actionInfo)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } QString name = actionInfo.name(); HActionInvoke actionInvoke = actionInvokes.value(name); if (!actionInvoke) { m_lastError = UnimplementedAction; m_lastErrorDescription = QString( "Service [%1]: action [%2] lacks an implementation").arg( service->info().serviceId().toString(), name); return false; } QScopedPointer action( new HDefaultServerAction(actionInfo, actionInvoke, service)); HDeviceValidator validator; if (!validator.validate(actionsSetupData.get(name), actionInfo)) { m_lastError = InvalidServiceDescription; m_lastErrorDescription = QString("Service [%1] validation error: %2").arg( service->info().serviceId().toString(), validator.lastErrorDescription()); return false; } service->h_ptr->m_actions.insert(name, action.take()); actionElement = actionElement.nextSiblingElement("action"); actionsSetupData.remove(name); } if (!actionsSetupData.isEmpty()) { foreach(const QString& name, actionsSetupData.names()) { HActionSetup setupInfo = actionsSetupData.get(name); if (setupInfo.inclusionRequirement() == InclusionMandatory && setupInfo.version() <= service->info().serviceType().version()) { m_lastError = InvalidServiceDescription; m_lastErrorDescription = QString( "Service description for [%1] is missing a mandatory action " "[%2]").arg(service->info().serviceId().toString(), name); return false; } } } return true; } bool HServerModelCreator::parseServiceDescription(HServerService* service) { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); Q_ASSERT(service); QDomDocument doc; QDomElement firstSv, firstAction; if (!m_docParser.parseServiceDescription( service->h_ptr->m_serviceDescription, &doc, &firstSv, &firstAction)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } if (!parseStateVariables(service, firstSv)) { return false; } HStateVariableInfos svInfos; HServerStateVariables svs = service->stateVariables(); foreach(const QString& key, svs.keys()) { svInfos.insert(key, svs.value(key)->info()); } return parseActions(service, firstAction, svInfos); } bool HServerModelCreator::parseServiceList( const QDomElement& serviceListElement, HServerDevice* device, QList* retVal) { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); Q_ASSERT(device); Q_ASSERT(!serviceListElement.isNull()); QDomElement serviceElement = serviceListElement.firstChildElement("service"); HServicesSetupData setupData = getServicesSetupData(device); while(!serviceElement.isNull()) { HServiceInfo info; if (!m_docParser.parseServiceInfo(serviceElement, &info)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } QScopedPointer service( m_creationParameters->creator()->createService(info, device->info())); if (!service) { m_lastError = UndefinedTypeError; m_lastErrorDescription = QString("No object for service type [%1] was created").arg( info.serviceType().toString()); return 0; } if (!service->init(info, device)) { m_lastError = InitializationError; m_lastErrorDescription = QString("Failed to initialize service [%1]").arg( info.serviceId().toString()); return false; } if (!m_creationParameters->m_serviceDescriptionFetcher( extractBaseUrl(m_creationParameters->m_deviceLocations[0]), info.scpdUrl(), &service->h_ptr->m_serviceDescription)) { m_lastError = FailedToGetDataError; m_lastErrorDescription = QString( "Could not retrieve service description from [%1]").arg( info.scpdUrl().toString()); return false; } if (!parseServiceDescription(service.data())) { return false; } QString errDescr; bool ok = service->finalizeInit(&errDescr); if (!ok) { m_lastError = InitializationError; m_lastErrorDescription = errDescr; return false; } retVal->push_back(service.take()); serviceElement = serviceElement.nextSiblingElement("service"); setupData.remove(info.serviceId()); } if (!setupData.isEmpty()) { foreach(const HServiceId& id, setupData.serviceIds()) { HServiceSetup setupInfo = setupData.get(id); if (setupInfo.inclusionRequirement() == InclusionMandatory && setupInfo.version() <= device->info().deviceType().version()) { m_lastError = InvalidServiceDescription; m_lastErrorDescription = QString( "Device description for [%1] is missing a mandatory service " "[%2]").arg(device->info().deviceType().toString(), id.toString()); return false; } } } return true; } namespace { QList generateLocations( const HUdn& udn, const QList& locations, const QString& ddPostFix) { QList retVal; foreach(const QUrl& location, locations) { QString locStr = location.toString(); if (!locStr.endsWith('/')) { locStr.append(QString("/%1/%2").arg(udn.toSimpleUuid(), ddPostFix)); } retVal.append(locStr); } return retVal; } } HServerDevice* HServerModelCreator::parseDevice( const QDomElement& deviceElement, HServerDevice* parentDevice) { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); HDeviceInfo deviceInfo; if (!m_docParser.parseDeviceInfo(deviceElement, &deviceInfo)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return 0; } QScopedPointer device( m_creationParameters->creator()->createDevice(deviceInfo)); if (!device.data()) { HLOG_DBG(QString("Creating default device for [%1]").arg( deviceInfo.deviceType().toString())); device.reset(new HDefaultServerDevice()); } if (!device->init(deviceInfo, parentDevice)) { m_lastError = InitializationError; m_lastErrorDescription = QString("Failed to initialize device [%1]").arg( deviceInfo.udn().toString()); return false; } device->h_ptr->m_deviceDescription = m_creationParameters->m_deviceDescription; QDomElement serviceListElement = deviceElement.firstChildElement("serviceList"); if (!serviceListElement.isNull()) { HServerServices services; if (!parseServiceList(serviceListElement, device.data(), &services)) { qDeleteAll(services); return 0; } device->h_ptr->m_services = services; } HDevicesSetupData setupData = getDevicesSetupData(device.data()); QDomElement deviceListElement = deviceElement.firstChildElement("deviceList"); if (!deviceListElement.isNull()) { QList embeddedDevices; QDomElement embeddedDeviceElement = deviceListElement.firstChildElement("device"); while(!embeddedDeviceElement.isNull()) { HServerDevice* embeddedDevice = parseDevice(embeddedDeviceElement, device.data()); if (!embeddedDevice) { qDeleteAll(embeddedDevices); return 0; } embeddedDevices.push_back(embeddedDevice); embeddedDeviceElement = embeddedDeviceElement.nextSiblingElement("device"); } device->h_ptr->m_embeddedDevices = embeddedDevices; setupData.remove(deviceInfo.deviceType()); } if (!setupData.isEmpty()) { foreach(const HResourceType& dt, setupData.deviceTypes()) { HDeviceSetup setupInfo = setupData.get(dt); if (setupInfo.inclusionRequirement() == InclusionMandatory && setupInfo.version() <= device->info().deviceType().version()) { m_lastError = InvalidServiceDescription; m_lastErrorDescription = QString( "Device description for [%1] is missing a mandatory embedded device " "[%2]").arg(device->info().deviceType().toString(), dt.toString()); return false; } } } if (!device->finalizeInit(&m_lastErrorDescription)) { m_lastError = InitializationError; return 0; } return device.take(); } HServerDevice* HServerModelCreator::createRootDevice() { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); QDomDocument doc; QDomElement rootElement; if (!m_docParser.parseRoot( m_creationParameters->m_deviceDescription, &doc, &rootElement)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return 0; } QScopedPointer createdDevice(parseDevice(rootElement, 0)); if (!createdDevice) { return 0; } createdDevice->h_ptr->m_deviceStatus.reset(new HDeviceStatus()); createdDevice->h_ptr->m_deviceStatus->setConfigId( m_docParser.readConfigId(rootElement)); createdDevice->h_ptr->m_locations = generateLocations( createdDevice->info().udn(), m_creationParameters->m_deviceLocations, m_creationParameters->deviceDescriptionPostfix()); HDeviceValidator validator; if (!validator.validateRootDevice( createdDevice.data())) { m_lastError = convert(validator.lastError()); m_lastErrorDescription = validator.lastErrorDescription(); return 0; } return createdDevice.take(); } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_dataretriever_p.cpp0000644000000000000000000000714511543637310026522 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicehost_dataretriever_p.h" #include "../../general/hlogger_p.h" #include #include namespace Herqq { namespace Upnp { DeviceHostDataRetriever::DeviceHostDataRetriever( const QByteArray& loggingId, const QUrl& rootDir) : m_loggingIdentifier(loggingId), m_rootDir(rootDir) { } bool DeviceHostDataRetriever::retrieveServiceDescription( const QUrl& /*deviceLocation*/, const QUrl& scpdUrl, QString* retVal) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QString localScpdPath = scpdUrl.toLocalFile(); if (localScpdPath.startsWith('/')) { localScpdPath = localScpdPath.mid(1); } QString fullScpdPath = m_rootDir.toString(); if (!fullScpdPath.endsWith('/')) { fullScpdPath.append('/'); } fullScpdPath.append(localScpdPath); // UDA mandates that the paths inside a device description are treated relative // to the device description location. QFile file(fullScpdPath); HLOG_DBG(QString( "Attempting to open service description from [%1]").arg(fullScpdPath)); if (!file.open(QIODevice::ReadOnly)) { m_lastError = QString("Could not open the service description file [%1].").arg( fullScpdPath); return false; } *retVal = QString::fromUtf8(file.readAll()); return true; } bool DeviceHostDataRetriever::retrieveIcon( const QUrl& /*devLoc*/, const QUrl& iconUrl, QByteArray* retVal) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QString localIconPath = iconUrl.toLocalFile(); if (localIconPath.startsWith('/')) { localIconPath = localIconPath.mid(1); } QString fullIconPath = m_rootDir.toString(); if (!fullIconPath.endsWith('/')) { fullIconPath.append('/'); } fullIconPath.append(localIconPath); // UDA mandates that the paths inside a device description are treated relative // to the device description location. HLOG_DBG(QString( "Attempting to open a file [%1] that should contain an icon").arg( fullIconPath)); QFile iconFile(fullIconPath); if (!iconFile.open(QIODevice::ReadOnly)) { m_lastError = QString("Could not open the icon file [%1]").arg(fullIconPath); return false; } *retVal = iconFile.readAll(); return true; } bool DeviceHostDataRetriever::retrieveDeviceDescription( const QString& filePath, QString* retVal) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { m_lastError = QString("Could not open the device description file: [%1].").arg( filePath); return false; } *retVal = QString::fromUtf8(file.readAll()); return true; } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost.h0000644000000000000000000004411511543637310022725 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_H_ #define HDEVICEHOST_H_ #include #include namespace Herqq { namespace Upnp { class HDeviceHostPrivate; /*! * \brief This is a class for creating and hosting \c %HServerDevice instances on the network. * * \headerfile hdevicehost.h HDeviceHost * * \ingroup hupnp_devicehosting * * As the name implies, this is the class in the HUPnP library * used to expose UPnP devices to UPnP control points. * The class \e hosts instances of HServerDevice, which means that the class takes * care of all of the UPnP mechanics detaching the HServerDevice from it. This * separation leaves the HServerDevice to model the UPnP device structure and to * focus on the functionality of the specific device type. This is what the * HUPnP \ref hupnp_devicemodel is all about. * * Hosting a device is simple, assuming you have the necessary device and service * descriptions ready and the HUPnP device and service classes implemented. * Basically, you only need to: * * \li instantiate an HDeviceConfiguration for each UPnP device type to be hosted and * pass them to the \c %HDeviceHost inside a HDeviceHostConfiguration instance * \li instantiate and initialize an \c %HDeviceHost * \li make sure a Qt event loop is present in the thread in which the * \c %HDeviceHost is run. * * As an example, consider the following: * * \code * * // myclass.h * * #include "my_hdevice.h" // your code containing the type MyHDevice * * #include * #include * * #include * * class MyClass : * public QObject * { * Q_OBJECT * * private: * Herqq::Upnp::HDeviceHost* m_deviceHost; * * public: * MyClass(QObject* parent = 0); * }; * * class MyCreator : public Herqq::Upnp::HDeviceModelCreator * { * * private: * * // overridden from HDeviceModelCreator * virtual MyCreator* newInstance() const; * * public: * * // overridden from HDeviceModelCreator * virtual MyHServerDevice* createDevice( * const Herqq::Upnp::HDeviceInfo& info) const; * * // overridden from HDeviceModelCreator * virtual MyHServerService* createService( * const Herqq::Upnp::HServiceInfo& serviceInfo, * const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const; * }; * * // myclass.cpp * * MyCreator* MyCreator::newInstance() const * { * return new MyCreator(); * } * * MyHServerDevice* MyCreator::createDevice(const Herqq::Upnp::HDeviceInfo& info) const * { * if (info.deviceType().toString() == "urn:herqq-org:device:MyDevice:1") * { * return new MyHServerDevice(); * } * * return 0; * } * * MyHServerService* MyCreator::createService( * const Herqq::Upnp::HServiceInfo& serviceInfo, * const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const * { * if (serviceInfo.serviceType().toString() == "urn:herqq-org:service:MyService:1") * { * return new HMyServerService(); * } * * // Note, parentDeviceInfo is not needed in this case, but there are * // scenarios when it is mandatory to know information of the parent * // device to create the correct HServerService type. * * return 0; * } * * MyClass::MyClass(QObject* parent) : * QObject(parent), * m_deviceHost(new Herqq::Upnp::HDeviceHost(this)) * { * Herqq::Upnp::HDeviceHostConfiguration hostConf; * hostConf.setDeviceModelCreator(MyCreator()); * * Herqq::Upnp::HDeviceConfiguration deviceConf; * deviceConf.setPathToDeviceDescription("my_hdevice_devicedescription.xml"); * * hostConf.add(deviceConf); * * if (!m_deviceHost->init(hostConf)) * { * // The initialization failed, perhaps you should do something? * // for starters, you can call error() to check the error type and * // errorDescription() for a human-readable description of * // the error that occurred. * return; * } * * // The host is running and your device should now be accessible to * // UPnP Control points until the host is destroyed (assuming the current * // thread has an event loop). * } * * \endcode * * There are a few noteworthy issues in the example above. * * -# The device host will fail to initialize if your HDeviceHostConfiguration * instance is invalid; for instance, the \e device \e model \e creator is not * specified or any of the paths to your UPnP device or service description * documents are invalid. The point is, you should always check the return * value. * -# Your HServerDevice is accessible only as long as your \c %HDeviceHost * is alive. When the device host is destroyed every UPnP device it hosted * are destroyed as well. * -# \c %HDeviceHost requires an event loop to function. * -# The example above uses an \c %HDeviceHost instance to host a single UPnP root * device, but the same host could be used to host multiple UPnP root devices. * Certainly you can create multiple \c %HDeviceHost instances that each host a single * root HServerDevice within a thread, even sharing an event loop. * However, using a single \c %HDeviceHost for multiple root HServerDevice instances * reduces resource usage in various ways and makes all the configured UPnP * root devices accessible to you from the same \c %HDeviceHost instance. * * \remarks * * \li \c %HDeviceHost has thread affinity, which mandates * that the \c %HDeviceHost and any object managed by it must be destroyed in the * thread in which the \c %HDeviceHost at the time lives. * You can use QObject::moveToThread() on the \c %HDeviceHost, which causes * the device host and every object managed by it to be moved to the chosen thread. * However, you cannot move individual objects managed by \c %HDeviceHost. * * \li \c %HDeviceHost is the owner of the instances of * \c %HServerDevice it manages. It manages the memory of every object it has created. * In other words, a device host \b never transfers the ownership of the * HServerDevice objects it manages; %HDeviceHost always destroys every * %HServerDevice it manages when it is being destroyed. * * \sa hupnp_devicehosting, HServerDevice, HDeviceHostConfiguration, * HDeviceConfiguration */ class H_UPNP_CORE_EXPORT HDeviceHost : public QObject { Q_OBJECT H_DISABLE_COPY(HDeviceHost) H_DECLARE_PRIVATE(HDeviceHost) friend class HDeviceHostRuntimeStatus; public: /*! * \brief Specifies return values that some of the methods of the class may return. */ enum DeviceHostError { /*! * Return value signifying general failure. * * This return code is used when * an operation could not be successfully completed, but the exact * cause for the error could not be determined. */ UndefinedError = -1, /*! * No error has occurred. */ NoError = 0, /*! * Return value signifying that the device host is already successfully * initialized. */ AlreadyInitializedError = 1, /*! * Return value signifying that the provided host configuration was incorrect. */ InvalidConfigurationError = 2, /*! * Return value signifying that a provided device description document * was invalid. */ InvalidDeviceDescriptionError = 3, /*! * Return value signifying that a provided service description document * was invalid. */ InvalidServiceDescriptionError = 4, /*! * Return value used to indicate one or more more problems in communications * layer. * * For instance, perhaps the HTTP server or could the SSDP listener * could not be initialized. */ CommunicationsError = 5, /*! * Return value used to indicate that the device host instance is not * property initiated. */ NotStarted = 6, /*! * Return value used to indicate that operation failed due to a resource * conflict. * * For instance, trying to add more than one device with a same UDN * will fail because of this. */ ResourceConflict = 7 }; private: /*! * Performs the initialization of a derived class. * * The \c %HDeviceHost uses two-phase initialization in which the user * first constructs an instance and then calls init() in order to ready * the object for use. This method is called by the \c %HDeviceHost * during its private initialization after all the private data structures * are constructed, but before any network operations are performed. At this * point no HTTP or SSDP requests are served. * * You can override this method to perform any further initialization of a derived * class. * * \return \e true if and only if the initialization succeeded. * If \e false is returned the initialization of the device host is * aborted. In addition, it is advised that you call setError() * before returning. * * \remarks the default implementation does nothing. * * \sa init() */ virtual bool doInit(); /*! * Performs the de-initialization of a derived class. * * Since it is possible to shutdown a device host without actually destroying the * instance by calling quit(), derived classes have the possibility to * run their own shutdown procedure by overriding this method. * This method is called \b before the \c %HDeviceHost cleans its * private data structures but after it has stopped listening requests * from the network. * * \remarks the default implementation does nothing. * * \sa quit() */ virtual void doQuit(); /*! * Checks if a (re-)subscription should be accepted. * * Derived classes can opt to override this method to decide what * event subscriptions are accepted and what are not. * * \param targetService specifies the target of the subscription. * * \param source specifies the location where the subscription came. * * \param isNew indicates the type of the subscription. The value is * \e true in case the subscription is new and \e false in case the * subscription is a renewal to an existing subscription. * * \return \e true in case the subscription should be accepted. * * \remarks by default all subscriptions are accepted. */ virtual bool acceptSubscription( HServerService* targetService, const HEndpoint& source, bool isNew); protected: HDeviceHostPrivate* h_ptr; /*! * \brief Returns the configuration used to initialize the device host. * * \return The configuration used to initialize the device host or null * in case the device host is not initialized. * * \remarks the returned object is not a copy and the ownership of the * object is not transferred. Do \b not delete it. */ const HDeviceHostConfiguration* configuration() const; /*! * \brief Returns the object that details information of the status of a * device host. * * \return The object that details information of the status of a * device host. * * \remarks * \li A device host creates a single HDeviceHostRuntimeStatus object * during its construction and deletes it when the device host is being * deleted. * \li The returned object is always owned by the device host. */ const HDeviceHostRuntimeStatus* runtimeStatus() const; /*! * \brief Sets the type and description of the last error occurred. * * \param error specifies the error type. * \param errorDescr specifies a human readable description of the error. * * \sa error(), errorDescription() */ void setError(DeviceHostError error, const QString& errorDescr); public: /*! * \brief Creates a new instance. * * \param parent specifies the parent \c QObject. */ explicit HDeviceHost(QObject* parent = 0); /*! * \brief Destroys the instance. * * Destroys the device host and every hosted device. */ virtual ~HDeviceHost(); /*! * \brief Returns a root device with the specified Unique Device Name. * * \param udn specifies the Unique Device Name of the desired root device. * \param target specifies the type of devices that are included in the * search. * * \return The root device with the specified Unique Device Name, or a * null pointer in case no currently managed root device has the * specified UDN. * * \warning the returned device will be deleted when the * device host is being destroyed. However, do \b not delete * the device object directly. The ownership of an HServerDevice is \b * never transferred. */ HServerDevice* device( const HUdn& udn, TargetDeviceType target = RootDevices) const; /*! * \brief Returns a list of UPnP root devices the host is currently managing. * * The returned list contains pointers to root HServerDevice objects * that are currently hosted by this instance. * * \return a list of pointers to root HServerDevice objects that are * currently managed by the device host. * * \warning the returned HServerDevice instances will be deleted when the * device host is being destroyed. However, do \b not delete * the device objects directly. The ownership of an HServerDevice is \b never * transferred. */ HServerDevices rootDevices() const; /*! * Initializes the device host and the devices it is supposed to host. * * \param configuration specifies the configuration for the instance. The * object has to contain at least one device configuration. * * \return \e true if the initialization of the device host succeeded. * If \e false is returned you can call error() to get the type of the error, * and you can call errorDescription() to get a human-readable description * of the error. * * \sa quit() */ bool init(const HDeviceHostConfiguration& configuration); /*! * \brief Returns the type of the last error occurred. * * \return The type of the last error occurred. */ DeviceHostError error() const; /*! * \brief Returns a human readable description of the last error occurred. * * \return a human readable description of the last error occurred. */ QString errorDescription() const; /*! * \brief Indicates whether or not the host is successfully started. * * \return \e true in case the host is successfully started. */ bool isStarted() const; /*! * Adds a new root device configuration to the device host. * * If the provided configuration is valid, the device host creates a new * device model instance, announces the new resource(s) to the network and adds * the device model available into the control of this instance. * * \param configuration specifies the new root device to add. * * \return \e true if a device model corresponding to the specified * configuration was created and added to the device host. If the method * returns \e false, you can call error() and errorDescription() to get * more information of the error that occurred. * * \remarks The specified device configuration has to be compatible with * the specified HDeviceHostConfiguration specified in init(). * * \sa error(), errorDescription() */ bool add(const HDeviceConfiguration& configuration); public Q_SLOTS: /*! * Quits the device host and destroys the UPnP devices it is hosting. Note that * this is automatically called when the device host is destroyed. * * \attention Every pointer to object retrieved from this instance will be * deleted. Be sure not to use any such pointer after calling this method. * * \sa init() */ void quit(); }; class HDeviceHostRuntimeStatusPrivate; /*! * This is a class for detailing information of the runtime status of an * HDeviceHost instance. * * \headerfile hdevicehost.h HDeviceHostRuntimeStatus * * \ingroup hupnp_devicehosting * * \sa HDeviceHost */ class H_UPNP_CORE_EXPORT HDeviceHostRuntimeStatus { H_DISABLE_COPY(HDeviceHostRuntimeStatus) friend class HDeviceHost; protected: HDeviceHostRuntimeStatusPrivate* h_ptr; // // \internal // HDeviceHostRuntimeStatus(HDeviceHostRuntimeStatusPrivate& dd); /*! * \brief Creates an instance. * * Creates an instance. */ HDeviceHostRuntimeStatus(); public: /*! * \brief Destroys the instance. */ virtual ~HDeviceHostRuntimeStatus(); /*! * \brief Returns the IP endpoints that the device host uses for SSDP communications. * * \return The IP endpoints that the device host uses for SSDP communications. */ QList ssdpEndpoints() const; /*! * \brief Returns the IP endpoints that the device host uses for HTTP communications. * * \return The IP endpoints that the device host uses for HTTP communications. */ QList httpEndpoints() const; }; } } #endif /* HDEVICEHOST_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hservermodel_creator_p.h0000644000000000000000000001050111543637310025145 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERMODEL_CREATOR_P_H_ #define HSERVERMODEL_CREATOR_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../hddoc_parser_p.h" #include "../hmodelcreation_p.h" #include "../../devicemodel/hactioninvoke.h" namespace Herqq { namespace Upnp { // // // class HServerModelCreationArgs : public HModelCreationArgs { private: HDeviceModelCreator* m_deviceModelCreator; // Not owned. HDeviceModelInfoProvider* m_infoProvider; // Not owned. QString m_ddPostFix; public: HServerModelCreationArgs(HDeviceModelCreator*); HServerModelCreationArgs(const HServerModelCreationArgs&); virtual ~HServerModelCreationArgs(); HServerModelCreationArgs& operator=(const HServerModelCreationArgs&); inline void setInfoProvider(HDeviceModelInfoProvider* arg) { m_infoProvider = arg; } inline HDeviceModelCreator* creator() const { return m_deviceModelCreator; } inline HDeviceModelInfoProvider* infoProvider() const { return m_infoProvider; } inline void setDeviceDescriptionPostfix(const QString& arg) { m_ddPostFix = arg; } inline QString deviceDescriptionPostfix() const { return m_ddPostFix; } }; // // The class that creates the HUPnP's device model from description files // class HServerModelCreator { H_DISABLE_COPY(HServerModelCreator) public: enum ErrorType { NoError, FailedToGetDataError, InvalidServiceDescription, InvalidDeviceDescription, UndefinedTypeError, UnimplementedAction, InitializationError, UndefinedError }; private: QScopedPointer m_creationParameters; HDocParser m_docParser; QString m_lastErrorDescription; ErrorType m_lastError; private: HStateVariablesSetupData getStateVariablesSetupData(HServerService*); HActionsSetupData getActionsSetupData(HServerService*); HServicesSetupData getServicesSetupData(HServerDevice*); HDevicesSetupData getDevicesSetupData(HServerDevice*); QList > parseIconList( const QDomElement& iconListElement); bool parseStateVariables( HServerService* service, QDomElement stateVariableElement); bool parseActions( HServerService* service, QDomElement actionElement, const HStateVariableInfos& svInfos); bool parseServiceDescription(HServerService*); bool parseServiceList( const QDomElement& serviceListElement, HServerDevice*, QList* retVal); HServerDevice* parseDevice( const QDomElement& deviceElement, HServerDevice* parentDevice); inline ErrorType convert(DocumentErrorTypes type) { switch(type) { case InvalidDeviceDescriptionError: return InvalidDeviceDescription; case InvalidServiceDescriptionError: return InvalidServiceDescription; case NoError: return NoError; default: return UndefinedError; } } public: HServerModelCreator(const HServerModelCreationArgs&); HServerDevice* createRootDevice(); inline ErrorType lastError() const { return m_lastError; } inline QString lastErrorDescription() const { return m_lastErrorDescription; } }; } } #endif /* HSERVERMODEL_CREATOR_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_ssdp_handler_p.cpp0000644000000000000000000003677511543637310026342 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicehost_ssdp_handler_p.h" #include "hserverdevicecontroller_p.h" #include "../../general/hupnp_global_p.h" #include "../../dataelements/hudn.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hserviceinfo.h" #include "../../dataelements/hdiscoverytype.h" #include "../../dataelements/hproduct_tokens.h" #include "../../devicemodel/hdevicestatus.h" #include "../../devicemodel/server/hserverdevice.h" #include "../../devicemodel/server/hserverservice.h" #include "../../general/hlogger_p.h" #include "../../utils/hsysutils_p.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HDelayedWriter ******************************************************************************/ HDelayedWriter::HDelayedWriter( HDeviceHostSsdpHandler& ssdp, const QList& responses, const HEndpoint& source, qint32 msecs) : QObject(&ssdp), m_ssdp(ssdp), m_responses(responses), m_source(source), m_msecs(msecs) { } void HDelayedWriter::timerEvent(QTimerEvent*) { HLOG2(H_AT, H_FUN, m_ssdp.loggingIdentifier()); foreach(const HDiscoveryResponse& resp, m_responses) { qint32 count = m_ssdp.sendDiscoveryResponse(resp, m_source); if (count <= 0) { HLOG_WARN(QString("Failed to send discovery response [%1] to: [%2].").arg( resp.usn().toString(), m_source.toString())); } } emit sent(); } void HDelayedWriter::run() { startTimer(m_msecs); } /******************************************************************************* * HDeviceHostSsdpHandler ******************************************************************************/ HDeviceHostSsdpHandler::HDeviceHostSsdpHandler( const QByteArray& loggingIdentifier, HDeviceStorage& ds, QObject* parent) : HSsdp(loggingIdentifier, parent), m_deviceStorage(ds) { Q_ASSERT(parent); setFilter(DiscoveryRequest); } HDeviceHostSsdpHandler::~HDeviceHostSsdpHandler() { } bool HDeviceHostSsdpHandler::processSearchRequest_specificDevice( const HDiscoveryRequest& req, const HEndpoint& source, QList* responses) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); HDiscoveryType st = req.searchTarget(); QUuid uuid = st.udn().value(); if (uuid.isNull()) { HLOG_DBG(QString("Invalid device-UUID: [%1]").arg(st.udn().toString())); return false; } const HServerDevice* device = m_deviceStorage.searchDeviceByUdn(HUdn(uuid), AllDevices); if (!device) { HLOG_DBG(QString("No device with the specified UUID: [%1]").arg( uuid.toString())); return false; } QUrl location; if (!m_deviceStorage.searchValidLocation(device, source, &location)) { HLOG_DBG(QString( "Found a device with uuid: [%1], but it is not " "available on the interface that has address: [%2]").arg( uuid.toString(), source.toString())); return false; } const HServerDeviceController* controller = m_deviceStorage.getController(device); Q_ASSERT(controller); responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, HSysInfo::instance().herqqProductTokens(), st, // the searched usn device->deviceStatus().bootId(), device->deviceStatus().configId() )); return true; } bool HDeviceHostSsdpHandler::processSearchRequest_deviceType( const HDiscoveryRequest& req, const HEndpoint& source, QList* responses) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); HDiscoveryType st = req.searchTarget(); QList foundDevices = m_deviceStorage.searchDevicesByDeviceType( st.resourceType(), HResourceType::EqualOrGreater, AllDevices); if (!foundDevices.size()) { HLOG_DBG(QString("No devices match the specified type: [%1]").arg( st.resourceType().toString())); return false; } qint32 prevSize = responses->size(); foreach(const HServerDevice* device, foundDevices) { QUrl location; if (!m_deviceStorage.searchValidLocation(device, source, &location)) { HLOG_DBG(QString( "Found a matching device, but it is not " "available on the interface that has address: [%1]").arg( source.toString())); continue; } st.setUdn(device->info().udn()); const HServerDeviceController* controller = m_deviceStorage.getController(device); Q_ASSERT(controller); responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, HSysInfo::instance().herqqProductTokens(), st, device->deviceStatus().bootId(), device->deviceStatus().configId() )); } return responses->size() > prevSize; } bool HDeviceHostSsdpHandler::processSearchRequest_serviceType( const HDiscoveryRequest& req, const HEndpoint& source, QList* responses) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); HDiscoveryType st = req.searchTarget(); QList foundServices = m_deviceStorage.searchServicesByServiceType( st.resourceType(), HResourceType::EqualOrGreater); if (!foundServices.size()) { HLOG_DBG(QString( "No services match the specified type: [%1]").arg( st.resourceType().toString())); return false; } qint32 prevSize = responses->size(); foreach(const HServerService* service, foundServices) { const HServerDevice* device = service->parentDevice(); Q_ASSERT(device); QUrl location; if (!m_deviceStorage.searchValidLocation(device, source, &location)) { HLOG_DBG(QString( "Found a matching device, but it is not " "available on the interface that has address: [%1]").arg( source.toString())); continue; } HDeviceInfo deviceInfo = device->info(); const HServerDevice* dc = m_deviceStorage.searchDeviceByUdn(deviceInfo.udn(), AllDevices); Q_ASSERT(dc); st.setUdn(deviceInfo.udn()); const HServerDeviceController* controller = m_deviceStorage.getController(device); Q_ASSERT(controller); responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, HSysInfo::instance().herqqProductTokens(), st, dc->deviceStatus().bootId(), dc->deviceStatus().configId() )); } return responses->size() > prevSize; } void HDeviceHostSsdpHandler::processSearchRequest( const HServerDevice* device, const QUrl& location, QList* responses) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); Q_ASSERT(device); HDeviceInfo deviceInfo = device->info(); HProductTokens pt = HSysInfo::instance().herqqProductTokens(); HDiscoveryType usn(deviceInfo.udn()); const HServerDeviceController* controller = m_deviceStorage.getController(device); Q_ASSERT(controller); const HDeviceStatus& deviceStatus = device->deviceStatus(); // device UDN responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, pt, usn, deviceStatus.bootId(), deviceStatus.configId())); usn.setResourceType(deviceInfo.deviceType()); // device type responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, pt, usn, deviceStatus.bootId(), deviceStatus.configId())); const HServerServices& services = device->services(); foreach(const HServerService* service, services) { usn.setResourceType(service->info().serviceType()); responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, pt, usn, deviceStatus.bootId(), deviceStatus.configId() )); } const HServerDevices& devices = device->embeddedDevices(); foreach(const HServerDevice* embeddedDevice, devices) { processSearchRequest(embeddedDevice, location, responses); } } bool HDeviceHostSsdpHandler::processSearchRequest_AllDevices( const HDiscoveryRequest& /*req*/, const HEndpoint& source, QList* responses) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); Q_ASSERT(responses); const HProductTokens& pt = HSysInfo::instance().herqqProductTokens(); const HServerDevices& rootDevices = m_deviceStorage.rootDevices(); qint32 prevSize = responses->size(); foreach(const HServerDevice* rootDevice, rootDevices) { QUrl location; if (!m_deviceStorage.searchValidLocation(rootDevice, source, &location)) { HLOG_DBG(QString( "Found a device, but it is not " "available on the interface that has address: [%1]").arg( source.toString())); continue; } HDiscoveryType usn(rootDevice->info().udn(), true); const HServerDeviceController* controller = m_deviceStorage.getController(rootDevice); Q_ASSERT(controller); responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, pt, usn, rootDevice->deviceStatus().bootId(), rootDevice->deviceStatus().configId() )); processSearchRequest(rootDevice, location, responses); const HServerDevices& devices = rootDevice->embeddedDevices(); foreach(const HServerDevice* embeddedDevice, devices) { if (!m_deviceStorage.searchValidLocation( embeddedDevice, source, &location)) { // highly uncommon, but possible; the root device is "active" // on the network interface to which the request came, // but at least one of its embedded devices is not. HLOG_DBG(QString( "Skipping an embedded device that is not " "available on the interface that has address: [%1]").arg( source.toString())); continue; } processSearchRequest(embeddedDevice, location, responses); } } return responses->size() > prevSize; } bool HDeviceHostSsdpHandler::processSearchRequest_RootDevice( const HDiscoveryRequest& /*req*/, const HEndpoint& source, QList* responses) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); Q_ASSERT(responses); const HServerDevices& rootDevices = m_deviceStorage.rootDevices(); qint32 prevSize = responses->size(); foreach(const HServerDevice* rootDevice, rootDevices) { QUrl location; if (!m_deviceStorage.searchValidLocation(rootDevice, source, &location)) { HLOG_DBG(QString( "Found a root device, but it is not " "available on the interface that has address: [%1]").arg( source.hostAddress().toString())); continue; } HDiscoveryType usn(rootDevice->info().udn(), true); const HServerDeviceController* controller = m_deviceStorage.getController(rootDevice); Q_ASSERT(controller); responses->push_back( HDiscoveryResponse( controller->deviceTimeoutInSecs() * 2, QDateTime::currentDateTime(), location, HSysInfo::instance().herqqProductTokens(), usn, rootDevice->deviceStatus().bootId(), rootDevice->deviceStatus().configId())); } return responses->size() > prevSize; } bool HDeviceHostSsdpHandler::incomingDiscoveryRequest( const HDiscoveryRequest& msg, const HEndpoint& source, DiscoveryRequestMethod requestType) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); HLOG_DBG(QString("Received discovery request for [%1] from [%2]").arg( msg.searchTarget().toString(), source.toString())); bool ok = false; QList responses; switch (msg.searchTarget().type()) { case HDiscoveryType::All: ok = processSearchRequest_AllDevices(msg, source, &responses); break; case HDiscoveryType::RootDevices: ok = processSearchRequest_RootDevice(msg, source, &responses); break; case HDiscoveryType::SpecificDevice: ok = processSearchRequest_specificDevice(msg, source, &responses); break; case HDiscoveryType::DeviceType: ok = processSearchRequest_deviceType(msg, source, &responses); break; case HDiscoveryType::ServiceType: ok = processSearchRequest_serviceType(msg, source, &responses); break; default: return true; } if (ok) { if (requestType == MulticastDiscovery) { HDelayedWriter* writer = new HDelayedWriter( *this, responses, source, (rand() % msg.mx()) * 1000); bool ok = connect(writer, SIGNAL(sent()), writer, SLOT(deleteLater())); Q_ASSERT(ok); Q_UNUSED(ok) writer->run(); } else { foreach (const HDiscoveryResponse& resp, responses) { qint32 count = sendDiscoveryResponse(resp, source); Q_ASSERT(count >= 0); Q_UNUSED(count) } } } else { HLOG_DBG(QString( "No resources found for discovery request [%1] from [%2]").arg( msg.searchTarget().toString(), source.toString())); } return true; } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_http_server_p.h0000644000000000000000000000571311543637310025672 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_HTTP_SERVER_H_ #define HDEVICEHOST_HTTP_SERVER_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hevent_notifier_p.h" #include "hserverdevicecontroller_p.h" #include "../hdevicestorage_p.h" #include "../../http/hhttp_server_p.h" #include namespace Herqq { namespace Upnp { // // // class HOpInfo { public: HServerService* m_service; HSubscribeRequest m_req; HServiceEventSubscriber* m_subscriber; HOpInfo() : m_service(0), m_req(), m_subscriber(0) { } HOpInfo(HServerService* service, const HSubscribeRequest& sreq, HServiceEventSubscriber* subscriber) : m_service(service), m_req(sreq), m_subscriber(subscriber) { } inline bool isValid() const { return m_service; } }; // // Internal class that provides minimal HTTP server functionality for the needs of // Device Host // class HDeviceHostHttpServer : public HHttpServer { Q_OBJECT H_DISABLE_COPY(HDeviceHostHttpServer) private: HDeviceStorage& m_deviceStorage; HEventNotifier& m_eventNotifier; QString m_ddPostFix; QList, HOpInfo> > m_ops; protected: virtual void incomingSubscriptionRequest( HMessagingInfo*, const HSubscribeRequest&); virtual void incomingUnsubscriptionRequest( HMessagingInfo*, const HUnsubscribeRequest&); virtual void incomingControlRequest( HMessagingInfo*, const HInvokeActionRequest&); virtual void incomingUnknownGetRequest( HMessagingInfo*, const HHttpRequestHeader&); virtual bool sendComplete(HHttpAsyncOperation*); public: HDeviceHostHttpServer( const QByteArray& loggingId, const QString& ddPostFix, HDeviceStorage&, HEventNotifier&, QObject* parent = 0); virtual ~HDeviceHostHttpServer(); }; } } #endif /* HDEVICEHOST_HTTP_SERVER_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hpresence_announcer_p.h0000644000000000000000000001707311543637310024766 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HPRESENCE_ANNOUNCER_H_ #define HPRESENCE_ANNOUNCER_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hserverdevicecontroller_p.h" #include "../../general/hupnp_global_p.h" #include "../../devicemodel/hdevicestatus.h" #include "../../devicemodel/server/hserverdevice.h" #include "../../devicemodel/server/hserverservice.h" #include "../../ssdp/hssdp.h" #include "../../ssdp/hdiscovery_messages.h" #include "../../dataelements/hudn.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hserviceinfo.h" #include "../../dataelements/hdiscoverytype.h" #include "../../dataelements/hproduct_tokens.h" #include namespace Herqq { namespace Upnp { // // // class Announcement { protected: HServerDevice* m_device; HDiscoveryType m_usn; QUrl m_location; int m_deviceTimeoutInSecs; public: Announcement() { } Announcement( HServerDevice* device, const HDiscoveryType& usn, const QUrl& location, int deviceTimeoutInSecs) : m_device(device), m_usn(usn), m_location(location), m_deviceTimeoutInSecs(deviceTimeoutInSecs) { Q_ASSERT(m_device); Q_ASSERT(m_usn.type() != HDiscoveryType::Undefined); Q_ASSERT(m_location.isValid() && !m_location.isEmpty()); } virtual ~Announcement() { } }; // // // class ResourceAvailableAnnouncement : private Announcement { public: ResourceAvailableAnnouncement() { } ResourceAvailableAnnouncement( HServerDevice* device, const HDiscoveryType& usn, const QUrl& location, int deviceTimeoutInSecs) : Announcement(device, usn, location, deviceTimeoutInSecs) { } HResourceAvailable operator()() const { const HProductTokens& pt = HSysInfo::instance().herqqProductTokens(); return HResourceAvailable( m_deviceTimeoutInSecs * 2, m_location, pt, m_usn, m_device->deviceStatus().bootId(), m_device->deviceStatus().configId() ); } }; // // // class ResourceUnavailableAnnouncement : private Announcement { public: ResourceUnavailableAnnouncement() { } ResourceUnavailableAnnouncement( HServerDevice* device, const HDiscoveryType& usn, const QUrl& location, int deviceTimeoutInSecs) : Announcement(device, usn, location, deviceTimeoutInSecs) { } HResourceUnavailable operator()() const { return HResourceUnavailable( m_usn, m_device->deviceStatus().bootId(), m_device->deviceStatus().configId() ); } }; class HDeviceHostSsdpHandler; // // Class that sends the SSDP announcements. // class PresenceAnnouncer { private: QList m_ssdps; quint32 m_advertisementCount; private: template void createAnnouncementMessagesForEmbeddedDevice( HServerDevice* device, int deviceTimeoutInSecs, QList* announcements) { QList locations = device->locations(); foreach(const QUrl& location, locations) { HDeviceInfo deviceInfo = device->info(); HUdn udn = deviceInfo.udn(); HDiscoveryType usn(udn); // device UDN advertisement announcements->push_back( AnnouncementType(device, usn, location, deviceTimeoutInSecs)); // device type advertisement usn.setResourceType(deviceInfo.deviceType()); announcements->push_back( AnnouncementType(device, usn, location, deviceTimeoutInSecs)); // service advertisements const HServerServices& services = device->services(); foreach(HServerService* service, services) { usn.setResourceType(service->info().serviceType()); announcements->push_back( AnnouncementType(device, usn, location, deviceTimeoutInSecs)); } } const HServerDevices& devices = device->embeddedDevices(); foreach(HServerDevice* embeddedDevice, devices) { createAnnouncementMessagesForEmbeddedDevice( embeddedDevice, deviceTimeoutInSecs, announcements); } } public: PresenceAnnouncer( const QList& ssdps, quint32 advertisementCount) : m_ssdps(ssdps), m_advertisementCount(advertisementCount) { Q_ASSERT(m_advertisementCount > 0); } ~PresenceAnnouncer() { } template void announce(const HServerDeviceController* rootDevice) { Q_ASSERT(rootDevice); QList announcements; createAnnouncementMessagesForRootDevice( rootDevice->m_device, rootDevice->deviceTimeoutInSecs(), &announcements); sendAnnouncements(announcements); } template void announce(const QList& rootDevices) { QList announcements; foreach(HServerDeviceController* rootDevice, rootDevices) { createAnnouncementMessagesForRootDevice( rootDevice->m_device, rootDevice->deviceTimeoutInSecs(), &announcements); } sendAnnouncements(announcements); } template void createAnnouncementMessagesForRootDevice( HServerDevice* rootDevice, int deviceTimeoutInSecs, QList* announcements) { QList locations = rootDevice->locations(); foreach(const QUrl& location, locations) { HUdn udn(rootDevice->info().udn()); HDiscoveryType usn(udn, true); announcements->push_back( AnnouncementType(rootDevice, usn, location, deviceTimeoutInSecs)); } // generic device advertisement (same for both root and embedded devices) createAnnouncementMessagesForEmbeddedDevice( rootDevice, deviceTimeoutInSecs, announcements); } template void sendAnnouncements(const QList& announcements) { for (quint32 i = 0; i < m_advertisementCount; ++i) { foreach(HSsdp* ssdp, m_ssdps) { foreach(const AnnouncementType& at, announcements) { ssdp->announcePresence(at()); } } } } }; } } #endif /* HPRESENCE_ANNOUNCER_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_dataretriever_p.h0000644000000000000000000000353611543637310026167 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_DATARETRIEVER_P_H_ #define HDEVICEHOST_DATARETRIEVER_P_H_ #include "../../general/hupnp_defs.h" #include #include namespace Herqq { namespace Upnp { // // // class DeviceHostDataRetriever { H_DISABLE_COPY(DeviceHostDataRetriever) private: const QByteArray m_loggingIdentifier; QUrl m_rootDir; QString m_lastError; bool retrieveData(const QUrl& baseUrl, const QUrl& query, QByteArray*); public: DeviceHostDataRetriever( const QByteArray& loggingId, const QUrl& rootDir); bool retrieveServiceDescription( const QUrl& deviceLocation, const QUrl& scpdUrl, QString*); bool retrieveIcon( const QUrl& deviceLocation, const QUrl& iconUrl, QByteArray*); bool retrieveDeviceDescription(const QString& path, QString*); inline QString lastError() const { return m_lastError; } }; } } #endif /* HDEVICEHOST_DATARETRIEVER_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hevent_subscriber_p.cpp0000644000000000000000000002064111543637310025004 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hevent_subscriber_p.h" #include "../../devicemodel/server/hserverservice.h" #include "../../dataelements/hserviceid.h" #include "../../dataelements/hserviceinfo.h" #include "../../http/hhttp_messagecreator_p.h" #include "../../general/hlogger_p.h" #include "../../utils/hsysutils_p.h" #include namespace Herqq { namespace Upnp { bool HServiceEventSubscriber::send(HMessagingInfo* mi) { HLOG2(H_AT, H_FUN, "__DEVICE HOST__: "); if (mi->socket().state() != QTcpSocket::ConnectedState) { HLOG_WARN(QString( "Client [sid: [%1]] is not connected. Failed to notify.").arg( m_sid.toString())); delete mi; return false; } QByteArray message = m_messagesToSend.head(); qint32 seq = m_seq++; HNotifyRequest req(m_location, m_sid, seq, message); QByteArray data = HHttpMessageCreator::create(req, mi); HLOG_DBG(QString( "Sending notification [seq: %1] to subscriber [%2] @ [%3]").arg( QString::number(seq), m_sid.toString(), m_location.toString())); HHttpAsyncOperation* oper = m_asyncHttp.msgIo(mi, data); if (!oper) { // notify failed // // according to UDA v1.1: // "the publisher SHOULD abandon sending this message to the // subscriber but MUST keep the subscription active and send future event // messages to the subscriber until the subscription expires or is canceled." HLOG_WARN(QString( "Could not send notify [seq: %1, sid: %2] to host @ [%3].").arg( QString::number(seq), m_sid.toString(), m_location.toString())); } return oper; } HServiceEventSubscriber::HServiceEventSubscriber( const QByteArray& loggingIdentifier, HServerService* service, const QUrl location, const HTimeout& timeout, QObject* parent) : QObject(parent), m_service(service), m_location(location), m_sid(QUuid::createUuid()), m_seq(0), m_timeout(timeout), m_timer(this), m_asyncHttp(loggingIdentifier, this), m_socket(new QTcpSocket(this)), m_messagesToSend(), m_expired(false), m_loggingIdentifier(loggingIdentifier) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(service); Q_ASSERT(location.isValid()); bool ok = connect( &m_timer, SIGNAL(timeout()), this, SLOT(subscriptionTimeout())); Q_ASSERT(ok); Q_UNUSED(ok) ok = connect( m_socket.data(), SIGNAL(connected()), this, SLOT(send())); Q_ASSERT(ok); ok = connect( &m_asyncHttp, SIGNAL(msgIoComplete(HHttpAsyncOperation*)), this, SLOT(msgIoComplete(HHttpAsyncOperation*))); Q_ASSERT(ok); if (!timeout.isInfinite()) { m_timer.start(timeout.value() * 1000); } } HServiceEventSubscriber::~HServiceEventSubscriber() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); HLOG_DBG(QString( "Subscription from [%1] with SID %2 cancelled").arg( m_location.toString(), m_sid.toString())); } bool HServiceEventSubscriber::connectToHost() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(QThread::currentThread() == m_socket->thread()); Q_ASSERT(m_socket.data()); QTcpSocket::SocketState state = m_socket->state(); if (state == QTcpSocket::ConnectedState) { return true; } else if (state == QTcpSocket::ConnectingState || state == QTcpSocket::HostLookupState) { return false; } m_socket->connectToHost(m_location.host(), m_location.port()); return false; } void HServiceEventSubscriber::msgIoComplete(HHttpAsyncOperation* operation) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); operation->deleteLater(); if (operation->state() == HHttpAsyncOperation::Failed) { HLOG_WARN(QString( "Notification [seq: %1, sid: %2] to host @ [%3] failed: %4.").arg( QString::number(m_seq-1), m_sid.toString(), m_location.toString(), operation->messagingInfo()->lastErrorDescription())); if (m_seq == 1) { m_seq--; send(); return; } } else { HLOG_DBG(QString( "Notification [seq: %1] successfully sent to subscriber [%2] @ [%3]").arg( QString::number(m_seq-1), m_sid.toString(), m_location.toString())); } if (!m_messagesToSend.isEmpty()) { m_messagesToSend.dequeue(); } if (!m_messagesToSend.isEmpty()) { send(); } } void HServiceEventSubscriber::send() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); if (m_messagesToSend.isEmpty() || !connectToHost() || !m_socket->isValid()) { return; } QByteArray message = m_messagesToSend.head(); qint32 seq = m_seq++; HMessagingInfo* mi = new HMessagingInfo(*m_socket, true, 10000); // timeout specified by UDA v 1.1 is 30 seconds, but that seems absurd // in this context. however, if this causes problems change it back. HNotifyRequest req(m_location, m_sid, seq, message); QByteArray data = HHttpMessageCreator::create(req, mi); HLOG_DBG(QString( "Sending notification [seq: %1] to subscriber [%2] @ [%3]").arg( QString::number(seq), m_sid.toString(), m_location.toString())); HHttpAsyncOperation* oper = m_asyncHttp.msgIo(mi, data); if (!oper) { // notify failed // // according to UDA v1.1: // "the publisher SHOULD abandon sending this message to the // subscriber but MUST keep the subscription active and send future event // messages to the subscriber until the subscription expires or is canceled." HLOG_WARN(QString( "Could not send notify [seq: %1, sid: %2] to host @ [%3].").arg( QString::number(seq), m_sid.toString(), m_location.toString())); } } void HServiceEventSubscriber::subscriptionTimeout() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); m_expired = true; if (m_timer.isActive()) { m_timer.stop(); } HLOG_DBG(QString( "Subscription from [%1] with SID %2 expired").arg( m_location.toString(), m_sid.toString())); } bool HServiceEventSubscriber::isInterested(const HServerService* service) const { HLOG2(H_AT, H_FUN, m_loggingIdentifier); return !expired() && m_seq && m_service->isEvented() && m_service->info().serviceId() == service->info().serviceId(); } void HServiceEventSubscriber::renew(const HTimeout& newTimeout) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); if (expired()) { return; } m_timeout = newTimeout; if (!m_timeout.isInfinite()) { m_timer.start(m_timeout.value() * 1000); } } void HServiceEventSubscriber::notify(const QByteArray& msgBody) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(QThread::currentThread() == thread()); m_messagesToSend.enqueue(msgBody); if (m_messagesToSend.size() <= 1) { // if there's more messages to send the sending process is active and // this message is enqueued to be sent once it's turn comes send(); } } bool HServiceEventSubscriber::initialNotify( const QByteArray& msg, HMessagingInfo* mi) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(!m_seq); m_messagesToSend.enqueue(msg); if (!mi) { send() ; } else { send(mi); } return true; } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hevent_notifier_p.cpp0000644000000000000000000002615611543637310024467 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hevent_notifier_p.h" #include "hevent_subscriber_p.h" #include "hdevicehost_configuration.h" #include "../messages/hevent_messages_p.h" #include "../../devicemodel/server/hserverdevice.h" #include "../../devicemodel/server/hserverservice.h" #include "../../devicemodel/server/hserverstatevariable.h" #include "../../dataelements/hudn.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hserviceinfo.h" #include "../../dataelements/hstatevariableinfo.h" #include "../../http/hhttp_messaginginfo_p.h" #include "../../general/hlogger_p.h" #include #include namespace Herqq { namespace Upnp { namespace { void getCurrentValues(QByteArray& msgBody, const HServerService* service) { HLOG(H_AT, H_FUN); QDomDocument dd; QDomProcessingInstruction proc = dd.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\""); dd.appendChild(proc); QDomElement propertySetElem = dd.createElementNS("urn:schemas-upnp-org:event-1-0", "e:propertyset"); dd.appendChild(propertySetElem); HServerStateVariables stateVars = service->stateVariables(); QHash::const_iterator ci = stateVars.constBegin(); for(; ci != stateVars.constEnd(); ++ci) { HServerStateVariable* stateVar = ci.value(); Q_ASSERT(stateVar); const HStateVariableInfo& info = stateVar->info(); if (info.eventingType() == HStateVariableInfo::NoEvents) { continue; } QDomElement propertyElem = dd.createElementNS("urn:schemas-upnp-org:event-1-0", "e:property"); QDomElement variableElem = dd.createElement(info.name()); variableElem.appendChild(dd.createTextNode(stateVar->value().toString())); propertyElem.appendChild(variableElem); propertySetElem.appendChild(propertyElem); } msgBody = dd.toByteArray(); } } /******************************************************************************* * HEventNotifier ******************************************************************************/ HEventNotifier::HEventNotifier( const QByteArray& loggingIdentifier, HDeviceHostConfiguration& configuration, QObject* parent) : QObject(parent), m_loggingIdentifier(loggingIdentifier), m_subscribers(), m_configuration(configuration) { } HEventNotifier::~HEventNotifier() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); qDeleteAll(m_subscribers); } HTimeout HEventNotifier::getSubscriptionTimeout(const HSubscribeRequest& sreq) { const static qint32 max = 60*60*24; qint32 configuredTimeout = m_configuration.subscriptionExpirationTimeout(); if (configuredTimeout > 0) { return HTimeout(configuredTimeout); } else if (configuredTimeout == 0) { HTimeout requested = sreq.timeout(); if (requested.isInfinite() || requested.value() > max) { return HTimeout(max); } return requested; } return HTimeout(max); } namespace { bool isSameService(HServerService* srv1, HServerService* srv2) { return srv1->parentDevice()->info().udn() == srv2->parentDevice()->info().udn() && srv1->info().scpdUrl() == srv2->info().scpdUrl(); } } HServiceEventSubscriber* HEventNotifier::remoteClient(const HSid& sid) const { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QList::const_iterator it = m_subscribers.constBegin(); for(; it != m_subscribers.end(); ++it) { if ((*it)->sid() == sid) { return *it; } } return 0; } StatusCode HEventNotifier::addSubscriber( HServerService* service, const HSubscribeRequest& sreq, HSid* sid) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(sid); Q_ASSERT(service->isEvented()); // The UDA v1.1 does not specify what to do when a subscription is received // to a service that is not evented. A "safe" route was taken here and // all subscriptions are accepted rather than returning some error. However, // in such a case the timeout is adjusted to a day and no events are ever sent. // This is enforced at the HServerService class, which should not send any // events unless one or more of its state variables are evented. for(qint32 i = 0; i < m_subscribers.size(); ++i) { HServiceEventSubscriber* rc = m_subscribers[i]; if (isSameService(rc->service(), service) && sreq.callbacks().contains(rc->location())) { HLOG_WARN(QString( "subscriber [%1] to the specified service URL [%2] already " "exists").arg( rc->location().toString(), service->info().scpdUrl().toString())); return PreconditionFailed; } } HLOG_INFO(QString("adding subscriber from [%1]").arg( sreq.callbacks().at(0).toString())); HTimeout timeout = service->isEvented() ? getSubscriptionTimeout(sreq) : HTimeout(60*60*24); HServiceEventSubscriber* rc = new HServiceEventSubscriber( m_loggingIdentifier, service, sreq.callbacks().at(0), timeout, this); m_subscribers.push_back(rc); *sid = rc->sid(); return Ok; } bool HEventNotifier::removeSubscriber(const HUnsubscribeRequest& req) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); bool found = false; QList::iterator it = m_subscribers.begin(); for(; it != m_subscribers.end(); ) { if ((*it)->sid() == req.sid()) { HLOG_INFO(QString("removing subscriber [SID [%1]] from [%2]").arg( req.sid().toString(), (*it)->location().toString())); delete *it; it = m_subscribers.erase(it); found = true; } else if ((*it)->expired()) { HLOG_INFO(QString( "removing an expired subscription [SID [%1]] from [%2]").arg( (*it)->sid().toString(), (*it)->location().toString())); delete *it; it = m_subscribers.erase(it); } else { ++it; } } if (!found) { HLOG_WARN(QString("Could not cancel subscription. Invalid SID [%1]").arg( req.sid().toString())); } return found; } StatusCode HEventNotifier::renewSubscription( const HSubscribeRequest& req, HSid* sid) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(sid); QList::iterator it = m_subscribers.begin(); for(; it != m_subscribers.end();) { HServiceEventSubscriber* sub = (*it); if (sub->sid() == req.sid()) { HLOG_INFO(QString("renewing subscription from [%1]").arg( (*it)->location().toString())); sub->renew(getSubscriptionTimeout(req)); *sid = sub->sid(); return Ok; } else if (sub->expired()) { HLOG_INFO(QString("removing subscriber [SID [%1]] from [%2]").arg( sub->sid().toString(), sub->location().toString())); delete *it; it = m_subscribers.erase(it); } else { ++it; } } HLOG_WARN(QString("Cannot renew subscription. Invalid SID: [%1]").arg( req.sid().toString())); return PreconditionFailed; } void HEventNotifier::stateChanged(const HServerService* source) { HLOG(H_AT, H_FUN); Q_ASSERT(source->isEvented()); QByteArray msgBody; getCurrentValues(msgBody, source); QList::iterator it = m_subscribers.begin(); for(; it != m_subscribers.end(); ) { HServiceEventSubscriber* sub = (*it); if (sub->isInterested(source)) { sub->notify(msgBody); ++it; } else if ((*it)->expired()) { HLOG_INFO(QString("removing subscriber [SID [%1]] from [%2]").arg( sub->sid().toString(), sub->location().toString())); delete *it; it = m_subscribers.erase(it); } else { ++it; } } // TODO add multicast event support } void HEventNotifier::initialNotify( HServiceEventSubscriber* rc, HMessagingInfo* mi) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QByteArray msgBody; getCurrentValues(msgBody, rc->service()); if (mi->keepAlive() && mi->socket().state() == QTcpSocket::ConnectedState) { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!slight deviation from the UDA v1.1 specification!! // // the timeout for acknowledging a initial notify request using the // same connection is set to two seconds, instead of the 30 as specified // in the standard. This is for two reasons: // 1) there exists UPnP software that do not implement and respect // HTTP keep-alive properly. // 2) initial notify using HTTP keep-alive is very fast (unless something // is wrong) and even a second should be more than enough. // with the above in mind, if the subscriber seems to use HTTP keep-alive, // the initial notify is sent using the connection in which the // subscription came. However, if that fails, the initial notify is // re-send using a new connection. mi->setReceiveTimeoutForNoData(2000); if (!rc->initialNotify(msgBody, mi)) { HLOG_WARN_NONSTD(QString( "Initial notify to SID [%1] failed. The device does not seem to " \ "respect HTTP keep-alive. Re-sending the initial notify using a new connection.").arg( rc->sid().toString())); } return; } // before sending the initial event message (specified in UDA), // the UDA mandates that FIN has been sent to the subscriber unless // the connection is to be kept alive. if (mi->socket().state() == QTcpSocket::ConnectedState) { mi->socket().disconnectFromHost(); if (mi->socket().state() != QAbstractSocket::UnconnectedState) { mi->socket().waitForDisconnected(50); } } delete mi; rc->initialNotify(msgBody); } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hevent_subscriber_p.h0000644000000000000000000000561311543637310024453 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HEVENT_SUBSCRIBER_P_H_ #define HEVENT_SUBSCRIBER_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../messages/hevent_messages_p.h" #include "../../http/hhttp_asynchandler_p.h" #include #include #include class QByteArray; class QTcpSocket; namespace Herqq { namespace Upnp { class HMessagingInfo; // // Internal class used to maintain information about a single event subscriber. // class HServiceEventSubscriber : public QObject { Q_OBJECT H_DISABLE_COPY(HServiceEventSubscriber) private: // attributes HServerService* m_service; QUrl m_location; HSid m_sid; quint32 m_seq; HTimeout m_timeout; QTimer m_timer; HHttpAsyncHandler m_asyncHttp; QScopedPointer m_socket; QQueue m_messagesToSend; bool m_expired; const QByteArray m_loggingIdentifier; bool connectToHost(); private Q_SLOTS: void send(); void msgIoComplete(HHttpAsyncOperation*); void subscriptionTimeout(); private: bool send(HMessagingInfo* mi); public: HServiceEventSubscriber( const QByteArray& loggingIdentifier, HServerService* service, const QUrl location, const HTimeout& timeout, QObject* parent = 0); virtual ~HServiceEventSubscriber(); void notify(const QByteArray& msgBody); bool initialNotify(const QByteArray& msgBody, HMessagingInfo* = 0); bool isInterested(const HServerService* service) const; inline QUrl location() const { return m_location; } inline HSid sid () const { return m_sid; } inline quint32 seq () const { return m_seq; } inline HTimeout timeout () const { return m_timeout; } inline HServerService* service () const { return m_service; } inline bool expired () const { return m_expired; } void renew(const HTimeout&); }; } } #endif /* HEVENT_SUBSCRIBER_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_http_server_p.cpp0000644000000000000000000003420711543637310026225 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicehost_http_server_p.h" #include "hevent_subscriber_p.h" #include "../messages/hcontrol_messages_p.h" #include "../../http/hhttp_messagecreator_p.h" #include "../../general/hupnp_global_p.h" #include "../../general/hupnp_datatypes_p.h" #include "../../devicemodel/hactionarguments.h" #include "../../devicemodel/server/hserveraction.h" #include "../../devicemodel/server/hserverdevice.h" #include "../../devicemodel/server/hserverservice.h" #include "../../dataelements/hudn.h" #include "../../dataelements/hactioninfo.h" #include "../../dataelements/hserviceinfo.h" #include "../../general/hlogger_p.h" #include #include namespace Herqq { namespace Upnp { namespace { QUuid extractUdn(const QUrl& arg) { QString path = extractRequestPart(arg); QUuid udn(path.section('/', 1, 1)); if (udn.isNull()) { return QUuid(); } return udn; } inline QString extractRequestExludingUdn(const QUrl& arg) { QString pathToSearch = extractRequestPart(arg).section( '/', 2, -1, QString::SectionIncludeLeadingSep); return pathToSearch; } } /******************************************************************************* * HDeviceHostHttpServer ******************************************************************************/ HDeviceHostHttpServer::HDeviceHostHttpServer( const QByteArray& loggingId, const QString& ddPostFix, HDeviceStorage& ds, HEventNotifier& en, QObject* parent) : HHttpServer(loggingId, parent), m_deviceStorage(ds), m_eventNotifier(en), m_ddPostFix(ddPostFix), m_ops() { } HDeviceHostHttpServer::~HDeviceHostHttpServer() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QList, HOpInfo> >::iterator it = m_ops.begin(); for(; it != m_ops.end(); ++it) { if (it->first) { it->first->deleteLater(); } } } void HDeviceHostHttpServer::incomingSubscriptionRequest( HMessagingInfo* mi, const HSubscribeRequest& sreq) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG("Subscription received."); QUuid udn = extractUdn(sreq.eventUrl()); HServerDevice* device = !udn.isNull() ? m_deviceStorage.searchDeviceByUdn(HUdn(udn), AllDevices) : 0; HServerService* service = 0; if (!device) { // the request did not have the UDN prefix, which means that either // 1) the request was for a EventUrl that was defined as an absolute URL // in the device description or // 2) the request is invalid service = m_deviceStorage.searchServiceByEventUrl(sreq.eventUrl()); if (!service) { HLOG_WARN(QString( "Ignoring invalid event subscription to: [%1].").arg( sreq.eventUrl().toString())); mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } } else if (!service) { service = m_deviceStorage.searchServiceByEventUrl( device, extractRequestExludingUdn(sreq.eventUrl())); } if (!service) { HLOG_WARN(QString("Subscription defined as [%1] is invalid.").arg( sreq.eventUrl().path())); mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } // The UDA v1.1 does not specify what to do when a subscription is received // to a service that is not evented. A "safe" route was taken here and // all subscriptions are accepted rather than returning some error. However, // in such a case the timeout is adjusted to a day and no events are ever sent. HSid sid; StatusCode sc; if (sreq.isRenewal()) { sc = m_eventNotifier.renewSubscription(sreq, &sid); } else { sc = m_eventNotifier.addSubscriber(service, sreq, &sid); } if (sc != Ok) { mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(sc, *mi)); return; } HServiceEventSubscriber* subscriber = m_eventNotifier.remoteClient(sid); HSubscribeResponse response( subscriber->sid(), HSysInfo::instance().herqqProductTokens(), subscriber->timeout()); HHttpAsyncOperation* op = m_httpHandler->send(mi, HHttpMessageCreator::create(response, *mi)); if (op) { HOpInfo opInfo(service, sreq, subscriber); m_ops.append(qMakePair(QPointer(op), opInfo)); } } void HDeviceHostHttpServer::incomingUnsubscriptionRequest( HMessagingInfo* mi, const HUnsubscribeRequest& usreq) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG("Unsubscription received."); bool ok = m_eventNotifier.removeSubscriber(usreq); mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(ok ? Ok : PreconditionFailed, *mi)); } void HDeviceHostHttpServer::incomingControlRequest( HMessagingInfo* mi, const HInvokeActionRequest& invokeActionRequest) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG(QString("Control message to [%1] received.").arg( invokeActionRequest.soapAction())); QUuid udn = extractUdn(invokeActionRequest.serviceUrl()); HServerDevice* device = !udn.isNull() ? m_deviceStorage.searchDeviceByUdn(HUdn(udn), AllDevices) : 0; HServerService* service = 0; if (!device) { // the request did not have the UDN prefix, which means that either // 1) the request was for a ControlURL that was defined as an absolute URL // in the device description or // 2) the request is invalid service = m_deviceStorage.searchServiceByControlUrl( invokeActionRequest.serviceUrl()); if (!service) { HLOG_WARN(QString( "Ignoring invalid action invocation to: [%1].").arg( invokeActionRequest.serviceUrl().toString())); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( BadRequest, *mi)); return; } } else if (!service) { service = m_deviceStorage.searchServiceByControlUrl( device, extractRequestExludingUdn(invokeActionRequest.serviceUrl())); } if (!service) { HLOG_WARN(QString("Ignoring invalid action invocation to: [%1].").arg( invokeActionRequest.serviceUrl().toString())); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( BadRequest, *mi)); return; } const QtSoapMessage* soapMsg = invokeActionRequest.soapMsg(); const QtSoapType& method = soapMsg->method(); if (!method.isValid()) { HLOG_WARN("Invalid control method."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( BadRequest, *mi)); return; } HServerAction* action = service->actions().value(method.name().name()); if (!action) { HLOG_WARN(QString("The service has no action named [%1].").arg( method.name().name())); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( *mi, UpnpInvalidArgs, soapMsg->toXmlString())); return; } HActionArguments iargs = action->info().inputArguments(); HActionArguments::iterator it = iargs.begin(); for(; it != iargs.end(); ++it) { HActionArgument iarg = *it; const QtSoapType& arg = method[iarg.name()]; if (!arg.isValid()) { mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( *mi, UpnpInvalidArgs, soapMsg->toXmlString())); return; } if (!iarg.setValue( HUpnpDataTypes::convertToRightVariantType( arg.value().toString(), iarg.dataType()))) { mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( *mi, UpnpInvalidArgs, soapMsg->toXmlString())); return; } } HActionArguments outArgs = action->info().outputArguments(); qint32 retVal = action->invoke(iargs, &outArgs); if (retVal != UpnpSuccess) { mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( *mi, retVal, soapMsg->toXmlString())); return; } QtSoapNamespaces::instance().registerNamespace( "u", service->info().serviceType().toString()); QtSoapMessage soapResponse; soapResponse.setMethod(QtSoapQName( QString("%1%2").arg(action->info().name(), "Response"), service->info().serviceType().toString())); foreach(const HActionArgument& oarg, outArgs) { QtSoapType* soapArg = new SoapType(oarg.name(), oarg.dataType(), oarg.value()); soapResponse.addMethodArgument(soapArg); } m_httpHandler->send(mi, HHttpMessageCreator::createResponse( Ok, *mi, soapResponse.toXmlString().toUtf8())); HLOG_DBG("Control message successfully handled."); } void HDeviceHostHttpServer::incomingUnknownGetRequest( HMessagingInfo* mi, const HHttpRequestHeader& requestHdr) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QString peer = peerAsStr(mi->socket()); QString requestPath = requestHdr.path(); HLOG_DBG(QString( "HTTP GET request received from [%1] to [%2].").arg(peer, requestPath)); QUuid searchedUdn(requestPath.section('/', 1, 1)); if (searchedUdn.isNull()) { // the request did not have the UDN prefix, which means that either // 1) the request was for a SCPD that was defined with an absolute URL // in the device description or // 2) the request is invalid HServerService* service = m_deviceStorage.searchServiceByScpdUrl(requestPath); if (service) { HLOG_DBG(QString( "Sending service description to [%1] as requested.").arg(peer)); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( Ok, *mi, service->description().toUtf8())); return; } HLOG_WARN(QString("Responding NOT_FOUND [%1] to [%2].").arg( requestHdr.path(), peerAsStr(mi->socket()))); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(NotFound, *mi)); return; } HServerDevice* device = m_deviceStorage.searchDeviceByUdn(HUdn(searchedUdn), AllDevices); if (!device) { HLOG_WARN(QString("Responding NOT_FOUND [%1] to [%2].").arg( requestHdr.path(), peerAsStr(mi->socket()))); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(NotFound, *mi)); return; } if (requestPath.endsWith(m_ddPostFix)) { HLOG_DBG(QString( "Sending device description to [%1] as requested.").arg(peer)); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( Ok, *mi, device->description().toUtf8())); return; } QString extractedRequestPart = extractRequestExludingUdn(requestPath); HServerService* service = m_deviceStorage.searchServiceByScpdUrl(device, extractedRequestPart); if (service) { HLOG_DBG(QString( "Sending service description to [%1] as requested.").arg(peer)); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( Ok, *mi, service->description().toUtf8())); return; } QUrl icon = m_deviceStorage.seekIcon(device, extractedRequestPart); if (!icon.isEmpty()) { QFile iconFile(icon.toLocalFile()); if (!iconFile.open(QIODevice::ReadOnly)) { HLOG_WARN(QString("Could not open icon file.").arg(icon.toLocalFile())); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(InternalServerError, *mi)); return; } HLOG_DBG(QString("Sending icon to [%1] as requested.").arg(peer)); m_httpHandler->send(mi, HHttpMessageCreator::createResponse( Ok, *mi, iconFile.readAll())); return; } HLOG_WARN(QString("Responding NOT_FOUND [%1] to [%2].").arg( requestHdr.path(), peerAsStr(mi->socket()))); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(NotFound, *mi)); } bool HDeviceHostHttpServer::sendComplete(HHttpAsyncOperation* op) { HOpInfo opInfo; QList, HOpInfo> >::iterator it = m_ops.begin(); for(; it != m_ops.end(); ++it) { if (it->first == op) { opInfo = it->second; break; } } if (opInfo.isValid()) { if (opInfo.m_service->isEvented() && !opInfo.m_req.isRenewal()) { // by now the UnicastRemoteClient for the subscriber is created if everything // went well and we can attempt to send the initial event message m_eventNotifier.initialNotify( opInfo.m_subscriber, op->takeMessagingInfo()); } m_ops.erase(it); return false; } return true; } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_configuration.h0000644000000000000000000003245111543637310025654 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_CONFIGURATION_H_ #define HDEVICEHOST_CONFIGURATION_H_ #include #include class QString; class QHostAddress; namespace Herqq { namespace Upnp { class HDeviceConfigurationPrivate; /*! * This is a class for specifying a configuration to an HServerDevice that is * to be created and hosted by an HDeviceHost. * * A valid device configuration contains at least a path to a * device description file. See setPathToDeviceDescription(). * * The other options available in this class affect the runtime behavior of a * HDeviceHost in regard to the HServerDevice instance that is created based * on the pathToDeviceDescription(). * * \headerfile hdevicehost_configuration.h HDeviceConfiguration * * \ingroup hupnp_devicehosting * * \sa HDeviceHostConfiguration, HDeviceHost, HDeviceHost::init(), HServerDevice */ class H_UPNP_CORE_EXPORT HDeviceConfiguration : public HClonable { H_DISABLE_COPY(HDeviceConfiguration) protected: HDeviceConfigurationPrivate* h_ptr; // // Documented in HClonable virtual void doClone(HClonable* target) const; // // Documented in HClonable virtual HDeviceConfiguration* newInstance() const; public: /*! * Default constructor. * * \brief Creates a new, empty instance. */ HDeviceConfiguration(); /*! * \brief Destroys the instance. */ virtual ~HDeviceConfiguration(); // // Documented in HClonable virtual HDeviceConfiguration* clone() const; /*! * \brief Sets the path to the UPnP device description. * * \param pathToDeviceDescription specifies the path to the UPnP * device description. * * \remarks The provided path or the device description document is not * validated in anyway. The device description validation occurs during the * initialization of the HDeviceHost. */ void setPathToDeviceDescription(const QString& pathToDeviceDescription); /*! * \brief Returns the path to the device description. * * \return The path to the device description. */ QString pathToDeviceDescription() const; /*! * \brief Sets the maximum age of presence announcements and discovery responses * in seconds. * * \param maxAge specifies the maximum age of presence announcements * and discovery messages. If a value smaller than 5 is specified, * the max age is set to 5. If positive value larger than a day is specified, * the max age is set to a day (60*60*24). The default is 1800 seconds, * which equals to 30 minutes. * * \attention the UDA instructs this value to be at least 30 minutes. */ void setCacheControlMaxAge(qint32 maxAge=1800); /*! * \brief Returns the maximum age of presence announcements and discovery * responses in seconds. * * If the cache control max age has not been explicitly set, * the return value is 1800. * * \return The maximum age of presence announcements and discovery * responses in seconds. */ qint32 cacheControlMaxAge() const; /*! * \brief Indicates whether or not the object contains the necessary details * for hosting an HServerDevice class in a HDeviceHost. * * \retval true in case the object contains the necessary details * for hosting an HServerDevice class in a HDeviceHost. * * \retval false otherwise. In this case, the initialization of HDeviceHost * cannot succeed. Make sure you have set the pathToDeviceDescription(). * * \sa pathToDeviceDescription() */ bool isValid() const; }; class HDeviceHostConfigurationPrivate; /*! * \brief This class is used to specify one or more device configurations to an * HDeviceHost instance and to configure the functionality of the HDeviceHost * that affect every hosted HServerDevice. * * The initialization of an HDeviceHost requires a valid host configuration. * A valid \e host \e configuration contains at least one \e device * \e configuration and a device model creator, as otherwise the host * would have nothing to do and no means to create UPnP device and service objects. * * The initialization of an HDeviceHost follows roughly these steps: * * - Create an HDeviceHostConfiguration instance. * - Set the device model creator using setDeviceModelCreator(). * - Create and setup one or more HDeviceConfiguration instances. * - Add the device configurations to the HDeviceHostConfiguration instance * using add(). * - Modify the behavior of the HDeviceHost by setting other variables * of this class. * - Create an HDeviceHost and initialize it by passing the * HDeviceHostConfiguration to its HDeviceHost::init() method. * * Besides specifying the device configurations, you can configure an HDeviceHost * in following ways: * - Specify how many times each resource advertisement is sent with * setIndividualAdvertisementCount(). The default is 2. * - Specify the timeout for event subscriptions with * setSubscriptionExpirationTimeout(). The default is 0, which means that * an HDeviceHost respects the subscription timeouts requested by control points * as long as the requested values are less than a day. * - Specify the network addresses an HDeviceHost should use in its operations * with setNetworkAddressesToUse(). * The default is the first found interface that is up. Non-loopback interfaces * have preference, but if none are found the loopback is used. However, in this * case UDP multicast is not available. * * \headerfile hdevicehost_configuration.h HDeviceHostConfiguration * * \ingroup hupnp_devicehosting * * \sa HDeviceConfiguration, HDeviceHost */ class H_UPNP_CORE_EXPORT HDeviceHostConfiguration : public HClonable { H_DISABLE_COPY(HDeviceHostConfiguration) protected: HDeviceHostConfigurationPrivate* h_ptr; // // Documented in HClonable virtual void doClone(HClonable* target) const; // // Documented in HClonable virtual HDeviceHostConfiguration* newInstance() const; public: /*! * Default constructor. * * \brief Creates a new, empty instance. * * \sa isEmpty(), isValid() */ HDeviceHostConfiguration(); /*! * \brief Creates a new instance. * * Creates an instance with a single device configuration. This is a convenience * method. * * \sa isEmpty(), isValid() */ HDeviceHostConfiguration(const HDeviceConfiguration&); /*! * \brief Destroys the instance. */ virtual ~HDeviceHostConfiguration(); // // Documented in HClonable virtual HDeviceHostConfiguration* clone() const; /*! * Adds a device configuration. * * \param deviceConfiguration specifies the device configuration to be added. * The configuration is added only if it is valid, * see HDeviceConfiguration::isValid(). * * \return \e true in case the configuration was added. Only valid * HDeviceConfiguration instances are added, * see HDeviceConfiguration::isValid(). */ bool add(const HDeviceConfiguration& deviceConfiguration); /*! * Removes device configurations. * * \remarks This method removes the device configurations, but it does not * reset other set attributes to their default values. */ void clear(); /*! * \brief Returns the currently stored device configurations. * * \return The currently stored device configurations. The returned list * contains pointers to const device configuration objects this instance * owns. The ownership of the objects is \b not transferred. */ QList deviceConfigurations() const; /*! * \brief Indicates how many times the device host sends each individual * advertisement / announcement. * * The default value is 2. * * \return how many times the device host sends each individual * advertisement / announcement. * * \sa setIndividualAdvertisementCount() */ qint32 individualAdvertisementCount() const; /*! * \brief Returns the network addresses a device host should use in its * operations. * * \return The network addresses a device host should use in its * operations. * * \sa setNetworkAddressesToUse() */ QList networkAddressesToUse() const; /*! * \brief Returns the timeout the device host uses for subscriptions. * * The default value is zero, which means that the device host honors the * timeouts requested by control points up to a day. Larger values are * set to a day. * * \return The timeout in seconds the device host uses for subscriptions. * * \sa setSubscriptionExpirationTimeout() */ qint32 subscriptionExpirationTimeout() const; /*! * \brief Returns the device model creator the HDeviceHost should use * to create HServerDevice instances. * * \return The device model creator the HDeviceHost should use * to create HServerDevice instances. * * \sa setDeviceModelCreator() */ HDeviceModelCreator* deviceModelCreator() const; /*! * \brief Returns the device model info provider the HDeviceHost should use to * validate device model components. * * \return The device model info provider the HDeviceHost should use to * validate device model components. */ HDeviceModelInfoProvider* deviceModelInfoProvider() const; /*! * \brief Sets the device model creator the HDeviceHost should use * to create HServerDevice instances. * * \param creator specifies the device model creator the HDeviceHost should use * to create HServerDevice instances. * * \sa deviceModelCreator() */ void setDeviceModelCreator(const HDeviceModelCreator& creator); /*! * \brief Sets the device model info provider the HDeviceHost should use to * validate device model components. * * \param infoProvider specifies the device model info provider the * HDeviceHost should use to validate device model components. */ void setDeviceModelInfoProvider(const HDeviceModelInfoProvider& infoProvider); /*! * \brief Specifies how many times the device host sends each individual * advertisement / announcement. * * By default, each advertisement is sent twice. * * \param count specifies how many times the device host sends each individual * advertisement / announcement. If the provided value is smaller than 1 the * advertisement count is set to 1. * * \sa individualAdvertisementCount() */ void setIndividualAdvertisementCount(qint32 count); /*! * \brief Specifies the timeout the device host uses for subscriptions. * * The default value is zero, which means that the device host honors the * timeouts requested by control points. * * \param timeout specifies the desired timeout in seconds. * - If timeout is greater than * zero the device host will use the timeout as such for subscriptions. * - If timeout is zero the device host will honor the timeout requested * by control points. * - If timeout is negative the subscription timeout is set to a day. * * \note the maximum expiration timeout value is a day. Larger values are * set to a day. This applies to the timeout requests made by control points * as well. * * \sa subscriptionExpirationTimeout() */ void setSubscriptionExpirationTimeout(qint32 timeout); /*! * Defines the network addresses the device host should use in its * operations. * * \param addresses specifies the network addresses the device host * should use in its operations. * * \sa networkAddressesToUse() */ bool setNetworkAddressesToUse(const QList& addresses); /*! * \brief Indicates if the instance contains any device configurations. * * \return \e true in case the instance contains no device configurations. * In this case the object cannot be used to initialize an HDeviceHost. * * \sa isValid() */ bool isEmpty() const; /*! * \brief Indicates if the object is valid, i.e it can be used to initialize * an HDeviceHost instance. * * \return \e true if the object is valid. A valid object is not empty and * its deviceModelCreator() is set. */ bool isValid() const; }; } } #endif /* HDEVICEHOST_CONFIGURATION_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_runtimestatus_p.h0000644000000000000000000000301411543637310026244 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_RUNTIMESTATUS_P_H_ #define HDEVICEHOST_RUNTIMESTATUS_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../../utils/hglobal.h" #include "../../general/hupnp_fwd.h" namespace Herqq { namespace Upnp { // // // class H_UPNP_CORE_EXPORT HDeviceHostRuntimeStatusPrivate { H_DISABLE_COPY(HDeviceHostRuntimeStatusPrivate) public: HDeviceHost* m_deviceHost; HDeviceHostRuntimeStatusPrivate(); }; } } #endif /* HDEVICEHOST_RUNTIMESTATUS_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_ssdp_handler_p.h0000644000000000000000000000662111543637310025772 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_SSDP_HANDLER_P_H_ #define HDEVICEHOST_SSDP_HANDLER_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../hdevicestorage_p.h" #include "../../ssdp/hssdp.h" #include "../../ssdp/hssdp_p.h" #include "../../ssdp/hdiscovery_messages.h" #include "../../socket/hendpoint.h" #include namespace Herqq { namespace Upnp { class HServerDevice; class HDeviceHostSsdpHandler; class HServerDeviceController; // // // class HDelayedWriter : public QObject { Q_OBJECT H_DISABLE_COPY(HDelayedWriter) private: HDeviceHostSsdpHandler& m_ssdp; QList m_responses; HEndpoint m_source; qint32 m_msecs; protected: void timerEvent(QTimerEvent*); public: HDelayedWriter( HDeviceHostSsdpHandler&, const QList&, const HEndpoint& source, qint32 msecs); void run(); Q_SIGNALS: void sent(); }; // // // class HDeviceHostSsdpHandler : public HSsdp { H_DISABLE_COPY(HDeviceHostSsdpHandler) private: HDeviceStorage& m_deviceStorage; private: void processSearchRequest( const HServerDevice*, const QUrl& deviceLocation, QList*); bool processSearchRequest_AllDevices( const HDiscoveryRequest&, const HEndpoint&, QList*); bool processSearchRequest_RootDevice( const HDiscoveryRequest&, const HEndpoint&, QList*); bool processSearchRequest_specificDevice( const HDiscoveryRequest&, const HEndpoint&, QList*); bool processSearchRequest_deviceType( const HDiscoveryRequest&, const HEndpoint&, QList*); bool processSearchRequest_serviceType( const HDiscoveryRequest&, const HEndpoint&, QList*); protected: virtual bool incomingDiscoveryRequest( const HDiscoveryRequest&, const HEndpoint&, DiscoveryRequestMethod); public: HDeviceHostSsdpHandler( const QByteArray& loggingIdentifier, HDeviceStorage&, QObject* parent = 0); virtual ~HDeviceHostSsdpHandler(); inline const QByteArray& loggingIdentifier() const { return h_ptr->m_loggingIdentifier; } }; } } #endif /* HDEVICEHOST_SSDP_HANDLER_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_configuration.cpp0000644000000000000000000001775011543637310026214 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicehost_configuration.h" #include "hdevicehost_configuration_p.h" #include "../../devicemodel/hdevicemodel_infoprovider.h" #include "../../devicemodel/server/hdevicemodelcreator.h" #include "../../general/hupnp_global_p.h" #include "../../utils/hmisc_utils_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HDeviceConfigurationPrivate ******************************************************************************/ HDeviceConfigurationPrivate::HDeviceConfigurationPrivate() : m_pathToDeviceDescriptor(), m_cacheControlMaxAgeInSecs(1800) { } HDeviceConfigurationPrivate::~HDeviceConfigurationPrivate() { } /******************************************************************************* * HDeviceConfiguration ******************************************************************************/ HDeviceConfiguration::HDeviceConfiguration() : h_ptr(new HDeviceConfigurationPrivate()) { } HDeviceConfiguration::~HDeviceConfiguration() { delete h_ptr; } HDeviceConfiguration* HDeviceConfiguration::newInstance() const { return new HDeviceConfiguration(); } void HDeviceConfiguration::doClone(HClonable* target) const { HDeviceConfiguration* conf = dynamic_cast(target); if (!conf) { return; } conf->h_ptr->m_cacheControlMaxAgeInSecs = h_ptr->m_cacheControlMaxAgeInSecs; conf->h_ptr->m_pathToDeviceDescriptor = h_ptr->m_pathToDeviceDescriptor; } HDeviceConfiguration* HDeviceConfiguration::clone() const { return static_cast(HClonable::clone()); } QString HDeviceConfiguration::pathToDeviceDescription() const { return h_ptr->m_pathToDeviceDescriptor; } void HDeviceConfiguration::setPathToDeviceDescription( const QString& pathToDeviceDescriptor) { h_ptr->m_pathToDeviceDescriptor = pathToDeviceDescriptor; } void HDeviceConfiguration::setCacheControlMaxAge(qint32 maxAgeInSecs) { static const qint32 max = 60*60*24; if (maxAgeInSecs < 5) { maxAgeInSecs = 5; } else if (maxAgeInSecs > max) { maxAgeInSecs = max; } h_ptr->m_cacheControlMaxAgeInSecs = maxAgeInSecs; } qint32 HDeviceConfiguration::cacheControlMaxAge() const { return h_ptr->m_cacheControlMaxAgeInSecs; } bool HDeviceConfiguration::isValid() const { return !h_ptr->m_pathToDeviceDescriptor.isEmpty(); } /******************************************************************************* * HDeviceHostConfigurationPrivate ******************************************************************************/ HDeviceHostConfigurationPrivate::HDeviceHostConfigurationPrivate() : m_collection(), m_individualAdvertisementCount(2), m_subscriptionExpirationTimeout(0), m_networkAddresses(), m_deviceCreator(0), m_infoProvider(0) { QHostAddress ha = findBindableHostAddress(); m_networkAddresses.append(ha); } /******************************************************************************* * HDeviceHostConfiguration ******************************************************************************/ HDeviceHostConfiguration::HDeviceHostConfiguration() : h_ptr(new HDeviceHostConfigurationPrivate()) { } HDeviceHostConfiguration::HDeviceHostConfiguration( const HDeviceConfiguration& arg) : h_ptr(new HDeviceHostConfigurationPrivate()) { add(arg); } HDeviceHostConfiguration::~HDeviceHostConfiguration() { qDeleteAll(h_ptr->m_collection); delete h_ptr; } HDeviceHostConfiguration* HDeviceHostConfiguration::newInstance() const { return new HDeviceHostConfiguration(); } void HDeviceHostConfiguration::doClone(HClonable* target) const { HDeviceHostConfiguration* conf = dynamic_cast(target); if (!conf) { return; } conf->h_ptr->m_individualAdvertisementCount = h_ptr->m_individualAdvertisementCount; conf->h_ptr->m_networkAddresses = h_ptr->m_networkAddresses; conf->h_ptr->m_subscriptionExpirationTimeout = h_ptr->m_subscriptionExpirationTimeout; QList confCollection; foreach(const HDeviceConfiguration* conf, h_ptr->m_collection) { confCollection.append(conf->clone()); } qDeleteAll(conf->h_ptr->m_collection); conf->h_ptr->m_collection = confCollection; conf->h_ptr->m_deviceCreator.reset( h_ptr->m_deviceCreator ? h_ptr->m_deviceCreator->clone() : 0); conf->h_ptr->m_infoProvider.reset( h_ptr->m_infoProvider ? h_ptr->m_infoProvider->clone() : 0); } HDeviceHostConfiguration* HDeviceHostConfiguration::clone() const { return static_cast(HClonable::clone()); } bool HDeviceHostConfiguration::add(const HDeviceConfiguration& arg) { if (arg.isValid()) { h_ptr->m_collection.push_back(arg.clone()); return true; } return false; } void HDeviceHostConfiguration::clear() { qDeleteAll(h_ptr->m_collection); h_ptr->m_collection.clear(); } QList HDeviceHostConfiguration::deviceConfigurations() const { return h_ptr->m_collection; } qint32 HDeviceHostConfiguration::individualAdvertisementCount() const { return h_ptr->m_individualAdvertisementCount; } QList HDeviceHostConfiguration::networkAddressesToUse() const { return h_ptr->m_networkAddresses; } HDeviceModelCreator* HDeviceHostConfiguration::deviceModelCreator() const { return h_ptr->m_deviceCreator.data(); } HDeviceModelInfoProvider* HDeviceHostConfiguration::deviceModelInfoProvider() const { return h_ptr->m_infoProvider.data(); } void HDeviceHostConfiguration::setDeviceModelCreator( const HDeviceModelCreator& deviceCreator) { h_ptr->m_deviceCreator.reset(deviceCreator.clone()); } void HDeviceHostConfiguration::setDeviceModelInfoProvider( const HDeviceModelInfoProvider& infoProvider) { h_ptr->m_infoProvider.reset(infoProvider.clone()); } void HDeviceHostConfiguration::setIndividualAdvertisementCount(qint32 arg) { if (arg < 1) { arg = 1; } h_ptr->m_individualAdvertisementCount = arg; } qint32 HDeviceHostConfiguration::subscriptionExpirationTimeout() const { return h_ptr->m_subscriptionExpirationTimeout; } void HDeviceHostConfiguration::setSubscriptionExpirationTimeout(qint32 arg) { static const qint32 max = 60*60*24; if (arg > max) { arg = max; } h_ptr->m_subscriptionExpirationTimeout = arg; } bool HDeviceHostConfiguration::setNetworkAddressesToUse( const QList& addresses) { if (!HSysInfo::instance().areLocalAddresses(addresses)) { return false; } h_ptr->m_networkAddresses = addresses; return true; } bool HDeviceHostConfiguration::isEmpty() const { return h_ptr->m_collection.isEmpty(); } bool HDeviceHostConfiguration::isValid() const { return !isEmpty() && deviceModelCreator(); } } } herqq-1.0.0/hupnp/src/devicehosting/devicehost/hdevicehost_p.h0000644000000000000000000000673211543637310023247 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEHOST_P_H_ #define HDEVICEHOST_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hdevicehost.h" #include "../hdevicestorage_p.h" #include #include class QTimer; class QNetworkAccessManager; namespace Herqq { namespace Upnp { class HDeviceHost; class HServerDevice; class HDeviceStatus; class HEventNotifier; class PresenceAnnouncer; class HDeviceHostHttpServer; class HDeviceHostSsdpHandler; class HServerDeviceController; class HDeviceHostConfiguration; // // Implementation details of HDeviceHost class // class HDeviceHostPrivate : public QObject { Q_OBJECT H_DECLARE_PUBLIC(HDeviceHost) H_DISABLE_COPY(HDeviceHostPrivate) private: void connectSelfToServiceSignals(HServerDevice* device); public: // attributes const QByteArray m_loggingIdentifier; // The prefix shown before the actual log output QScopedPointer m_config; // The configuration of this instance QList m_ssdps; // An SSDP listener /sender for each configured network interface QScopedPointer m_httpServer; // A HTTP server for each configured network interface QScopedPointer m_eventNotifier; // Handles the UPnP eventing QScopedPointer m_presenceAnnouncer; // Creates and sends the SSDP "presence announcement" messages QScopedPointer m_runtimeStatus; // HDeviceHost* q_ptr; HDeviceHost::DeviceHostError m_lastError; QString m_lastErrorDescription; // description of the error that occurred last bool m_initialized; HDeviceStorage m_deviceStorage; // This contains the root devices and it provides lookup methods to the // contents of the device tree QNetworkAccessManager* m_nam; public Q_SLOTS: void announcementTimedout(HServerDeviceController*); // called when it is about for the device to be re-advertised public: // methods HDeviceHostPrivate(); virtual ~HDeviceHostPrivate(); void stopNotifiers(); void startNotifiers(HServerDeviceController*); void startNotifiers(); bool createRootDevice(const HDeviceConfiguration*); bool createRootDevices(); inline static const QString& deviceDescriptionPostFix() { static QString retVal = "device_description.xml"; return retVal; } }; } } #endif /* HDEVICEHOST_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/hmodelcreation_p.h0000644000000000000000000000417411543637310021600 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HMODELCREATOR_P_H_ #define HMODELCREATOR_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_global.h" #include "../utils/hfunctor.h" #include #include #include #include namespace Herqq { namespace Upnp { // // // typedef Functor ServiceDescriptionFetcher; // // // typedef Functor IconFetcher; // // A class that contains information for the creation of HUPnP's device model // This information is set by the HDeviceHost and HControlPoint according // to their needs // class HModelCreationArgs { public: HModelCreationArgs(); virtual ~HModelCreationArgs() = 0; QString m_deviceDescription; QList m_deviceLocations; ServiceDescriptionFetcher m_serviceDescriptionFetcher; // provides the possibility of defining how the service description is // retrieved qint32 m_deviceTimeoutInSecs; IconFetcher m_iconFetcher; QByteArray m_loggingIdentifier; }; } } #endif /* HMODELCREATOR_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/messages/0000755000000000000000000000000011543637460017722 5ustar rootrootherqq-1.0.0/hupnp/src/devicehosting/messages/hevent_messages_p.h0000644000000000000000000001514111543637310023566 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HEVENT_MESSAGES_P_H_ #define HEVENT_MESSAGES_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hnt_p.h" #include "hsid_p.h" #include "htimeout_p.h" #include #include #include #include #include #include class QString; namespace Herqq { namespace Upnp { // // Class that represents the UPnP eventing subscription request. // class HSubscribeRequest { private: QList m_callbacks; HTimeout m_timeout; HSid m_sid; QUrl m_eventUrl; HProductTokens m_userAgent; public: enum RetVal { Success = 0, PreConditionFailed = -1, IncompatibleHeaders = -2, BadRequest = -3 }; public: // creates an empty, invalid object. HSubscribeRequest(); // creates a renew subscription object (HSid present) HSubscribeRequest( const QUrl& eventUrl, const HSid& sid, const HTimeout& timeout); // creates a normal subscription request with a single callback HSubscribeRequest( const QUrl& eventUrl, const HProductTokens& userAgent, const QUrl& callback, const HTimeout& timeout); // creates a normal subscription request with multiple callbacks HSubscribeRequest( const QUrl& eventUrl, const HProductTokens& userAgent, const QList& callbacks, const HTimeout& timeout); // RetVal setContents( const QString& nt, const QUrl& eventUrl, const QString& sid, const QString& callback, const QString& timeout, const QString& userAgent); ~HSubscribeRequest(); inline HNt nt() const { return HNt(HNt::Type_UpnpEvent); } inline QList callbacks() const { return m_callbacks; } inline bool isValid(bool strict) const { return !m_callbacks.isEmpty() || (strict ? m_sid.isValid() : !m_sid.isEmpty()); } inline HTimeout timeout() const { return m_timeout; } inline HSid sid() const { return m_sid; } inline QUrl eventUrl() const { return m_eventUrl; } inline bool isRenewal() const { return !m_sid.isEmpty(); } inline HProductTokens userAgent() const { return m_userAgent; } inline bool hasUserAgent() const { return m_userAgent.isValid(); } }; // // // class HSubscribeResponse { private: HSid m_sid; HTimeout m_timeout; HProductTokens m_server; QDateTime m_responseGenerated; public: HSubscribeResponse(); HSubscribeResponse( const HSid& sid, const HProductTokens& server, const HTimeout& timeout, const QDateTime& responseGenerated = QDateTime::currentDateTime()); ~HSubscribeResponse(); inline bool isValid(bool strict) const { return strict ? m_sid.isValid() : !m_sid.isEmpty(); } inline HTimeout timeout() const { return m_timeout; } inline HSid sid() const { return m_sid; } inline HProductTokens server() const { return m_server; } inline QDateTime responseGenerated() const { return m_responseGenerated; } }; // // // class HUnsubscribeRequest { private: QUrl m_eventUrl; HSid m_sid; public: enum RetVal { Success = 0, PreConditionFailed = -1, BadRequest = -2, IncompatibleHeaders = -3 }; public: HUnsubscribeRequest(); HUnsubscribeRequest(const QUrl& eventUrl, const HSid& sid); ~HUnsubscribeRequest(); RetVal setContents(const QUrl& eventUrl, const QString& sid); inline bool isValid(bool strict)const { return strict ? m_sid.isValid() : !m_sid.isEmpty(); } inline HSid sid() const { return m_sid; } inline QUrl eventUrl() const { return m_eventUrl; } }; // // // class HNotifyRequest { public: enum RetVal { Success = 0, PreConditionFailed = -1, InvalidContents = -2, InvalidSequenceNr = -3, BadRequest = -4 }; typedef QList > Variables; private: QUrl m_callback; HSid m_sid; quint32 m_seq; Variables m_dataAsVariables; QByteArray m_data; public: HNotifyRequest(); HNotifyRequest( const QUrl& callback, const HSid& sid, quint32 seq, const QByteArray& contents); ~HNotifyRequest(); RetVal setContents( const QUrl& callback, const QString& nt, const QString& nts, const QString& sid, const QString& seq, const QString& contents); inline bool isValid(bool strict) const { return strict ? m_sid.isValid() : !m_sid.isEmpty(); // if this is defined then everything else is defined as well } inline QUrl callback() const { return m_callback; } inline HNt nt() const { return HNt(HNt::Type_UpnpEvent, HNt::SubType_UpnpPropChange); } inline HSid sid () const { return m_sid ; } inline quint32 seq () const { return m_seq ; } inline QByteArray data () const { return m_data ; } inline Variables variables() const { return m_dataAsVariables; } }; } } #endif /* HEVENT_MESSAGES_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/messages/hnt_p.h0000644000000000000000000000420311543637310021174 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HNT_H_ #define HNT_H_ #include #include namespace Herqq { namespace Upnp { // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // // // // class HNt { public: enum Type { Type_Undefined = 0, Type_UpnpEvent = 1 }; enum SubType { SubType_Undefined = 0, SubType_UpnpPropChange = 1 }; private: QPair m_typeValue; QPair m_subTypeValue; public: HNt (); explicit HNt(const QString& type); explicit HNt(const QString& type, const QString& subTybe); explicit HNt(Type type); HNt(Type type, SubType subType); ~HNt(); HNt& operator=(const QString& nt); QString typeToString() const; inline Type type() const { return m_typeValue.first; } QString subTypeToString() const; inline SubType subType() const { return m_subTypeValue.first; } static QString toString(Type type); static QString toString(SubType subType); }; } } #endif /* HNT_H_ */ herqq-1.0.0/hupnp/src/devicehosting/messages/hsid_p.cpp0000644000000000000000000000507111543637310021671 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hsid_p.h" #include "../../utils/hmisc_utils_p.h" namespace Herqq { namespace Upnp { HSid::HSid() : m_value(), m_valueAsStr() { } HSid::HSid(const QUuid& sid) : m_value(sid), m_valueAsStr( QString("uuid:%1").arg(sid.toString().remove('{').remove('}'))) { } HSid::HSid(const HSid& other) : m_value(), m_valueAsStr() { Q_ASSERT(&other != this); m_value = other.m_value; m_valueAsStr = other.m_valueAsStr; } HSid::HSid(const QString& sid) : m_value(), m_valueAsStr() { QString tmp(sid.simplified()); if (tmp.isEmpty()) { // in essence, only "empty" strings are not acceptable. If UUIDs are not // enforced, there can be no "minimum" requirement for an "invalid" UUID. return; } else if (tmp.startsWith("uuid:", Qt::CaseInsensitive)) { m_value = tmp.trimmed().mid(5); m_valueAsStr = tmp; } else { m_value = QUuid(tmp); m_valueAsStr = QString("uuid:%1").arg(tmp); } } HSid::~HSid() { } HSid& HSid::operator=(const HSid& other) { Q_ASSERT(&other != this); m_value = other.m_value; m_valueAsStr = other.m_valueAsStr; return *this; } HSid& HSid::operator=(const QString& other) { HSid copy(other); *this = copy; return *this; } HSid& HSid::operator=(const QUuid& other) { HSid copy(other); *this = copy; return *this; } bool operator==(const HSid& sid1, const HSid& sid2) { return sid1.m_valueAsStr == sid2.m_valueAsStr; } quint32 qHash(const HSid& key) { QByteArray data = key.toString().toLocal8Bit(); return hash(data.constData(), data.size()); } } } herqq-1.0.0/hupnp/src/devicehosting/messages/htimeout_p.h0000644000000000000000000000361011543637310022242 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HTIMEOUT_H_ #define HTIMEOUT_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include class QString; namespace Herqq { namespace Upnp { // // // class HTimeout { friend bool operator==(const HTimeout&, const HTimeout&); private: qint32 m_value; public: HTimeout(); explicit HTimeout(qint32); explicit HTimeout(const QString&); ~HTimeout(); HTimeout& operator=(qint32); HTimeout& operator=(const QString&); inline qint32 value() const { return m_value; } QString toString() const; inline bool isInfinite() const { return m_value == -1; } }; bool operator==(const HTimeout&, const HTimeout&); inline bool operator!=(const HTimeout& obj1, const HTimeout& obj2) { return !(obj1 == obj2); } } } #endif /* HTIMEOUT_H_ */ herqq-1.0.0/hupnp/src/devicehosting/messages/hnt_p.cpp0000644000000000000000000000562311543637310021536 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hnt_p.h" namespace Herqq { namespace Upnp { HNt::HNt() : m_typeValue(qMakePair(Type_Undefined , QString(""))), m_subTypeValue(qMakePair(SubType_Undefined, QString(""))) { } HNt::HNt(const QString& type) : m_typeValue(qMakePair(Type_Undefined, QString(""))), m_subTypeValue(qMakePair(SubType_Undefined, QString(""))) { if (type.compare("upnp:event", Qt::CaseInsensitive) == 0) { m_typeValue.first = Type_UpnpEvent; m_typeValue.second = "upnp:event"; } } HNt::HNt(const QString& type, const QString& subtype) : m_typeValue(qMakePair(Type_Undefined, QString(""))), m_subTypeValue(qMakePair(SubType_Undefined, QString(""))) { if (type.compare("upnp:event", Qt::CaseInsensitive) == 0) { m_typeValue.first = Type_UpnpEvent; m_typeValue.second = "upnp:event"; } if (subtype.compare("upnp:propchange", Qt::CaseInsensitive) == 0) { m_subTypeValue.first = SubType_UpnpPropChange; m_subTypeValue.second = "upnp:propchange"; } } HNt::HNt(Type type) : m_typeValue(qMakePair(type, toString(type))), m_subTypeValue(qMakePair(SubType_Undefined, QString(""))) { } HNt::HNt(Type type, SubType subType) : m_typeValue(qMakePair(type, toString(type))), m_subTypeValue(qMakePair(subType, toString(subType))) { } HNt::~HNt() { } HNt& HNt::operator=(const QString& nt) { HNt copy(nt); *this = copy; return *this; } QString HNt::typeToString() const { return m_typeValue.second; } QString HNt::subTypeToString() const { return m_subTypeValue.second; } QString HNt::toString(Type type) { switch(type) { case Type_Undefined: return ""; case Type_UpnpEvent: return "upnp:event"; } return ""; } QString HNt::toString(SubType subType) { switch(subType) { case SubType_Undefined: return ""; case SubType_UpnpPropChange: return "upnp:propchange"; } return ""; } } } herqq-1.0.0/hupnp/src/devicehosting/messages/hsid_p.h0000644000000000000000000000467011543637310021342 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSID_H_ #define HSID_H_ #include #include // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // namespace Herqq { namespace Upnp { // // Implementation note: this class cannot enforce the requirement of a valid UUID, // since there are UPnP software that do not generate and use valid UUIDs. // Because of this, the class "accepts" any string. However, validity can be checked // with the isValid(). **Do NOT change the semantics of this class** class HSid { friend quint32 qHash(const HSid& key); friend bool operator==(const HSid&, const HSid&); private: QUuid m_value; QString m_valueAsStr; public: HSid(); explicit HSid(const QUuid&); explicit HSid(const QString&); HSid(const HSid&); ~HSid(); HSid& operator=(const HSid&); HSid& operator=(const QUuid&); HSid& operator=(const QString&); inline QUuid value() const { return m_value; } inline QString toString() const { return m_valueAsStr; } inline bool isValid()const { return !m_value.isNull(); } inline bool isEmpty() const { return m_valueAsStr.isEmpty(); } }; bool operator==(const HSid&, const HSid&); inline bool operator!=(const HSid& obj1, const HSid& obj2) { return !(obj1 == obj2); } quint32 qHash(const HSid& key); } } #endif /* HSID_H_ */ herqq-1.0.0/hupnp/src/devicehosting/messages/hcontrol_messages_p.cpp0000644000000000000000000000241611543637310024461 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hcontrol_messages_p.h" namespace Herqq { namespace Upnp { HInvokeActionRequest::HInvokeActionRequest() : m_soapAction(), m_soapMsg(), m_serviceUrl() { } HInvokeActionRequest::HInvokeActionRequest( const QString& soapAction, const QtSoapMessage& soapMsg, const QUrl& serviceUrl) : m_soapAction(soapAction), m_soapMsg(soapMsg), m_serviceUrl(serviceUrl) { } HInvokeActionRequest::~HInvokeActionRequest() { } } } herqq-1.0.0/hupnp/src/devicehosting/messages/hevent_messages_p.cpp0000644000000000000000000002407211543637310024124 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hevent_messages_p.h" #include "../../general/hlogger_p.h" #include #include #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HSubscribeRequest *******************************************************************************/ namespace { inline bool isValidCallback(const QUrl& callback) { return callback.isValid() && !callback.isEmpty() && callback.scheme() == "http" && !(QHostAddress(callback.host()).isNull()); } inline bool isValidEventUrl(const QUrl& eventUrl) { return eventUrl.isValid() && !eventUrl.isEmpty() && !(QHostAddress(eventUrl.host()).isNull()); } } HSubscribeRequest::HSubscribeRequest() : m_callbacks(), m_timeout(), m_sid(), m_eventUrl(), m_userAgent() { } HSubscribeRequest::HSubscribeRequest( const QUrl& eventUrl, const HSid& sid, const HTimeout& timeout) : m_callbacks(), m_timeout(), m_sid(), m_eventUrl(), m_userAgent() { HLOG(H_AT, H_FUN); if (!isValidEventUrl(eventUrl)) { HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString())); return; } else if (sid.isEmpty()) { HLOG_WARN("Empty SID"); return; } m_timeout = timeout; m_eventUrl = eventUrl; m_sid = sid; } HSubscribeRequest::HSubscribeRequest( const QUrl& eventUrl, const HProductTokens& userAgent, const QUrl& callback, const HTimeout& timeout) : m_callbacks (), m_timeout(), m_sid(), m_eventUrl(), m_userAgent() { HLOG(H_AT, H_FUN); if (!isValidEventUrl(eventUrl)) { HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString())); return; } else if (!isValidCallback(callback)) { HLOG_WARN(QString("Invalid callback: [%1]").arg(callback.toString())); return; } m_callbacks.push_back(callback); m_timeout = timeout; m_eventUrl = eventUrl; m_userAgent = userAgent; } HSubscribeRequest::HSubscribeRequest( const QUrl& eventUrl, const HProductTokens& userAgent, const QList& callbacks, const HTimeout& timeout) : m_callbacks(), m_timeout(), m_sid(), m_eventUrl(), m_userAgent() { HLOG(H_AT, H_FUN); if (!isValidEventUrl(eventUrl)) { HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString())); return; } foreach(const QUrl& callback, callbacks) { if (!isValidCallback(callback)) { HLOG_WARN(QString("Invalid callback: [%1]").arg(callback.toString())); return; } } m_timeout = timeout; m_eventUrl = eventUrl; m_userAgent = userAgent; m_callbacks = callbacks; } HSubscribeRequest::~HSubscribeRequest() { } namespace { QList parseCallbacks(const QString& arg) { QList retVal; QStringList callbacks = arg.split(QRegExp("<[.]*>"), QString::SkipEmptyParts); foreach(QString callbackStr, callbacks) { QUrl callback(callbackStr.remove('<').remove('>')); if (!callback.isValid() || callback.isEmpty() || callback.scheme() != "http") { return QList(); } retVal.push_back(callback); } return retVal; } } HSubscribeRequest::RetVal HSubscribeRequest::setContents( const QString& nt, const QUrl& eventUrl, const QString& sid, const QString& callback, const QString& timeout, const QString& userAgent) { HLOG(H_AT, H_FUN); // this has to be properly defined no matter what if (!isValidEventUrl(eventUrl)) { HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString())); return BadRequest; } HSubscribeRequest tmp; // these fields are the same regardless of message type tmp.m_eventUrl = eventUrl; tmp.m_timeout = timeout; if (!HSid(sid).isEmpty()) { // this appears to be a renewal, confirm. if (!callback.isEmpty() || !nt.isEmpty()) { return IncompatibleHeaders; } tmp.m_sid = sid; *this = tmp; return Success; } // this appears to be an initial subscription if (nt.simplified().compare("upnp:event", Qt::CaseInsensitive) != 0) { return PreConditionFailed; } tmp.m_callbacks = parseCallbacks(callback); if (tmp.m_callbacks.isEmpty()) { return PreConditionFailed; } tmp.m_userAgent = HProductTokens(userAgent); *this = tmp; return Success; } /******************************************************************************* * HSubscribeResponse *******************************************************************************/ HSubscribeResponse::HSubscribeResponse() : m_sid(), m_timeout(), m_server(), m_responseGenerated() { } HSubscribeResponse::HSubscribeResponse( const HSid& sid, const HProductTokens& server, const HTimeout& timeout, const QDateTime& responseGenerated) : m_sid(sid), m_timeout(timeout), m_server(server), m_responseGenerated(responseGenerated) { if (m_sid.isEmpty()) { *this = HSubscribeResponse(); } } HSubscribeResponse::~HSubscribeResponse() { } /******************************************************************************* * HUnsubscribeRequest *******************************************************************************/ HUnsubscribeRequest::HUnsubscribeRequest() : m_eventUrl(), m_sid() { } HUnsubscribeRequest::HUnsubscribeRequest(const QUrl& eventUrl, const HSid& sid) : m_eventUrl(), m_sid() { if (sid.isEmpty() || !isValidEventUrl(eventUrl)) { return; } m_eventUrl = eventUrl; m_sid = sid; } HUnsubscribeRequest::~HUnsubscribeRequest() { } HUnsubscribeRequest::RetVal HUnsubscribeRequest::setContents( const QUrl& eventUrl, const QString& sid) { HUnsubscribeRequest tmp; tmp.m_sid = sid; tmp.m_eventUrl = eventUrl; if (tmp.m_sid.isEmpty()) { return PreConditionFailed; } else if (!isValidEventUrl(tmp.m_eventUrl)) { return BadRequest; } *this = tmp; return Success; } /******************************************************************************* * HNotifyRequest *******************************************************************************/ namespace { HNotifyRequest::RetVal parseData( const QByteArray& data, QList >& parsedData) { HLOG(H_AT, H_FUN); QDomDocument dd; if (!dd.setContent(data, true)) { return HNotifyRequest::InvalidContents; } //QDomNodeList propertySetNodes = // dd.elementsByTagNameNS("urn:schemas-upnp.org:event-1-0", "propertyset"); QDomElement propertySetElement = dd.firstChildElement("propertyset"); if (propertySetElement.isNull()) { return HNotifyRequest::InvalidContents; } QDomElement propertyElement = propertySetElement.firstChildElement("property"); //propertySetNodes.at(0).toElement().elementsByTagNameNS( // "urn:schemas-upnp.org:event-1-0", "property"); QList > tmp; while(!propertyElement.isNull()) { QDomElement variableElement = propertyElement.firstChildElement(); if (variableElement.isNull()) { return HNotifyRequest::InvalidContents; } QDomText variableValue = variableElement.firstChild().toText(); tmp.push_back( qMakePair(variableElement.localName(), variableValue.data())); propertyElement = propertyElement.nextSiblingElement("property"); } parsedData = tmp; return HNotifyRequest::Success; } } HNotifyRequest::HNotifyRequest() : m_callback(), m_sid(), m_seq(0), m_dataAsVariables(), m_data() { } HNotifyRequest::HNotifyRequest( const QUrl& callback, const HSid& sid, quint32 seq, const QByteArray& contents) : m_callback(), m_sid(), m_seq(0), m_dataAsVariables(), m_data () { HLOG(H_AT, H_FUN); if (!isValidCallback(callback) || sid.isEmpty() || contents.isEmpty()) { return; } if (parseData(contents, m_dataAsVariables) != Success) { return; } m_callback = callback; m_sid = sid; m_seq = seq; m_data = contents; } HNotifyRequest::~HNotifyRequest() { } HNotifyRequest::RetVal HNotifyRequest::setContents( const QUrl& callback, const QString& nt, const QString& nts, const QString& sid, const QString& seq, const QString& contents) { HLOG(H_AT, H_FUN); HNt tmpNt(nt, nts); if (tmpNt.type () != HNt::Type_UpnpEvent || tmpNt.subType() != HNt::SubType_UpnpPropChange) { return PreConditionFailed; } HNotifyRequest tmp; tmp.m_callback = callback; if (!isValidCallback(tmp.m_callback)) { return BadRequest; } tmp.m_sid = sid; if (tmp.m_sid.isEmpty()) { return PreConditionFailed; } QString tmpSeq = seq.trimmed(); bool ok = false; tmp.m_seq = tmpSeq.toUInt(&ok); if (!ok) { return InvalidSequenceNr; } tmp.m_data = contents.toUtf8(); RetVal rv = parseData(tmp.m_data, tmp.m_dataAsVariables); if (rv != Success) { return rv; } *this = tmp; return Success; } } } herqq-1.0.0/hupnp/src/devicehosting/messages/htimeout_p.cpp0000644000000000000000000000404411543637310022577 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "htimeout_p.h" #include namespace Herqq { namespace Upnp { HTimeout::HTimeout() : m_value(-1) { } HTimeout::HTimeout(qint32 timeout) : m_value(timeout < 0 ? -1 : timeout) { } HTimeout::HTimeout(const QString& timeout) : m_value(-1) { QString tmp(timeout.simplified()); if (tmp.compare("infinite", Qt::CaseInsensitive) != 0) { if (tmp.startsWith("Second-", Qt::CaseInsensitive)) { tmp = tmp.mid(7); } bool ok = false; qint32 tmpValue = tmp.toInt(&ok); if (ok) { m_value = tmpValue; } } } HTimeout::~HTimeout() { } HTimeout& HTimeout::operator=(qint32 value) { HTimeout copy(value); *this = copy; return *this; } HTimeout& HTimeout::operator=(const QString& value) { HTimeout copy(value); *this = copy; return *this; } QString HTimeout::toString() const { return QString("Second-%1").arg( m_value < 0 ? "infinite" : QString::number(m_value)); } bool operator==(const HTimeout& obj1, const HTimeout& obj2) { return obj1.m_value == obj2.m_value; } } } herqq-1.0.0/hupnp/src/devicehosting/messages/hcontrol_messages_p.h0000644000000000000000000000361011543637310024123 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCONTROL_MESSAGES_H_ #define HCONTROL_MESSAGES_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include #include namespace Herqq { namespace Upnp { // // // class HInvokeActionRequest { private: QString m_soapAction; QtSoapMessage m_soapMsg; QUrl m_serviceUrl; public: HInvokeActionRequest(); HInvokeActionRequest( const QString& soapAction, const QtSoapMessage& soapMsg, const QUrl& serviceUrl); ~HInvokeActionRequest(); inline QString soapAction() const { return m_soapAction; } inline const QtSoapMessage* soapMsg() const { return &m_soapMsg; } inline QUrl serviceUrl() const { return m_serviceUrl; } }; } } #endif /* HCONTROL_MESSAGES_H_ */ herqq-1.0.0/hupnp/src/devicehosting/hddoc_parser_p.h0000644000000000000000000002545011543637310021240 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDDOC_PARSER_P_H_ #define HDDOC_PARSER_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_defs.h" #include "../general/hupnp_fwd.h" #include "../general/hupnp_global.h" #include "../dataelements/hserviceid.h" #include "../dataelements/hactioninfo.h" #include "../dataelements/hserviceinfo.h" #include "../dataelements/hstatevariableinfo.h" #include "../devicemodel/hactionarguments.h" #include "../devicemodel/hactions_setupdata.h" #include #include #include #include class QDomElement; class QDomDocument; namespace Herqq { namespace Upnp { // // // enum DocumentErrorTypes { NoError, InvalidDeviceDescriptionError, InvalidServiceDescriptionError }; // // The class that creates the HUPnP's device model from description files // class HDocParser { H_DISABLE_COPY(HDocParser) private: QList parseIconList( const QDomElement& iconListElement); bool parseActionArguments( const QDomElement& argListElement, const QHash&, QVector* inArgs, QVector* outArgs, bool* hasRetVal); HStateVariableInfo parseStateVariableInfo_str( const QString& name, const QVariant& defValue, const QDomElement& svElement, HStateVariableInfo::EventingType, HInclusionRequirement); HStateVariableInfo parseStateVariableInfo_numeric( const QString& name, const QVariant& defValue, const QDomElement& svElement, HStateVariableInfo::EventingType, HInclusionRequirement, HUpnpDataTypes::DataType dataTypeEnumValue); private: const QByteArray m_loggingIdentifier; HValidityCheckLevel m_cLevel; QString m_lastErrorDescription; DocumentErrorTypes m_lastError; public: HDocParser(const QByteArray& loggingIdentifier, HValidityCheckLevel); inline QString lastErrorDescription() const { return m_lastErrorDescription; } inline DocumentErrorTypes lastError() const { return m_lastError; } bool parseRoot(const QString& doc, QDomDocument*, QDomElement*); qint32 readConfigId(const QDomElement&); bool parseDeviceInfo(const QDomElement&, HDeviceInfo*); bool parseServiceInfo(const QDomElement& serviceDefinition, HServiceInfo*); bool parseServiceDescription( const QString& docStr, QDomDocument* doc, QDomElement* stateVarElement, QDomElement* actionElement); bool parseStateVariable( const QDomElement& stateVariableElement, HStateVariableInfo*); bool parseActionInfo( const QDomElement& actionElement, const QHash&, HActionInfo*); bool verifySpecVersion(const QDomElement&, QString* err = 0); }; // // // class HDeviceValidator { private: QString m_lastErrorDescription; DocumentErrorTypes m_lastError; public: inline QString lastErrorDescription() const { return m_lastErrorDescription; } inline DocumentErrorTypes lastError() const { return m_lastError; } template bool validateRootDevice(Device* device) { class DeviceValidator { private: QSet eventUrls; QSet controlUrls; QSet scpdUrls; QSet iconUrls; QSet serviceIds; public: QString m_lastErrorDescription; DocumentErrorTypes m_lastError; bool validateIcons(Device* device) { QList icons = device->info().icons(); for (qint32 i = 0; i < icons.size(); ++i) { QString iconUrl = icons.at(i).toString(); if (iconUrls.contains(iconUrl)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Multiple icons have the same URL [%1] within a device tree. " "Icon URLs MUST be unique within a device tree.").arg( iconUrl); return false; } else { iconUrls.insert(iconUrl); } } return true; } bool validateService(Service* service) { const HServiceId& serviceId = service->info().serviceId(); if (serviceIds.contains(serviceId)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "ServiceId [%1] encountered more than once. " "ServiceIDs MUST be unique within a device tree.").arg( serviceId.toString()); return false; } else { serviceIds.insert(serviceId); } QString eventUrl = service->info().eventSubUrl().toString(); if (!eventUrl.isEmpty()) { if (eventUrls.contains(eventUrl)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "EventSubUrl [%1] encountered more than once." "EventSubUrls MUST be unique within a device tree.").arg(eventUrl); return false; } else { eventUrls.insert(eventUrl); } } QString scpdUrl = service->info().scpdUrl().toString(); if (scpdUrls.contains(scpdUrl)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "ScpdUrl [%1] encountered more than once." "ScpdUrls MUST be unique within a device tree.").arg(eventUrl); return false; } else { scpdUrls.insert(eventUrl); } QString controlUrl = service->info().controlUrl().toString(); if (controlUrls.contains(controlUrl)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "ControlUrl [%1] encountered more than once. " "ControlUrls MUST be unique within a device tree.").arg(eventUrl); return false; } else { controlUrls.insert(eventUrl); } return true; } bool validateDevice(Device* device) { if (!validateIcons(device)) { return false; } QList services = device->services(); for(qint32 i = 0; i < services.size(); ++i) { Service* service = services[i]; if (!validateService(service)) { return false; } } QList devices = device->embeddedDevices(); for(qint32 i = 0; i < devices.size(); ++i) { if (!validateDevice(devices[i])) { return false; } } return true; } }; DeviceValidator validator; if (!validator.validateDevice(device)) { m_lastError = validator.m_lastError; m_lastErrorDescription = validator.m_lastErrorDescription; return false; } return true; } bool validate(const HStateVariableInfo& setupInfo, const HStateVariableInfo&) { if (!setupInfo.isValid()) { // The setup information was not defined, which means that no // further validation should be run. return true; } return true; } bool validate(const HActionSetup& setupInfo, const HActionInfo& createdInfo) { if (!setupInfo.isValid()) { // The setup information was not defined, which means that no // further validation should be run. return true; } bool b = true; // the setup info does not necessarily contain information about the // action arguments, which is fine and it just means that the arguments // should not be validated. if (!setupInfo.inputArguments().isEmpty()) { b = setupInfo.inputArguments() != createdInfo.inputArguments(); } if (!b) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = "Invalid input arguments provided. Remember to check the " "order in which they are defined."; return false; } if (!setupInfo.outputArguments().isEmpty()) { b = setupInfo.outputArguments() != createdInfo.outputArguments(); } if (!b) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = "Invalid output arguments provided. Remember to check the " "order in which they are defined."; } return b; } }; } } #endif /* HDDOC_PARSER_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/hddoc_parser_p.cpp0000644000000000000000000006053411543637310021575 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hddoc_parser_p.h" #include "../dataelements/hudn.h" #include "../dataelements/hdeviceinfo.h" #include "../dataelements/hresourcetype.h" #include "../general/hupnp_global_p.h" #include "../general/hupnp_datatypes_p.h" #include "../general/hlogger_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HDocParser ******************************************************************************/ HDocParser::HDocParser( const QByteArray& loggingIdentifier, HValidityCheckLevel clevel) : m_loggingIdentifier(loggingIdentifier), m_cLevel(clevel), m_lastErrorDescription(), m_lastError(NoError) { } HStateVariableInfo HDocParser::parseStateVariableInfo_str( const QString& name, const QVariant& defValue, const QDomElement& svElement, HStateVariableInfo::EventingType evType, HInclusionRequirement incReq) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QStringList allowedValues; QDomElement allowedValueListElement = svElement.firstChildElement("allowedValueList"); if (!allowedValueListElement.isNull()) { QDomElement allowedValueElement = allowedValueListElement.firstChildElement("allowedValue"); while(!allowedValueElement.isNull()) { allowedValues.push_back(allowedValueElement.text()); allowedValueElement = allowedValueElement.nextSiblingElement("allowedValue"); } } return HStateVariableInfo( name, defValue, allowedValues, evType, incReq, &m_lastErrorDescription); } HStateVariableInfo HDocParser::parseStateVariableInfo_numeric( const QString& name, const QVariant& defValue, const QDomElement& svElement, HStateVariableInfo::EventingType evType, HInclusionRequirement incReq, HUpnpDataTypes::DataType dataTypeEnumValue) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QDomElement allowedValueRangeElement = svElement.firstChildElement("allowedValueRange"); if (allowedValueRangeElement.isNull()) { return HStateVariableInfo( name, dataTypeEnumValue, defValue, evType, incReq, &m_lastErrorDescription); } QString minimumStr = readElementValue("minimum", allowedValueRangeElement); if (minimumStr.isEmpty()) { QString descr = QString( "State variable [%1] is missing a mandatory element " "within .").arg(name); if (m_cLevel == StrictChecks) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = descr; return HStateVariableInfo(); } else { HLOG_WARN_NONSTD(descr); minimumStr = QString::number(INT_MIN); } } QString maximumStr = readElementValue("maximum", allowedValueRangeElement); if (maximumStr.isEmpty()) { QString descr = QString( "State variable [%1] is missing a mandatory element " "within .").arg(name); if (m_cLevel == StrictChecks) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = descr; return HStateVariableInfo(); } else { HLOG_WARN_NONSTD(descr); maximumStr = QString::number(INT_MAX); } } QString stepStr = readElementValue("step", allowedValueRangeElement); if (stepStr.isEmpty()) { if (HUpnpDataTypes::isRational(dataTypeEnumValue)) { bool ok = false; double maxTmp = maximumStr.toDouble(&ok); if (ok && maxTmp < 1) { stepStr = QString::number(maxTmp / 10); } else { stepStr = "1.0"; } } else { stepStr = "1"; } } return HStateVariableInfo( name, dataTypeEnumValue, defValue, minimumStr, maximumStr, stepStr, evType, incReq); } bool HDocParser::parseActionArguments( const QDomElement& argListElement, const QHash& stateVars, QVector* inArgs, QVector* outArgs, bool* hasRetVal) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); bool firstOutArgFound = false; QDomElement argumentElement = argListElement.firstChildElement("argument"); while(!argumentElement.isNull()) { QString name = readElementValue("name", argumentElement); QString dirStr = readElementValue("direction", argumentElement); bool retValWasDefined = false; readElementValue("retval", argumentElement, &retValWasDefined); QString relatedSvStr = readElementValue("relatedStateVariable", argumentElement); if (!stateVars.contains(relatedSvStr)) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid action argument: the specified " "[%1] is undefined.").arg(relatedSvStr); return false; } HActionArgument createdArg; if (dirStr.compare("out", Qt::CaseInsensitive) == 0) { if (retValWasDefined) { if (firstOutArgFound) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid action argument ordering: " "[retval] MUST be the first [out] argument.").arg( relatedSvStr); return false; } *hasRetVal = true; } firstOutArgFound = true; createdArg = HActionArgument( name, stateVars.value(relatedSvStr), &m_lastErrorDescription); if (!createdArg.isValid()) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid action argument: %1").arg(m_lastErrorDescription); return false; } outArgs->push_back(createdArg); } else if (dirStr.compare("in", Qt::CaseInsensitive) == 0) { if (firstOutArgFound) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = "Invalid action argument order. Input arguments MUST all come " "before output arguments."; return false; } createdArg = HActionArgument(name, stateVars.value(relatedSvStr)); if (!createdArg.isValid()) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid action argument: %1").arg(m_lastErrorDescription); return false; } inArgs->push_back(createdArg); } else { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid action argument: " "invalid [direction] value: [%1].").arg(dirStr); return false; } argumentElement = argumentElement.nextSiblingElement("argument"); } return true; } QList HDocParser::parseIconList(const QDomElement& iconListElement) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QList retVal; QDomElement iconElement = iconListElement.firstChildElement("icon"); while(!iconElement.isNull()) { QUrl iconUrl = readElementValue("url", iconElement); QString iconUrlAsStr = iconUrl.toString(); retVal.append(QUrl(iconUrlAsStr)); iconElement = iconElement.nextSiblingElement("icon"); } return retVal; } bool HDocParser::parseRoot( const QString& docStr, QDomDocument* doc, QDomElement* rootEl) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(doc); Q_ASSERT(rootEl); QString errMsg; qint32 errLine = 0; if (!doc->setContent(docStr, false, &errMsg, &errLine)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Failed to parse the device description: [%1] @ line [%2].").arg( errMsg, QString::number(errLine)); return false; } QDomElement rootElement = doc->firstChildElement("root"); // "urn:schemas-upnp-org:device-1-0", if (rootElement.isNull()) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = "Invalid device description: missing element."; return false; } if (!verifySpecVersion(rootElement, &m_lastErrorDescription)) { if (m_cLevel == StrictChecks) { m_lastError = InvalidDeviceDescriptionError; return false; } else { HLOG_WARN_NONSTD(QString( "Error in device description: %1").arg(m_lastErrorDescription)); } } QDomElement rootDeviceElement = rootElement.firstChildElement("device"); if (rootDeviceElement.isNull()) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = "Invalid device description: no valid root device definition " "was found."; return false; } *rootEl = rootDeviceElement; return true; } qint32 HDocParser::readConfigId(const QDomElement& rootElement) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); bool ok = false; QString cid = readElementValue("configId", rootElement); qint32 retVal = cid.toInt(&ok); if (!ok || retVal < 0 || retVal > ((1 << 24)-1)) { return 0; } return retVal; } bool HDocParser::parseDeviceInfo( const QDomElement& deviceElement, HDeviceInfo* info) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(info); QString deviceType = readElementValue("deviceType" , deviceElement); QString friendlyName = readElementValue("friendlyName" , deviceElement); QString manufacturer = readElementValue("manufacturer" , deviceElement); QString manufacturerURL = readElementValue("manufacturerURL" , deviceElement); QString modelDescription = readElementValue("modelDescription", deviceElement); QString modelName = readElementValue("modelName" , deviceElement); QString modelNumber = readElementValue("modelNumber" , deviceElement); QUrl modelUrl = readElementValue("modelURL" , deviceElement); QString serialNumber = readElementValue("serialNumber" , deviceElement); HUdn udn(readElementValue("UDN" , deviceElement)); QString upc = readElementValue("UPC" , deviceElement); QDomElement iconListElement = deviceElement.firstChildElement("iconList"); QList icons; if (!iconListElement.isNull()) { icons = parseIconList(iconListElement); } bool wasDefined = false; QString tmp = readElementValue("presentationURL", deviceElement, &wasDefined); if (wasDefined && tmp.isEmpty()) { QString err = "Presentation URL should be defined if the " "corresponding element is used."; if (m_cLevel == StrictChecks) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = err; return false; } else { HLOG_WARN(QString("Error in device description: %1").arg(err)); } } QUrl presentationUrl(tmp); *info = HDeviceInfo( HResourceType(deviceType), friendlyName, manufacturer, manufacturerURL, modelDescription, modelName, modelNumber, modelUrl, serialNumber, udn, upc, icons, presentationUrl, m_cLevel, &m_lastErrorDescription); if (!info->isValid(m_cLevel)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Invalid device description: %1").arg(m_lastErrorDescription); return false; } return true; } bool HDocParser::parseServiceInfo( const QDomElement& serviceDefinition, HServiceInfo* serviceInfo) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(serviceInfo); Q_ASSERT(!serviceDefinition.isNull()); bool wasDefined = false; HServiceId serviceId = readElementValue("serviceId", serviceDefinition, &wasDefined); if (!wasDefined) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Invalid definition. " "Missing mandatory element:\n%1").arg( toString(serviceDefinition)); return false; } HResourceType resourceType = readElementValue("serviceType", serviceDefinition, &wasDefined); if (!wasDefined) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Invalid definition. " "Missing mandatory element:\n%1").arg( toString(serviceDefinition)); return false; } QUrl scpdUrl = readElementValue("SCPDURL", serviceDefinition, &wasDefined); if (!wasDefined) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Invalid definition. " "Missing mandatory element:\n%1").arg( toString(serviceDefinition)); return false; } QUrl controlUrl = readElementValue("controlURL" , serviceDefinition, &wasDefined); if (!wasDefined) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Invalid definition. " "Missing mandatory element:\n%1").arg( toString(serviceDefinition)); return false; } QUrl eventSubUrl = readElementValue("eventSubURL", serviceDefinition, &wasDefined); if (!wasDefined) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString( "Invalid definition. " "Missing mandatory element:\n%1").arg( toString(serviceDefinition)); return false; } HServiceInfo tmpServiceInfo( serviceId, resourceType, controlUrl, eventSubUrl, scpdUrl, InclusionMandatory, m_cLevel, &m_lastErrorDescription); if (!tmpServiceInfo.isValid(m_cLevel)) { m_lastError = InvalidDeviceDescriptionError; m_lastErrorDescription = QString("%1:\n%2").arg( m_lastErrorDescription, toString(serviceDefinition)); return false; } *serviceInfo = tmpServiceInfo; return true; } bool HDocParser::parseServiceDescription( const QString& docStr, QDomDocument* doc, QDomElement* stateVarElement, QDomElement* retVal) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(stateVarElement); Q_ASSERT(retVal); qint32 errLine; QString errMsg; if (!doc->setContent(docStr, false, &errMsg, &errLine)) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Failed to parse the service description: [%1] @ line [%2].").arg( errMsg, QString::number(errLine)); return false; } //QDomNodeList scpdElementNodeList = //tmp.elementsByTagNameNS("urn:schemas-upnp-org:service-1-0","scpd"); QDomElement scpdElement = doc->firstChildElement("scpd"); if (scpdElement.isNull()) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = "Invalid service description: missing element."; return false; } if (!verifySpecVersion(scpdElement, &m_lastErrorDescription)) { if (m_cLevel == StrictChecks) { m_lastError = InvalidServiceDescriptionError; return false; } else { HLOG_WARN_NONSTD(QString("Error in service description: %1").arg( m_lastErrorDescription)); } } QDomElement serviceStateTableElement = scpdElement.firstChildElement("serviceStateTable"); if (serviceStateTableElement.isNull()) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = "Service description is missing a mandatory element."; return false; } QDomElement stateVariableElement = serviceStateTableElement.firstChildElement("stateVariable"); if (stateVariableElement.isNull()) { QString err = "Service description document does not have a " "single element. " "Each service MUST have at least one state variable."; if (m_cLevel == StrictChecks) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = err; return false; } else { HLOG_WARN_NONSTD(err); } } QDomElement actionListElement = scpdElement.firstChildElement("actionList"); if (actionListElement.isNull()) { return true; } QDomElement actionElement = actionListElement.firstChildElement("action"); if (actionElement.isNull()) { QString err = "Service description document has " "element that has no elements."; if (m_cLevel == StrictChecks) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = err; return false; } else { HLOG_WARN(err); } } *stateVarElement = stateVariableElement; *retVal = actionElement; return true; } bool HDocParser::parseStateVariable( const QDomElement& stateVariableElement, HStateVariableInfo* svInfo) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(svInfo); QString strSendEvents = stateVariableElement.attribute("sendEvents", "no"); bool bSendEvents = false; if (strSendEvents.compare("yes", Qt::CaseInsensitive) == 0) { bSendEvents = true; } else if (strSendEvents.compare("no", Qt::CaseInsensitive) != 0) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid definition: " "invalid value for [sendEvents] attribute:\n%1.").arg( toString(stateVariableElement)); return false; } QString strMulticast = stateVariableElement.attribute("multicast", "no"); bool bMulticast = false; if (strMulticast.compare("yes", Qt::CaseInsensitive) == 0) { bMulticast = true; } else if (strMulticast.compare("no", Qt::CaseInsensitive) != 0) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid definition: " "invalid value for [multicast]: %1.").arg( toString(stateVariableElement)); return false; } HStateVariableInfo::EventingType evType = HStateVariableInfo::NoEvents; if (bSendEvents) { evType = bMulticast ? HStateVariableInfo::UnicastAndMulticast : HStateVariableInfo::UnicastOnly; } QString name = readElementValue("name", stateVariableElement); QString dataType = readElementValue("dataType", stateVariableElement); HUpnpDataTypes::DataType dtEnumValue = HUpnpDataTypes::dataType(dataType); bool defValueWasDefined = false; QString defaultValueStr = readElementValue( "defaultValue", stateVariableElement, &defValueWasDefined); QVariant defaultValue = defValueWasDefined ? HUpnpDataTypes::convertToRightVariantType( defaultValueStr, dtEnumValue) : QVariant(); HStateVariableInfo parsedInfo; if (dtEnumValue == HUpnpDataTypes::string) { parsedInfo = parseStateVariableInfo_str( name, defValueWasDefined ? defaultValueStr : QVariant(), stateVariableElement, evType, InclusionMandatory); } else if (HUpnpDataTypes::isNumeric(dtEnumValue)) { parsedInfo = parseStateVariableInfo_numeric( name, defaultValue, stateVariableElement, evType, InclusionMandatory, dtEnumValue); } else { parsedInfo = HStateVariableInfo( name, dtEnumValue, defaultValue, evType, InclusionMandatory, &m_lastErrorDescription); } if (!parsedInfo.isValid()) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString("Invalid [%1] definition: %2").arg( name, m_lastErrorDescription); return false; } *svInfo = parsedInfo; return true; } bool HDocParser::parseActionInfo( const QDomElement& actionElement, const QHash& stateVars, HActionInfo* ai) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QString name = readElementValue("name", actionElement); bool hasRetVal = false; QVector inputArguments; QVector outputArguments; QDomElement argumentListElement = actionElement.firstChildElement("argumentList"); if (!argumentListElement.isNull()) { if (!parseActionArguments( argumentListElement, stateVars, &inputArguments, &outputArguments, &hasRetVal)) { m_lastErrorDescription = QString( "Invalid action [%1] definition: %2").arg( name, m_lastErrorDescription); return false; } } HActionArguments inArgs(inputArguments); HActionArguments outArgs(outputArguments); HActionInfo actionInfo( name, inArgs, outArgs, hasRetVal, InclusionMandatory, &m_lastErrorDescription); if (!actionInfo.isValid()) { m_lastError = InvalidServiceDescriptionError; m_lastErrorDescription = QString( "Invalid [%1] definition: %2").arg( name, m_lastErrorDescription); return false; } *ai = actionInfo; return true; } bool HDocParser::verifySpecVersion(const QDomElement& rootElement, QString* err) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QDomElement specVersionElement = rootElement.firstChildElement("specVersion"); if (specVersionElement.isNull()) { if (err) { *err = "Missing mandatory element."; } return false; } QString minorVersion = readElementValue("minor", specVersionElement); QString majorVersion = readElementValue("major", specVersionElement); bool ok; qint32 major = majorVersion.toInt(&ok); if (!ok || major != 1) { if (err) { *err = "Major element of is not 1."; } return false; } qint32 minor = minorVersion.toInt(&ok); if (!ok || (minor != 1 && minor != 0)) { if (err) { *err = "Minor element of is not 0 or 1."; } return false; } return true; } } } herqq-1.0.0/hupnp/src/devicehosting/hdevicestorage_p.h0000644000000000000000000003446411543637310021604 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICESTORAGE_H_ #define HDEVICESTORAGE_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_global_p.h" #include "../general/hlogger_p.h" #include #include #include #include #include #include #include #include namespace Herqq { namespace Upnp { // // // template class MatchFunctor { private: T m_t; public: MatchFunctor(const T& t) : m_t(t){} inline bool operator()(Controller* obj) const { return m_t(obj); } }; static bool compareUrls(const QUrl& u1, const QUrl& u2) { QString u1Str = extractRequestPart(u1); QString u2Str = extractRequestPart(u2); if (u1Str.startsWith('/')) { u1Str.remove(0, 1); } if (u2Str.startsWith('/')) { u2Str.remove(0, 1); } return u1Str == u2Str; } // // // template class ScpdUrlTester { private: QUrl m_url; public: ScpdUrlTester(const QUrl& url) : m_url(url){} inline bool operator()(Service* service) const { Q_ASSERT(service); return compareUrls(m_url, service->info().scpdUrl()); } }; // // // template class ControlUrlTester { private: QUrl m_url; public: ControlUrlTester(const QUrl& url) : m_url(url){} inline bool operator()(Service* service) const { Q_ASSERT(service); //return service->controlUrl() == m_url; return compareUrls(m_url, service->info().controlUrl()); } }; // // // template class EventUrlTester { private: QUrl m_url; public: EventUrlTester(const QUrl& url) : m_url(url){} inline bool operator()(Service* service) const { Q_ASSERT(service); //return service->eventSubUrl() == m_url; return compareUrls(m_url, service->info().eventSubUrl()); } }; // // // template class UdnTester { private: HUdn m_udn; public: UdnTester(const HUdn& udn) : m_udn(udn){} inline bool operator()(Device* device) const { Q_ASSERT(device); return device->info().udn() == m_udn; } }; // // // template class DeviceTypeTester { private: HResourceType m_resourceType; HResourceType::VersionMatch m_versionMatch; public: DeviceTypeTester( const HResourceType& resType, HResourceType::VersionMatch vm) : m_resourceType(resType), m_versionMatch(vm) { } bool test(const HResourceType& resType) const { return resType.compare(m_resourceType, m_versionMatch); } bool operator()(Device* device) const { Q_ASSERT(device); return test(device->info().deviceType()); } }; // // // template class ServiceTypeTester { private: HResourceType m_resourceType; HResourceType::VersionMatch m_versionMatch; public: ServiceTypeTester( const HResourceType& resType, HResourceType::VersionMatch vm) : m_resourceType(resType), m_versionMatch(vm) { } bool test(const HResourceType& resType) const { return resType.compare(m_resourceType, m_versionMatch); } bool operator()(Service* service) const { Q_ASSERT(service); return test(service->info().serviceType()); } }; template void seekDevices( Device* device, const MatchFunctor& mf, QList& foundDevices, TargetDeviceType dts) { Q_ASSERT(device); if (dts == RootDevices && device->parentDevice()) { return; } if (mf(device)) { foundDevices.push_back(device); } QList devices = device->embeddedDevices(); foreach(Device* device, devices) { seekDevices(device, mf, foundDevices, dts); } } // // // template void seekDevices( const QList& devices, const MatchFunctor& mf, QList& foundDevices, TargetDeviceType dts) { foreach(Device* device, devices) { seekDevices(device, mf, foundDevices, dts); } } // // // template Service* seekService( const QList& devices, const MatchFunctor& mf) { foreach(Device* device, devices) { QList services = device->services(); foreach(Service* service, services) { if (mf(service)) { return service; } } Service* service = seekService(device->embeddedDevices(), mf); if (service) { return service; } } return 0; } // // // template void seekServices( const QList& devices, const MatchFunctor& mf, QList& foundServices, bool rootDevicesOnly) { foreach(Device* device, devices) { if (rootDevicesOnly && device->parentDevice()) { continue; } QList services = device->services(); foreach(Service* service, services) { if (mf(service)) { foundServices.push_back(service); } } if (rootDevicesOnly) { continue; } seekServices(device->embeddedDevices(), mf, foundServices, rootDevicesOnly); } } // // // template class HDeviceStorage { H_DISABLE_COPY(HDeviceStorage) private: const QByteArray m_loggingIdentifier; QList m_rootDevices; // the device trees stored by this instance QList > m_deviceControllers; QString m_lastError; public: // instance methods HDeviceStorage(const QByteArray& lid) : m_loggingIdentifier(lid), m_rootDevices() { } ~HDeviceStorage() { clear(); } inline QString lastError() const { return m_lastError; } void clear() { qDeleteAll(m_rootDevices); m_rootDevices.clear(); for(int i = 0; i < m_deviceControllers.size(); ++i) { delete m_deviceControllers.at(i).second; } m_deviceControllers.clear(); } Controller* getController(const Device* device) const { Device* rootDev = device->rootDevice(); for(int i = 0; i < m_deviceControllers.size(); ++i) { if (m_deviceControllers.at(i).first == rootDev) { return m_deviceControllers.at(i).second; } } return 0; } Device* searchDeviceByUdn(const HUdn& udn, TargetDeviceType dts) const { QList devices; seekDevices( m_rootDevices, MatchFunctor >(udn), devices, dts); return devices.size() > 0 ? devices[0] : 0; } bool searchValidLocation( const Device* device, const HEndpoint& interface, QUrl* location) { Q_ASSERT(device); QList locations = device->locations(); QList::const_iterator ci = locations.constBegin(); for(; ci != locations.constEnd(); ++ci) { /*if (QHostAddress(ci->host()) == interface.hostAddress()) { *location = *ci; return true; }*/ // TODO if (interface.hostAddress().isInSubnet( QHostAddress::parseSubnet(ci->host().append("/24")))) { *location = *ci; return true; } } return false; } QList searchDevicesByDeviceType( const HResourceType& deviceType, HResourceType::VersionMatch vm, TargetDeviceType dts) const { QList retVal; seekDevices( m_rootDevices, MatchFunctor >( DeviceTypeTester(deviceType, vm)), retVal, dts); return retVal; } QList searchServicesByServiceType( const HResourceType& serviceType, HResourceType::VersionMatch vm) const { QList retVal; seekServices( m_rootDevices, MatchFunctor >( ServiceTypeTester(serviceType, vm)), retVal, false); return retVal; } bool checkDeviceTreeForUdnConflicts(Device* device) { if (searchDeviceByUdn(device->info().udn(), RootDevices)) { m_lastError = QString("Cannot host multiple devices with the same UDN [%1]").arg( device->info().udn().toSimpleUuid()); return false; } QList devices = device->embeddedDevices(); foreach(Device* embeddeDevice, devices) { if (!checkDeviceTreeForUdnConflicts(embeddeDevice)) { return false; } } return true; } bool addRootDevice(Device* root, Controller* controller = 0) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(root); Q_ASSERT(root); Q_ASSERT(!root->parentDevice()); if (!checkDeviceTreeForUdnConflicts(root)) { return false; } m_rootDevices.push_back(root); m_deviceControllers.append(qMakePair(root, controller)); HLOG_DBG(QString("New root device [%1] added. Current device count is %2").arg( root->info().friendlyName(), QString::number(m_rootDevices.size()))); return true; } bool removeRootDevice(Device* root) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(root); Q_ASSERT(!root->parentDevice()); HDeviceInfo devInfo = root->info(); bool ok = m_rootDevices.removeOne(root); if (!ok) { HLOG_WARN(QString("Device [%1] was not found.").arg( devInfo.friendlyName())); return false; } bool found = false; for(int i = 0; i < m_deviceControllers.size(); ++i) { if (m_deviceControllers.at(i).first == root) { delete m_deviceControllers.at(i).second; m_deviceControllers.removeAt(i); found = true; break; } } delete root; Q_ASSERT(found); HLOG_DBG(QString("Root device [%1] removed. Current device count is %2").arg( devInfo.friendlyName(), QString::number(m_rootDevices.size()))); return true; } QUrl seekIcon( Device* device, const QString& iconUrl) { Q_ASSERT(device); QList icons = device->info().icons(); for (qint32 i = 0; i < icons.size(); ++i) { if (compareUrls(icons[i], iconUrl)) { return icons[i]; } } QList devices = device->embeddedDevices(); foreach(Device* device, devices) { QUrl icon = seekIcon(device, iconUrl); if (!icon.isEmpty() && icon.isValid()) { return icon; } } return QUrl(); } Service* searchServiceByScpdUrl(Device* device, const QUrl& scpdUrl) const { QList tmp; tmp.push_back(device); return seekService( tmp, MatchFunctor >(scpdUrl)); } Service* searchServiceByScpdUrl(const QUrl& scpdUrl) const { return seekService( m_rootDevices, MatchFunctor >(scpdUrl)); } Service* searchServiceByControlUrl( Device* device, const QUrl& controlUrl) const { QList tmp; tmp.push_back(device); return seekService( tmp, MatchFunctor >(controlUrl)); } Service* searchServiceByControlUrl(const QUrl& controlUrl) const { return seekService( m_rootDevices, MatchFunctor >(controlUrl)); } Service* searchServiceByEventUrl(Device* device, const QUrl& eventUrl) const { QList tmp; tmp.push_back(device); return seekService( tmp, MatchFunctor >(eventUrl)); } Service* searchServiceByEventUrl(const QUrl& eventUrl) const { return seekService( m_rootDevices, MatchFunctor >(eventUrl)); } template QList rootDevices() const { QList retVal; foreach(Device* dev, m_rootDevices) { retVal.append(dev); } return retVal; } const QList& rootDevices() const { return m_rootDevices; } QList controllers() const { QList retVal; for(int i = 0; i < m_deviceControllers.size(); ++i) { retVal.append(m_deviceControllers.at(i).second); } return retVal; } }; } } #endif /* HDEVICESTORAGE_H_ */ herqq-1.0.0/hupnp/src/devicehosting/hmodelcreation_p.cpp0000644000000000000000000000260611543637310022131 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hmodelcreation_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HModelCreationArgs ******************************************************************************/ HModelCreationArgs::HModelCreationArgs() : m_deviceDescription(), m_deviceLocations(), m_serviceDescriptionFetcher(), m_deviceTimeoutInSecs(0), m_iconFetcher(), m_loggingIdentifier() { } HModelCreationArgs::~HModelCreationArgs() { } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/0000755000000000000000000000000011543637460020645 5ustar rootrootherqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint_dataretriever_p.h0000644000000000000000000000445111543637310027156 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCONTROLPOINT_DATARETRIEVER_H_ #define HCONTROLPOINT_DATARETRIEVER_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../../general/hupnp_defs.h" #include #include #include class QUrl; class QNetworkReply; namespace Herqq { namespace Upnp { // // // class HDataRetriever : public QEventLoop { Q_OBJECT H_DISABLE_COPY(HDataRetriever) private slots: void finished(); private: const QByteArray m_loggingIdentifier; QNetworkAccessManager m_nam; QNetworkReply* m_reply; QString m_lastError; bool m_success; private: bool retrieveData(const QUrl& baseUrl, const QUrl& query, QByteArray*); protected: virtual void timerEvent(QTimerEvent*); public: HDataRetriever(const QByteArray& loggingId); inline QString lastError() const { return m_lastError; } bool retrieveServiceDescription( const QUrl& deviceLocation, const QUrl& scpdUrl, QString*); bool retrieveIcon( const QUrl& deviceLocation, const QUrl& iconUrl, QByteArray*); bool retrieveDeviceDescription(const QUrl& deviceLocation, QString*); }; } } #endif /* HCONTROLPOINT_DATARETRIEVER_H_ */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hevent_subscriptionmanager_p.h0000644000000000000000000000615511543637310026766 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HEVENT_SUBSCRIPTIONMANAGER_P_H_ #define HEVENT_SUBSCRIPTIONMANAGER_P_H_ #include "hevent_subscription_p.h" #include "../../general/hupnp_global.h" #include "../../devicemodel/client/hclientdevice.h" #include #include #include #include namespace Herqq { namespace Upnp { class HControlPointPrivate; // // // class HEventSubscriptionManager : public QObject { Q_OBJECT H_DISABLE_COPY(HEventSubscriptionManager) private: HControlPointPrivate* m_owner; QHash m_subscribtionsByUuid; QHash* > m_subscriptionsByUdn; private: HEventSubscription* createSubscription(HClientService*, qint32 timeout); QUrl getSuitableHttpServerRootUrl(const QList& deviceLocations); // attempts to figure out the most suitable HTTP server URL for one of the // device locations specified public Q_SLOTS: void subscribed_slot(HEventSubscription*); void subscriptionFailed_slot(HEventSubscription*); void unsubscribed(HEventSubscription*); Q_SIGNALS: void subscribed(Herqq::Upnp::HClientService*); void subscriptionFailed(Herqq::Upnp::HClientService*); void unsubscribed(Herqq::Upnp::HClientService*); public: HEventSubscriptionManager(HControlPointPrivate*); virtual ~HEventSubscriptionManager(); enum SubscriptionResult { Sub_Success = 0, Sub_AlreadySubscribed = 1, Sub_Failed_NotEvented = 2, }; bool subscribe(HClientDevice*, DeviceVisitType, qint32 timeout); SubscriptionResult subscribe(HClientService*, qint32 timeout); HEventSubscription::SubscriptionStatus subscriptionStatus( const HClientService*) const; // the unsubscribe flag specifies whether to send unsubscription to the UPnP device // if not, the subscription is just reset to default state (in which it does nothing) bool cancel(HClientDevice*, DeviceVisitType, bool unsubscribe); bool cancel(HClientService*, bool unsubscribe); void cancelAll(qint32 msecsToWait); bool remove(HClientDevice*, bool recursive); bool remove(HClientService*); void removeAll(); StatusCode onNotify(const QUuid& id, const HNotifyRequest& req); }; } } #endif /* HEVENT_SUBSCRIPTIONMANAGER_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hevent_subscription_p.cpp0000644000000000000000000004145711543637310025772 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hevent_subscription_p.h" #include "../../devicemodel/client/hclientdevice.h" #include "../../devicemodel/client/hdefault_clientservice_p.h" #include "../../dataelements/hserviceinfo.h" #include "../../general/hupnp_global_p.h" #include "../../http/hhttp_messagecreator_p.h" #include "../../general/hlogger_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HEventSubscription definition ******************************************************************************/ HEventSubscription::HEventSubscription( const QByteArray& loggingIdentifier, HClientService* service, const QUrl& serverRootUrl, const HTimeout& desiredTimeout, QObject* parent) : QObject(parent), m_loggingIdentifier(loggingIdentifier), m_randomIdentifier (QUuid::createUuid()), m_deviceLocations(), m_nextLocationToTry(0), m_eventUrl(), m_sid(), m_seq(0), m_desiredTimeout(desiredTimeout), m_timeout(), m_subscriptionTimer(this), m_announcementTimer(this), m_announcementTimedOut(false), m_service(service), m_serverRootUrl(serverRootUrl), m_http(loggingIdentifier, this), m_socket(this), m_currentOpType(Op_None), m_nextOpType(Op_None), m_subscribed(false) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(m_service); Q_ASSERT(!m_serverRootUrl.isEmpty()); Q_ASSERT_X(m_serverRootUrl.isValid(), H_AT, m_serverRootUrl.toString().toLocal8Bit()); m_deviceLocations = service->parentDevice()->locations(); Q_ASSERT(m_deviceLocations.size() > 0); for(qint32 i = 0; i < m_deviceLocations.size(); ++i) { Q_ASSERT(!m_deviceLocations[i].isEmpty()); Q_ASSERT_X(m_deviceLocations[i].isValid(), H_AT, m_deviceLocations[i].toString().toLocal8Bit()); } bool ok = connect( &m_subscriptionTimer, SIGNAL(timeout()), this, SLOT(subscriptionTimeout())); Q_ASSERT(ok); Q_UNUSED(ok) ok = connect( &m_announcementTimer, SIGNAL(timeout()), this, SLOT(announcementTimeout())); Q_ASSERT(ok); ok = connect(&m_socket, SIGNAL(connected()), this, SLOT(connected())); Q_ASSERT(ok); ok = connect( &m_http, SIGNAL(msgIoComplete(HHttpAsyncOperation*)), this, SLOT(msgIoComplete(HHttpAsyncOperation*)), Qt::DirectConnection); Q_ASSERT(ok); } HEventSubscription::~HEventSubscription() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); } void HEventSubscription::subscriptionTimeout() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); m_subscriptionTimer.stop(); if (m_sid.isEmpty()) { subscribe(); } else { renewSubscription(); } } void HEventSubscription::announcementTimeout() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); m_announcementTimedOut = true; } void HEventSubscription::resetSubscription() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); m_seq = 0; m_sid = HSid(); m_eventUrl = QUrl(); m_timeout = HTimeout(); m_nextLocationToTry = 0; m_currentOpType = Op_None; m_subscribed = false; m_connectErrorCount = 0; m_subscriptionTimer.stop(); if (m_socket.state() == QAbstractSocket::ConnectedState) { m_socket.disconnectFromHost(); } } void HEventSubscription::runNextOp() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); OperationType curOp = m_currentOpType; m_currentOpType = Op_None; switch(curOp) { case Op_None: break; case Op_Subscribe: subscribe(); break; case Op_Renew: renewSubscription(); break; case Op_Unsubscribe: unsubscribe(); break; }; } void HEventSubscription::connected() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); bool ok = disconnect( &m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); Q_ASSERT(ok); Q_UNUSED(ok) m_connectErrorCount = 0; runNextOp(); } void HEventSubscription::msgIoComplete(HHttpAsyncOperation* op) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(op); switch(m_currentOpType) { case Op_Subscribe: subscribe_done(op); break; case Op_Renew: renewSubscription_done(op); break; case Op_Unsubscribe: unsubscribe_done(op); break; default: Q_ASSERT(false); break; }; if (m_socket.state() == QTcpSocket::ConnectedState) { m_socket.disconnectFromHost(); } delete op; if (m_currentOpType == Op_Subscribe || m_currentOpType == Op_Renew) { foreach(const HNotifyRequest& req, m_queuedNotifications) { if (processNotify(req) != Ok) { break; } } m_queuedNotifications.clear(); } if (m_nextOpType != Op_None) { m_currentOpType = m_nextOpType; m_nextOpType = Op_None; runNextOp(); } else { m_currentOpType = Op_None; } } void HEventSubscription::renewSubscription_done(HHttpAsyncOperation* op) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(!m_sid.isEmpty()); Q_ASSERT(m_currentOpType == Op_Renew); if (op->state() == HHttpAsyncOperation::Failed) { HLOG_WARN(QString("Event subscription renewal [sid: %1] failed.").arg( m_sid.toString())); emit subscriptionFailed(this); return; } const HHttpResponseHeader* hdr = static_cast(op->headerRead()); Q_ASSERT(hdr); HSubscribeResponse response; if (!HHttpMessageCreator::create(*hdr, response)) { HLOG_WARN(QString("Received an invalid response to event " "subscription renewal: %1.").arg(hdr->toString())); emit subscriptionFailed(this); return; } if (response.sid() != m_sid) { // TODO, in this case could re-subscribe HLOG_WARN(QString( "Received an invalid SID [%1] to event subscription [%2] renewal").arg( response.sid().toString(), m_sid.toString())); emit subscriptionFailed(this); return; } m_subscribed = true; HLOG_DBG(QString("Subscription renewal to [%1] succeeded [sid: %2].").arg( m_eventUrl.toString(), m_sid.toString())); m_timeout = response.timeout(); if (!m_timeout.isInfinite()) { m_subscriptionTimer.start(m_timeout.value() * 1000 / 2); } } void HEventSubscription::renewSubscription() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); if (m_currentOpType != Op_None || m_sid.isEmpty()) { return; } m_announcementTimer.stop(); m_currentOpType = Op_Renew; if (!connectToDevice()) { return; } HLOG_DBG(QString("Renewing subscription [sid: %1].").arg( m_sid.toString())); QUrl eventUrl = resolveUri( extractBaseUrl(m_deviceLocations[m_nextLocationToTry]), m_service->info().eventSubUrl()); HMessagingInfo* mi = new HMessagingInfo(m_socket, false); mi->setHostInfo(eventUrl); HSubscribeRequest req(eventUrl, m_sid, m_desiredTimeout); QByteArray data = HHttpMessageCreator::create(req, *mi); if (!m_http.msgIo(mi, data)) { HLOG_WARN(QString("Failed to renew subscription [sid %1].").arg( m_sid.toString())); emit subscriptionFailed(this); } } void HEventSubscription::resubscribe() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); if (m_sid.isEmpty()) { subscribe(); } else { unsubscribe(); } } void HEventSubscription::error(QAbstractSocket::SocketError /*err*/) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); // this can be called only when connecting to host if (++m_connectErrorCount >= m_deviceLocations.size() * 2) { return; } if (m_nextLocationToTry >= m_deviceLocations.size() - 1) { m_nextLocationToTry = 0; } else { ++m_nextLocationToTry; } connectToDevice(); } bool HEventSubscription::connectToDevice(qint32 msecsToWait) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(m_currentOpType != Op_None); if (m_socket.state() == QTcpSocket::ConnectedState) { return true; } else if (m_socket.state() == QTcpSocket::ConnectingState || m_socket.state() == QTcpSocket::HostLookupState) { return false; } QUrl lastLoc = m_deviceLocations[m_nextLocationToTry]; bool ok = connect( &m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); Q_ASSERT(ok); Q_UNUSED(ok) m_socket.connectToHost(lastLoc.host(), lastLoc.port()); if (msecsToWait > 0) { m_socket.waitForConnected(msecsToWait); } return m_socket.state() == QAbstractSocket::ConnectedState; } void HEventSubscription::subscribe_done(HHttpAsyncOperation* op) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(m_sid.isEmpty()); Q_ASSERT(m_currentOpType == Op_Subscribe); if (op->state() == HHttpAsyncOperation::Failed) { HLOG_WARN(QString("Event subscription failed: [%1]").arg( op->messagingInfo()->lastErrorDescription())); emit subscriptionFailed(this); return; } const HHttpResponseHeader* hdr = static_cast(op->headerRead()); Q_ASSERT(hdr); HSubscribeResponse response; if (!HHttpMessageCreator::create(*hdr, response)) { HLOG_WARN(QString("Failed to subscribe: %1.").arg(hdr->toString())); emit subscriptionFailed(this); return; } m_seq = 0; m_sid = response.sid(); m_subscribed = true; m_timeout = response.timeout(); HLOG_DBG(QString("Subscription to [%1] succeeded. Received SID: [%2]").arg( m_eventUrl.toString(), m_sid.toString())); if (!m_timeout.isInfinite()) { m_subscriptionTimer.start(m_timeout.value() * 1000 / 2); } emit subscribed(this); } void HEventSubscription::subscribe() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); switch(m_currentOpType) { case Op_None: if (m_subscribed) { return; } m_currentOpType = Op_Subscribe; break; case Op_Renew: case Op_Subscribe: if (m_nextOpType != Op_None) { m_nextOpType = Op_None; } return; case Op_Unsubscribe: m_nextOpType = Op_Subscribe; return; } if (!m_sid.isEmpty()) { HLOG_DBG("Ignoring subscription request, since subscription is already active"); return; } if (!connectToDevice()) { return; } m_eventUrl = resolveUri( extractBaseUrl(m_deviceLocations[m_nextLocationToTry]), m_service->info().eventSubUrl()); HMessagingInfo* mi = new HMessagingInfo(m_socket, false); mi->setHostInfo(m_eventUrl); HSubscribeRequest req( m_eventUrl, HSysInfo::instance().herqqProductTokens(), m_serverRootUrl.toString().append("/").append( m_randomIdentifier.toString().remove('{').remove('}')), m_desiredTimeout); QByteArray data = HHttpMessageCreator::create(req, *mi); HLOG_DBG(QString("Attempting to subscribe to [%1]").arg( m_eventUrl.toString())); if (!m_http.msgIo(mi, data)) { HLOG_WARN(QString( "Failed to subscribe to events @ [%1]: %2").arg( urlsAsStr(m_deviceLocations), m_socket.errorString())); emit subscriptionFailed(this); } } StatusCode HEventSubscription::processNotify(const HNotifyRequest& req) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG(QString("Processing notification [sid: %1, seq: %2].").arg( m_sid.toString(), QString::number(req.seq()))); if (m_sid != req.sid()) { HLOG_WARN(QString("Invalid SID [%1]").arg(req.sid().toString())); return PreconditionFailed; } qint32 seq = req.seq(); if (seq != m_seq) { HLOG_WARN(QString( "Received sequence number is not expected. Expected [%1], got [%2]. " "Re-subscribing...").arg( QString::number(m_seq), QString::number(seq))); // in this case the received sequence number does not match to what is // expected. UDA instructs to re-subscribe in this scenario. resubscribe(); return PreconditionFailed; } HDefaultClientService* srv = static_cast(m_service); // TODO, this should not be necessary, or it should be done elsewhere. if (srv->updateVariables(req.variables(), m_seq > 0)) { HLOG_DBG(QString( "Notify [sid: %1, seq: %2] OK. State variable(s) were updated.").arg( m_sid.toString(), QString::number(m_seq))); ++m_seq; return Ok; } HLOG_WARN(QString("Notify failed. State variable(s) were not updated.")); return InternalServerError; } StatusCode HEventSubscription::onNotify(const HNotifyRequest& req) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); if (!m_subscribed) { if (m_currentOpType == Op_Subscribe || m_currentOpType == Op_Renew) { m_queuedNotifications.append(req); return Ok; } else { HLOG_WARN("Ignoring notify: subscription inactive."); return PreconditionFailed; } } return processNotify(req); } void HEventSubscription::unsubscribe_done(HHttpAsyncOperation* /*op*/) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(!m_sid.isEmpty()); Q_ASSERT(m_currentOpType == Op_Unsubscribe); HLOG_DBG(QString("Subscription to [%1] canceled").arg( m_eventUrl.toString())); resetSubscription(); emit unsubscribed(this); } void HEventSubscription::unsubscribe(qint32 msecsToWait) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); switch(m_currentOpType) { case Op_None: if (!m_subscribed) { return; } m_currentOpType = Op_Unsubscribe; break; case Op_Renew: case Op_Subscribe: m_nextOpType = Op_Unsubscribe; return; case Op_Unsubscribe: if (m_nextOpType != Op_None) { m_nextOpType = Op_None; } return; default: Q_ASSERT(false); } Q_ASSERT(m_sid.isValid()); Q_ASSERT(!m_eventUrl.isEmpty()); m_subscriptionTimer.stop(); if (!connectToDevice(msecsToWait)) { return; } m_eventUrl = resolveUri( extractBaseUrl(m_deviceLocations[m_nextLocationToTry]), m_service->info().eventSubUrl()); HLOG_DBG(QString( "Attempting to cancel event subscription from [%1]").arg( m_eventUrl.toString())); HMessagingInfo* mi = new HMessagingInfo(m_socket, false); mi->setHostInfo(m_eventUrl); HUnsubscribeRequest req(m_eventUrl, m_sid); QByteArray data = HHttpMessageCreator::create(req, mi); if (!m_http.msgIo(mi, data)) { HLOG_WARN(QString( "Encountered an error during subscription cancellation: %1").arg( mi->lastErrorDescription())); // if the unsubscription "failed", there's nothing much to do, but to log // the error and perhaps to retry. Then again, UPnP has expiration mechanism // for events and thus even if the device failed to process the request, eventually // the subscription will expire. resetSubscription(); emit unsubscribed(this); } } HEventSubscription::SubscriptionStatus HEventSubscription::subscriptionStatus() const { HLOG2(H_AT, H_FUN, m_loggingIdentifier); if (m_subscribed) { return Status_Subscribed; } if (m_currentOpType == Op_Subscribe || m_currentOpType == Op_Renew) { return Status_Subscribing; } return Status_Unsubscribed; } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint.h0000644000000000000000000011623611543637310023723 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCONTROLPOINT_H_ #define HCONTROLPOINT_H_ #include #include #include class QNetworkReply; class QAuthenticator; namespace Herqq { namespace Upnp { class HControlPointPrivate; class HControlPointConfiguration; /*! * \brief This is a class for discovering and interacting with UPnP devices in the network. * * \headerfile hcontrolpoint.h HControlPoint * * \ingroup hupnp_devicehosting * * According to the UPnP Device Architecture specification, a control point is an * entity, which "retrieves device and service descriptions, sends actions to * services, polls for service state variables, and receives events from services" . * In other words, a UPnP control point discovers UPnP devices, queries their state, * listens their asynchronous events and invokes them to perform actions. A * control point is the \em client in the UPnP architecture, whereas a UPnP * device is the \em server. * * \c %HControlPoint does all of the above, but mostly hiding it from the user if * the user wishes so. * To discover UPnP devices all you need to do is create an instance of * \c %HControlPoint, initialize it by calling init() and check if devices are * already found by calling rootDevices(), devices() or device(). * You can also listen for a number of events, such as: * - HControlPoint::rootDeviceOnline(), which is emitted when a UPnP * device has become available on the network. * - HControlPoint::rootDeviceOffline(), which is emitted when a UPnP device in * control of the control point has gone offline. * - HControlPoint::rootDeviceRemoved(), which is emitted when a control point has * removed and deleted an HClientDevice. Note, an HClientDevice is never deleted without * an explicit request from a user. See removeRootDevice() for further information. * * Consider an example: * * \code * * // myclass.h * #include * * class MyClass : * public QObject * { * Q_OBJECT * * private: * * Herqq::Upnp::HControlPoint* m_controlPoint; * * private slots: * * void rootDeviceOnline(Herqq::Upnp::HClientDevice*); * void rootDeviceOffline(Herqq::Upnp::HClientDevice*); * * public: * * MyClass(QObject* parent = 0); * }; * * // myclass.cpp * * #include "myclass.h" * #include * * MyClass::MyClass(QObject* parent) : * QObject(parent), m_controlPoint(new Herqq::Upnp::HControlPoint(this)) * { * connect( * m_controlPoint, * SIGNAL(rootDeviceOnline(Herqq::Upnp::HClientDevice*)), * this, * SLOT(rootDeviceOnline(Herqq::Upnp::HClientDevice*))); * * connect( * m_controlPoint, * SIGNAL(rootDeviceOffline(Herqq::Upnp::HClientDevice*)), * this, * SLOT(rootDeviceOffline(Herqq::Upnp::HClientDevice*))); * * if (!m_controlPoint->init()) * { * // the initialization failed, perhaps you should do something? * // for starters, you can call error() to check the error type and * // errorDescription() for a human-readable description of * // the error that occurred. * return; * } * * // the control point is running and any standard-compliant UPnP device * // on the same network should now be discoverable. * * // remember also that the current thread has to have an event loop * } * * void MyClass::rootDeviceOnline(Herqq::Upnp::HClientDevice* newDevice) * { * // device discovered, should something be done with it? Perhaps we want * // to learn something from it: * Herqq::Upnp::HDeviceInfo info = newDevice->info(); * // do something with the info object * } * * void MyClass::rootDeviceOffline(Herqq::Upnp::HClientDevice* rootDevice) * { * // device announced that it is going away and the control point sends * // a notification of this. However, the device isn't removed from the * // control point until explicitly requested: * * m_controlPoint->removeRootDevice(rootDevice); * } * * \endcode * * Once you have obtained a pointer to a HClientDevice you can * enumerate its services, invoke its actions, listen for events of changed * state and so on. Basically, a root \c %HClientDevice object at the control * point side is an entry point to a very accurate object model depicting the * real root UPnP device that has been discovered. For more information about * the \c %HClientDevice and the object model, see the page detailing the * HUPnP \ref hupnp_devicemodel. * * You can call quit() to stop an initialized control point instance from listening * the network and to clear its state. * * \remarks * \li This class has thread affinity. You have to use it and destroy it in the * thread in which it is located. * \li You can use \c QObject::moveToThread() on the \c %HControlPoint, which causes * the control point and every object managed by it to be moved to the chosen thread. * However, you cannot move individual objects managed by \c %HControlPoint. * \li a control point never transfers the ownership of the HClientDevice objects it manages. * \li %HControlPoint always destroys every %HClientDevice it manages when it is * being destroyed. * * \warning See notes about object deletion in ~HControlPoint(). * * \sa HClientDevice, HClientDevices, hupnp_devicemodel */ class H_UPNP_CORE_EXPORT HControlPoint : public QObject { Q_OBJECT H_DISABLE_COPY(HControlPoint) H_DECLARE_PRIVATE(HControlPoint) protected: /*! * \brief This enumeration specifies the actions to take when a device has been * discovered. * * \sa acceptRootDevice() */ enum DeviceDiscoveryAction { /*! * Ignores the device. * * In case the discovered device is a new device * this value instructs the control point to ignore and delete it. * * In case the discovered device is already in the control of the control * point this value instructs the control point to ignore it. However, * the device is not removed from the control point. To do that you have * to call removeRootDevice(). */ IgnoreDevice, /*! * Adds a new device into the control point and retains an existing device * in the control point. * * In case the discovered device is a new device the new device is * added into the \c %HControlPoint. Otherwise the device is already in * the control point and nothing is done. * * The control point will not subscribe to events. */ AddDevice, /*! * Adds the device into the control point and subscribes to evented services * according to the configuration of the control point. * * In case the discovered device is a new device the new device is * added into the \c %HControlPoint. Otherwise the device is already in * the control point and nothing is done in this regard. * * The control point determines whether to subscribe to events based on * its configuration. Default configuration instructs the control point * to subscribe to all events. The same is done if no configuration was * provided. */ AddDevice_SubscribeEventsIfConfigured, /*! * Adds the device into the control point and subscribes to all * evented services. * * In case the discovered device is a new device the new device is * added into the \c %HControlPoint. Otherwise the device is already in * the control point and nothing is done in this regard. * * The control points subscribes to all evented services contained by the * device and its embedded devices. */ AddDevice_SubscribeAllEvents }; public: /*! * \brief This enumeration specifies error types some of the methods of * \c %HControlPoint may return. */ enum ControlPointError { /*! * General failure or no error. * * This error code is used to indicate that either: * - the exact cause for an error could not be determined or * - no error has occurred. */ UndefinedError, /*! * Control point is not initialized. * * This error code is used to indicate that the control point has not been * initialized. */ NotInitializedError, /*! * Control point is already initialized. * * This error code is used to indicate that the control point is already * initialized. */ AlreadyInitializedError, /*! * Networking error. * * This error code is used to indicate that an error occurred in some * networking component, such as in HTTP server or in SSDP module. */ CommunicationsError, /*! * Argument error. * * This error code is used to indicate that a member function * was called with an invalid argument and the call was aborted. */ InvalidArgumentError }; /*! * \brief This enumeration is used to describe the status of an event subscription. * * \sa subscriptionStatus() */ enum SubscriptionStatus { /*! * No subscription exists for the specified service. * * This value is used when there is no subscription or subscription attempt * being made to a specified service. */ Unsubscribed, /*! * A subscription attempt is in progress. * * This value is used when a subscription attempt to the events of the * specified service is in progress. * * \sa subscriptionSucceeded(), subscriptionFailed() */ Subscribing, /*! * A subscription is active. * * This value is used when the control point has successfully * subscribed to the events of the specified service. */ Subscribed }; /*! * */ /*enum ErrorType { };*/ private: /*! * Performs the initialization of a derived class. * * The \c %HControlPoint uses two-phase initialization in which the user * first constructs an instance and then calls init() in order to ready * the object for use. This method is called by the \c %HControlPoint * during its private initialization after all the private data structures * are constructed but before any network activity. At this point, no HTTP * or SSDP requests are served. * * You can override this method to perform any further initialization of a * derived class. * * \return \e true if and only if the initialization succeeded. * If \e false is returned the initialization of the control point is * aborted. In addition, it is advised that you call setError() * before returning. * * \remarks the default implementation does nothing. * * \sa init() */ virtual bool doInit(); /*! * Performs the de-initialization of a derived class. * * Since it is possible to shutdown a control point without actually destroying the * instance by calling quit(), derived classes have the possibility to * run their own shutdown procedure by overriding this method. * This method is called \b before the \c %HControlPoint cleans its * private data structures but after it has stopped listening requests * from the network. * * \remarks the default implementation does nothing. * * \sa quit() */ virtual void doQuit(); /*! * This method specifies the actions to take when a device has been * discovered. * * A discovered device may be a new device to the control point * or a device that is already in the control point. The latter scenario is * true when a device goes offline, is not removed from the * control point and later comes back online with the same UPnP configuration * (see UDA for more information about a UPnP device configuration). * * If you have derived a class from HControlPoint you have the option of * choosing whether a discovered device should be managed by the * control point, and whether the control point should subscribe to the events * published by the services of the device. To do this you have to * override this method. * * \note * - This method takes precedence over any configuration options provided * to the control point at the time of its construction * - This method is called when: * - a new root HClientDevice has been built and * - a previously known device comes back online with the same UPnP device * configuration value it had before it went offline. * * \param device specifies the discovered device. * * \return value indicating what should be done with the specified device. * * By default every successfully built device will be added to the control * point and its events are subscribed according to the control point * configuration. * * \sa DeviceDiscoveryAction() */ virtual DeviceDiscoveryAction acceptRootDevice(HClientDevice* device); /*! * This method is called whenever a new a device has been detected on * the network. * * Override this method in case you want to control which devices get built. * * Every UPnP \e resource belongs to a UPnP device tree, and every \e advertisement * and \e notification of a \e resource contains all the information needed * to build a full model of the device tree. An \e advertisement * is sent by a UPnP device to advertise itself, its embedded devices or * any of the services contained within the device tree. A \e notification * is the response from a UPnP device to a discovery sent by a control point. * * If an advertisement or a notification is received that identifies a resource * belonging to a device that is currently not in the control of this control point, * this method is called. If you accept the specified resource the * control point will retrieve all the information from the target UPnP device * to build a device model of the device tree the UPnP device represents. * * \note once you have accepted a resource from a particular UPnP device, * this method will not be called again for other resource advertisements or * notifications from the UPnP device. On the other hand, if you do not accept * a resource and the same UPnP device sends another * notification or advertisement, this method will be called again. * * \param usn contains information about the resource. * \param source specifies the source of the advertisement. * * \return \e true when the resource is accepted and a device model should * be built for the UPnP device that sent the notification / advertisement. * If the device is built successfully the acceptRootDevice() will be called. * By default every new device is accepted, built and added into an * \c %HControlPoint. */ virtual bool acceptResource( const HDiscoveryType& usn, const HEndpoint& source); protected: HControlPointPrivate* h_ptr; // // \internal // HControlPoint( HControlPointPrivate& dd, const HControlPointConfiguration* config = 0, QObject* parent = 0); /*! * \brief Returns the configuration used to initialize the control point. * * \return The configuration used to initialize the control point. * * \note If no configuration was provided at the time of object construction * the control point creates a default configuration and uses that. * This method \b always returns a pointer to a valid object, even if the * control point is not initialized. * * \remarks the returned object is not a copy and the ownership of the * object is \b not transferred. Do \b not delete the object. */ const HControlPointConfiguration* configuration() const; /*! * \brief Sets the type and description of the last occurred error. * * \param error specifies the error type. * \param errorDescr specifies a human readable description of the error. * * \sa error(), errorDescription() */ void setError(ControlPointError error, const QString& errorDescr); public: /*! * \brief Creates a new instance. * * \param parent specifies the parent \c QObject, if any. * * \sa HControlPointConfiguration * * \remarks the created control point creates and uses a default * configuration. */ HControlPoint(QObject* parent = 0); /*! * \brief Creates a new instance. * * \param configuration specifies information that can be used to modify the * default behavior of the control point instance. If you want to use * the default configuration, you should use the default constructor. * * \param parent specifies the parent \c QObject, if any. * * \sa HControlPointConfiguration */ HControlPoint( const HControlPointConfiguration& configuration, QObject* parent = 0); /*! * Destroys the control point and every hosted device. * * \warning When a control point is being destroyed the control point * destroys all of its child objects. You should discard any pointers retrieved * from the control point to prevent accidental dereference. * * \remarks An \c %HControlPoint instance has to be destroyed in the thread * in which it is located. */ virtual ~HControlPoint(); /*! * Initializes the control point. * * This has to be called for the control point to start * monitoring the network for UPnP devices. To stop an initialized control point * instance from listening network events you can call quit() or delete * the object. * * \note * By default an \c %HControlPoint instance performs a device * discovery upon initialization. However, you can override this * in the configuration. * * \return \e true if the initialization of the control point succeeded. * If \e false is returned you can call error() to get the type of the error, * and you can call errorDescription() to get a human-readable description of the error. * * \sa quit(), error(), errorDescription() */ bool init(); /*! * \brief Returns the type of the last error occurred. * \return The type of the last error occurred. */ ControlPointError error() const; /*! * \brief Returns a human readable description of the last error occurred. * \return a human readable description of the last error occurred. */ QString errorDescription() const; /*! * \brief Indicates whether or not the host is successfully started. * * \return true in case the host is successfully started. */ bool isStarted() const; /*! * \brief Returns a device with the specified Unique Device Name that the * control point is currently managing. * * \param udn specifies the Unique Device Name of the desired device. * \param deviceType specifies whether the search should consider root * devices only. The default is to search root devices only. * * \return The device with the specified Unique Device Name, or a * null pointer in case no currently managed device has the * specified UDN. * * \warning the returned device will be deleted at the latest when the * control point is being destroyed. In addition, you can call * removeRootDevice() to remove and delete a \b root device. However, the call * will fail if you pass it an embedded device. Moreover, do not delete a * device object directly. The ownership of an HClientDevice is \b never * transferred. * * \remarks This method does not perform a network scan. The search is run * against the devices that are already in the control of the control point. * You can call scan() to perform an explicit network scan. */ HClientDevice* device( const HUdn& udn, TargetDeviceType deviceType = RootDevices) const; /*! * \brief Returns a list of UPnP root devices the control point is currently managing. * * The returned list contains pointers to root HClientDevice objects that are currently * managed by this instance. * * \return a list of pointers to root HClientDevice objects the control point * is currently managing. * * \warning the returned devices will be deleted at the latest when the * control point is being destroyed. In addition, you can call * removeRootDevice() to remove and delete a root device. However, do not delete * the device objects directly. The ownership of an HClientDevice is \b never * transferred. * * \remarks This method does not perform a network scan. */ HClientDevices rootDevices() const; /*! * \brief Returns a list of UPnP devices the control point is currently managing and * that match the provided search criteria. * * The returned list contains pointers to HClientDevice objects that are currently * managed by this instance. It is important to note that unlike the method * rootDevices() this method may return pointers to both root and * embedded devices. * * \param deviceType specifies the UPnP device type to be searched. * \param versionMatch specifies how the version information in argument * \c deviceType should be used. The default is inclusive match, * which essentially means that any device with a device type version that * is \b less than or \b equal to the version specified in argument * \c deviceType is successfully matched. * \param deviceTypes specifies whether the search should consider root * devices only. The default is to search root devices only. * * \return a list of pointers to HClientDevice objects the control point * is currently managing. * * \warning the returned devices will be deleted at the latest when the * control point is being destroyed. In addition, you can call * removeRootDevice() to remove and delete a \b root device. However, the call * will fail if you pass it an embedded device. Moreover, do not delete the * device objects directly. The ownership of an HClientDevice is \b never transferred. * * \remarks This method does not perform a network scan. The search is run * against the devices that are already in the control of the control point. * You can call scan() to perform an explicit network scan. */ HClientDevices devices( const HResourceType& deviceType, HResourceType::VersionMatch versionMatch = HResourceType::Inclusive, TargetDeviceType deviceTypes = RootDevices); /*! * Removes the root device from the control point and deletes it. * * \param rootDevice specifies the root device to be removed. Nothing is done if * the device is not in the control of this control point or the device is * not a root device. * * \retval true in case the device was successfully removed and deleted. * \retval false in case: * - the specified argument was null, * - the specified device is not managed by this control point or * - the specified device is not a root device. * * \remarks * the specified object is deleted if and only if the method returns \e true. * * \sa error(), errorDescription() */ bool removeRootDevice(HClientDevice* rootDevice); /*! * Subscribes to events of the specified services contained by the * specified device. * * You can use this method to subscribe to events of multiple evented services * contained by the specified device at once. * * \param device specifies the device that contains the services, which * events are subscribed. * * \param visitType specifies how the device tree is traversed. A subscription * is sent to every service of every visited device. * * \retval true in case the subscriptions were successfully * dispatched. Note, \b any subscription may still fail. You can connect to * subscriptionSucceeded() and subscriptionFailed() signals to be notified * upon subscription success and failure. * * \retval false in case the specified argument * is null or it does not belong to a device held by the control point. * * \remarks * - services which events are already subscribed to are skipped. * - the method returns immediately. Every successful subscription results * in subscriptionSucceeded() signal sent. Every failed subscription results in * subscriptionFailed() signal sent. * - every subscription is maintained until: * - an error occurs * - it is explicitly canceled * * Thus, a subscription is automatically renewed before expiration until * an error occurs or it is canceled. * * \sa error(), errorDescription() */ bool subscribeEvents( HClientDevice* device, DeviceVisitType visitType); /*! * Subscribes to the events of the service. * * \param service specifies the service * * \retval true in case the subscription request was successfully * dispatched. Note, the subscription \b may still fail. You can connect to * subscriptionSucceeded() and subscriptionFailed() signals to be notified * upon subscription success and failure. * * \retval false in case the specified argument: * - is null, * - it does not belong to a device held by the control point, * - is not evented or * - there already exists a subscription for the specified service. * * \remarks * - the method returns immediately. A successful subscription results * in subscriptionSucceeded() signal sent. A failed subscription results in * subscriptionFailed() signal sent. * - a subscription is maintained by the control point until: * - an error occurs * - it is explicitly canceled * * Thus, a subscription is automatically renewed before expiration until * an error occurs or it is canceled. * * \sa error(), errorDescription() */ bool subscribeEvents(HClientService* service); /*! * Checks if there exists a subscription to the events of the specified service. * * \param service specifies the service to be checked. * * \retval HControlPoint::Unsubscribed when the service is not * evented or there is no active susbcription or subscription attempt going * on to the specified service. * * \retval HControlPoint::Subscribing when the service is * evented and an subscription attempt is being made to the specified service. * * \retval HControlPoint::Subscribed when there exists an active * subscription to the specified service. */ SubscriptionStatus subscriptionStatus(const HClientService* service) const; /*! * Cancels the event subscriptions of every service contained by the device. * * Any services which events are not subscribed are skipped. * * \param device specifies the device that contains the services, which * subscriptions are canceled. * * \param visitType specifies how the device tree is traversed. * A subscription cancellation request is sent to every service of * every visited device. * * \retval true in case the cancellation request of a subscription * was successfully dispatched. Note, this does not mean that the cancellation * was successfully received and handled by the UPnP device in question. * Upon success the state of the control point instance is modified * appropriately, but it is never guaranteed that the * target UPnP device receives or processes the cancellation request. * * \retval false in case * - the specified argument is null, * - the device is not managed by this control point or * - there were no active subscriptions matching the search criteria * to cancel. * * \remarks This method returns immediately. * * \sa error(), errorDescription() */ bool cancelEvents(HClientDevice* device, DeviceVisitType visitType); /*! * Cancels the event subscription of the service. * * \param service specifies the service, which event subscription is * to be canceled. * * \retval true in case the cancellation request of a subscription * was successfully dispatched. Note, this does not mean that the cancellation * was successfully received and handled by the UPnP device in question. * Upon success the state of the control point instance is modified * appropriately, but it is never guaranteed that the * target UPnP device receives or processes the cancellation request. * * \retval false in case * - the specified argument is null, * - the service does not belong to a device held by the control point or * - there is no active subscription to the specified service. * * \remarks This method returns immediately. * * \sa error(), errorDescription() */ bool cancelEvents(HClientService* service); /*! * Scans the network for resources of interest. * * Using the default configuration \c %HControlPoint automatically searches * and adds every device it finds. In that case the device list returned * by rootDevices() usually reflects the UPnP device status of the network. * However, there are situations where you may want to explicitly ask * the \c %HControlPoint to update its status and you can call this method * to do that. * * \param discoveryType specifies the type of the discovery to perform. * \param count specifies how many times the discovery should be performed. * The number translates directly to the number of SSDP messages send. The * default is 1. * * \remarks * \li This method returns immediately. * \li As a result of this call there may be any number of rootDeviceOnline() * signals emitted as a consequence of newly found devices. * \li The call will not affect the expiration of existing devices. * More specifically, any device that does not respond * to the scan will not be considered as expired and no rootDeviceOffline() * signals will be sent consequently. */ bool scan(const HDiscoveryType& discoveryType, qint32 count = 1); /*! * Scans the network for resources of interest. * * Using the default configuration \c %HControlPoint automatically searches * and adds every device it finds. In that case the device list returned * by rootDevices() usually reflects the UPnP device status of the network. * However, there are situations where you may want to explicitly ask * the \c %HControlPoint to perform a discovery on a specific TCP/IP * endpoint. In other words, you can perform a unicast device discovery using * this method. * * \param discoveryType specifies the type of the discovery to perform. * \param destination specifies the location where the discovery is sent. * If the port of the specified endpoint is set to zero the message is sent * to the specified host address using the default port 1900. * \param count specifies how many times the discovery should be performed. * The number translates directly to the number of SSDP messages send. The * default is 1. * * \remarks * \li This method returns immediately. * \li As a result of this call there may be any number of rootDeviceOnline() * signals emitted as a consequence of newly found devices. * \li The call will not affect the expiration of existing devices. * More specifically, any device that does not respond * to the scan will not be considered as expired and no rootDeviceOffline() * signals will be sent consequently. */ bool scan( const HDiscoveryType& discoveryType, const HEndpoint& destination, qint32 count = 1); public Q_SLOTS: /*! * Shuts down the control point. * * The control point stops listening for network events, * deletes all the devices it is hosting and cancels all event subscriptions. * In essence, the control point purges it state. You can re-initialize the * control point by calling init() again. * * \attention Every pointer to object retrieved from this instance will be * deleted. Be sure not to use any such pointer after calling this method. * * \sa init() */ void quit(); Q_SIGNALS: /*! * \brief This signal is emitted whenever a final server requests authentication * before it delivers the requested contents. * * \brief This signal is relayed from the underlying \c QNetworkAccessManager, * which is used by the \c %HControlPoint to run HTTP messaging. * As specified in the reference documentation of QNetworkAccessManager, * the slot connected to this signal should fill the credentials * for the contents (which can be determined by inspecting the reply object) * in the authenticator object. \c QNetworkAccessManager will cache the * credentials internally and will send the same values if the server * requires authentication again, without emitting the authenticationRequired() signal. * If it rejects the credentials, this signal will be emitted again. * * \param reply specifies the requested contents. * * \param authenticator specifies the authenticator object to which the * user should fill in the credentials. */ void authenticationRequired( QNetworkReply* reply, QAuthenticator* authenticator); /*! * \brief This signal is emitted when the initial subscription to the specified * service succeeded. * * \param service specifies the target service of the event subscription. * * \sa subscriptionFailed() */ void subscriptionSucceeded(Herqq::Upnp::HClientService* service); /*! * \brief This signal is emitted when an event subscription to the specified * service failed. * * \note this signal may be emitted in three different scenarios: * - the initial subscription failed * - an automatic subscription renewal failed * - a re-subscription failed * If you want to try to re-subscribe to the service you can * call subscribe() again. * * \param service specifies the service, which event subscription * failed. * * \sa subscriptionSucceeded() */ void subscriptionFailed(Herqq::Upnp::HClientService* service); /*! * \brief This signal is emitted when an event subscription to the specified * service has been canceled. * * \param service specifies the service, which subscription was canceled. */ void subscriptionCanceled(Herqq::Upnp::HClientService* service); /*! * \brief This signal is emitted when a device has been discovered. * * \param device is the discovered device. * * \remarks the discovered device may already be managed by this instance. * This is the case when a device goes offline and comes back online before * it is removed from the control point. * * \sa rootDeviceOffline(), removeRootDevice() */ void rootDeviceOnline(Herqq::Upnp::HClientDevice* device); /*! * \brief This signal is sent when a root device has announced that it is going * offline or the expiration timeout associated with the device tree has elapsed. * * After a device has gone offline you may want to remove the device from the * control point using removeRootDevice(). Alternatively, if you do not remove the * device and the device comes back online later: * * \li a rootDeviceOnline() signal is emitted in case the device uses the * same configuration as it did before going offline or * * \li a rootDeviceInvalidated() signal is emitted in case the device uses * a different configuration as it did before going offline. If this is the case * you should remove the device as it no longer reflects the real device * accurately. * * \param device is the device that went offline and is not reachable * at the moment. * * \sa rootDeviceOnline(), rootDeviceInvalidated(), removeRootDevice() */ void rootDeviceOffline(Herqq::Upnp::HClientDevice* device); /*! * \brief This signal is emitted when a previously discovered device has changed its * configuration and must be discarded. * * The UDA v1.1 specifies the configuration of a root device to consist of * the device description documents of all the devices in the device tree and * all the service description documents of the services in the device tree. * If the configuration changes the old device tree has to be discarded in * place of the new one. * * After this signal is emitted the specified HClientDevice object has become * invalid and should be discarded and removed immediately. * In addition, rootDeviceOnline() signal may be emitted shortly after this * signal, but only when the new configuration of the device is accepted * by this instance. * * \param device is the device that has been invalidated. */ void rootDeviceInvalidated(Herqq::Upnp::HClientDevice* device); /*! * \brief This signal is emitted when a root device has been removed from the control * of this control point and deleted. * * \param deviceInfo specifies information about the device that was removed * and deleted. * * \sa rootDeviceOffline() */ void rootDeviceRemoved(const Herqq::Upnp::HDeviceInfo& deviceInfo); /*! * \brief This signal is emitted when a run-time error has occurred. * * \param err specifies the type of the error that occurred * \param errStr specifies a human-readable description of the error that * occurred. */ //void error(ErrorType err, const QString& errStr); }; } } #endif /* HCONTROLPOINT_H_ */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint.cpp0000644000000000000000000007533011543637310024255 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hcontrolpoint.h" #include "hcontrolpoint_p.h" #include "hevent_subscription_p.h" #include "hclientmodel_creator_p.h" #include "hcontrolpoint_configuration.h" #include "hcontrolpoint_configuration_p.h" #include "hcontrolpoint_dataretriever_p.h" #include "../../general/hupnp_global_p.h" #include "../../general/hupnp_datatypes_p.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hdiscoverytype.h" #include "../../dataelements/hproduct_tokens.h" #include "../../devicemodel/client/hdefault_clientdevice_p.h" #include "../../devicemodel/client/hdefault_clientservice_p.h" #include "../../http/hhttp_messagecreator_p.h" #include "../../general/hlogger_p.h" #include "../../utils/hsysutils_p.h" #include #include #include static bool registerMetaTypes() { qRegisterMetaType("Herqq::Upnp::HUdn"); return true; } static bool test = registerMetaTypes(); namespace Herqq { namespace Upnp { /******************************************************************************* * ControlPointHttpServer ******************************************************************************/ ControlPointHttpServer::ControlPointHttpServer(HControlPointPrivate* owner) : HHttpServer(owner->m_loggingIdentifier, owner), m_owner(owner) { Q_ASSERT(m_owner); } ControlPointHttpServer::~ControlPointHttpServer() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); close(); } void ControlPointHttpServer::incomingNotifyMessage( HMessagingInfo* mi, const HNotifyRequest& req) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); HLOG_DBG(QString( "Incoming event notify from [%1]").arg(peerAsStr(mi->socket()))); QString serviceCallbackId = req.callback().path().remove('/'); StatusCode statusCode = m_owner->m_eventSubscriber->onNotify(serviceCallbackId, req); if (statusCode != Ok) { mi->setKeepAlive(false); } m_httpHandler->send(mi, HHttpMessageCreator::createResponse(statusCode, *mi)); } /******************************************************************************* * HControlPointSsdpHandler ******************************************************************************/ HControlPointSsdpHandler::HControlPointSsdpHandler( HControlPointPrivate* owner) : HSsdp(owner->m_loggingIdentifier, owner), m_owner(owner) { setFilter(DiscoveryResponse | DeviceUnavailable | DeviceAvailable); } HControlPointSsdpHandler::~HControlPointSsdpHandler() { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); } bool HControlPointSsdpHandler::incomingDiscoveryResponse( const HDiscoveryResponse& msg, const HEndpoint& source) { return m_owner->processDeviceDiscovery(msg, source, this); } bool HControlPointSsdpHandler::incomingDeviceAvailableAnnouncement( const HResourceAvailable& msg, const HEndpoint& source) { return m_owner->processDeviceDiscovery(msg, source, this); } bool HControlPointSsdpHandler::incomingDeviceUnavailableAnnouncement( const HResourceUnavailable& msg, const HEndpoint& source) { return m_owner->processDeviceOffline(msg, source, this); } /******************************************************************************* * HControlPointPrivate ******************************************************************************/ HControlPointPrivate::HControlPointPrivate() : QObject(), m_deviceBuildTasks(), m_loggingIdentifier( QString("__CONTROL POINT %1__: ").arg( QUuid::createUuid().toString()).toLocal8Bit()), m_configuration(), m_ssdps(), m_server(0), m_eventSubscriber(0), m_lastError(HControlPoint::UndefinedError), q_ptr(0), m_nam(new QNetworkAccessManager(this)), m_state(HControlPointPrivate::Uninitialized), m_threadPool(new HThreadPool(this)), m_deviceStorage(m_loggingIdentifier) { } HControlPointPrivate::~HControlPointPrivate() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); } HDefaultClientDevice* HControlPointPrivate::buildDevice( const QUrl& deviceLocation, qint32 maxAgeInSecs, QString* err) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HDataRetriever dataRetriever(m_loggingIdentifier); QString deviceDescr; if (!dataRetriever.retrieveDeviceDescription(deviceLocation, &deviceDescr)) { *err = dataRetriever.lastError(); return 0; } QList deviceLocations; deviceLocations.push_back(deviceLocation); HClientModelCreationArgs creatorParams(m_nam); creatorParams.m_deviceDescription = deviceDescr; creatorParams.m_deviceLocations = deviceLocations; creatorParams.m_serviceDescriptionFetcher = ServiceDescriptionFetcher( &dataRetriever, &HDataRetriever::retrieveServiceDescription); creatorParams.m_deviceTimeoutInSecs = maxAgeInSecs; creatorParams.m_iconFetcher = IconFetcher(&dataRetriever, &HDataRetriever::retrieveIcon); creatorParams.m_loggingIdentifier = m_loggingIdentifier; HClientModelCreator creator(creatorParams); HDefaultClientDevice* device = creator.createRootDevice(); if (!device && err) { *err = creator.lastErrorDescription(); } return device; } bool HControlPointPrivate::addRootDevice(HDefaultClientDevice* newRootDevice) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); HDefaultClientDevice* existingDevice = static_cast( m_deviceStorage.searchDeviceByUdn( newRootDevice->info().udn(), AllDevices)); if (existingDevice) { // it seems that the device we've built has already been added // (it is possible, although unlikely, we begin multiple device build // processes of the same device tree) // in this case we only make sure that the device's location list is // updated if necessary existingDevice = static_cast(existingDevice->rootDevice()); existingDevice->addLocations(newRootDevice->locations()); return false; } if (q_ptr->acceptRootDevice(newRootDevice) == HControlPoint::IgnoreDevice) { HLOG_DBG(QString("Device [%1] rejected").arg( newRootDevice->info().udn().toString())); return false; } newRootDevice->setParent(this); newRootDevice->startStatusNotifier(HDefaultClientDevice::All); bool ok = connect( newRootDevice, SIGNAL(statusTimeout(HDefaultClientDevice*)), this, SLOT(deviceExpired(HDefaultClientDevice*))); Q_ASSERT(ok); Q_UNUSED(ok) if (!m_deviceStorage.addRootDevice(newRootDevice)) { HLOG_WARN(QString( "Failed to add root device [UDN: %1]: %2").arg( newRootDevice->info().udn().toSimpleUuid(), m_deviceStorage.lastError())); return false; } emit q_ptr->rootDeviceOnline(newRootDevice); return true; } void HControlPointPrivate::deviceExpired(HDefaultClientDevice* source) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); // according to the UDA v1.1 a "device tree" (root, embedded and services) // are "timed out" only when every advertisement has timed out. source = static_cast(source->rootDevice()); if (source->isTimedout(HDefaultClientDevice::All)) { source->deviceStatus()->setOnline(false); m_eventSubscriber->cancel( source, VisitThisRecursively, false); emit q_ptr->rootDeviceOffline(source); } } void HControlPointPrivate::unsubscribed(HClientService* service) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(service); emit q_ptr->subscriptionCanceled(service); } bool HControlPointPrivate::processDeviceOffline( const HResourceUnavailable& msg, const HEndpoint& /*source*/, HControlPointSsdpHandler* /*origin*/) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); HDefaultClientDevice* device = static_cast( m_deviceStorage.searchDeviceByUdn(msg.usn().udn(), AllDevices)); if (!device) { // the device is not known by us. // note that even service announcements contain the "UDN", which identifies // the device that contains them. return true; } HLOG_INFO(QString("Resource [%1] is unavailable.").arg( msg.usn().resourceType().toString())); // according to the UDA v1.1 specification, if a bye bye message of any kind // is received, the control point can assume that nothing in that // device tree is available anymore HDefaultClientDevice* root = static_cast(device->rootDevice()); Q_ASSERT(root); root->deviceStatus()->setOnline(false); m_eventSubscriber->cancel(root, VisitThisRecursively, false); emit q_ptr->rootDeviceOffline(root); return true; } template bool HControlPointPrivate::processDeviceDiscovery( const Msg& msg, const HEndpoint& source, HControlPointSsdpHandler*) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); const HUdn& resourceUdn = msg.usn().udn(); HDefaultClientDevice* device = static_cast( m_deviceStorage.searchDeviceByUdn(msg.usn().udn(), AllDevices)); if (device) { // according to the UDA v1.1 spec, if a control point receives an // alive announcement of any type for a device tree, the control point // can assume that all devices and services are available. // ==> reset timeouts for entire device tree and all services. device = static_cast(device->rootDevice()); device->startStatusNotifier(HDefaultClientDevice::All); // it cannot be that only some embedded device is available at certain // interface, since the device description is always fetched from the // the location that the root device specifies ==> the entire device // tree has to be available at that location. if (device->addLocation(msg.location())) { HLOG_DBG(QString("Existing device [%1] now available at [%2]").arg( resourceUdn.toString(), msg.location().toString())); } if (!device->deviceStatus()->online()) { device->deviceStatus()->setOnline(true); emit q_ptr->rootDeviceOnline(device); processDeviceOnline(device, false); } return true; } // it does not matter if the device is an embedded device, since the // location of the device always points to the root device's description // and the internal device model is built of that. Hence, any advertisement // will do to build the entire model correctly. DeviceBuildTask* dbp = m_deviceBuildTasks.get(msg); if (dbp) { if (!dbp->m_locations.contains(msg.location())) { dbp->m_locations.push_back(msg.location()); } return true; } if (!q_ptr->acceptResource(msg.usn(), source)) { HLOG_DBG(QString("Resource advertisement [%1] rejected").arg( msg.usn().toString())); return true; } DeviceBuildTask* newBuildTask = new DeviceBuildTask(this, msg); newBuildTask->setAutoDelete(false); m_deviceBuildTasks.add(newBuildTask); bool ok = connect( newBuildTask, SIGNAL(done(Herqq::Upnp::HUdn)), this, SLOT(deviceModelBuildDone(Herqq::Upnp::HUdn))); Q_ASSERT(ok); Q_UNUSED(ok) HLOG_INFO(QString( "New resource [%1] is available @ [%2]. " "Attempting to build the device model.").arg( msg.usn().toString(), msg.location().toString())); m_threadPool->start(newBuildTask); return true; } void HControlPointPrivate::processDeviceOnline( HDefaultClientDevice* device, bool newDevice) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HControlPoint::DeviceDiscoveryAction actionToTake = q_ptr->acceptRootDevice(device); bool subscribe = false; switch(actionToTake) { case HControlPoint::IgnoreDevice: HLOG_DBG(QString("Discarding device with UDN %1").arg( device->info().udn().toString())); if (newDevice) { delete device; device = 0; } break; case HControlPoint::AddDevice: break; case HControlPoint::AddDevice_SubscribeEventsIfConfigured: subscribe = m_configuration->subscribeToEvents(); break; case HControlPoint::AddDevice_SubscribeAllEvents: subscribe = true; break; default: Q_ASSERT(false); break; }; if (device) { if (newDevice) { if (!addRootDevice(device)) { delete device; return; } } if (subscribe) { m_eventSubscriber->subscribe( device, VisitThisRecursively, m_configuration->desiredSubscriptionTimeout()); } } } void HControlPointPrivate::deviceModelBuildDone(const Herqq::Upnp::HUdn& udn) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); DeviceBuildTask* build = m_deviceBuildTasks.get(udn); Q_ASSERT(build); if (m_state == Initialized) { // The check is done because it is possible that a user has called // HControlPoint::quit() before this event is delivered. if (build->completionValue() == 0) { HLOG_INFO(QString("Device model for [%1] built successfully.").arg( udn.toString())); HDefaultClientDevice* device = build->createdDevice(); Q_ASSERT(device); for (qint32 i = 0; i < build->m_locations.size(); ++i) { device->addLocation(build->m_locations[i]); } processDeviceOnline(device, true); } else { HLOG_WARN(QString("Device model for [%1] could not be built: %2.").arg( udn.toString(), build->errorString())); } } m_deviceBuildTasks.remove(udn); } /******************************************************************************* * HControlPoint ******************************************************************************/ HControlPoint::HControlPoint(QObject* parent) : QObject(parent), h_ptr(new HControlPointPrivate()) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); h_ptr->m_configuration.reset(new HControlPointConfiguration()); h_ptr->setParent(this); h_ptr->q_ptr = this; bool ok = connect( h_ptr->m_nam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*))); Q_ASSERT(ok); Q_UNUSED(ok) } HControlPoint::HControlPoint( const HControlPointConfiguration& configuration, QObject* parent) : QObject(parent), h_ptr(new HControlPointPrivate()) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); h_ptr->m_configuration.reset(configuration.clone()); h_ptr->setParent(this); h_ptr->q_ptr = this; } HControlPoint::HControlPoint( HControlPointPrivate& dd, const HControlPointConfiguration* configuration, QObject* parent) : QObject(parent), h_ptr(&dd) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); h_ptr->m_configuration.reset(configuration ? configuration->clone() : new HControlPointConfiguration()); h_ptr->setParent(this); h_ptr->q_ptr = this; } HControlPoint::~HControlPoint() { quit(); delete h_ptr; } bool HControlPoint::doInit() { // the default implementation does nothing. return true; } void HControlPoint::doQuit() { // the default implementation does nothing. } HControlPoint::DeviceDiscoveryAction HControlPoint::acceptRootDevice( HClientDevice* /*device*/) { return AddDevice_SubscribeEventsIfConfigured; } bool HControlPoint::acceptResource( const HDiscoveryType& /*usn*/, const HEndpoint& /*source*/) { return true; } const HControlPointConfiguration* HControlPoint::configuration() const { return h_ptr->m_configuration.data(); } void HControlPoint::setError(ControlPointError error, const QString& errorStr) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); h_ptr->m_lastError = error; h_ptr->m_lastErrorDescription = errorStr; } bool HControlPoint::init() { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); Q_ASSERT_X( thread() == QThread::currentThread(), H_AT, "The control point has to be initialized in the thread in which it is " "currently located."); if (h_ptr->m_state == HControlPointPrivate::Initialized) { setError( AlreadyInitializedError, "The control point is already initialized"); return false; } Q_ASSERT(h_ptr->m_state == HControlPointPrivate::Uninitialized); bool ok = true; const QList addrs = h_ptr->m_configuration->networkAddressesToUse();; h_ptr->m_state = HControlPointPrivate::Initializing; HLOG_INFO("ControlPoint initializing."); h_ptr->m_eventSubscriber = new HEventSubscriptionManager(h_ptr); ok = connect( h_ptr->m_eventSubscriber, SIGNAL(subscribed(Herqq::Upnp::HClientService*)), this, SIGNAL(subscriptionSucceeded(Herqq::Upnp::HClientService*))); ok = connect( h_ptr->m_eventSubscriber, SIGNAL(subscriptionFailed(Herqq::Upnp::HClientService*)), this, SIGNAL(subscriptionFailed(Herqq::Upnp::HClientService*))); Q_ASSERT(ok); ok = connect( h_ptr->m_eventSubscriber, SIGNAL(unsubscribed(Herqq::Upnp::HClientService*)), h_ptr, SLOT(unsubscribed(Herqq::Upnp::HClientService*))); Q_ASSERT(ok); h_ptr->m_server = new ControlPointHttpServer(h_ptr); if (!doInit()) { // it is assumed that the derived class filled the error and // error description ok = false; goto end; } if (!h_ptr->m_server->init(convertHostAddressesToEndpoints(addrs))) { setError(CommunicationsError, "Failed to start HTTP server"); ok = false; goto end; } foreach(const QHostAddress& ha, addrs) { quint32 netwAddr; ok = HSysInfo::instance().localNetwork(ha, &netwAddr); Q_ASSERT(ok); HControlPointSsdpHandler* ssdp = new HControlPointSsdpHandler(h_ptr); if (!ssdp->init(ha)) { delete ssdp; setError(CommunicationsError, "Failed to start SSDP"); ok = false; goto end; } h_ptr->m_ssdps.append(qMakePair(netwAddr, ssdp)); } if (h_ptr->m_configuration->autoDiscovery()) { HLOG_DBG("Searching for UPnP devices"); for(qint32 i = 0; i < h_ptr->m_ssdps.size(); ++i) { QString ep = h_ptr->m_ssdps[i].second->unicastEndpoint().toString(); HLOG_DBG(QString( "Sending discovery request using endpoint [%1]").arg(ep)); qint32 messagesSent = h_ptr->m_ssdps[i].second->sendDiscoveryRequest( HDiscoveryRequest( 1, HDiscoveryType::createDiscoveryTypeForRootDevices(), HSysInfo::instance().herqqProductTokens())); if (!messagesSent) { HLOG_WARN(QString( "Failed to send discovery request using endpoint " "[%1]").arg(ep)); } } } else { HLOG_DBG("Omitting initial device discovery as configured"); } h_ptr->m_state = HControlPointPrivate::Initialized; end: if (!ok) { h_ptr->m_state = HControlPointPrivate::Exiting; quit(); HLOG_INFO("ControlPoint initialization failed."); return false; } setError(UndefinedError, ""); HLOG_INFO("ControlPoint initialized."); return true; } HControlPoint::ControlPointError HControlPoint::error() const { return h_ptr->m_lastError; } QString HControlPoint::errorDescription() const { return h_ptr->m_lastErrorDescription; } void HControlPoint::quit() { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); Q_ASSERT_X( thread() == QThread::currentThread(), H_AT, "The control point has to be shutdown in the thread in which it is " "currently located."); if (!isStarted()) { return; } HLOG_INFO("Shutting down."); h_ptr->m_state = HControlPointPrivate::Exiting; h_ptr->m_eventSubscriber->cancelAll(100); h_ptr->m_eventSubscriber->removeAll(); h_ptr->m_server->close(); h_ptr->m_threadPool->shutdown(); doQuit(); delete h_ptr->m_server; h_ptr->m_server = 0; for(qint32 i = 0; i < h_ptr->m_ssdps.size(); ++i) { delete h_ptr->m_ssdps[i].second; h_ptr->m_ssdps[i].second = 0; } h_ptr->m_ssdps.clear(); h_ptr->m_deviceStorage.clear(); delete h_ptr->m_eventSubscriber; h_ptr->m_eventSubscriber = 0; h_ptr->m_state = HControlPointPrivate::Uninitialized; HLOG_INFO("Shut down."); } bool HControlPoint::isStarted() const { return h_ptr->m_state == HControlPointPrivate::Initialized; } HClientDevices HControlPoint::rootDevices() const { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { HLOG_WARN("The control point is not started"); return HClientDevices(); } return h_ptr->m_deviceStorage.rootDevices(); } HClientDevices HControlPoint::devices( const HResourceType& deviceType, HResourceType::VersionMatch vm, TargetDeviceType dts) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { HLOG_WARN("The control point is not started"); return HClientDevices(); } return h_ptr->m_deviceStorage.searchDevicesByDeviceType(deviceType, vm, dts); } HClientDevice* HControlPoint::device( const HUdn& udn, TargetDeviceType dts) const { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { HLOG_WARN("The control point is not started"); return 0; } return h_ptr->m_deviceStorage.searchDeviceByUdn(udn, dts); } bool HControlPoint::subscribeEvents( HClientDevice* device, DeviceVisitType visitType) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotInitializedError, "The control point is not initialized"); return false; } else if (!device) { setError(InvalidArgumentError, "Null pointer error"); return false; } else if (!h_ptr->m_deviceStorage.searchDeviceByUdn( device->info().udn(), AllDevices)) { setError(InvalidArgumentError, "The specified device was not found in this control point"); return false; } bool ok = h_ptr->m_eventSubscriber->subscribe( device, visitType, h_ptr->m_configuration->desiredSubscriptionTimeout()); if (!ok) { setError( InvalidArgumentError, "Could not subscribe to any of the services contained by the device; " "The device may not have services or none of them are evented, or " "there is active subscription to every one of them already"); return false; } return true; } bool HControlPoint::subscribeEvents(HClientService* service) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotInitializedError, "The control point is not initialized"); return false; } else if (!service) { setError(InvalidArgumentError, "Null pointer error"); return false; } else if (!h_ptr->m_deviceStorage.searchDeviceByUdn( service->parentDevice()->info().udn(), AllDevices)) { setError(InvalidArgumentError, "The specified service was not found in this control point"); return false; } HEventSubscriptionManager::SubscriptionResult res = h_ptr->m_eventSubscriber->subscribe( static_cast(service), h_ptr->m_configuration->desiredSubscriptionTimeout()); switch(res) { case HEventSubscriptionManager::Sub_Success: return true; case HEventSubscriptionManager::Sub_AlreadySubscribed: setError( InvalidArgumentError, "Already subscribed to the specified service"); break; case HEventSubscriptionManager::Sub_Failed_NotEvented: setError( InvalidArgumentError, "The specified service is not evented"); break; default: Q_ASSERT(false); } return false; } HControlPoint::SubscriptionStatus HControlPoint::subscriptionStatus( const HClientService* service) const { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); return static_cast( h_ptr->m_eventSubscriber->subscriptionStatus(service)); } bool HControlPoint::cancelEvents( HClientDevice* device, DeviceVisitType visitType) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotInitializedError, "The control point is not initialized"); return false; } else if (!device) { setError(InvalidArgumentError, "Null pointer error"); return false; } else if (!h_ptr->m_deviceStorage.searchDeviceByUdn( device->info().udn(), AllDevices)) { setError( InvalidArgumentError, "The specified device was not found in this control point"); return false; } if (h_ptr->m_eventSubscriber->cancel(device, visitType, true)) { return true; } setError( InvalidArgumentError, "No active subscriptions to any of the services contained by the device"); return false; } bool HControlPoint::cancelEvents(HClientService* service) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotInitializedError, "The control point is not initialized"); return false; } else if (!service) { setError(InvalidArgumentError, "Null pointer error"); return false; } else if (!h_ptr->m_deviceStorage.searchDeviceByUdn( service->parentDevice()->info().udn(), AllDevices)) { setError( InvalidArgumentError, "The specified service was not found in this control point"); return false; } if (h_ptr->m_eventSubscriber->cancel(service, true)) { return true; } setError( InvalidArgumentError, "No active subscription to the specified service"); return false; } bool HControlPoint::removeRootDevice(HClientDevice* rootDevice) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotInitializedError, "The control point is not initialized"); return false; } else if (!rootDevice) { setError(InvalidArgumentError, "Null pointer error"); return false; } else if (rootDevice->parentDevice()) { setError(InvalidArgumentError, "Cannot remove embedded devices"); return false; } Q_ASSERT(thread() == QThread::currentThread()); h_ptr->m_eventSubscriber->remove(rootDevice, true); // TODO should send unsubscription to the UPnP device? HDeviceInfo info(rootDevice->info()); if (h_ptr->m_deviceStorage.removeRootDevice(rootDevice)) { emit rootDeviceRemoved(info); return true; } setError( InvalidArgumentError, "The device was not found in this control point"); return false; } bool HControlPoint::scan(const HDiscoveryType& discoveryType, qint32 count) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotInitializedError, "The control point is not initialized"); return false; } else if (discoveryType.type() == HDiscoveryType::Undefined) { setError(InvalidArgumentError, "Discovery type was undefined"); return false; } else if (count <= 0) { setError( InvalidArgumentError, "The number of messages has to be greater than zero"); return false; } for(qint32 i = 0; i < h_ptr->m_ssdps.size(); ++i) { QPair ssdp = h_ptr->m_ssdps[i]; HDiscoveryRequest req( 1, discoveryType, HSysInfo::instance().herqqProductTokens()); qint32 messagesSent = ssdp.second->sendDiscoveryRequest(req, count); if (messagesSent != count) { return false; } } return true; } bool HControlPoint::scan( const HDiscoveryType& discoveryType, const HEndpoint& destination, qint32 count) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (!isStarted()) { setError(NotInitializedError, "The control point is not initialized"); return false; } else if (discoveryType.type() == HDiscoveryType::Undefined) { setError(InvalidArgumentError, "Discovery type was undefined"); return false; } else if (count <= 0) { setError( InvalidArgumentError, "The number of messages has to be greater than zero"); return false; } for(qint32 i = 0; i < h_ptr->m_ssdps.size(); ++i) { QPair ssdp = h_ptr->m_ssdps[i]; HDiscoveryRequest req( 1, discoveryType, HSysInfo::instance().herqqProductTokens()); quint32 netAddr; bool ok = HSysInfo::instance().localNetwork( destination.hostAddress(), &netAddr); if (ok && netAddr == ssdp.first) { qint32 messagesSent = ssdp.second->sendDiscoveryRequest( req, destination, count); return messagesSent == count; } } return false; } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint_p.h0000644000000000000000000001144711543637310024240 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCONTROL_POINT_P_H_ #define HCONTROL_POINT_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hcontrolpoint.h" #include "hdevicebuild_p.h" #include "hevent_subscriptionmanager_p.h" #include "../hdevicestorage_p.h" #include "../../devicemodel/client/hclientdevice.h" #include "../../devicemodel/client/hclientservice.h" #include "../../ssdp/hssdp.h" #include "../../ssdp/hssdp_p.h" #include "../../http/hhttp_server_p.h" #include "../../ssdp/hdiscovery_messages.h" #include "../../utils/hthreadpool_p.h" #include #include #include namespace Herqq { namespace Upnp { class HControlPointPrivate; // // The HTTP server the control point uses to receive event notifications. // class ControlPointHttpServer : public HHttpServer { Q_OBJECT H_DISABLE_COPY(ControlPointHttpServer) private: HControlPointPrivate* m_owner; protected: virtual void incomingNotifyMessage(HMessagingInfo*, const HNotifyRequest&); public: explicit ControlPointHttpServer(HControlPointPrivate*); virtual ~ControlPointHttpServer(); }; // // // class HControlPointSsdpHandler : public HSsdp { H_DISABLE_COPY(HControlPointSsdpHandler) private: HControlPointPrivate* m_owner; protected: virtual bool incomingDiscoveryResponse( const HDiscoveryResponse&, const HEndpoint& source); virtual bool incomingDeviceAvailableAnnouncement( const HResourceAvailable&, const HEndpoint& source); virtual bool incomingDeviceUnavailableAnnouncement( const HResourceUnavailable&, const HEndpoint& source); public: HControlPointSsdpHandler(HControlPointPrivate*); virtual ~HControlPointSsdpHandler(); }; // // Implementation details of HControlPoint // class H_UPNP_CORE_EXPORT HControlPointPrivate : public QObject { Q_OBJECT H_DECLARE_PUBLIC(HControlPoint) H_DISABLE_COPY(HControlPointPrivate) friend class DeviceBuildTask; friend class HControlPointSsdpHandler; private: DeviceBuildTasks m_deviceBuildTasks; // this is accessed only from the thread in which all the HUpnp objects live. private Q_SLOTS: void deviceModelBuildDone(const Herqq::Upnp::HUdn&); private: bool addRootDevice(HDefaultClientDevice*); void subscribeToEvents(HDefaultClientDevice*); void processDeviceOnline(HDefaultClientDevice*, bool newDevice); bool processDeviceOffline( const HResourceUnavailable&, const HEndpoint& source, HControlPointSsdpHandler* origin); template bool processDeviceDiscovery( const Msg&, const HEndpoint& source, HControlPointSsdpHandler* origin); template bool shouldFetch(const Msg&); private Q_SLOTS: void deviceExpired(HDefaultClientDevice* source); void unsubscribed(Herqq::Upnp::HClientService*); public: const QByteArray m_loggingIdentifier; // the prefix shown before the actual log output QScopedPointer m_configuration; QList > m_ssdps; // the int is a ipv4 network address ControlPointHttpServer* m_server; HEventSubscriptionManager* m_eventSubscriber; HControlPoint::ControlPointError m_lastError; QString m_lastErrorDescription; // description of the error that occurred last HControlPoint* q_ptr; QNetworkAccessManager* m_nam; enum InitState { Exiting = -1, Uninitialized = 0, Initializing = 1, Initialized = 2 }; volatile InitState m_state; HThreadPool* m_threadPool; HDeviceStorage m_deviceStorage; HControlPointPrivate(); virtual ~HControlPointPrivate(); HDefaultClientDevice* buildDevice( const QUrl& deviceLocation, qint32 maxAge, QString* err); }; } } #endif /* HCONTROL_POINT_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hdevicebuild_p.h0000644000000000000000000001137211543637310023762 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEBUILD_P_H #define HDEVICEBUILD_P_H // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../../general/hupnp_defs.h" #include "../../dataelements/hudn.h" #include "../../utils/hthreadpool_p.h" #include namespace Herqq { namespace Upnp { class HServiceSubscribtion; class HControlPointPrivate; class HDefaultClientDevice; // // This class is used as a thread pool task to fetch a device description, its // accompanying service descriptions (if any) and to build the device model. // class DeviceBuildTask : public HRunnable { Q_OBJECT H_DISABLE_COPY(DeviceBuildTask) private: HControlPointPrivate* m_owner; QAtomicInt m_completionValue; // 0 for success QString m_errorString; // empty when succeeded QScopedPointer m_createdDevice; const HUdn m_udn; const qint32 m_cacheControlMaxAge; public: QList m_locations; template DeviceBuildTask(HControlPointPrivate* owner, const Msg& msg) : m_owner(owner), m_completionValue(-1), m_errorString(), m_createdDevice(0), m_udn(msg.usn().udn()), m_cacheControlMaxAge(msg.cacheControlMaxAge()), m_locations() { m_locations.append(msg.location()); } virtual ~DeviceBuildTask(); // deletes the created device if it has not been retrieved virtual void run(); inline HUdn udn() const { return m_udn; } inline qint32 completionValue() const { return m_completionValue; } inline QString errorString() const { return m_errorString; } // returns an error description only if something went wrong // and the build failed HDefaultClientDevice* createdDevice(); // releases ownership Q_SIGNALS: void done(const Herqq::Upnp::HUdn&); }; // // A class used by the controlpoint to store information about ongoing // device model builds (initiated by advertisement and discovery messages) // class DeviceBuildTasks { H_DISABLE_COPY(DeviceBuildTasks) private: QList m_builds; public: DeviceBuildTasks(); ~DeviceBuildTasks(); template DeviceBuildTask* get(const Msg& msg) const { QList::const_iterator ci = m_builds.constBegin(); for(; ci != m_builds.constEnd(); ++ci) { if ((*ci)->udn() == msg.usn().udn()) { // UDN match, we are definitely already building the device // the message advertises return *ci; } QList::const_iterator ci2 = (*ci)->m_locations.constBegin(); for(; ci2 != (*ci)->m_locations.constEnd(); ++ci2) { if (*ci2 == msg.location()) { // exact "location" (the URL to device description) match. // This means that we are already // building the device tree, but the build started from // a different advertisement message advertising another // device in the tree (root & embedded devices do not share // a common UDN). return *ci; } } } return 0; } // ownership is not transferred DeviceBuildTask* get(const HUdn& udn) const; // also deletes the removed object void remove(const HUdn& udn); // takes ownership void add(DeviceBuildTask* arg); // ownership is not transferred QList values() const; }; } } #endif /* HDEVICEBUILD_P_H */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint_configuration_p.h0000644000000000000000000000345711543637310027171 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCONTROLPOINT_CONFIGURATION_P_H_ #define HCONTROLPOINT_CONFIGURATION_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../../utils/hglobal.h" #include #include namespace Herqq { namespace Upnp { // // Implementation details of HControlPointConfiguration class // class H_UPNP_CORE_EXPORT HControlPointConfigurationPrivate { H_DISABLE_COPY(HControlPointConfigurationPrivate) public: // attributes bool m_subscribeToEvents; qint32 m_desiredSubscriptionTimeout; bool m_autoDiscovery; QList m_networkAddresses; public: // methods HControlPointConfigurationPrivate(); virtual ~HControlPointConfigurationPrivate(); virtual HControlPointConfigurationPrivate* clone() const; }; } } #endif /* HCONTROLPOINT_CONFIGURATION_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint_configuration.h0000644000000000000000000001524111543637310026644 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCONTROLPOINT_CONFIGURATION_H_ #define HCONTROLPOINT_CONFIGURATION_H_ #include class QHostAddress; namespace Herqq { namespace Upnp { class HControlPointConfigurationPrivate; /*! * Class for specifying initialization information to HControlPoint instances. * * \brief This class is used to pass initialization information for HControlPoint * instances. The use of this is optional and an HControlPoint instance is perfectly * functional with the default configuration. * * However, you can configure an HControlPoint in following ways: * - Define whether an HControlPoint should subscribe to events when a * device has been discovered by using setSubscribeToEvents(). * By default an HControlPoint instances subscribes to all events. * - Set the timeout request for event subscriptions with setDesiredSubscriptionTimeout(). * The default is 30 minutes. * - Specify whether an HControlPoint should perform initial discovery upon * startup using setAutoDiscovery(). The default is yes. * - Specify the network addresses an HControlPoint should use in its operations * with setNetworkAddressesToUse(). * The default is the first found interface that is up. Non-loopback interfaces * have preference, but if none are found the loopback is used. However, in this * case UDP multicast is not available. * * \headerfile hcontrolpoint_configuration.h HControlPointConfiguration * * \ingroup hupnp_devicehosting * * \sa HControlPoint * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HControlPointConfiguration : public HClonable { H_DISABLE_COPY(HControlPointConfiguration) friend class HControlPoint; protected: // // Documented in HClonable virtual void doClone(HClonable* target) const; // // Documented in HClonable virtual HControlPointConfiguration* newInstance() const; protected: HControlPointConfigurationPrivate* h_ptr; HControlPointConfiguration(HControlPointConfigurationPrivate& dd); public: /*! * \brief Creates a new instance. * * Creates a new instance with default values. */ HControlPointConfiguration(); /*! * \brief Destroys the instance. */ virtual ~HControlPointConfiguration(); // // Documented in HClonable virtual HControlPointConfiguration* clone() const; /*! * \brief Indicates whether to automatically subscribe to all events on all services * of a device when a new device is added into the control of an HControlPoint. * * \return \e true in case the HControlPoint instance should subscribe to all * events of all services of a newly added device. * * \sa setSubscribeToEvents() */ bool subscribeToEvents() const; /*! * \brief Returns the subscription timeout a control point requests when it subscribes * to an evented service. * * The default value is 30 minutes. * * \return The subscription timeout in seconds a control point requests * when it subscribes to an evented service. * * \sa setDesiredSubscriptionTimeout() */ qint32 desiredSubscriptionTimeout() const; /*! * \brief Indicates whether the control point should perform discovery upon * initialization. * * \return \e true in case the the control point should perform discovery upon * initialization. This is the default value. * * \remarks if the discovery is not performed the control point will be * unaware of UPnP devices that are already active in the network until they * re-advertise themselves. * * \sa setAutoDiscovery() */ bool autoDiscovery() const; /*! * \brief Returns the network addresses a control point should use in its * operations. * * \return The network addresses a control point should use in its * operations. * * \sa setNetworkAddressesToUse() */ QList networkAddressesToUse() const; /*! * Defines whether a control point should automatically subscribe to all * events on all services of a device when a new device is added * into the control of an HControlPoint. * * \param subscribeAutomatically when \e true an HControlPoint instance * should by default subscribe to all events of all services of a newly added * device. * * \sa subscribeToEvents() */ void setSubscribeToEvents(bool subscribeAutomatically); /*! * \brief Sets the subscription timeout a control point requests when it subscribes * to an evented service. * * Values less than or equal to zero are rejected and instead the default value * is used. The default value is 30 minutes. * * \param timeout specifies the requested timeout in seconds. * * \sa desiredSubscriptionTimeout() */ void setDesiredSubscriptionTimeout(qint32 timeout); /*! * Defines whether the control point should perform discovery upon * initialization. * * \param arg when \e true an HControlPoint instance will perform discovery * when it is initialized. This is the default. * * \remarks if the discovery is not performed the control point will be * unaware of UPnP devices that are already active in the network until they * re-advertise themselves. * * \sa autoDiscovery() */ void setAutoDiscovery(bool arg); /*! * Defines the network addresses the control point should use in its * operations. * * \param addresses specifies the network addresses the control point * should use in its operations. * * \return \e true in case the provided addresses are valid and can be * used. * * \sa networkAddressesToUse() */ bool setNetworkAddressesToUse(const QList& addresses); }; } } #endif /* HCONTROLPOINT_CONFIGURATION_H_ */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint_configuration.cpp0000644000000000000000000001036511543637310027201 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hcontrolpoint_configuration.h" #include "hcontrolpoint_configuration_p.h" #include "../../general/hupnp_global_p.h" #include "../../devicemodel/client/hclientdevice.h" #include "../../devicemodel/client/hclientservice.h" #include "../../utils/hmisc_utils_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HControlPointConfigurationPrivate ******************************************************************************/ HControlPointConfigurationPrivate::HControlPointConfigurationPrivate() : m_subscribeToEvents(true), m_desiredSubscriptionTimeout(1800), m_autoDiscovery(true), m_networkAddresses() { QHostAddress ha = findBindableHostAddress(); m_networkAddresses.append(ha); } HControlPointConfigurationPrivate::~HControlPointConfigurationPrivate() { } HControlPointConfigurationPrivate* HControlPointConfigurationPrivate::clone() const { HControlPointConfigurationPrivate* newObj = new HControlPointConfigurationPrivate(); newObj->m_subscribeToEvents = m_subscribeToEvents; newObj->m_desiredSubscriptionTimeout = m_desiredSubscriptionTimeout; newObj->m_autoDiscovery = m_autoDiscovery; newObj->m_networkAddresses = m_networkAddresses; return newObj; } /******************************************************************************* * HControlPointConfiguration ******************************************************************************/ HControlPointConfiguration::HControlPointConfiguration() : h_ptr(new HControlPointConfigurationPrivate()) { } HControlPointConfiguration::HControlPointConfiguration( HControlPointConfigurationPrivate& dd) : h_ptr(&dd) { } HControlPointConfiguration::~HControlPointConfiguration() { delete h_ptr; } HControlPointConfiguration* HControlPointConfiguration::newInstance() const { return new HControlPointConfiguration(); } void HControlPointConfiguration::doClone(HClonable* target) const { HControlPointConfiguration* conf = dynamic_cast(target); if (!conf) { return; } delete conf->h_ptr; conf->h_ptr = h_ptr->clone(); } HControlPointConfiguration* HControlPointConfiguration::clone() const { return static_cast(HClonable::clone()); } bool HControlPointConfiguration::subscribeToEvents() const { return h_ptr->m_subscribeToEvents; } qint32 HControlPointConfiguration::desiredSubscriptionTimeout() const { return h_ptr->m_desiredSubscriptionTimeout; } bool HControlPointConfiguration::autoDiscovery() const { return h_ptr->m_autoDiscovery; } QList HControlPointConfiguration::networkAddressesToUse() const { return h_ptr->m_networkAddresses; } void HControlPointConfiguration::setSubscribeToEvents(bool arg) { h_ptr->m_subscribeToEvents = arg; } void HControlPointConfiguration::setDesiredSubscriptionTimeout(qint32 arg) { static const qint32 def = 60*30; if (arg <= 0) { arg = def; } h_ptr->m_desiredSubscriptionTimeout = arg; } void HControlPointConfiguration::setAutoDiscovery(bool arg) { h_ptr->m_autoDiscovery = arg; } bool HControlPointConfiguration::setNetworkAddressesToUse( const QList& addresses) { if (!HSysInfo::instance().areLocalAddresses(addresses)) { return false; } h_ptr->m_networkAddresses = addresses; return true; } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hcontrolpoint_dataretriever_p.cpp0000644000000000000000000001001511543637310027502 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hcontrolpoint_dataretriever_p.h" #include "../../general/hlogger_p.h" #include "../../general/hupnp_global_p.h" #include #include #include #include namespace Herqq { namespace Upnp { HDataRetriever::HDataRetriever(const QByteArray& loggingId) : m_loggingIdentifier(loggingId), m_nam(), m_reply(0), m_lastError(), m_success(false) { bool ok = connect( &m_nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished())); Q_ASSERT(ok); Q_UNUSED(ok) } void HDataRetriever::finished() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); quit(); if (m_reply->error() != QNetworkReply::NoError) { m_success = false; HLOG_WARN(QString("Request failed: %1").arg(m_reply->errorString())); } else { m_success = true; } } bool HDataRetriever::retrieveData( const QUrl& baseUrl, const QUrl& query, QByteArray* data) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QString queryPart = extractRequestPart(query); QString request = queryPart.startsWith('/') ? extractHostPart(baseUrl.toString()) : baseUrl.toString(); if (!query.isEmpty()) { if (!request.endsWith('/')) { request.append('/'); } if (queryPart.startsWith('/')) { queryPart.remove(0, 1); } request.append(queryPart); } if (request.isEmpty()) { request.append('/'); } QNetworkRequest req(request); m_reply = m_nam.get(req); int id = startTimer(3000); exec(); killTimer(id); if (m_success) { *data = m_reply->readAll(); } m_reply->deleteLater(); m_reply = 0; return m_success; } void HDataRetriever::timerEvent(QTimerEvent* event) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN(QString("Request timed out.")); quit(); killTimer(event->timerId()); m_success = false; } bool HDataRetriever::retrieveServiceDescription( const QUrl& deviceLocation, const QUrl& scpdUrl, QString* data) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG(QString( "Attempting to fetch a service description for [%1] from: [%2]").arg( scpdUrl.toString(), deviceLocation.toString())); QByteArray tmp; if (!retrieveData(deviceLocation, scpdUrl, &tmp)) { return false; } *data = QString::fromUtf8(tmp); return true; } bool HDataRetriever::retrieveIcon( const QUrl& deviceLocation, const QUrl& iconUrl, QByteArray* data) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG(QString( "Attempting to retrieve icon [%1] from: [%2]").arg( iconUrl.toString(), deviceLocation.toString())); return retrieveData(deviceLocation, iconUrl, data); } bool HDataRetriever::retrieveDeviceDescription( const QUrl& deviceLocation, QString* data) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG(QString( "Attempting to fetch a device description from: [%1]").arg( deviceLocation.toString())); QByteArray tmp; if (!retrieveData(deviceLocation, QUrl(), &tmp)) { return false; } *data = QString::fromUtf8(tmp); return true; } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hevent_subscriptionmanager_p.cpp0000644000000000000000000003102211543637310027310 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hevent_subscriptionmanager_p.h" #include "hcontrolpoint_configuration.h" #include "hcontrolpoint_p.h" #include "../../general/hupnp_global_p.h" #include "../../devicemodel/client/hclientdevice.h" #include "../../devicemodel/client/hdefault_clientservice_p.h" #include "../../dataelements/hserviceid.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hserviceinfo.h" #include "../../general/hlogger_p.h" namespace Herqq { namespace Upnp { HEventSubscriptionManager::HEventSubscriptionManager(HControlPointPrivate* owner) : QObject(owner), m_owner(owner), m_subscribtionsByUuid(), m_subscriptionsByUdn() { Q_ASSERT(m_owner); } HEventSubscriptionManager::~HEventSubscriptionManager() { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); removeAll(); } void HEventSubscriptionManager::subscribed_slot(HEventSubscription* sub) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(sub); emit subscribed(sub->service()); } void HEventSubscriptionManager::subscriptionFailed_slot(HEventSubscription* sub) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(sub); HClientService* service = sub->service(); sub->resetSubscription(); emit subscriptionFailed(service); } void HEventSubscriptionManager::unsubscribed(HEventSubscription* sub) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(sub); emit unsubscribed(sub->service()); } HEventSubscription* HEventSubscriptionManager::createSubscription( HClientService* service, qint32 timeout) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(service); Q_ASSERT(thread() == QThread::currentThread()); QUrl httpSrvRootUrl = getSuitableHttpServerRootUrl( service->parentDevice()->locations()); Q_ASSERT(!httpSrvRootUrl.isEmpty()); HEventSubscription* subscription = new HEventSubscription( m_owner->m_loggingIdentifier, service, httpSrvRootUrl, HTimeout(timeout), this); bool ok = connect( subscription, SIGNAL(subscribed(HEventSubscription*)), this, SLOT(subscribed_slot(HEventSubscription*))); Q_ASSERT(ok); Q_UNUSED(ok) ok = connect( subscription, SIGNAL(subscriptionFailed(HEventSubscription*)), this, SLOT(subscriptionFailed_slot(HEventSubscription*))); Q_ASSERT(ok); ok = connect( subscription, SIGNAL(unsubscribed(HEventSubscription*)), this, SLOT(unsubscribed(HEventSubscription*))); Q_ASSERT(ok); return subscription; } QUrl HEventSubscriptionManager::getSuitableHttpServerRootUrl( const QList& deviceLocations) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); if (m_owner->m_server->endpointCount() == 1) { return m_owner->m_server->rootUrls().at(0); } foreach(const QUrl& deviceLocation, deviceLocations) { quint32 localNetw; bool b = HSysInfo::instance().localNetwork( HEndpoint(deviceLocation).hostAddress(), &localNetw); if (b) { QUrl rootUrl = m_owner->m_server->rootUrl(QHostAddress(localNetw)); if (rootUrl.isValid() && !rootUrl.isEmpty()) { return rootUrl; } } } return m_owner->m_server->rootUrls().at(0); } bool HEventSubscriptionManager::subscribe( HClientDevice* device, DeviceVisitType visitType, qint32 timeout) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(device); bool ok = false; HClientServices services(device->services()); for(qint32 i = 0; i < services.size(); ++i) { HClientService* service = services.at(i); if (service->isEvented()) { if (subscribe(service, timeout) == Sub_Success) { ok = true; } } } if (visitType == VisitThisAndDirectChildren || visitType == VisitThisRecursively) { HClientDevices devices(device->embeddedDevices()); for(qint32 i = 0; i < devices.size(); ++i) { DeviceVisitType visitTypeForChildren = visitType == VisitThisRecursively ? VisitThisRecursively : VisitThisOnly; if (subscribe(devices.at(i), visitTypeForChildren, timeout) && !ok) { ok = true; } } } return ok; } HEventSubscriptionManager::SubscriptionResult HEventSubscriptionManager::subscribe(HClientService* service, qint32 timeout) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(service); if (!service->isEvented()) { HLOG_WARN(QString( "Cannot subscribe to a service [%1] that is not evented").arg( service->info().serviceId().toString())); return Sub_Failed_NotEvented; } HUdn deviceUdn = service->parentDevice()->info().udn(); QList* subs = m_subscriptionsByUdn.value(deviceUdn); if (!subs) { subs = new QList(); goto end; } else { QList::iterator it = subs->begin(); for(; it != subs->end(); ++it) { HEventSubscription* sub = (*it); if (sub->service() == service) { if (sub->subscriptionStatus() == HEventSubscription::Status_Subscribed) { HLOG_WARN(QString("Subscription to service [%1] exists").arg( service->info().serviceId().toString())); return Sub_AlreadySubscribed; } else { sub->subscribe(); return Sub_Success; } } } } end: HEventSubscription* sub = createSubscription(service, timeout); m_subscribtionsByUuid.insert(sub->id(), sub); m_subscriptionsByUdn.insert(deviceUdn, subs); subs->append(sub); sub->subscribe(); return Sub_Success; } HEventSubscription::SubscriptionStatus HEventSubscriptionManager::subscriptionStatus( const HClientService* service) const { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(service); HUdn udn = service->parentDevice()->info().udn(); QList* subs = m_subscriptionsByUdn.value(udn); if (!subs) { return HEventSubscription::Status_Unsubscribed; } QList::iterator it = subs->begin(); for(; it != subs->end(); ++it) { HEventSubscription* sub = (*it); if (sub->service() == service) { return sub->subscriptionStatus(); } } return HEventSubscription::Status_Unsubscribed; } bool HEventSubscriptionManager::cancel( HClientDevice* device, DeviceVisitType visitType, bool unsubscribe) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(device); Q_ASSERT(thread() == QThread::currentThread()); HUdn udn = device->info().udn(); QList* subs = m_subscriptionsByUdn.value(udn); if (!subs) { return false; } QList::iterator it = subs->begin(); for(; it != subs->end(); ++it) { if (unsubscribe) { (*it)->unsubscribe(); } else { (*it)->resetSubscription(); } } if (visitType == VisitThisAndDirectChildren || visitType == VisitThisRecursively) { HClientDevices devices(device->embeddedDevices()); for(qint32 i = 0; i < devices.size(); ++i) { DeviceVisitType visitTypeForChildren = visitType == VisitThisRecursively ? VisitThisRecursively : VisitThisOnly; cancel(devices.at(i), visitTypeForChildren, unsubscribe); } } return true; } bool HEventSubscriptionManager::remove(HClientDevice* device, bool recursive) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(device); Q_ASSERT(thread() == QThread::currentThread()); HUdn udn = device->info().udn(); QList* subs = m_subscriptionsByUdn.value(udn); if (!subs) { return false; } QList::iterator it = subs->begin(); for(; it != subs->end(); ++it) { HEventSubscription* sub = (*it); m_subscribtionsByUuid.remove(sub->id()); delete sub; } m_subscriptionsByUdn.remove(udn); delete subs; if (recursive) { HClientDevices devices(device->embeddedDevices()); for(qint32 i = 0; i < devices.size(); ++i) { remove(devices.at(i), recursive); } } return true; } bool HEventSubscriptionManager::cancel(HClientService* service, bool unsubscribe) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(service); Q_ASSERT(thread() == QThread::currentThread()); HClientDevice* parentDevice = service->parentDevice(); HUdn udn = parentDevice->info().udn(); QList* subs = m_subscriptionsByUdn.value(udn); if (!subs) { return false; } QList::iterator it = subs->begin(); for(; it != subs->end(); ++it) { HEventSubscription* sub = (*it); if (sub->service() != service) { continue; } if (unsubscribe) { (*it)->unsubscribe(); } else { (*it)->resetSubscription(); } return true; } return false; } bool HEventSubscriptionManager::remove(HClientService* service) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(service); Q_ASSERT(thread() == QThread::currentThread()); HClientDevice* parentDevice = service->parentDevice(); HUdn udn = parentDevice->info().udn(); QList* subs = m_subscriptionsByUdn.value(udn); if (!subs) { return false; } QList::iterator it = subs->begin(); for(; it != subs->end(); ++it) { HEventSubscription* sub = (*it); if (sub->service() != service) { continue; } subs->erase(it); if (subs->isEmpty()) { delete subs; m_subscriptionsByUdn.remove(udn); } m_subscribtionsByUuid.remove(sub->id()); delete sub; return true; } return false; } void HEventSubscriptionManager::cancelAll(qint32 msecsToWait) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); QHash::iterator it = m_subscribtionsByUuid.begin(); for(; it != m_subscribtionsByUuid.end(); ++it) { (*it)->unsubscribe(msecsToWait); } } void HEventSubscriptionManager::removeAll() { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); qDeleteAll(m_subscribtionsByUuid); m_subscribtionsByUuid.clear(); qDeleteAll(m_subscriptionsByUdn); m_subscriptionsByUdn.clear(); } StatusCode HEventSubscriptionManager::onNotify( const QUuid& id, const HNotifyRequest& req) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); HEventSubscription* sub = m_subscribtionsByUuid.value(id); if (!sub) { HLOG_WARN(QString( "Ignoring notification [seq: %1] due to invalid callback ID [%2]: " "no such subscription found.").arg( QString::number(req.seq()), id.toString())); return BadRequest; } return sub->onNotify(req); } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hdevicebuild_p.cpp0000644000000000000000000000651011543637310024313 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicebuild_p.h" #include "hcontrolpoint_p.h" #include "../../devicemodel/client/hdefault_clientdevice_p.h" #include "../../general/hlogger_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * DeviceBuildTask ******************************************************************************/ DeviceBuildTask::~DeviceBuildTask() { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); if (m_createdDevice.data()) { m_createdDevice->deleteLater(); } m_createdDevice.take(); } HDefaultClientDevice* DeviceBuildTask::createdDevice() { return m_createdDevice.take(); } void DeviceBuildTask::run() { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); QString err; QScopedPointer device; device.reset( m_owner->buildDevice(m_locations[0], m_cacheControlMaxAge, &err)); // the returned device is a fully built root device containing every // embedded device and service advertised in the device and service descriptions // otherwise, the creation failed if (!device.data()) { HLOG_WARN(QString("Couldn't create a device: %1").arg(err)); m_completionValue = -1; m_errorString = err; } else { device->moveToThread(m_owner->thread()); m_completionValue = 0; m_createdDevice.swap(device); } emit done(m_udn); } /******************************************************************************* * DeviceBuildTasks ******************************************************************************/ DeviceBuildTasks::DeviceBuildTasks() : m_builds() { } DeviceBuildTasks::~DeviceBuildTasks() { qDeleteAll(m_builds); } DeviceBuildTask* DeviceBuildTasks::get(const HUdn& udn) const { QList::const_iterator ci = m_builds.constBegin(); for(; ci != m_builds.constEnd(); ++ci) { if ((*ci)->udn() == udn) { return *ci; } } return 0; } void DeviceBuildTasks::remove(const HUdn& udn) { QList::iterator i = m_builds.begin(); for(; i != m_builds.end(); ++i) { if ((*i)->udn() == udn) { delete (*i); m_builds.erase(i); return; } } Q_ASSERT(false); } void DeviceBuildTasks::add(DeviceBuildTask* arg) { Q_ASSERT(arg); m_builds.push_back(arg); } QList DeviceBuildTasks::values() const { return m_builds; } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hevent_subscription_p.h0000644000000000000000000001231211543637310025423 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HEVENT_SUBSCRIPTION_H_ #define HEVENT_SUBSCRIPTION_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../messages/hsid_p.h" #include "../messages/hevent_messages_p.h" #include "../../http/hhttp_asynchandler_p.h" #include "../../general/hupnp_defs.h" #include "../../general/hupnp_fwd.h" #include #include #include #include #include namespace Herqq { namespace Upnp { class HMessagingInfo; class HEventSubscription; class HHttpAsyncOperation; class HControlPointPrivate; // // This class represents and maintains a subscription to a service instantiated on the // device host (server) side. // class HEventSubscription : public QObject { Q_OBJECT H_DISABLE_COPY(HEventSubscription) friend class RenewSubscription; friend class Unsubscribe; private: QByteArray m_loggingIdentifier; QUuid m_randomIdentifier; // identifies the service subscription. used in the callback url QList m_deviceLocations; // the URLs of the device where the desired service is located qint32 m_nextLocationToTry; // index of the device location URL that has been tried / used previously // the URL identified by this index will be used until communication to the // URL fails. At that time the index is incremented if there are more // device locations to try. QUrl m_eventUrl; // the URL that is currently used in HTTP messaging qint32 m_connectErrorCount; HSid m_sid; // the unique identifier of the subscription created by the upnp device qint32 m_seq; // the sequence number which is incremented upon each notify HTimeout m_desiredTimeout; // the desired timeout for the subscription HTimeout m_timeout; // the actual timeout of the subscription. this is received from the device // upon successful subscription. if no error occurs, the subscription will // be renewed before the specified timeout elapses. QTimer m_subscriptionTimer; // used to signal the time when the subscription should be renewed QTimer m_announcementTimer; bool m_announcementTimedOut; HClientService* m_service; // the target service of the subscription QUrl m_serverRootUrl; // the URL of the server that relays the notifications to this instance. // this is used in subscription requests to tell the upnp device where the // notifications are to be sent HHttpAsyncHandler m_http; // the class used to perform HTTP messaging enum OperationType { Op_None = 0, Op_Subscribe, Op_Renew, Op_Unsubscribe }; QTcpSocket m_socket; // socket for the messaging OperationType m_currentOpType; OperationType m_nextOpType; bool m_subscribed; QList m_queuedNotifications; private Q_SLOTS: void subscriptionTimeout(); void announcementTimeout(); void connected(); void msgIoComplete(HHttpAsyncOperation*); void error(QAbstractSocket::SocketError); private: bool connectToDevice(qint32 msecsToWait=0); void subscribe_done(HHttpAsyncOperation*); void renewSubscription_done(HHttpAsyncOperation*); void unsubscribe_done(HHttpAsyncOperation*); void runNextOp(); void resubscribe(); void renewSubscription(); StatusCode processNotify(const HNotifyRequest&); Q_SIGNALS: void subscribed(HEventSubscription*); void subscriptionFailed(HEventSubscription*); void unsubscribed(HEventSubscription*); public: enum SubscriptionStatus { Status_Unsubscribed = 0, Status_Subscribing, Status_Subscribed }; HEventSubscription( const QByteArray& loggingIdentifier, HClientService* service, const QUrl& serverRootUrl, const HTimeout& desiredTimeout, QObject* parent = 0); virtual ~HEventSubscription(); inline QUuid id() const { return m_randomIdentifier ; } inline HClientService* service() const { return m_service; } void subscribe(); void unsubscribe(qint32 msecsToWait=0); void resetSubscription(); StatusCode onNotify(const HNotifyRequest&); SubscriptionStatus subscriptionStatus() const; }; } } #endif /* HEVENT_SUBSCRIPTION_H_ */ herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hclientmodel_creator_p.cpp0000644000000000000000000002413511543637310026055 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hclientmodel_creator_p.h" #include "../../dataelements/hudn.h" #include "../../dataelements/hserviceid.h" #include "../../dataelements/hdeviceinfo.h" #include "../../general/hupnp_global_p.h" #include "../../general/hupnp_datatypes_p.h" #include "../../devicemodel/client/hclientservice_p.h" #include "../../devicemodel/client/hclientdevice_p.h" #include "../../devicemodel/client/hdefault_clientaction_p.h" #include "../../devicemodel/client/hdefault_clientdevice_p.h" #include "../../devicemodel/client/hdefault_clientservice_p.h" #include "../../devicemodel/client/hdefault_clientstatevariable_p.h" #include "../../devicemodel/hactionarguments.h" #include "../../general/hlogger_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HClientModelCreationArgs ******************************************************************************/ HClientModelCreationArgs::HClientModelCreationArgs(QNetworkAccessManager* nam) : m_nam(nam) { } HClientModelCreationArgs::~HClientModelCreationArgs() { } HClientModelCreationArgs::HClientModelCreationArgs( const HClientModelCreationArgs& other) : HModelCreationArgs(other), m_nam(other.m_nam) { } HClientModelCreationArgs& HClientModelCreationArgs::operator=( const HClientModelCreationArgs& other) { Q_ASSERT(this != &other); HModelCreationArgs::operator=(other); m_nam = other.m_nam; return *this; } /******************************************************************************* * HClientModelCreator ******************************************************************************/ HClientModelCreator::HClientModelCreator( const HClientModelCreationArgs& creationParameters) : m_creationParameters(new HClientModelCreationArgs(creationParameters)), m_docParser(creationParameters.m_loggingIdentifier, LooseChecks) { Q_ASSERT(creationParameters.m_serviceDescriptionFetcher); Q_ASSERT(creationParameters.m_deviceLocations.size() > 0); Q_ASSERT(creationParameters.m_iconFetcher); Q_ASSERT(!creationParameters.m_loggingIdentifier.isEmpty()); } bool HClientModelCreator::parseStateVariables( HDefaultClientService* service, QDomElement stateVariableElement) { while(!stateVariableElement.isNull()) { HStateVariableInfo svInfo; if (!m_docParser.parseStateVariable(stateVariableElement, &svInfo)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } HDefaultClientStateVariable* sv = new HDefaultClientStateVariable(svInfo, service); service->addStateVariable(sv); bool ok = QObject::connect( sv, SIGNAL(valueChanged( const Herqq::Upnp::HClientStateVariable*, const Herqq::Upnp::HStateVariableEvent&)), service, SLOT(notifyListeners())); Q_ASSERT(ok); Q_UNUSED(ok) Q_ASSERT(ok); Q_UNUSED(ok) stateVariableElement = stateVariableElement.nextSiblingElement("stateVariable"); } return true; } bool HClientModelCreator::parseActions( HDefaultClientService* service, QDomElement actionElement, const HStateVariableInfos& svInfos) { while(!actionElement.isNull()) { HActionInfo actionInfo; if (!m_docParser.parseActionInfo( actionElement, svInfos, &actionInfo)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } HDefaultClientAction* action = new HDefaultClientAction( actionInfo, service, *m_creationParameters->m_nam); QString name = action->info().name(); service->addAction(action); actionElement = actionElement.nextSiblingElement("action"); } return true; } bool HClientModelCreator::parseServiceDescription(HDefaultClientService* service) { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); Q_ASSERT(service); QDomDocument doc; QDomElement firstSv, firstAction; if (!m_docParser.parseServiceDescription( service->description(), &doc, &firstSv, &firstAction)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } if (!parseStateVariables(service, firstSv)) { return false; } HStateVariableInfos svInfos; HClientStateVariables svs = service->stateVariables(); foreach(const QString& key, svs.keys()) { svInfos.insert(key, svs.value(key)->info()); } return parseActions(service, firstAction, svInfos); } bool HClientModelCreator::parseServiceList( const QDomElement& serviceListElement, HClientDevice* device, QList* retVal) { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); Q_ASSERT(device); Q_ASSERT(!serviceListElement.isNull()); QDomElement serviceElement = serviceListElement.firstChildElement("service"); while(!serviceElement.isNull()) { HServiceInfo info; if (!m_docParser.parseServiceInfo(serviceElement, &info)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return false; } QScopedPointer service( new HDefaultClientService(info, device)); QString description; if (!m_creationParameters->m_serviceDescriptionFetcher( extractBaseUrl(m_creationParameters->m_deviceLocations[0]), info.scpdUrl(), &description)) { m_lastError = FailedToGetDataError; m_lastErrorDescription = QString( "Could not retrieve service description from [%1]").arg( info.scpdUrl().toString()); return false; } service->setDescription(description); if (!parseServiceDescription(service.data())) { return false; } retVal->push_back(service.take()); serviceElement = serviceElement.nextSiblingElement("service"); } return true; } HDefaultClientDevice* HClientModelCreator::parseDevice( const QDomElement& deviceElement, HDefaultClientDevice* parentDevice) { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); HDeviceInfo deviceInfo; if (!m_docParser.parseDeviceInfo(deviceElement, &deviceInfo)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return 0; } QScopedPointer device( new HDefaultClientDevice( m_creationParameters->m_deviceDescription, m_creationParameters->m_deviceLocations, deviceInfo, m_creationParameters->m_deviceTimeoutInSecs, parentDevice)); QDomElement serviceListElement = deviceElement.firstChildElement("serviceList"); if (!serviceListElement.isNull()) { QList services; if (!parseServiceList(serviceListElement, device.data(), &services)) { return 0; } device->setServices(services); } QDomElement deviceListElement = deviceElement.firstChildElement("deviceList"); if (!deviceListElement.isNull()) { QList embeddedDevices; QDomElement embeddedDeviceElement = deviceListElement.firstChildElement("device"); while(!embeddedDeviceElement.isNull()) { HDefaultClientDevice* embeddedDevice = parseDevice(embeddedDeviceElement, device.data()); if (!embeddedDevice) { return 0; } embeddedDevice->setParent(device.data()); embeddedDevices.push_back(embeddedDevice); embeddedDeviceElement = embeddedDeviceElement.nextSiblingElement("device"); } device->setEmbeddedDevices(embeddedDevices); } return device.take(); } HDefaultClientDevice* HClientModelCreator::createRootDevice() { HLOG2(H_AT, H_FUN, m_creationParameters->m_loggingIdentifier); QDomDocument doc; QDomElement rootElement; if (!m_docParser.parseRoot( m_creationParameters->m_deviceDescription, &doc, &rootElement)) { m_lastError = convert(m_docParser.lastError()); m_lastErrorDescription = m_docParser.lastErrorDescription(); return 0; } QScopedPointer createdDevice( parseDevice(rootElement, 0)); if (!createdDevice) { return 0; } createdDevice->setConfigId(m_docParser.readConfigId(rootElement)); HDeviceValidator validator; if (!validator.validateRootDevice(createdDevice.data())) { m_lastError = convert(validator.lastError()); m_lastErrorDescription = validator.lastErrorDescription(); return 0; } return createdDevice.take(); } } } herqq-1.0.0/hupnp/src/devicehosting/controlpoint/hclientmodel_creator_p.h0000644000000000000000000000706711543637310025527 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTMODEL_CREATOR_P_H_ #define HCLIENTMODEL_CREATOR_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../hddoc_parser_p.h" #include "../hmodelcreation_p.h" #include class QNetworkAccessManager; namespace Herqq { namespace Upnp { class HDefaultClientDevice; // // // class HClientModelCreationArgs : public HModelCreationArgs { public: QNetworkAccessManager* m_nam; HClientModelCreationArgs(QNetworkAccessManager* nam); virtual ~HClientModelCreationArgs(); HClientModelCreationArgs(const HClientModelCreationArgs&); HClientModelCreationArgs& operator=(const HClientModelCreationArgs&); }; class HDefaultClientService; // // The class that creates the HUPnP's device model from description files // class HClientModelCreator { H_DISABLE_COPY(HClientModelCreator) public: enum ErrorType { NoError, FailedToGetDataError, InvalidServiceDescription, InvalidDeviceDescription, UndefinedTypeError, UnimplementedAction, InitializationError, UndefinedError }; private: QScopedPointer m_creationParameters; HDocParser m_docParser; QString m_lastErrorDescription; ErrorType m_lastError; private: QList > parseIconList( const QDomElement& iconListElement); bool parseStateVariables( HDefaultClientService* service, QDomElement stateVariableElement); bool parseActions( HDefaultClientService*, QDomElement actionElement, const HStateVariableInfos& svInfos); bool parseServiceDescription(HDefaultClientService*); bool parseServiceList( const QDomElement& serviceListElement, HClientDevice*, QList* retVal); HDefaultClientDevice* parseDevice( const QDomElement& deviceElement, HDefaultClientDevice* parentDevice); inline ErrorType convert(DocumentErrorTypes type) { switch(type) { case InvalidDeviceDescriptionError: return InvalidDeviceDescription; case InvalidServiceDescriptionError: return InvalidServiceDescription; case NoError: return NoError; default: return UndefinedError; } } public: HClientModelCreator(const HClientModelCreationArgs&); HDefaultClientDevice* createRootDevice(); inline ErrorType lastError() const { return m_lastError; } inline QString lastErrorDescription() const { return m_lastErrorDescription; } }; } } #endif /* HCLIENTMODEL_CREATOR_P_H_ */ herqq-1.0.0/hupnp/src/devicehosting/hdevicestorage_p.cpp0000644000000000000000000000163111543637310022125 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicestorage_p.h" namespace Herqq { namespace Upnp { } } herqq-1.0.0/hupnp/src/devicehosting/devicehosting.pri0000644000000000000000000000644311543637310021463 0ustar rootroot HEADERS += \ $$SRC_LOC/devicehosting/hdevicestorage_p.h \ $$SRC_LOC/devicehosting/hddoc_parser_p.h \ $$SRC_LOC/devicehosting/hmodelcreation_p.h \ $$SRC_LOC/devicehosting/messages/hcontrol_messages_p.h \ $$SRC_LOC/devicehosting/messages/hevent_messages_p.h \ $$SRC_LOC/devicehosting/messages/hnt_p.h \ $$SRC_LOC/devicehosting/messages/hsid_p.h \ $$SRC_LOC/devicehosting/messages/htimeout_p.h \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint_p.h \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint.h \ $$SRC_LOC/devicehosting/controlpoint/hdevicebuild_p.h \ $$SRC_LOC/devicehosting/controlpoint/hclientmodel_creator_p.h \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint_configuration.h \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint_configuration_p.h \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint_dataretriever_p.h \ $$SRC_LOC/devicehosting/controlpoint/hevent_subscription_p.h \ $$SRC_LOC/devicehosting/controlpoint/hevent_subscriptionmanager_p.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_p.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost.h \ $$SRC_LOC/devicehosting/devicehost/hserverdevicecontroller_p.h \ $$SRC_LOC/devicehosting/devicehost/hservermodel_creator_p.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_dataretriever_p.h \ $$SRC_LOC/devicehosting/devicehost/hevent_notifier_p.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_configuration.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_configuration_p.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_runtimestatus_p.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_ssdp_handler_p.h \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_http_server_p.h \ $$SRC_LOC/devicehosting/devicehost/hpresence_announcer_p.h \ $$SRC_LOC/devicehosting/devicehost/hevent_subscriber_p.h SOURCES += \ $$SRC_LOC/devicehosting/hdevicestorage_p.cpp \ $$SRC_LOC/devicehosting/hddoc_parser_p.cpp \ $$SRC_LOC/devicehosting/hmodelcreation_p.cpp \ $$SRC_LOC/devicehosting/messages/hcontrol_messages_p.cpp \ $$SRC_LOC/devicehosting/messages/hevent_messages_p.cpp \ $$SRC_LOC/devicehosting/messages/hnt_p.cpp \ $$SRC_LOC/devicehosting/messages/hsid_p.cpp \ $$SRC_LOC/devicehosting/messages/htimeout_p.cpp \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint.cpp \ $$SRC_LOC/devicehosting/controlpoint/hclientmodel_creator_p.cpp \ $$SRC_LOC/devicehosting/controlpoint/hdevicebuild_p.cpp \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint_configuration.cpp \ $$SRC_LOC/devicehosting/controlpoint/hcontrolpoint_dataretriever_p.cpp \ $$SRC_LOC/devicehosting/controlpoint/hevent_subscription_p.cpp \ $$SRC_LOC/devicehosting/controlpoint/hevent_subscriptionmanager_p.cpp \ $$SRC_LOC/devicehosting/devicehost/hdevicehost.cpp \ $$SRC_LOC/devicehosting/devicehost/hservermodel_creator_p.cpp \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_dataretriever_p.cpp \ $$SRC_LOC/devicehosting/devicehost/hevent_notifier_p.cpp \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_configuration.cpp \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_ssdp_handler_p.cpp \ $$SRC_LOC/devicehosting/devicehost/hdevicehost_http_server_p.cpp \ $$SRC_LOC/devicehosting/devicehost/hevent_subscriber_p.cpp herqq-1.0.0/hupnp/src/dataelements/0000755000000000000000000000000011543637460015726 5ustar rootrootherqq-1.0.0/hupnp/src/dataelements/hdiscoverytype.cpp0000644000000000000000000002306011543637310021506 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdiscoverytype.h" #include "../dataelements/hudn.h" #include "../dataelements/hresourcetype.h" #include "../general/hlogger_p.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HDiscoveryTypePrivate ******************************************************************************/ class HDiscoveryTypePrivate : public QSharedData { public: HDiscoveryType::Type m_type; QString m_contents; HUdn m_udn; HResourceType m_resourceType; public: HDiscoveryTypePrivate() : m_type(HDiscoveryType::Undefined), m_contents(), m_udn(), m_resourceType() { } bool parse(const HResourceType& rt) { if (!rt.isValid()) { return false; } m_resourceType = rt; return true; } bool parse(const QString& arg, HValidityCheckLevel checkLevel) { HLOG(H_AT, H_FUN); QString tmp(arg.simplified()); HUdn udn; qint32 indx = tmp.indexOf("::"); if (indx == 41) // the length of "uuid:UUID" is 41 { udn = HUdn(tmp.left(41)); if (!udn.isValid(checkLevel)) { return false; } if (tmp.size() > 43) { tmp = tmp.mid(43); } else { m_udn = udn; m_type = HDiscoveryType::SpecificDevice; m_contents = udn.toString(); return true; } } QStringList parsed = tmp.split(':'); if (parsed.size() < 2) { HLOG_WARN(QString("Invalid resource identifier: %1").arg(arg)); return false; } if (!udn.isValid(checkLevel)) { if (parsed[0] == "ssdp" && parsed[1] == "all") { m_type = HDiscoveryType::All; m_contents = "ssdp:all"; return true; } } if (parsed[0] == "upnp" && parsed[1] == "rootdevice") { m_udn = udn; if (m_udn.isValid(checkLevel)) { m_type = HDiscoveryType::SpecificRootDevice; m_contents = QString("%1::upnp:rootdevice").arg(udn.toString()); } else { m_type = HDiscoveryType::RootDevices; m_contents = "upnp:rootdevice"; } return true; } else if (parsed[0] == "uuid") { udn = HUdn(parsed[1]); if (udn.isValid(checkLevel)) { m_udn = udn; m_type = HDiscoveryType::SpecificDevice; m_contents = udn.toString(); return true; } } HResourceType resourceType(tmp); if (parse(resourceType)) { m_udn = udn; if (m_udn.isValid(checkLevel)) { m_type = resourceType.isDeviceType() ? HDiscoveryType::SpecificDeviceWithType : HDiscoveryType::SpecificServiceWithType; m_contents = QString("%1::%2").arg( udn.toString(), resourceType.toString()); } else { m_type = resourceType.isDeviceType() ? HDiscoveryType::DeviceType : HDiscoveryType::ServiceType; m_contents = QString("%1").arg(resourceType.toString()); } return true; } HLOG_WARN(QString("Invalid resource identifier: %1").arg(arg)); return false; } void setState( const HUdn& udn, const HResourceType& rt, HValidityCheckLevel checkLevel) { if (udn.isValid(checkLevel)) { switch(rt.type()) { case HResourceType::Undefined: m_udn = udn; m_type = HDiscoveryType::SpecificDevice; m_resourceType = rt; m_contents = udn.toString(); return; case HResourceType::StandardDeviceType: case HResourceType::VendorSpecifiedDeviceType: m_type = HDiscoveryType::SpecificDeviceWithType; break; case HResourceType::StandardServiceType: case HResourceType::VendorSpecifiedServiceType: m_type = HDiscoveryType::SpecificServiceWithType; break; default: Q_ASSERT(false); } m_contents = QString("%1::%2").arg(udn.toString(), rt.toString()); } else { switch(rt.type()) { case HResourceType::Undefined: m_udn = udn; m_type = HDiscoveryType::Undefined; m_resourceType = rt; m_contents = QString(); return; case HResourceType::StandardDeviceType: case HResourceType::VendorSpecifiedDeviceType: m_type = HDiscoveryType::DeviceType; break; case HResourceType::StandardServiceType: case HResourceType::VendorSpecifiedServiceType: m_type = HDiscoveryType::ServiceType; break; default: Q_ASSERT(false); } m_contents = QString("%1").arg(rt.toString()); } m_udn = udn; m_resourceType = rt; } }; /******************************************************************************* * HDiscoveryType ******************************************************************************/ HDiscoveryType::HDiscoveryType() : h_ptr(new HDiscoveryTypePrivate()) { } HDiscoveryType::HDiscoveryType( const HUdn& udn, bool isRootDevice, HValidityCheckLevel checkLevel) : h_ptr(new HDiscoveryTypePrivate()) { if (udn.isValid(checkLevel)) { if (isRootDevice) { h_ptr->m_type = HDiscoveryType::SpecificRootDevice; h_ptr->m_contents = QString("%1::upnp:rootdevice").arg(udn.toString()); } else { h_ptr->m_type = HDiscoveryType::SpecificDevice; h_ptr->m_contents = udn.toString(); } h_ptr->m_udn = udn; } } HDiscoveryType::HDiscoveryType(const HResourceType& resourceType) : h_ptr(new HDiscoveryTypePrivate()) { if (h_ptr->parse(resourceType)) { h_ptr->m_contents = resourceType.toString(); h_ptr->m_type = resourceType.isDeviceType() ? HDiscoveryType::DeviceType : HDiscoveryType::ServiceType; } } HDiscoveryType::HDiscoveryType( const HUdn& udn, const HResourceType& resourceType, HValidityCheckLevel checkLevel) : h_ptr(new HDiscoveryTypePrivate()) { if (h_ptr->parse(resourceType) && udn.isValid(checkLevel)) { h_ptr->m_udn = udn; h_ptr->m_contents = QString("%1::%2").arg(udn.toString(), resourceType.toString()); h_ptr->m_type = resourceType.isDeviceType() ? HDiscoveryType::SpecificDeviceWithType : HDiscoveryType::SpecificServiceWithType; } } HDiscoveryType::HDiscoveryType( const QString& resource, HValidityCheckLevel checkLevel) : h_ptr(new HDiscoveryTypePrivate()) { h_ptr->parse(resource, checkLevel); } HDiscoveryType::~HDiscoveryType() { } HDiscoveryType::HDiscoveryType(const HDiscoveryType& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HDiscoveryType& HDiscoveryType::operator=( const HDiscoveryType& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HDiscoveryType::Type HDiscoveryType::type() const { return h_ptr->m_type; } const HUdn& HDiscoveryType::udn() const { return h_ptr->m_udn; } void HDiscoveryType::setUdn(const HUdn& udn, HValidityCheckLevel checkLevel) { h_ptr->setState(udn, h_ptr->m_resourceType, checkLevel); } const HResourceType& HDiscoveryType::resourceType() const { return h_ptr->m_resourceType; } void HDiscoveryType::setResourceType(const HResourceType& resource) { h_ptr->setState(h_ptr->m_udn, resource, LooseChecks); } QString HDiscoveryType::toString() const { return h_ptr->m_contents; } HDiscoveryType HDiscoveryType::createDiscoveryTypeForRootDevices() { static HDiscoveryType retVal("upnp:rootdevice"); return retVal; } HDiscoveryType HDiscoveryType::createDiscoveryTypeForAllResources() { static HDiscoveryType retVal("ssdp:all"); return retVal; } bool operator==(const HDiscoveryType& obj1, const HDiscoveryType& obj2) { return obj1.h_ptr->m_contents == obj2.h_ptr->m_contents; } } } herqq-1.0.0/hupnp/src/dataelements/hdeviceinfo_p.h0000644000000000000000000000606611543637310020703 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEINFO_P_H_ #define HDEVICEINFO_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hudn.h" #include "hresourcetype.h" #include "../general/hlogger_p.h" #include #include #include #include namespace Herqq { namespace Upnp { // // Implementation details of HDeviceInfo // class HDeviceInfoPrivate : public QSharedData { HDeviceInfoPrivate& operator=(const HDeviceInfoPrivate&); public: // attributes HResourceType m_deviceType; QString m_friendlyName; QString m_manufacturer; QUrl m_manufacturerUrl; QString m_modelDescription; QString m_modelName; QString m_modelNumber; QUrl m_modelUrl; QString m_serialNumber; HUdn m_udn; QString m_upc; QUrl m_presentationUrl; QList m_icons; public: // methods HDeviceInfoPrivate(); ~HDeviceInfoPrivate(); bool setDeviceType(const HResourceType& deviceType); bool setFriendlyName(const QString& friendlyName); bool setManufacturer(const QString& manufacturer); inline bool setManufacturerUrl(const QUrl& manufacturerUrl) { m_manufacturerUrl = manufacturerUrl; return true; } bool setModelDescription(const QString& modelDescription); bool setModelName(const QString& modelName); bool setModelNumber(const QString& modelNumber); inline bool setModelUrl(const QUrl& modelUrl) { m_modelUrl = modelUrl; return true; } bool setSerialNumber(const QString& serialNumber); inline bool setUdn(const HUdn& udn, HValidityCheckLevel checkLevel) { if (!udn.isValid(checkLevel)) { return false; } m_udn = udn; return true; } bool setUpc(const QString& upc); bool setIcons(const QList& icons); inline bool setPresentationUrl(const QUrl& presentationUrl) { Q_ASSERT(presentationUrl.isValid() || presentationUrl.isEmpty()); m_presentationUrl = presentationUrl; return true; } }; } } #endif /* HDEVICEINFO_P_H_ */ herqq-1.0.0/hupnp/src/dataelements/hserviceinfo.h0000644000000000000000000001443411543637310020563 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVICEINFO_H_ #define HSERVICEINFO_H_ #include #include class QUrl; class QString; namespace Herqq { namespace Upnp { class HServiceInfoPrivate; /*! * \brief This class is used to contain information of a UPnP service * found in a UPnP device description document. * * A device description defines a UPnP device and among other things, * the definition includes the declarations of the services the device contains. * \brief This class contains the service declaration information. * * \headerfile hserviceinfo.h HServiceInfo * * \ingroup hupnp_common * * \remarks This class is not thread-safe. * * \sa HDeviceInfo, HActionInfo and HStateVariableInfo. */ class H_UPNP_CORE_EXPORT HServiceInfo { friend H_UPNP_CORE_EXPORT bool operator==( const HServiceInfo& obj1, const HServiceInfo& obj2); private: QSharedDataPointer h_ptr; public: /*! * \brief Creates a new, empty instance. * * \sa isValid() */ HServiceInfo(); /*! * Constructs a new instance from the specified parameters that the UDA * specification mandates for a UPnP service. * * The parameters the constructor expects are arguments defined in the * device description document and they are all mandatory for a valid * UPnP service. * * \param serviceId specifies the identifier of the service. * * \param serviceType specifies the type of the service. * * \param controlUrl specifies the URL for control. * * \param eventSubUrl specifies the URL for eventing. * * \param scpdUrl specifies the URL for service description. * * \param incReq specifies whether the service is required or optional. * This parameter is optional. * * \param checkLevel specifies the level of strictness used in validating * the specified arguments. This parameter is optional. * * \param err specifies a pointer to a \c QString that will contain * an error description in case the construction failed. This is optional. * * \remarks in case any of the provided arguments does not meet the * specified requirements, the created object is \e invalid. * * \sa isValid() */ HServiceInfo( const HServiceId& serviceId, const HResourceType& serviceType, const QUrl& controlUrl, const QUrl& eventSubUrl, const QUrl& scpdUrl, HInclusionRequirement incReq = InclusionMandatory, HValidityCheckLevel checkLevel = StrictChecks, QString* err = 0); /*! * \brief Destroys the instance. */ ~HServiceInfo(); /*! * \brief Copy constructor. * * Copies the contents of the \c other to this. * * \param other specifies the object to be copied. */ HServiceInfo(const HServiceInfo& other); /*! * \brief Assignment operator. * * Assigns the contents of the other to this. * * \param other specifies the object to be copied. */ HServiceInfo& operator=(const HServiceInfo& other); /*! * \brief Indicates if the object is valid. * * A valid object contains the mandatory data of a UPnP service. * * \param level specifies the level of strictness used in validating * the object. This parameter is optional and the default level is strict. * * \return \e true in case the object is valid. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Returns the service identifier found in the device description file. * * \return The service identifier found in the device description file. */ const HServiceId& serviceId() const; /*! * \brief Returns the type of the service found in the device description file. * * \return The type of the service found in the device description file. */ const HResourceType& serviceType() const; /*! * \brief Returns the URL for service description. * * This is the URL where the service description can be retrieved. * This is defined in the device description. * * \return The URL for service description. */ QUrl scpdUrl() const; /*! * \brief Returns the URL for control. * * This is the URL to which the action invocations must be sent. * This is defined in the device description. * * \return The URL for control. */ QUrl controlUrl() const; /*! * \brief Returns the URL for eventing. * * This is the URL to which subscriptions and un-subscriptions are sent. * This is defined in the device description. * * \return The URL for eventing. */ QUrl eventSubUrl() const; /*! * \brief Indicates whether the service is required or optional. * * \return value indicating whether the service is required or optional. */ HInclusionRequirement inclusionRequirement() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically equivalent. * * \relates HServiceInfo */ H_UPNP_CORE_EXPORT bool operator==(const HServiceInfo&, const HServiceInfo&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HServiceInfo */ inline bool operator!=(const HServiceInfo& obj1, const HServiceInfo& obj2) { return !(obj1 == obj2); } } } #endif /* HSERVICEINFO_H_ */ herqq-1.0.0/hupnp/src/dataelements/hactioninfo.h0000644000000000000000000001650411543637310020400 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HACTIONINFO_H_ #define HACTIONINFO_H_ #include #include class QString; namespace Herqq { namespace Upnp { class HActionInfoPrivate; /*! * \brief This class is used to contain information of a UPnP action * found in a UPnP service description document. * * UPnP service description documents specify the actions and state variables * of the service. An instance of this class contain the information of an * action found in a service description document: * * - name() returns the name of the action. * - inputArguments() return the arguments that has to be provided to the * action when it is invoked. * - outputArguments() return the arguments the action will provide after a * successful action invocation. * - returnArgumentName() identifies the output argument that has been * designated as the return value. Note that this may not be defined. * * In addition to the information found in the service description document, * the UPnP service containing the action that is depicted by the HActionInfo object * may have specified additional information about the action. Currently * only inclusionRequirement() is available and it details * whether the action is considered as mandatory or optional. * * \headerfile hactioninfo.h HActionInfo * * \ingroup hupnp_common * * \remarks This class is not thread-safe. * \sa HDeviceInfo, HServiceInfo and HStateVariableInfo. */ class H_UPNP_CORE_EXPORT HActionInfo { friend H_UPNP_CORE_EXPORT bool operator==( const HActionInfo&, const HActionInfo&); private: QSharedDataPointer h_ptr; public: /*! * Creates a new, invalid instance. * * \sa isValid() */ HActionInfo(); /*! * \brief Creates a new instance. * * \param name specifies the name of the action. * * \param incReq specifies whether the action is required by the containing * service. * * \param err specifies a pointer to a \c QString, which contains an * error description in case the construction failed. This * parameter is optional. * * \sa isValid() */ HActionInfo( const QString& name, HInclusionRequirement incReq = InclusionMandatory, QString* err = 0); /*! * \brief Creates a new instance. * * \param name specifies the name of the action. * * \param inputArguments specifies the input arguments of the action. These * are the arguments the user has to provide when the action is invoked. * * \param outputArguments specifies the output arguments of the action. * These are the arguments the action will "return" when the action invocation * is successfully completed. * * \param hasRetVal specifies whether the action has a return value. If this * is \e true the first element of the \c outputArguments is considered as * the return value. Note also that if this is true the \c outputArguments * cannot be empty. * * \param incReq specifies whether the action is required or optional. * * \param err specifies a pointer to a \c QString, which contains an * error description in case the construction failed. This * parameter is optional. * * \sa isValid() */ HActionInfo( const QString& name, const HActionArguments& inputArguments, const HActionArguments& outputArguments, bool hasRetVal, HInclusionRequirement incReq = InclusionMandatory, QString* err = 0); /*! * Copies the contents of the other to this. * * \param other specifies the object to be copied. */ HActionInfo(const HActionInfo& other); /*! * \brief Destroys the instance. */ ~HActionInfo(); /*! * Assigns the contents of the other to this. * * \param other specifies the object to be copied. */ HActionInfo& operator=(const HActionInfo& other); /*! * \brief Returns the name of the action. * * This is the name specified in the corresponding service description file. * * \return The name of the action. */ QString name() const; /*! * \brief Returns the input arguments the action expects. * * These are the arguments the user has to provide when invoking the * action that this info object portrays. * * \return The input arguments the action. * * \sa outputArguments() */ const HActionArguments& inputArguments() const; /*! * \brief Returns the output arguments of the action. * * These are the arguments each successful action invocation will "return" * to user as output values. * * \return The output arguments of the action. * * \sa inputArguments() */ const HActionArguments& outputArguments() const; /*! * \brief Returns the name of the output argument that is marked as the * action's return value. * * \return The name of the output argument that is marked as the action's * return value, or an empty string, if no output argument has been marked as * the action's return value. */ QString returnArgumentName() const; /*! * \brief Indicates whether the action is required or optional. * * \return value indicating whether the action is required or optional. */ HInclusionRequirement inclusionRequirement() const; /*! * \brief Indicates if the object is empty. * * \return \e true in case the object is valid. */ bool isValid() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the object are logically equivalent. * * \relates HActionInfo */ H_UPNP_CORE_EXPORT bool operator==(const HActionInfo&, const HActionInfo&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HActionInfo */ inline bool operator!=(const HActionInfo& obj1, const HActionInfo& obj2) { return !(obj1 == obj2); } /*! * \brief Returns a value that can be used as a unique key in a hash-map identifying * the object. * * \param key specifies the HActionInfo object from which the hash value is created. * * \return a value that can be used as a unique key in a hash-map identifying * the object. * * \remarks the hash is calculated from the name() of the HActionInfo. * * \relates HActionInfo */ H_UPNP_CORE_EXPORT quint32 qHash(const HActionInfo& key); } } #endif /* HACTIONINFO_H_ */ herqq-1.0.0/hupnp/src/dataelements/hserviceid.h0000644000000000000000000001666711543637310020236 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVICEID_H_ #define HSERVICEID_H_ #include #include class QString; namespace Herqq { namespace Upnp { class HServiceIdPrivate; /*! * Class that represents the service identifier of a UPnP service. * * Service identifiers are found in UPnP device descriptions and they use * the following format within services defined by the UPnP Forum: * \verbatim urn:upnp-org:serviceId:serviceID \endverbatim * * In the above format only the tailing \e serviceID varies. * Every service identifier of a standard service type has to begin with * urn:upnp-org:serviceId:. * * With a vendor defined service the format for a service identifier is: * \verbatim urn:domain-name:serviceId:serviceID \endverbatim * * Note, according to the UDA specification Period characters in the * Vendor Domain Name MUST be replaced with hyphens in accordance with RFC 2141. * * In both formats, the last \e serviceID component is the * service identifier suffix. * * \note * For interoperability reasons the class does not enforce the prefix prior * to the actual \c serviceID to be exactly as defined in the UDA. However, you * can call isValid() to check if the instance contains strictly valid information. * * \headerfile hserviceid.h HServiceId * * \remarks This class is not thread-safe. * * \ingroup hupnp_common */ class H_UPNP_CORE_EXPORT HServiceId { friend H_UPNP_CORE_EXPORT bool operator==(const HServiceId&, const HServiceId&); friend H_UPNP_CORE_EXPORT quint32 qHash(const HServiceId& key); private: HServiceIdPrivate* h_ptr; public: /*! * Constructs a new, empty instance. * * Instance created by this constructor is not valid, i.e. isValid() * will return false. * * \sa isValid */ HServiceId(); /*! * Constructs a new instance. * * \param serviceId specifies the contents of the object. If the provided * argument is invalid an empty instance is created. For an object * to be strictly valid the parameter has to follow either of the formats * exactly: * * \li urn:upnp-org:serviceId:serviceID for service identifiers * belonging to a standard service type. * * \li urn:domain-name:serviceId:serviceID for service identifiers * belonging to a vendor defined service type. * * The postfix serviceID is the service identifier suffix. * * \note a valid object will be constructed when the specified string contains * the following tokens separated by a colon: * "urn", "domain-name", "some string" and "some string". * Case sensitivity is forced only when checking for strict validity. * * \sa isValid() */ HServiceId(const QString& serviceId); /*! * Creates a new instance based on the other instance provided. * * \param other specifies the other instance. */ HServiceId(const HServiceId& other); /*! * Assigns the contents of the other instance to this. * * \param other specifies the other instance. * * \return a reference to this instance. */ HServiceId& operator=(const HServiceId& other); /*! * \brief Destroys the instance. */ ~HServiceId(); /*! * \brief Indicates if the service identifier is properly defined. * * \param level specifies whether the contents of the object are checked * for strict validity. Only an object that is strictly valid contains information * as defined in the UDA. * * \return \e true in case the object is considered valid in terms * of the requested strictness. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Indicates whether the service identifier belongs to a standard service * type defined by the UPnP forum or to a vendor defined service. * * \retval true in case the service identifier belongs to a standard service * type defined by the UPnP forum. * \retval false in case the service identifier belongs to a vendor * defined service type or the object is invalid. * * \sa isValid() */ bool isStandardType() const; /*! * \brief Returns the URN of the service identifier. * * \param completeUrn specifies whether the prefix \c urn is returned * as well. If the argument is false, only the actual URN is returned. i.e * if the service identifier is defined as urn:upnp-org:serviceId:MyServiceId * only upnp-org is returned. * * \returns the URN of the service identifier if the object is valid. * If the object is not valid, an empty string is returned. * * \sa isValid() */ QString urn(bool completeUrn = true) const; /*! * \brief Returns the service identifier suffix. * * \returns the service identifier suffix if the object is valid. For instance, if the * service identifier is defined as urn:upnp-org:serviceId:MyServiceId, * the suffix identifier and thus the value returned is \c "MyServiceId". * If the object is not valid, an empty string is returned. * * \sa isValid() */ QString suffix() const; /*! * \brief Returns a string representation of the instance. * * \return a string representation of the instance. The returned string * follows the format defined by UDA if the object is valid. In case of a valid * object, the return value is the string that was used to construct the object. * If the object is invalid, the returned string is empty. * * \sa isValid() */ QString toString() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the provided objects are equal, false otherwise. * * \relates HServiceId */ H_UPNP_CORE_EXPORT bool operator==(const HServiceId&, const HServiceId&); /*! * Compares the two objects for inequality. * * \return \e true in case the provided objects are not equal, false otherwise. * * \relates HServiceId */ inline bool operator!=(const HServiceId& obj1, const HServiceId& obj2) { return !(obj1 == obj2); } /*! * \brief Returns a value that can be used as a unique key in a hash-map identifying * the resource type object. * * \param key specifies the service ID from which the hash value is created. * * \return a value that can be used as a unique key in a hash-map identifying * the resource type object. * * \relates HServiceId */ H_UPNP_CORE_EXPORT quint32 qHash(const HServiceId& key); } } Q_DECLARE_METATYPE(Herqq::Upnp::HServiceId) #endif /* HSERVICEID_H_ */ herqq-1.0.0/hupnp/src/dataelements/hdiscoverytype.h0000644000000000000000000003525611543637310021165 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDISCOVERYTYPE_H_ #define HDISCOVERYTYPE_H_ #include #include class QString; namespace Herqq { namespace Upnp { class HDiscoveryTypePrivate; /*! * \brief This is a class that depicts the different discovery types used in * UPnP networking. * * The UPnP discovery is based on SSDP messages that provide information * about UPnP devices and services the UPnP devices provide. When UPnP devices * use SSDP messages they \e advertise themselves and the embedded devices and * services they contain. When UPnP control points use SSDP messages they * \e search UPnP devices or services matching some criteria. In HUPnP these * different search and and advertisement types are called \e discovery \e types * represented by instances of this class. * * For instance, if a UPnP device advertises itself to the network the * \e discovery \e type is HDiscoveryType::SpecificDevice, since the * Unique Device Name that identifies the device is known. On the other hand, * a control point may be interested in searching all UPnP root devices on a * network in which case the \e discovery \e type would be HDiscoveryType::RootDevices. * Then again, if a control point is interested in searching some specific * UPnP root device it can issue a search with the discovery type set to * HDiscoveryType::SpecificRootDevice and the UDN set to the desired value. * * The above example implies that a \e discovery \e type may identify a UPnP device. * If a discovery type identifies a UPnP device you can call udn() to retrieve the * Unique Device Name. Similarly, you can call setUdn() to specify the desired UDN. * * A discovery type may also have a \e resource \e type associated with it. * A \e resource \e type specifies the exact type of a device or a service * and whether it is standard or vendor defined. If the resource type is specified * you can call resourceType() to retrieve it. Similarly, you can call * setResourceType() to specify it. * * \headerfile hdiscoverytype.h HDiscoveryType * * \remarks This class is not thread-safe. * * \ingroup hupnp_common * * \sa Type, type() */ class H_UPNP_CORE_EXPORT HDiscoveryType { friend H_UPNP_CORE_EXPORT bool operator==( const HDiscoveryType&, const HDiscoveryType&); private: QSharedDataPointer h_ptr; public: /*! * \brief Specifies the discovery type. See UPnP v1.1 Device Architecture * specification chapter 1 for more information. */ enum Type { /*! * The discovery type is unspecified. * * This value is used when the discovery type is invalid. */ Undefined = 0, /*! * The discovery type is "ssdp:all". * * This is used when the discovery type specifies all UPnP devices and services. * This value is used by control points to perform a device discovery for all * UPnP devices and services. */ All, /*! * The discovery type is "upnp:rootdevice". * * This is used when the discovery type specifies all UPnP root devices. * This value is used by control points to perform a device discovery for * all UPnP root devices. */ RootDevices, /*! * The discovery type is "uuid:device-UUID::upnp:rootdevice". * * This is used when the discovery type specifies a particular * UPnP root device. * * This value is used by control points and UPnP devices to search or * advertise a specific UPnP root device. */ SpecificRootDevice, /*! * The discovery type is "uuid:device-UUID". * * This is used when the discovery type specifies a particular UPnP device, * which may be a root or an embedded device. * * This value is used by control points and UPnP devices to search or * advertise a specific UPnP device. */ SpecificDevice, /*! * The discovery type is "urn:schemas-upnp-org:device:deviceType:ver" or * "urn:domain-name:device:deviceType:ver". * * This is used when the discovery type specifies devices of certain type. * * This value is used by control points to perform discovery for * specific type of UPnP devices. */ DeviceType, /*! * The discovery type is * "uuid-device-UUID::urn:schemas-upnp-org:device:deviceType:ver" * or "uuid-device-UUID::urn:domain-name:device:deviceType:ver". * * This is used when the discovery type specifies a particular device * that is of certain type. * * This value is used by control points and UPnP devices to search or * advertise a specific UPnP device that is of specific type. */ SpecificDeviceWithType, /*! * The discovery type is "urn:schemas-upnp-org:service:serviceType:ver" or * "urn:domain-name:service:serviceType:ver". * * This is used when the discovery type specifies services of certain type. * * This value is used by control points to perform discovery for * specific type of UPnP services. */ ServiceType, /*! * The discovery type is * "uuid-device-UUID::urn:schemas-upnp-org:service:serviceType:ver" * or "uuid-device-UUID::urn:domain-name:service:serviceType:ver". * * This is used when the discovery type specifies particular service * that is of certain type. * * This value is used by control points and UPnP devices to search or * advertise a specific type of UPnP service within a specific UPnP device. */ SpecificServiceWithType }; /*! * Creates a new empty instance. * * The type is set to HDiscoveryType::Undefined. * * \sa type() */ HDiscoveryType(); /*! * \brief Creates a new instance. * * A discovery type created using a valid UDN identifies a UPnP * device as the resource. The resource type is not specified. * * \param udn specifies the contents of the object. In case the provided * argument is valid the type() of the created object is * HDiscoveryType::SpecificDevice. Otherwise the type is set to * HDiscoveryType::Undefined. * * \param isRootDevice indicates whether the specified UDN belongs to a * root device. If the value is \e true the type() is set to * HDiscoveryType::SpecificRootDevice. If the value is \e false the * type is set to HDiscoveryType::SpecificDevice. * * \param checkLevel specifies the level of strictness used in validating * the specified arguments. This parameter is optional. * * \sa type() */ explicit HDiscoveryType( const HUdn& udn, bool isRootDevice=false, HValidityCheckLevel checkLevel = StrictChecks); /*! * \brief Creates a new instance. * * A discovery type created using a valid resource type specifies the device * or service type. No UDN is provided, which means the discovery type does not * specify a UPnP device. * * \param resourceType specifies the contents of the object. In case * the provided argument is valid the type() of the created object is either * - HDiscoveryType::DeviceType or * - HDiscoveryType::ServiceType depending of the argument. In case the * provided argument is invalid the type is set to HDiscoveryType::Undefined. * * \sa type(), setUdn() */ explicit HDiscoveryType(const HResourceType& resourceType); /*! * \brief Creates a new instance. * * A discovery type created with a valid UDN and a valid resource type * identifies a specific UPnP device or UPnP service that is of certain type. * Both of the provided arguments have to be valid in order to create a valid type. * Otherwise the type() is set to HDiscoveryType::Undefined. * * \param udn specifies the Unique Device Name. * * \param resourceType specifies the resource type. * * \param checkLevel specifies the level of strictness used in validating * the specified arguments. This parameter is optional. * * \sa type(), udn(), resourceType() */ HDiscoveryType( const HUdn& udn, const HResourceType& resourceType, HValidityCheckLevel checkLevel = StrictChecks); /*! * \brief Creates a new instance. * * \param resource specifies the contents of the object. In case the * the provided argument cannot be parsed to a valid resource identifier the * type() is set to HDiscoveryType::Undefined. * * \param checkLevel specifies the level of strictness used in validating * the specified arguments. This parameter is optional. * * Valid string formats are: * * - ssdp:all to specify "any UPnP device and service", * - [uuid:device-UUID] to spesify a specific UPnP device, * - [uuid:device-UUID::]upnp:rootdevice to specify a specific UPnP root device, * - [uuid:device-UUID::]urn:schemas-upnp-org:device:deviceType:ver * to specify a specific UPnP device, which type is standard defined. * - [uuid:device-UUID::]urn:domain-name:device:deviceType:ver * to specify a specific UPnP device that, which type is vendor defined. * - [uuid:device-UUID::]urn:schemas-upnp-org:service:serviceType:ver * to specify a specific UPnP service, which type is standard defined. * - [uuid:device-UUID::]urn:domain-name:service:serviceType:ver * to specify a specific UPnP device, which type is vendor defined. * * The content inside square brackets (uuid:device-UUID) is optional and does * not have to be provided. */ explicit HDiscoveryType( const QString& resource, HValidityCheckLevel checkLevel = StrictChecks); /*! * \brief Destroys the instance. */ ~HDiscoveryType(); /*! * Copies the contents of the other object to this. */ HDiscoveryType(const HDiscoveryType&); /*! * Assigns the contents of the other object to this. * * \return a reference to this object. */ HDiscoveryType& operator=(const HDiscoveryType&); /*! * \brief Returns the type of the object. * * \return The type of the object. If the resource is not specified the type * returned is HDiscoveryType::Undefined. */ Type type() const; /*! * \brief Returns the Unique Device Name of the resource. * * \return The Unique Device Name of the resource if it is set. Note, * the UDN is never set when the type() is either * HDiscoveryType::AllDevices or HDiscoveryType::Undefined. * * \sa setUdn() */ const HUdn& udn() const; /*! * \brief Sets the UDN of the object. * * \note Changing the UDN may change the resourceType() and the type(). * For instance, if the object did not have UDN set before, * changing the UDN will change the type() of the object. * * \param udn specifies the new UDN. The specified UDN has to be valid * in terms of the level of validity checks being run. Otherwise the UDN * will not be set. * * \param checkLevel specifies the level of strictness used in validating * the specified UDN. This parameter is optional, but by default * the UDN is verified strictly. * * \sa udn() */ void setUdn(const HUdn& udn, HValidityCheckLevel checkLevel = StrictChecks); /*! * \brief Returns the resource type associated with this identifier, if any. * * \return The resource type associated with this identifier if it is set. * Note, the returned object is valid only when the type() is either * standard or vendor specified device or service type. * * \sa setResourceType() */ const HResourceType& resourceType() const; /*! * \brief Sets the resource type of the object. * * \param resourceType specifies the new resource type. * * \sa resourceType() */ void setResourceType(const HResourceType& resourceType); /*! * \brief Returns a string representation of the object. * * \return a string representation of the object or an empty string, * if the object does not specify a valid resource. * * \sa Type */ QString toString() const; /*! * Creates an object, which type is set to HDiscoveryType::RootDevices. * * \return an object, which type is set to HDiscoveryType::RootDevices. * * \remarks This is only a helper method. A logically equivalent object * can be constructed with the string "upnp:rootdevice". */ static HDiscoveryType createDiscoveryTypeForRootDevices(); /*! * Creates an object, which type is set to HDiscoveryType::All. * * \return an object, which type is set to HDiscoveryType::All. * * \remarks This is only a helper method. A logically equivalent object * can be constructed with the string "ssdp:all". */ static HDiscoveryType createDiscoveryTypeForAllResources(); }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically equivalent. * * \relates HDiscoveryType */ H_UPNP_CORE_EXPORT bool operator==(const HDiscoveryType&, const HDiscoveryType&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HDiscoveryType */ inline bool operator!=(const HDiscoveryType& obj1, const HDiscoveryType& obj2) { return !(obj1 == obj2); } } } #endif /* HDISCOVERYTYPE_H_ */ herqq-1.0.0/hupnp/src/dataelements/hdeviceinfo.cpp0000644000000000000000000002657311543637310020724 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdeviceinfo.h" #include "hdeviceinfo_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HDeviceInfoPrivate ******************************************************************************/ HDeviceInfoPrivate::HDeviceInfoPrivate() : m_deviceType (), m_friendlyName(), m_manufacturer(), m_manufacturerUrl(), m_modelDescription(), m_modelName (), m_modelNumber (), m_modelUrl (), m_serialNumber (), m_udn (), m_upc (), m_presentationUrl(), m_icons() { } HDeviceInfoPrivate::~HDeviceInfoPrivate() { } bool HDeviceInfoPrivate::setDeviceType(const HResourceType& deviceType) { if (!deviceType.isValid()) { return false; } if (deviceType.type() != HResourceType::StandardDeviceType && deviceType.type() != HResourceType::VendorSpecifiedDeviceType) { return false; } m_deviceType = deviceType; return true; } bool HDeviceInfoPrivate::setFriendlyName(const QString& friendlyName) { HLOG(H_AT, H_FUN); if (friendlyName.isEmpty()) { return false; } if (friendlyName.size() > 64) { HLOG_WARN(QString( "friendlyName longer than 64 characters").arg(friendlyName)); } m_friendlyName = friendlyName; return true; } bool HDeviceInfoPrivate::setManufacturer(const QString& manufacturer) { HLOG(H_AT, H_FUN); if (manufacturer.isEmpty()) { return false; } if (manufacturer.size() > 64) { HLOG_WARN(QString( "manufacturer longer than 64 characters").arg(manufacturer)); } m_manufacturer = manufacturer; return true; } bool HDeviceInfoPrivate::setModelDescription(const QString& modelDescription) { HLOG(H_AT, H_FUN); if (modelDescription.size() > 128) { HLOG_WARN(QString( "modelDescription longer than 64 characters").arg(modelDescription)); } m_modelDescription = modelDescription; return true; } bool HDeviceInfoPrivate::setModelName(const QString& modelName) { HLOG(H_AT, H_FUN); if (modelName.isEmpty()) { return false; } if (modelName.size() > 32) { HLOG_WARN(QString( "modelName longer than 32 characters: [%1]").arg(modelName)); } m_modelName = modelName; return true; } bool HDeviceInfoPrivate::setModelNumber(const QString& modelNumber) { HLOG(H_AT, H_FUN); if (modelNumber.size() > 32) { HLOG_WARN(QString( "modelNumber longer than 32 characters: [%1]").arg(modelNumber)); } m_modelNumber = modelNumber; return true; } bool HDeviceInfoPrivate::setSerialNumber(const QString& serialNumber) { HLOG(H_AT, H_FUN); if (serialNumber.size() > 64) { HLOG_WARN(QString( "serialNumber longer than 64 characters: [%1]").arg(serialNumber)); } m_serialNumber = serialNumber; return true; } bool HDeviceInfoPrivate::setUpc(const QString& upc) { HLOG(H_AT, H_FUN); if (upc.isEmpty()) { // UPC is optional, so if it is not provided at all, that is okay. return false; } // even if something is provided, we only warn the user of possible error. // (since upc is optional) if (upc.size() > 13 || upc.size() < 12) { // a white-space and a hyphen in the middle are acceptable HLOG_WARN_NONSTD(QString( "UPC should be 12-digit, all-numeric code. Encountered: [%1].").arg( upc)); } else { for(qint32 i = 0; i < upc.size(); ++i) { QChar ch = upc[i]; if ((i == 6 && !ch.isSpace() && ch != '-' && upc.size() == 13) || !ch.isDigit()) { HLOG_WARN_NONSTD(QString( "UPC should be 12-digit, all-numeric code. " "Ignoring invalid value [%1].").arg(upc)); break; } } } m_upc = upc; return true; } bool HDeviceInfoPrivate::setIcons(const QList& icons) { m_icons = icons; return true; } /******************************************************************************* * HDeviceInfo ******************************************************************************/ HDeviceInfo::HDeviceInfo() : h_ptr(new HDeviceInfoPrivate()) { } HDeviceInfo::HDeviceInfo(const HDeviceInfo& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HDeviceInfo& HDeviceInfo::operator=(const HDeviceInfo& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HDeviceInfo::HDeviceInfo( const HResourceType& deviceType, const QString& friendlyName, const QString& manufacturer, const QString& modelName, const HUdn& udn, HValidityCheckLevel checkLevel, QString* err) : h_ptr(new HDeviceInfoPrivate()) { QScopedPointer tmp(new HDeviceInfoPrivate()); QString errTmp; if (!tmp->setDeviceType(deviceType)) { errTmp = QString("Invalid device type: [%1]").arg(deviceType.toString()); } else if (!tmp->setFriendlyName(friendlyName)) { errTmp = QString("Invalid friendly name: [%1]").arg(friendlyName); } else if (!tmp->setManufacturer(manufacturer)) { errTmp = QString("Invalid manufacturer: [%1]").arg(manufacturer); } else if (!tmp->setModelName(modelName)) { errTmp = QString("Invalid model name: [%1]").arg(modelName); } else if (!tmp->setUdn(udn, checkLevel)) { errTmp = QString("Invalid UDN: [%1]").arg(udn.toString()); } if (!errTmp.isEmpty()) { if (err) { *err = errTmp; } } else { h_ptr = tmp.take(); } } HDeviceInfo::HDeviceInfo( const HResourceType& deviceType, const QString& friendlyName, const QString& manufacturer, const QUrl& manufacturerUrl, const QString& modelDescription, const QString& modelName, const QString& modelNumber, const QUrl& modelUrl, const QString& serialNumber, const HUdn& udn, const QString& upc, const QList& icons, const QUrl& presentationUrl, HValidityCheckLevel checkLevel, QString* err) : h_ptr(new HDeviceInfoPrivate()) { QScopedPointer tmp(new HDeviceInfoPrivate()); QString errTmp; if (!tmp->setDeviceType(deviceType)) { errTmp = QString("Invalid device type: [%1]").arg(deviceType.toString()); } else if (!tmp->setFriendlyName(friendlyName)) { errTmp = QString("Invalid friendly name: [%1]").arg(friendlyName); } else if (!tmp->setManufacturer(manufacturer)) { errTmp = QString("Invalid manufacturer: [%1]").arg(manufacturer); } else if (!tmp->setModelName(modelName)) { errTmp = QString("Invalid model name: [%1]").arg(modelName); } else if (!tmp->setUdn(udn, checkLevel)) { errTmp = QString("Invalid UDN: [%1]").arg(udn.toString()); } if (!errTmp.isEmpty()) { if (err) { *err = errTmp; } } else { h_ptr = tmp.take(); } // these are optional ==> no need to be strict h_ptr->setManufacturerUrl (manufacturerUrl.toString()); h_ptr->setModelDescription(modelDescription); h_ptr->setModelNumber (modelNumber); h_ptr->setModelUrl (modelUrl.toString()); h_ptr->setSerialNumber (serialNumber); h_ptr->setUpc (upc); h_ptr->setIcons (icons); h_ptr->setPresentationUrl (presentationUrl.toString()); } HDeviceInfo::~HDeviceInfo() { } bool HDeviceInfo::isValid(HValidityCheckLevel level) const { return h_ptr->m_deviceType.isValid() && h_ptr->m_udn.isValid(level); } void HDeviceInfo::setManufacturerUrl(const QUrl& arg) { h_ptr->setManufacturerUrl(arg); } void HDeviceInfo::setModelDescription(const QString& arg) { h_ptr->setModelDescription(arg); } void HDeviceInfo::setModelNumber(const QString& arg) { h_ptr->setModelNumber(arg); } void HDeviceInfo::setModelUrl(const QUrl& arg) { h_ptr->setModelUrl(arg); } void HDeviceInfo::setSerialNumber(const QString& arg) { h_ptr->setSerialNumber(arg); } void HDeviceInfo::setUpc(const QString& arg) { h_ptr->setUpc(arg); } void HDeviceInfo::setIcons(const QList& arg) { h_ptr->setIcons(arg); } void HDeviceInfo::setPresentationUrl(const QUrl& arg) { h_ptr->setPresentationUrl(arg); } const HResourceType& HDeviceInfo::deviceType() const { return h_ptr->m_deviceType; } QString HDeviceInfo::friendlyName() const { return h_ptr->m_friendlyName; } QString HDeviceInfo::manufacturer() const { return h_ptr->m_manufacturer; } QUrl HDeviceInfo::manufacturerUrl() const { return h_ptr->m_manufacturerUrl; } QString HDeviceInfo::modelDescription() const { return h_ptr->m_modelDescription; } QString HDeviceInfo::modelName () const { return h_ptr->m_modelName; } QString HDeviceInfo::modelNumber() const { return h_ptr->m_modelNumber; } QUrl HDeviceInfo::modelUrl() const { return h_ptr->m_modelUrl; } QString HDeviceInfo::serialNumber() const { return h_ptr->m_serialNumber; } const HUdn& HDeviceInfo::udn() const { return h_ptr->m_udn; } QString HDeviceInfo::upc() const { return h_ptr->m_upc; } QList HDeviceInfo::icons() const { return h_ptr->m_icons; } QUrl HDeviceInfo::presentationUrl() const { return h_ptr->m_presentationUrl; } bool operator==(const HDeviceInfo& obj1, const HDeviceInfo& obj2) { return obj1.h_ptr->m_deviceType == obj2.h_ptr->m_deviceType && obj1.h_ptr->m_friendlyName == obj2.h_ptr->m_friendlyName && obj1.h_ptr->m_manufacturer == obj2.h_ptr->m_manufacturer && obj1.h_ptr->m_manufacturerUrl == obj2.h_ptr->m_manufacturerUrl && obj1.h_ptr->m_modelDescription == obj2.h_ptr->m_modelDescription && obj1.h_ptr->m_modelName == obj2.h_ptr->m_modelName && obj1.h_ptr->m_modelNumber == obj2.h_ptr->m_modelNumber && obj1.h_ptr->m_modelUrl == obj2.h_ptr->m_modelUrl && obj1.h_ptr->m_serialNumber == obj2.h_ptr->m_serialNumber && obj1.h_ptr->m_udn == obj2.h_ptr->m_udn && obj1.h_ptr->m_upc == obj2.h_ptr->m_upc && obj1.h_ptr->m_presentationUrl == obj2.h_ptr->m_presentationUrl && obj1.h_ptr->m_icons == obj2.h_ptr->m_icons; } } } herqq-1.0.0/hupnp/src/dataelements/dataelements.pri0000644000000000000000000000216611543637310021107 0ustar rootroot HEADERS += \ $$SRC_LOC/dataelements/hactioninfo.h \ $$SRC_LOC/dataelements/hactioninfo_p.h \ $$SRC_LOC/dataelements/hdeviceinfo.h \ $$SRC_LOC/dataelements/hdeviceinfo_p.h \ $$SRC_LOC/dataelements/hserviceinfo.h \ $$SRC_LOC/dataelements/hserviceinfo_p.h \ $$SRC_LOC/dataelements/hserviceid.h \ $$SRC_LOC/dataelements/hudn.h \ $$SRC_LOC/dataelements/hresourcetype.h \ $$SRC_LOC/dataelements/hproduct_tokens.h \ $$SRC_LOC/dataelements/hdiscoverytype.h \ $$SRC_LOC/dataelements/hstatevariableinfo.h \ $$SRC_LOC/dataelements/hstatevariableinfo_p.h \ $$SRC_LOC/dataelements/hvaluerange_p.h SOURCES += \ $$SRC_LOC/dataelements/hactioninfo.cpp \ $$SRC_LOC/dataelements/hdeviceinfo.cpp \ $$SRC_LOC/dataelements/hserviceinfo.cpp \ $$SRC_LOC/dataelements/hserviceid.cpp \ $$SRC_LOC/dataelements/hudn.cpp \ $$SRC_LOC/dataelements/hresourcetype.cpp \ $$SRC_LOC/dataelements/hproduct_tokens.cpp \ $$SRC_LOC/dataelements/hdiscoverytype.cpp \ $$SRC_LOC/dataelements/hstatevariableinfo.cpp \ $$SRC_LOC/dataelements/hvaluerange_p.cpp herqq-1.0.0/hupnp/src/dataelements/hstatevariableinfo.h0000644000000000000000000004364011543637310021752 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSTATEVARIABLEINFO_H_ #define HSTATEVARIABLEINFO_H_ #include #include #include class QString; class QVariant; namespace Herqq { namespace Upnp { class HStateVariableInfoPrivate; /*! * \brief This class is used to contain information of a UPnP state variable * found in a UPnP service description document. * * UPnP service description documents specify the actions and state variables * of the service. An instance of this class contain the information of a * state variable found in a service description document, such as the * name() and the dataType(). * * In addition to the information found in the service description document, * the UPnP service containing the state variable that is depicted by the * HStateVariableInfo object may have specified additional information * about the state variable: * * - inclusionRequirement() details whether the state variable is considered as * mandatory or optional. * - maxEventRate() specifies the maximum rate at which an evented * state variable may send events. * * Further, the class contains a few helper methods: * - isConstrained() indicates if the state variable is restricted either by * a value range or a value list. * - isValidValue() checks if a specified \c QVariant contains a value that could be * inserted into the state variable taking into consideration the data types * of the state variable and the specified value as well as any possible * constraint set to the state variable. * * \headerfile hstatevariableinfo.h HStateVariableInfo * * \ingroup hupnp_common * * \remarks This class is not thread-safe. * * \sa HDeviceInfo, HServiceInfo and HActionInfo. */ class H_UPNP_CORE_EXPORT HStateVariableInfo { friend H_UPNP_CORE_EXPORT bool operator==( const HStateVariableInfo&, const HStateVariableInfo&); public: /*! * \brief Specifies different types of eventing. * * \sa hupnp_devicehosting */ enum EventingType { /*! * The state variable is not evented and it will never emit * valueChanged() signal. */ NoEvents = 0, /*! * The state variable is evented, valueChanged() signal is emitted upon * value change and the HUPnP will propagate events over network * to registered listeners through unicast only. */ UnicastOnly = 1, /*! * The state variable is evented, valueChanged() signal is emitted upon * value change and the HUPnP will propagate events over network * using uni- and multicast. */ UnicastAndMulticast = 2 }; private: QSharedDataPointer h_ptr; public: /*! * \brief Creates a new, empty instance. * * \sa isValid() */ HStateVariableInfo(); /*! * \brief Creates a new instance. * * \param name specifies the name of the state variable. * * \param dataType specifies the UPnP data type of the state variable. * * \param incReq specifies whether the service is required or optional. * This parameter is optional. * * \param err specifies a pointer to a \c QString that will contain * an error description in case the construction failed. This is optional. * * \sa isValid() */ HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType dataType, HInclusionRequirement incReq, QString* err = 0); /*! * \brief Creates a new instance. * * \param name specifies the name of the state variable. * * \param dataType specifies the UPnP data type of the state variable. * * \param eventingType specifies the type of eventing used with the * state variable. This is optional. * * \param incReq specifies whether the service is required or optional. * This parameter is optional. * * \param err specifies a pointer to a \c QString that will contain * an error description in case the construction failed. This is optional. * * \sa isValid() */ HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType dataType, EventingType eventingType = NoEvents, HInclusionRequirement incReq = InclusionMandatory, QString* err = 0); /*! * \brief Creates a new instance. * * \param name specifies the name of the state variable. * * \param dataType specifies the UPnP data type of the state variable. * * \param defaultValue specifies the default value. * * \param eventingType specifies the type of eventing used with the * state variable. This is optional. * * \param incReq specifies whether the service is required or optional. * This parameter is optional. * * \param err specifies a pointer to a \c QString that will contain * an error description in case the construction failed. This is optional. * * \sa isValid() */ HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType dataType, const QVariant& defaultValue, EventingType eventingType = NoEvents, HInclusionRequirement incReq = InclusionMandatory, QString* err = 0); /*! * Creates a new instance with the data type set to \c HUpnpDataTypes::string. * * \param name specifies the name of the state variable. * * \param defaultValue specifies the default value. * * \param allowedValueList specifies the values the state variable * accepts. * * \param eventingType specifies the type of eventing used with the * state variable. This is optional. * * \param incReq specifies whether the service is required or optional. * This parameter is optional. * * \param err specifies a pointer to a \c QString that will contain * an error description in case the construction failed. This is optional. * * \sa isValid() */ HStateVariableInfo( const QString& name, const QVariant& defaultValue, const QStringList& allowedValueList, EventingType eventingType = NoEvents, HInclusionRequirement incReq = InclusionMandatory, QString* err = 0); /*! * \param name specifies the name of the state variable. * * \param dataType specifies the UPnP data type of the state variable. * * \param defaultValue specifies the default value. * * \param minimumValue specifies the inclusive lower bound of an * acceptable value. This cannot be larger than the \c maximumValue. * * \param maximumValue specifies the inclusive upper bound of an * acceptable value. This cannot be smaller than the \c minimumValue. * * \param stepValue specifies the step value. This value cannot be * larger than the subtraction of the maximum and minimum values. * * \param eventingType specifies the type of eventing used with the * state variable. This is optional. * * \param incReq specifies whether the service is required or optional. * This parameter is optional. * * \param err specifies a pointer to a \c QString that will contain * an error description in case the construction failed. This is optional. * */ HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType dataType, const QVariant& defaultValue, const QVariant& minimumValue, const QVariant& maximumValue, const QVariant& stepValue, EventingType eventingType = NoEvents, HInclusionRequirement incReq = InclusionMandatory, QString* err = 0); /*! * \brief Copy constructor. * * Creates a new instance identical to the \c other object. */ HStateVariableInfo(const HStateVariableInfo&); /*! * \brief Assignment operator. * * Assigns the contents of the \c other to this. */ HStateVariableInfo& operator=(const HStateVariableInfo&); /*! * \brief Destroys the instance. */ ~HStateVariableInfo(); /*! * \brief Returns the UPnP service version in which the state variable * was first specified. * * \return The UPnP service version in which the state variable * was first specified or \c -1, if the version is not defined. * * \remarks It is perfectly normal that the version information is not * defined. * * \sa setVersion() */ qint32 version() const; /*! * \brief Specifies the UPnP service version in which the state variable * was first specified. * * \param version specifies the UPnP service version in which the * state variable was first specified. If a value smaller than \c -1 is * given, the version value will be set to \c -1, which means that the * version() is not defined. * * \sa version() */ void setVersion(qint32 version); /*! * \brief Returns the name of the action. * * This is the name specified in the corresponding service description file. * * \return The name of the action. */ QString name() const; /*! * \brief Returns the type of the action, i.e. is it required or optional. * * This is the name specified in the corresponding service description file. * * \return The type of the action. */ HInclusionRequirement inclusionRequirement() const; /*! * \brief Specifies whether the depicted state variable is required or optional. * * \param arg specifies whether the service is required or optional. */ void setInclusionRequirement(HInclusionRequirement arg); /*! * \brief Returns the maximum rate at which an evented state variable may send * events. * * \return The maximum rate at which an evented state variable may send * events. The returned value is -1 if the state variable is not evented or * the maximum rate has not been defined. * * \sa setMaxEventRate(), eventingType() */ qint32 maxEventRate() const; /*! * \brief Sets the maximum rate at which an evented state variable may send * events. * * \param arg specifies the maximum rate at which an evented state * variable may send events. The rate is not set if the state variable is * not evented. * * \sa maxEventRate(), eventingType() */ void setMaxEventRate(qint32 arg); /*! * \brief Returns the data type of the state variable. * * \return The data type of the state variable. */ HUpnpDataTypes::DataType dataType() const; /*! * \brief Returns the type of eventing the state variable supports, if any. * * \return The type of eventing the state variable supports, if any. */ EventingType eventingType() const; /*! * \brief Sets the type of eventing the state variable supports, if any. * * \param arg specifies the type of eventing the state variable supports, if any. */ void setEventingType(EventingType arg); /*! * \brief Returns the list of allowed values. * * \return The list of allowed values if the contained data type is string * or empty list otherwise. * * \remarks This is only applicable on state variables, which data type is * HUpnpDataTypes::string. * * \sa setAllowedValueList(), dataType() */ QStringList allowedValueList() const; /*! * \brief Specifies the values the state variable accepts. * * \param arg specifies the values the state variable accepts. * * \remarks This is only applicable on state variables, which data type is * HUpnpDataTypes::string. * * \sa allowedValueList(), dataType() */ bool setAllowedValueList(const QStringList& arg); /*! * \brief Returns the minimum value of the specified value range. * * \return The minimum value of the specified value range. * * \remarks This is only applicable on state variables, which data type is * numeric. In addition, it is optional and it may not be defined. * * \sa dataType() */ QVariant minimumValue() const; /*! * \brief Returns the maximum value of the specified value range. * * \return The maximum value of the specified value range. * * \remarks This is only applicable on state variables, which data type is * numeric. In addition, it is optional and it may not be defined. * * \sa dataType() */ QVariant maximumValue() const; /*! * \brief Returns the step value of the specified value range. * * \return The step value of the specified value range. * * \remarks This is only applicable on state variables, which data type is * numeric. In addition, it is optional and it may not be defined. * * \sa dataType() */ QVariant stepValue() const; /*! * \brief Sets the allowed value range. * * \param minimumValue specifies the inclusive lower bound of an * acceptable value. This cannot be larger than the \c maximumValue. * * \param maximumValue specifies the inclusive upper bound of an * acceptable value. This cannot be smaller than the \c minimumValue. * * \param stepValue specifies the step value. This value cannot be * larger than the subtraction of the maximum and minimum values. * * \param err specifies a pointer to a \c QString, which contains an * error description in case the any of the provided values is invalid. This * parameter is optional. * * \remarks This is only applicable on state variables, which data type is * numeric. In addition, it is optional and it may not be defined. * * \return \e true in case the values were successfully set. */ bool setAllowedValueRange( const QVariant& minimumValue, const QVariant& maximumValue, const QVariant& stepValue, QString* err = 0); /*! * \brief Returns the default value of the state variable. * * \return The default value of the state variable. If no default has been * specified, QVariant::Invalid is returned. */ QVariant defaultValue() const; /*! * \brief Sets the default value. * * \param arg specifies the default value. If the value range has been * specified the value has to be within the specified range. * * \param err specifies a pointer to a \c QString, which contains an * error description in case the value is invalid. This * parameter is optional. * * \return \e true in case the default value was successfully set. */ bool setDefaultValue(const QVariant& arg, QString* err = 0); /*! * \brief Indicates if the state variable's value is constrained either by minimum, * maximum or by a list of allowed values. * * \return true in case the state variable's value is constrained either by minimum, * maximum or by a list of allowed values. * * \sa minimumValue(), maximumValue(), allowedValueList() */ bool isConstrained() const; /*! * \brief Indicates whether or not the value is valid in terms of this particular * state variable. * * \param value specifies the value to be checked. * * \param convertedValue specifies a pointer to a \c QVariant that contains * the value as a variant of the correct type. This is optional. * Further, it will not be set if the value is invalid. * * \param err specifies a pointer to a \c QString, which contains an * error description in case the value is invalid. This * parameter is optional. * * \retval \e true in case the specified value is valid in terms of the * state variable this info object depicts. In other words, setValue() will * succeed with the value. * * \retval false otherwise. */ bool isValidValue( const QVariant& value, QVariant* convertedValue = 0, QString* err = 0) const; /*! * \brief Indicates if the object is valid. * * \return \e true in case the object is valid. */ bool isValid() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the object are logically equivalent. * * \relates HStateVariableInfo */ H_UPNP_CORE_EXPORT bool operator==( const HStateVariableInfo&, const HStateVariableInfo&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HStateVariableInfo */ inline bool operator!=( const HStateVariableInfo& obj1, const HStateVariableInfo& obj2) { return !(obj1 == obj2); } /*! * \brief Returns a value that can be used as a unique key in a hash-map identifying * the object. * * \param key specifies the HStateVariableInfo object from which the hash value * is created. * * \return a value that can be used as a unique key in a hash-map identifying * the object. * * \relates HStateVariableInfo */ H_UPNP_CORE_EXPORT quint32 qHash(const HStateVariableInfo& key); } } #endif /* HSTATEVARIABLEINFO_H_ */ herqq-1.0.0/hupnp/src/dataelements/hstatevariableinfo.cpp0000644000000000000000000004021511543637310022300 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hstatevariableinfo.h" #include "hstatevariableinfo_p.h" #include "../general/hupnp_global_p.h" #include "../general/hupnp_datatypes_p.h" #include "../utils/hmisc_utils_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HStateVariableInfoPrivate ******************************************************************************/ HStateVariableInfoPrivate::HStateVariableInfoPrivate() : m_name(), m_dataType(HUpnpDataTypes::Undefined), m_variantDataType(QVariant::Invalid), m_defaultValue(), m_eventingType(HStateVariableInfo::NoEvents), m_allowedValueList(), m_allowedValueRange(), m_inclusionRequirement(InclusionRequirementUnknown), m_maxRate(-1), m_version(-1) { } bool HStateVariableInfoPrivate::isWithinAllowedRange( const QVariant& value, QString* errDescr) { Q_ASSERT(!m_allowedValueRange.isNull()); Q_ASSERT(HUpnpDataTypes::isNumeric(m_dataType)); if (HUpnpDataTypes::isRational(m_dataType)) { qreal tmp = value.toDouble(); if (tmp < m_allowedValueRange.minimum().toDouble() || tmp > m_allowedValueRange.maximum().toDouble()) { if (errDescr) { *errDescr = QString( "Value [%1] is not within the specified allowed values range.").arg( value.toString()); } return false; } } else { qlonglong tmp = value.toLongLong(); if (tmp < m_allowedValueRange.minimum().toLongLong() || tmp > m_allowedValueRange.maximum().toLongLong()) { if (errDescr) { *errDescr = QString( "Value [%1] is not within the specified allowed values range.").arg( value.toString()); } return false; } } return true; } bool HStateVariableInfoPrivate::checkValue( const QVariant& value, QVariant* acceptableValue, QString* errDescr) const { QVariant tmp(value); if (m_dataType == HUpnpDataTypes::Undefined) { if (errDescr) { *errDescr = QString( "Data type of the state variable [%1] is not defined.").arg( m_name); } return false; } if (value.type() != m_variantDataType) { if (m_variantDataType == QVariant::Url) { // for some reason, QVariant does not provide automatic conversion between // QUrl and other types (this includes QString, unfortunately) and until it does, // this has to be handled as a special case. QUrl valueAsUrl(value.toString()); if (!valueAsUrl.isValid()) { if (errDescr) { *errDescr = QString( "Invalid value for a URL type: [%1]").arg( value.toString()); } return false; } tmp = valueAsUrl; } else if (!tmp.convert(m_variantDataType)) { if (errDescr) { *errDescr = "Data type mismatch."; } return false; } } if (m_dataType == HUpnpDataTypes::string && m_allowedValueList.size()) { if (m_allowedValueList.indexOf(value.toString()) < 0) { if (errDescr) { *errDescr = QString( "Value [%1] is not included in the allowed values list.").arg( value.toString()); } return false; } } else if (HUpnpDataTypes::isRational(m_dataType) && !m_allowedValueRange.isNull()) { qreal tmp = value.toDouble(); if (tmp < m_allowedValueRange.minimum().toDouble() || tmp > m_allowedValueRange.maximum().toDouble()) { if (errDescr) { *errDescr = QString( "Value [%1] is not within the specified allowed values range.").arg( value.toString()); } return false; } } else if (HUpnpDataTypes::isNumeric(m_dataType) && !m_allowedValueRange.isNull()) { qlonglong tmp = value.toLongLong(); if (tmp < m_allowedValueRange.minimum().toLongLong() || tmp > m_allowedValueRange.maximum().toLongLong()) { if (errDescr) { *errDescr = QString( "Value [%1] is not within the specified allowed values range.").arg( value.toString()); } return false; } } *acceptableValue = tmp; return true; } bool HStateVariableInfoPrivate::setName(const QString& name, QString* err) { if (verifyName(name, err)) { m_name = name; return true; } return false; } bool HStateVariableInfoPrivate::setDataType( HUpnpDataTypes::DataType arg, QString* err) { if (arg == HUpnpDataTypes::Undefined) { if (err) { *err = "Data type was undefined"; } return false; } m_dataType = arg; m_variantDataType = HUpnpDataTypes::convertToVariantType(m_dataType); m_defaultValue = QVariant(m_variantDataType); return true; } bool HStateVariableInfoPrivate::setDefaultValue( const QVariant& defVal, QString* err) { if (defVal.isNull() || !defVal.isValid() || ((m_dataType == HUpnpDataTypes::string && m_allowedValueList.size()) && defVal.toString().isEmpty())) { // according to the UDA, default value is OPTIONAL. return true; } QVariant acceptableValue; if (checkValue(defVal, &acceptableValue, err)) { m_defaultValue = acceptableValue; return true; } return false; } bool HStateVariableInfoPrivate::setAllowedValueList( const QStringList& allowedValueList, QString* err) { if (m_dataType != HUpnpDataTypes::string) { if (err) { *err = "The data type of the state variable has to be [string]"; } return false; } m_allowedValueList = allowedValueList; if (!allowedValueList.contains(m_defaultValue.toString())) { m_defaultValue = QVariant(QVariant::String); } return true; } bool HStateVariableInfoPrivate::setAllowedValueRange( const QVariant& minimumValue, const QVariant& maximumValue, const QVariant& stepValue, QString* err) { if (!HUpnpDataTypes::isNumeric(m_dataType)) { if (err) { *err = "Cannot define allowed value range when the data type " "of the state variable is not numeric"; } return false; } HValueRange valueRange; bool ok = HValueRange::fromVariant( m_variantDataType, minimumValue, maximumValue, stepValue, &valueRange, err); if (!ok) { return false; } m_allowedValueRange = valueRange; if (!isWithinAllowedRange(m_defaultValue)) { m_defaultValue = QVariant(m_variantDataType); } return true; } /******************************************************************************* * HStateVariableInfo ******************************************************************************/ HStateVariableInfo::HStateVariableInfo() : h_ptr(new HStateVariableInfoPrivate()) { } HStateVariableInfo::HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType datatype, HInclusionRequirement inclusionReq, QString* err) : h_ptr(new HStateVariableInfoPrivate()) { QScopedPointer hptr( new HStateVariableInfoPrivate()); if (!hptr->setName(name, err)) { return; } if (!hptr->setDataType(datatype, err)) { return; } hptr->m_eventingType = NoEvents; hptr->m_inclusionRequirement = inclusionReq; h_ptr = hptr.take(); } HStateVariableInfo::HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType datatype, EventingType eventingType, HInclusionRequirement inclusionReq, QString* err) : h_ptr(new HStateVariableInfoPrivate()) { QScopedPointer hptr( new HStateVariableInfoPrivate()); if (!hptr->setName(name, err)) { return; } if (!hptr->setDataType(datatype, err)) { return; } hptr->m_eventingType = eventingType; hptr->m_inclusionRequirement = inclusionReq; h_ptr = hptr.take(); } HStateVariableInfo::HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType datatype, const QVariant& defaultValue, EventingType eventingType, HInclusionRequirement inclusionReq, QString* err) : h_ptr(new HStateVariableInfoPrivate()) { QScopedPointer hptr( new HStateVariableInfoPrivate()); if (!hptr->setName(name, err)) { return; } if (!hptr->setDataType(datatype, err)) { return; } if (!hptr->setDefaultValue(defaultValue, err)) { return; } hptr->m_eventingType = eventingType; hptr->m_inclusionRequirement = inclusionReq; h_ptr = hptr.take(); } HStateVariableInfo::HStateVariableInfo( const QString& name, const QVariant& defaultValue, const QStringList& allowedValueList, EventingType eventingType, HInclusionRequirement inclusionReq, QString* err) : h_ptr(new HStateVariableInfoPrivate()) { QScopedPointer hptr( new HStateVariableInfoPrivate()); if (!hptr->setName(name, err)) { return; } if (!hptr->setDataType(HUpnpDataTypes::string)) { return; } if (!hptr->setDefaultValue(defaultValue, err)) { return; } if (!hptr->setAllowedValueList(allowedValueList, err)) { return; } hptr->m_eventingType = eventingType; hptr->m_inclusionRequirement = inclusionReq; h_ptr = hptr.take(); } HStateVariableInfo::HStateVariableInfo( const QString& name, HUpnpDataTypes::DataType datatype, const QVariant& defaultValue, const QVariant& minimumValue, const QVariant& maximumValue, const QVariant& stepValue, EventingType eventingType, HInclusionRequirement inclusionReq, QString* err) : h_ptr(new HStateVariableInfoPrivate()) { QScopedPointer hptr( new HStateVariableInfoPrivate()); if (!hptr->setName(name, err)) { return; } if (!hptr->setDataType(datatype, err)) { return; } if (!hptr->setDefaultValue(defaultValue, err)) { return; } if (!hptr->setAllowedValueRange(minimumValue, maximumValue, stepValue, err)) { return; } hptr->m_eventingType = eventingType; hptr->m_inclusionRequirement = inclusionReq; h_ptr = hptr.take(); } HStateVariableInfo::HStateVariableInfo(const HStateVariableInfo& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HStateVariableInfo& HStateVariableInfo::operator=( const HStateVariableInfo& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HStateVariableInfo::~HStateVariableInfo() { } qint32 HStateVariableInfo::version() const { return h_ptr->m_version; } void HStateVariableInfo::setVersion(qint32 version) { h_ptr->m_version = version < 0 ? -1 : version; } QString HStateVariableInfo::name() const { return h_ptr->m_name; } HInclusionRequirement HStateVariableInfo::inclusionRequirement() const { return h_ptr->m_inclusionRequirement; } void HStateVariableInfo::setInclusionRequirement(HInclusionRequirement arg) { h_ptr->m_inclusionRequirement = arg; } qint32 HStateVariableInfo::maxEventRate() const { return h_ptr->m_maxRate; } void HStateVariableInfo::setMaxEventRate(qint32 arg) { if (h_ptr->m_eventingType != NoEvents) { h_ptr->m_maxRate = arg < 0 ? -1 : arg; } } HUpnpDataTypes::DataType HStateVariableInfo::dataType() const { return h_ptr->m_dataType; } HStateVariableInfo::EventingType HStateVariableInfo::eventingType() const { return h_ptr->m_eventingType; } void HStateVariableInfo::setEventingType(HStateVariableInfo::EventingType arg) { h_ptr->m_eventingType = arg; } QStringList HStateVariableInfo::allowedValueList() const { return h_ptr->m_allowedValueList; } bool HStateVariableInfo::setAllowedValueList( const QStringList& allowedValueList) { return h_ptr->setAllowedValueList(allowedValueList); } QVariant HStateVariableInfo::minimumValue() const { return h_ptr->m_allowedValueRange.minimum(); } QVariant HStateVariableInfo::maximumValue() const { return h_ptr->m_allowedValueRange.maximum(); } QVariant HStateVariableInfo::stepValue() const { return h_ptr->m_allowedValueRange.step(); } bool HStateVariableInfo::setAllowedValueRange( const QVariant& minimumValue, const QVariant& maximumValue, const QVariant& stepValue, QString* err) { return h_ptr->setAllowedValueRange( minimumValue, maximumValue, stepValue, err); } QVariant HStateVariableInfo::defaultValue() const { return h_ptr->m_defaultValue; } bool HStateVariableInfo::setDefaultValue(const QVariant& defVal, QString* err) { return h_ptr->setDefaultValue(defVal, err); } bool HStateVariableInfo::isConstrained() const { return !h_ptr->m_allowedValueList.isEmpty() || !h_ptr->m_allowedValueRange.isNull(); } bool HStateVariableInfo::isValidValue( const QVariant& value, QVariant* convertedValue, QString* err) const { QVariant acceptableValue; if (h_ptr->checkValue(value, &acceptableValue, err)) { if (convertedValue) { *convertedValue = acceptableValue; } return true; } return false; } bool HStateVariableInfo::isValid() const { return !h_ptr->m_name.isEmpty(); } bool operator==(const HStateVariableInfo& arg1, const HStateVariableInfo& arg2) { return arg1.h_ptr->m_name == arg2.h_ptr->m_name && arg1.h_ptr->m_maxRate == arg2.h_ptr->m_maxRate && arg1.h_ptr->m_version == arg2.h_ptr->m_version && arg1.h_ptr->m_dataType == arg2.h_ptr->m_dataType && arg1.h_ptr->m_defaultValue == arg2.h_ptr->m_defaultValue && arg1.h_ptr->m_eventingType == arg2.h_ptr->m_eventingType && arg1.h_ptr->m_allowedValueList == arg2.h_ptr->m_allowedValueList && arg1.h_ptr->m_allowedValueRange == arg2.h_ptr->m_allowedValueRange && arg1.h_ptr->m_inclusionRequirement == arg2.h_ptr->m_inclusionRequirement; } quint32 qHash(const HStateVariableInfo& key) { QByteArray data = key.name().toLocal8Bit(); return hash(data.constData(), data.size()); } } } herqq-1.0.0/hupnp/src/dataelements/hproduct_tokens.h0000644000000000000000000003305711543637310021314 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HPRODUCT_TOKENS_H #define HPRODUCT_TOKENS_H #include #include #include template class QVector; namespace Herqq { namespace Upnp { /*! * \brief This class represents a product token as defined in the RFC 2616, * section 3.8. * * \headerfile hproduct_tokens.h HProductToken * * \remarks This class is not thread-safe. * * \ingroup hupnp_common */ class H_UPNP_CORE_EXPORT HProductToken { friend H_UPNP_CORE_EXPORT bool operator==( const HProductToken& obj1, const HProductToken& obj2); private: QString m_token; QString m_productVersion; public: /*! * \brief Creates a new, empty instance. An object created with the default * constructor is invalid. * * \sa isValid() */ HProductToken(); /*! * Creates a new object based on the provided token data. If the token data * is invalid, the object will be invalid as well. * * \param token specifies the token part, which is supposed to identify * a product. If this is empty, the created object will be invalid. * * \param productVersion specifies the version part. If this is empty, * the created object will be invalid. * * \sa isValid() */ HProductToken(const QString& token, const QString& productVersion); /*! * \brief Destroys the instance. */ ~HProductToken(); /*! * \brief Indicates if the object is valid, i.e both the token and the product * version are defined. * * \param checkLevel specifies whether the contents of the object are checked * for strict validity. Only an object that is strictly valid * contains information as defined in the UDA. In other words, * a strictly valid product token takes the form * UPnP/majorVersion.minorVersion, where currently major version is * always 1 and minor version is either 0 or 1. * * \return true in case both the \e token and product version * are appropriately specified. * * \sa token(), productVersion() */ bool isValid(HValidityCheckLevel checkLevel) const; /*! * \brief Returns the \e token part. * * \return The \e token part in case the object is valid. * The token part is used to identify the product and an example * of a token is for instance \c "Apache". An empty string is returned in case * the object is invalid. * * \sa isValid() */ inline QString token() const { return m_token; } /*! * \brief Returns the \e version part. * * \return The \e version part in case the object is valid. An example of a * version part is \c "1.0". An empty string is returned in case * the object is invalid. * * \sa isValid() */ inline QString version() const { return m_productVersion; } /*! * \brief Returns a string representation of the object. * * The format of the returned string is \c "token"/"version". * * \return a string representation of the object. */ QString toString() const; /*! * Attempts to parse the \e version part of a product token to a major and * minor component and returns the minor component if the function succeeded. * * For the function to succeed the specified product token has to contain * a version string that follows the format "major.minor". The function ignores * any further "version information" after the "minor" component separated * by a dot. The "minor" component has to be convertible to an integer. * * \return The minor version component of the specified product token or -1 * if the specified token does not contain a minor version component that * can be represented as an integer. */ qint32 minorVersion(); /*! * Attempts to parse the \e version part of a product token to a major and * minor component and returns the major component if the function succeeded. * * For the function to succeed the specified product token has to contain * a version string that either * - can be directly converted to an integer or * - contains information following the format "major.minor", where * the major component can be converted to an integer. Any data following * the "minor" component and separated from it by a dot is ignored. * * \return The major version component of the specified product token or -1 * if the specified token does not contain a major version component that * can be represented as an integer. */ qint32 majorVersion(); }; /*! * Compares the two objects for equality. * * \return \e true in case the object are logically equivalent. * * \relates HProductToken */ H_UPNP_CORE_EXPORT bool operator==(const HProductToken&, const HProductToken&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HProductToken */ H_UPNP_CORE_EXPORT bool operator!=(const HProductToken&, const HProductToken&); class HProductTokensPrivate; /*! * \brief This class is used to parse the product tokens defined by HTTP/1.1. * * According to the HTTP/1.1, Product tokens are used to allow communicating applications * to identify themselves by software name and version. In UDA, * the product tokens consist of three tokens, * in which The first product token identifes the operating system in * the form OS name/OS version, the second token represents the UPnP version and * MUST be UPnP/1.1, and the third token identifes the product using the form * product name/product version. For example, "SERVER: unix/5.1 UPnP/1.1 MyProduct/1.0". * * Unfortunately, product tokens found in UPnP products are rarely conforming to * the HTTP/1.1 and UDA specifications. Many products handle "product tokens" as a string that * contains "key/value" pairs laid out and delimited arbitrarily. Because of this, * \c %HProductTokens has to accept input that is not strictly standard-conformant. * However, at absolute minimum UPnP devices have to provide the UPnP version token. * Because of that, \c %HProductTokens instance is considered valid if the * instance contains a valid UPnP version token. All other tokens are considered * optional and they may not be present in a valid instance. In practice this means that * if isValid() returns true the instance contains a valid UPnP version * token, which can be retrieved using upnpToken(). In that case the tokens() * returns a list at least of size one. In addition, the instance may contain other * data that could not be parsed following the HTTP/1.1 and UDA specifications. This * data cannot be retrieved using any of the functions that return HProductToken * instances, but you can retrieve the full unparsed product tokens string using * toString(). * * \headerfile hproduct_tokens.h HProductTokens * * \remarks This class is not thread-safe. * * \ingroup hupnp_common */ class H_UPNP_CORE_EXPORT HProductTokens { private: QSharedDataPointer h_ptr; public: /*! * Constructs a new invalid and empty instance. * * \sa isValid(), isEmpty() */ HProductTokens(); /*! * Creates a new instance based on the provided argument. * * \param arg specifies the product tokens. In case the specified argument * does not contain a valid UPnP version token the created * object will be invalid. However, the object will not be empty and the * provided string is returned when toString() is called. * * \sa isValid(), isEmpty(), toString(), upnpToken() */ explicit HProductTokens(const QString& arg); /*! * \brief Copy constructor. * * Creates a copy of the other object. */ HProductTokens(const HProductTokens&); /*! * \brief Destroys the instance. */ ~HProductTokens(); /*! * Assigns the contents of the other to this. * * \return a reference to this object. */ HProductTokens& operator=(const HProductTokens&); /*! * \brief Indicates whether the object contains at least the UPnP * version token defined in the UDA. * * \return \e true in case the object contains at least the UPnP version * token defined in the UDA. * * \remarks an invalid object is not necessarily empty; an object may contain * data that could not be parsed into HProductToken objects. In this case * you can call toString() to retrieve the full product tokens string. * * \sa isEmpty() */ bool isValid() const; /*! * \brief Indicates whether the object contains any information at all. * * \return true in case the object does not contain any information. * * \remarks an empty object is also invalid. * * \sa isValid() */ bool isEmpty() const; /*! * \brief Returns the product token that defines information of an operating system. * * \return The product token that defines information of an operating system. * * \remarks This is not necessarily defined in a non-empty object. * * \sa isValid() */ HProductToken osToken() const; /*! * \brief Returns the product token that defines UPnP version. * * \return The product token that defines UPnP version. This token always * follows the format "UPnP"/majorVersion.minorVersion, where \e majorVersion * and \e minorVersion are positive integers. Furthermore, currently * the \e majorVersion is \b always 1 and the \e minorVersion is either 0 * or 1. * * \remarks This is always defined in a valid object. * * \sa isValid() */ HProductToken upnpToken() const; /*! * \brief Returns the product token that defines the actual product in the form * product name/product version. * * \return The product token that defines the actual product in the form * product name/product version. * * \remarks This is not necessarily defined in a non-empty object. * * \sa isValid() */ HProductToken productToken() const; /*! * \brief Returns the extra tokens. * * A valid \c %HProductTokens object contains at least the * upnpToken(). A strictly valid \c %HProductTokens object contains at least * the osToken(), upnpToken() and producToken(). However, a \c %HProductTokens * instance may contain more than these three tokens, which are called extra * tokens in this context. * * \return The extra tokens, if such are defined and the object is valid. * * \sa hasExtraTokens(), isValid(), tokens() */ QVector extraTokens() const; /*! * \brief Indicates if the object contains extra tokens in addition to * osToken(), upnpToken() and producToken(). * * \return true in case the object contains extra tokens in addition to * osToken(), upnpToken() and producToken(). */ bool hasExtraTokens() const; /*! * \brief Returns all product tokens the instance contains. * * A valid \c %HProductTokens object will return a vector that contains * at least one entry, the upnpToken(). A strictly valid \c %HProductTokens * object will return a vector that contains at least three entries, * the osToken(), upnpToken() and producToken(). If the object contains * extra tokens the extra tokens are appended to the returned vector. * * \return all product tokens in a vector. An invalid object returns a * vector with no elements. However, even in this case the object may not be empty. * * \sa isValid(), isEmpty(), extraTokens(), toString() */ QVector tokens() const; /*! * \brief Returns a string representation of the object. * * \return a string representation of the object. * * \remarks This method may return a non-empty string even in case * isValid() returns false. In this case the instance was created with * a string that could not be tokenized according to the UDA and HTTP 1.1 * specifications. * * \sa isEmpty(), isValid() */ QString toString() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically equivalent. * * \relates HProductTokens */ H_UPNP_CORE_EXPORT bool operator==( const HProductTokens&, const HProductTokens&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HProductTokens */ inline bool operator!=(const HProductTokens& obj1, const HProductTokens& obj2) { return !(obj1 == obj2); } } } #endif /* HPRODUCT_TOKENS_H */ herqq-1.0.0/hupnp/src/dataelements/hactioninfo_p.h0000644000000000000000000000315711543637310020717 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HACTIONINFO_P_H_ #define HACTIONINFO_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../devicemodel/hactionarguments.h" #include namespace Herqq { namespace Upnp { // // Implementation details of HActionInfo // class HActionInfoPrivate : public QSharedData { HActionInfo& operator=(const HActionInfoPrivate&); public: // attributes QString m_name; HInclusionRequirement m_inclusionRequirement; HActionArguments m_inputArguments; HActionArguments m_outputArguments; bool m_hasRetValArg; public: // methods HActionInfoPrivate(); }; } } #endif /* HACTIONINFO_P_H_ */ herqq-1.0.0/hupnp/src/dataelements/hserviceid.cpp0000644000000000000000000001406211543637310020554 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hserviceid.h" #include "../general/hlogger_p.h" #include "../utils/hmisc_utils_p.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HServiceIdPrivate ******************************************************************************/ class HServiceIdPrivate { public: QString m_suffix; QStringList m_elements; public: HServiceIdPrivate() : m_suffix(), m_elements() { } HServiceIdPrivate(const QString& arg) : m_suffix(), m_elements() { HLOG(H_AT, H_FUN); QStringList tmp = arg.simplified().split(":"); if (tmp.size() < 4) { HLOG_WARN_NONSTD( QString("Invalid service identifier [%1]").arg(arg)); return; } if (tmp[0].compare("urn", Qt::CaseInsensitive) != 0) { HLOG_WARN_NONSTD( QString("Invalid service identifier [%1]").arg(arg)); return; } if (tmp[1].compare("upnp-org", Qt::CaseInsensitive) != 0) { tmp[1] = tmp[1].replace('.', '-'); if (tmp[1].isEmpty()) { HLOG_WARN_NONSTD(QString( "Invalid service identifier [%1]").arg(arg)); return; } } bool warned = false; if (tmp[2].compare("serviceId", Qt::CaseInsensitive) != 0) { HLOG_WARN_NONSTD(QString("Invalid service identifier [%1]").arg(arg)); warned = true; // at least some Intel software fails to specify this right } if (tmp[3].isEmpty()) { if (!warned) { HLOG_WARN(QString("Invalid service identifier [%1]").arg(arg)); } return; } m_suffix = tmp[3]; for (qint32 i = 4; i < tmp.size(); ++i) { m_suffix.append(':').append(tmp[i]); } m_elements = tmp; } ~HServiceIdPrivate() { } }; /******************************************************************************* * HServiceId ******************************************************************************/ HServiceId::HServiceId() : h_ptr(new HServiceIdPrivate()) { } HServiceId::HServiceId(const QString& serviceId) : h_ptr(new HServiceIdPrivate(serviceId)) { } HServiceId::HServiceId(const HServiceId& other) : h_ptr(0) { Q_ASSERT(&other != this); h_ptr = new HServiceIdPrivate(*other.h_ptr); } HServiceId& HServiceId::operator=(const HServiceId& other) { Q_ASSERT(&other != this); HServiceIdPrivate* newHptr = new HServiceIdPrivate(*other.h_ptr); delete h_ptr; h_ptr = newHptr; return *this; } HServiceId::~HServiceId() { delete h_ptr; } bool HServiceId::isValid(HValidityCheckLevel checkLevel) const { if (checkLevel == LooseChecks) { return !h_ptr->m_suffix.isEmpty(); } return h_ptr->m_elements.size() >= 4 && h_ptr->m_elements[0] == "urn" && h_ptr->m_elements[2] == "serviceId"; } bool HServiceId::isStandardType() const { if (!isValid(LooseChecks)) { return false; } return h_ptr->m_elements[1] == "upnp-org"; } QString HServiceId::urn(bool completeUrn) const { if (!isValid(LooseChecks)) { return QString(); } QString retVal; if (completeUrn) { retVal.append("urn:"); } retVal.append(h_ptr->m_elements[1]); return retVal; } QString HServiceId::suffix() const { if (!isValid(LooseChecks)) { return QString(); } return h_ptr->m_suffix; } QString HServiceId::toString() const { return h_ptr->m_elements.join(":"); } bool operator==(const HServiceId& sid1, const HServiceId& sid2) { // This check is made first, since most often it is the suffix that is // different, if anything. if (sid1.h_ptr->m_suffix != sid2.h_ptr->m_suffix) { return false; } // The rest of the checks are lengthy because the // "serviceId" component has to be ignored and the "domain" part cannot be // strictly compared... // The operator is supposed to test for logical equivalence and since // some notable UPnP software fails to specify both the serviceId and // the domain components right, they have to be ignored. QStringList elems1 = sid1.h_ptr->m_elements; QStringList elems2 = sid2.h_ptr->m_elements; if (elems1.size() != elems2.size()) { return false; } for(qint32 i = 0; i < elems1.size() - 1; ++i) { if (i != 1 && i != 2) { if (elems1.at(i) != elems2.at(i)) { return false; } } } return true; } quint32 qHash(const HServiceId& key) { // See the comments within == operator. The serviceId component is not // part of the hash for the same reason. QString tmp; QStringList elems = key.h_ptr->m_elements; for(qint32 i = 0; i < elems.size() - 1; ++i) { if (i != 1 && i != 2) { tmp.append(elems.at(i)); } } QByteArray data = tmp.toLocal8Bit(); return hash(data.constData(), data.size()); } } } herqq-1.0.0/hupnp/src/dataelements/hserviceinfo_p.h0000644000000000000000000000332111543637310021073 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVICEINFO_P_H_ #define HSERVICEINFO_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hserviceid.h" #include "hresourcetype.h" #include "../general/hupnp_global.h" #include #include namespace Herqq { namespace Upnp { // // Implementation details of HDeviceInfo // class HServiceInfoPrivate : public QSharedData { public: // attributes HServiceId m_serviceId; HResourceType m_serviceType; QUrl m_scpdUrl; QUrl m_controlUrl; QUrl m_eventSubUrl; HInclusionRequirement m_inclusionRequirement; public: // methods HServiceInfoPrivate(); ~HServiceInfoPrivate(); }; } } #endif /* HSERVICEINFO_P_H_ */ herqq-1.0.0/hupnp/src/dataelements/hdeviceinfo.h0000644000000000000000000003063311543637310020361 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEINFO_H_ #define HDEVICEINFO_H_ #include #include #include class QUrl; class QString; namespace Herqq { namespace Upnp { class HDeviceInfoPrivate; /*! * \brief This class is used to contain information of a UPnP device * found in a UPnP device description document. * * A device description specifies a UPnP device. A device description specifies * the services of a device, the embedded devices of a device and other information, * such as the manufacturer, model name, serial number and the Unique Device Name * that uniquely identifies a device. Instances of this class contain the * previously mentioned "other" information found in device description documents. * * \headerfile hdeviceinfo.h HDeviceInfo * * \ingroup hupnp_common * * \remarks This class is not thread-safe. * * \sa HServiceInfo, HActionInfo and HStateVariableInfo. */ class H_UPNP_CORE_EXPORT HDeviceInfo { friend H_UPNP_CORE_EXPORT bool operator==( const HDeviceInfo& obj1, const HDeviceInfo& obj2); private: QSharedDataPointer h_ptr; public: /*! * \brief Creates a new, empty instance. * * \sa isValid() */ HDeviceInfo(); /*! * Constructs a new instance from the specified parameters that the UDA * specification mandates for a UPnP device. * * The parameters the constructor expects are arguments defined in the * device description file and they are all mandatory for a valid UPnP device. * * \param deviceType specifies the device type. * * \param friendlyName specifies a short description for the end-user. This * cannot be empty and should be less than 64 characters. * * \param manufacturer specifies the name of the manufacturer. This cannot * be empty and should be less than 64 characters. * * \param modelName specifies the model name. This cannot be empty and * should be less than 32 characters. * * \param udn specifies the unique device name. This is a universally * unique identifier for the device, regardless if the device is root * or embedded. The specified UDN has to be valid. * * \param checkLevel specifies the level of strictness used in validating * the specified arguments. This parameter is optional. * * \param err specifies a pointer to a \c QString that contains * an error description in case the construction failed. * This parameter is optional. * * \remarks in case any of the provided arguments does not meet the * specified requirements, the created object is \e invalid. * * \sa isValid() */ HDeviceInfo( const HResourceType& deviceType, const QString& friendlyName, const QString& manufacturer, const QString& modelName, const HUdn& udn, HValidityCheckLevel checkLevel = StrictChecks, QString* err = 0); /*! * Constructs a new instance from the specified parameters. These are * all the arguments found in the device description file. * * \param deviceType specifies the device type. * * \param friendlyName specifies a short description for the end-user. This * cannot be empty and should be less than 64 characters. * * \param manufacturer specifies the name of the manufacturer. This cannot * be empty and should be less than 64 characters. * * \param manufacturerUrl specifies the web site for the manufacturer. * * \param modelDescription specifies the long description for the end user. * This can be empty and should be less than 128 characters. * * \param modelName specifies the model name. This cannot be empty and * should be less than 32 characters. * * \param modelNumber specifies the model number of the device. There is * no format specified. This should be less than 32 characters. * * \param modelUrl specifies the web site for the device model. * * \param serialNumber specifies the serial number of the device. No * format specified. This should be less than 64 characters. * * \param udn specifies the unique device name. This is a universally * unique identifier for the device, regardless if the device is root * or embedded. The specified UDN has to be valid. * * \param upc specifies the Universal Product Code, which is 12-digit, * all-numeric code that identifies the consumer package. * Managed by the Uniform Code Council. * * \param icons specifies the icons of the device, if any. * * \param presentationUrl specifies the URL for HTML-based user interface * for controlling and/or viewing device status. * * \param checkLevel specifies the level of strictness used in validating * the specified arguments. This parameter is optional. * * \param err specifies a pointer to a \c QString that contains * an error description in case the construction failed. This is optional. * * \remarks in case any of the provided arguments does not meet the * specified requirements, the created object is \e invalid. * * \sa isValid() */ HDeviceInfo( const HResourceType& deviceType, const QString& friendlyName, const QString& manufacturer, const QUrl& manufacturerUrl, const QString& modelDescription, const QString& modelName, const QString& modelNumber, const QUrl& modelUrl, const QString& serialNumber, const HUdn& udn, const QString& upc, const QList& icons, const QUrl& presentationUrl, HValidityCheckLevel checkLevel = StrictChecks, QString* err = 0); /*! * \brief Destroys the instance. */ ~HDeviceInfo(); /*! * Copies the contents of the other to this. * * \param other specifies the object to be copied. */ HDeviceInfo(const HDeviceInfo& other); /*! * Assigns the contents of the other to this. * * \param other specifies the object to be copied. */ HDeviceInfo& operator=(const HDeviceInfo& other); /*! * \brief Indicates if the object is valid. * * A valid object contains the mandatory data of a device description. * * \param level specifies the level of strictness used in validating * the object. This parameter is optional and the default level is strict. * * \return \e true in case the object is valid. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Sets the URL for the web site of the manufacturer. * * \param arg specifies the URL for the web site of the manufacturer. * * \sa manufacturerUrl() */ void setManufacturerUrl(const QUrl& arg); /*! * \brief Sets the model description. * * A model description is used to display a long description for end user. * Should be < 128 characters. * * \param arg specifies the model description. * * \sa modelDescription() */ void setModelDescription(const QString& arg); /*! * \brief Sets the model number. * * There is no format specified for the model number, * other than it should be < 32 characters. * * \param arg specifies the model number. * * \sa modelNumber() */ void setModelNumber(const QString& arg); /*! * \brief Sets the URL for the web site of the model. * * \param arg specifies the model URL. * * \sa modelUrl() */ void setModelUrl(const QUrl& arg); /*! * \brief Sets the serial number of the device. * * There is no format specified for the serial number, * other than it should be < 64 characters. * * \param arg specifies the serial number. * * \sa serialNumber() */ void setSerialNumber(const QString& arg); /*! * \brief Sets the Universal Product Code. * * UPC is a 12-digit, all-numeric code that * identifies the consumer package. Managed by the Uniform Code Council. * * \param arg specifies the UPC. * * \sa upc() */ void setUpc(const QString& arg); /*! * \brief Sets the icons of the device. * * \param arg specifies the icons of the device. * * \sa icons() */ void setIcons(const QList& arg); /*! * \brief Sets the presentation URL. * * Presentation URL specifies the URL for HTML-based user interface * for controlling and/or viewing device status. * * \param arg specifies the presentation URL. * * \sa presentationUrl() */ void setPresentationUrl(const QUrl& arg); /*! * \brief Returns the type of the device found in the device description file. * * \return The type of the device found in the device description file. */ const HResourceType& deviceType() const; /*! * \brief Returns short description for end user. * * \return short description for end user. */ QString friendlyName() const; /*! * \brief Returns manufacturer's name. * * \return manufacturer's name. */ QString manufacturer() const; /*! * \brief Returns the manufacturer's web site. * * \return The manufacturer's web site. * * \sa setManufacturerUrl() */ QUrl manufacturerUrl() const; /*! * \brief Returns long description for end user. * * \return long description for end user. * * \sa setModelDescription() */ QString modelDescription() const; /*! * \brief Returns the model name. * * \return The model name. */ QString modelName() const; /*! * \brief Returns the model number. * * \return The model number. * * \sa setModelNumber() */ QString modelNumber() const; /*! * \brief Returns the web site for the device model. * * \return The web site for the device model. * * \sa setModelUrl() */ QUrl modelUrl() const; /*! * \brief Returns the serial number. * * \return The serial number. * * \sa setSerialNumber() */ QString serialNumber() const; /*! * \brief Returns the Unique Device Name. * * \return Universally-unique identifier for the device, whether root or embedded. * * \remarks the UDN is same over time for a specific device instance. */ const HUdn& udn() const; /*! * \brief Returns the Universal Product Code. * * \return The Universal Product Code. * * \sa setUpc() */ QString upc() const; /*! * \brief Returns the icons of the device, if any. * * \return The icons of the device. * * \sa setIcons() */ QList icons() const; /*! * \brief Returns the location of the device's presentation page. * * \return The location of the device's presentation page. * * \sa setPresentationUrl() */ QUrl presentationUrl() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically equivalent. * * \relates HDeviceInfo */ H_UPNP_CORE_EXPORT bool operator==(const HDeviceInfo&, const HDeviceInfo&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HDeviceInfo */ inline bool operator!=(const HDeviceInfo& obj1, const HDeviceInfo& obj2) { return !(obj1 == obj2); } } } #endif /* HDEVICEINFO_H_ */ herqq-1.0.0/hupnp/src/dataelements/hactioninfo.cpp0000644000000000000000000001021611543637310020725 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hactioninfo.h" #include "hactioninfo_p.h" #include "../general/hupnp_global_p.h" #include "../utils/hmisc_utils_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HActionInfoPrivate ******************************************************************************/ HActionInfoPrivate::HActionInfoPrivate() : m_name(), m_inclusionRequirement(InclusionRequirementUnknown), m_inputArguments(), m_outputArguments(), m_hasRetValArg(false) { } /******************************************************************************* * HActionInfo ******************************************************************************/ HActionInfo::HActionInfo() : h_ptr(new HActionInfoPrivate()) { } HActionInfo::HActionInfo( const QString& name, HInclusionRequirement ireq, QString* err) : h_ptr(new HActionInfoPrivate()) { if (!verifyName(name, err)) { return; } h_ptr->m_name = name; h_ptr->m_inclusionRequirement = ireq; } HActionInfo::HActionInfo( const QString& name, const HActionArguments& inputArguments, const HActionArguments& outputArguments, bool hasRetVal, HInclusionRequirement ireq, QString* err) : h_ptr(new HActionInfoPrivate()) { if (!verifyName(name, err)) { return; } if (!outputArguments.size() && hasRetVal) { if (err) { *err = "Cannot contain a return value when no output arguments " "are specified"; } return; } h_ptr->m_name = name; h_ptr->m_inputArguments = inputArguments; h_ptr->m_outputArguments = outputArguments; h_ptr->m_hasRetValArg = hasRetVal; h_ptr->m_inclusionRequirement = ireq; } HActionInfo::HActionInfo(const HActionInfo& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HActionInfo::~HActionInfo() { } HActionInfo& HActionInfo::operator=(const HActionInfo& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } QString HActionInfo::name() const { return h_ptr->m_name; } const HActionArguments& HActionInfo::inputArguments() const { return h_ptr->m_inputArguments; } const HActionArguments& HActionInfo::outputArguments() const { return h_ptr->m_outputArguments; } QString HActionInfo::returnArgumentName() const { return h_ptr->m_hasRetValArg ? h_ptr->m_outputArguments.get(0).name() : ""; } HInclusionRequirement HActionInfo::inclusionRequirement() const { return h_ptr->m_inclusionRequirement; } bool HActionInfo::isValid() const { return !h_ptr->m_name.isEmpty(); } bool operator==(const HActionInfo& arg1, const HActionInfo& arg2) { return arg1.h_ptr->m_name == arg2.h_ptr->m_name && arg1.h_ptr->m_hasRetValArg == arg2.h_ptr->m_hasRetValArg && arg1.h_ptr->m_inclusionRequirement == arg2.h_ptr->m_inclusionRequirement && arg1.h_ptr->m_inputArguments == arg2.h_ptr->m_inputArguments && arg1.h_ptr->m_outputArguments == arg2.h_ptr->m_outputArguments; } quint32 qHash(const HActionInfo& key) { QByteArray data = key.name().toLocal8Bit(); return hash(data.constData(), data.size()); } } } herqq-1.0.0/hupnp/src/dataelements/hresourcetype.h0000644000000000000000000002617511543637310021005 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HRESOURCE_TYPE_H_ #define HRESOURCE_TYPE_H_ #include #include #include namespace Herqq { namespace Upnp { class HResourceTypePrivate; /*! * \brief This is a class used to depict a UPnP resource, which is either a UPnP device or a * UPnP service. * * Both UPnP device and service descriptions use the \em type concept to a give the * corresponding device or service context that can be used in identification. * In device descriptions the device type is specified following the format * \verbatim urn:schemas-upnp-org:device:deviceType:ver \endverbatim or * \verbatim urn:domain-name:device:deviceType:ver \endverbatim in case of a * vendor defined type. * * In service descriptions the service type is specified as * \verbatim urn:schemas-upnp-org:service:serviceType:ver \endverbatim or * \verbatim urn:domain-name:service:serviceType:ver \endverbatim in case of a * vendor defined type. * * For more information, see the device type and service type * definitions in UDA v1.1 at pages 44 and 46, respectively. * * \brief This class abstracts the above service and device type concepts to a \em resource * and helps in handling the various elements of a resource type. * * \headerfile hresourcetype.h HResourceType * * \remarks This class is not thread-safe. * * \ingroup hupnp_common */ class H_UPNP_CORE_EXPORT HResourceType { friend H_UPNP_CORE_EXPORT bool operator==( const HResourceType&, const HResourceType&); public: /*! * \brief Specifies the type of the resource. See UPnP v1.1 Device Architecture * specification for more information. */ enum Type { /*! * No resource defined. This is used when the object is constructed using * the default constructor. */ Undefined = 0, /*! * The resource is urn:schemas-upnp-org:device:deviceType:ver. */ StandardDeviceType, /*! * The resource is urn:schemas-upnp-org:service:serviceType:ver. */ StandardServiceType, /*! * The resource is urn:domain-name:device:deviceType:ver. */ VendorSpecifiedDeviceType, /*! * The resource is urn:domain-name:service:serviceType:ver. */ VendorSpecifiedServiceType }; /*! * \brief This enumeration specifies how the version part of a HResourceType * is matched against a target value. */ enum VersionMatch { /*! * The version part of HResoureType objects is ignored. */ Ignore, /*! * The version part of HResourceType object has to be identical * to the specified value. */ Exact, /*! * The version part of HResourceType object has to be * less than or equal to the specified value. */ Inclusive, /*! * The version part of HResourceType object has to be greater than or * equal to the specified value. */ EqualOrGreater }; private: Type m_type; QStringList m_resourceElements; public: /*! * Constructs a new, empty instance. * * Instance created by this constructor is not valid, i.e. isValid() will return false. * * \sa isValid() */ HResourceType(); /*! * Constructs a new, empty instance from the specified parameter. * * \param resourceTypeAsStr specifies the resource type following the one of * the following formats: * * \li urn:schemas-upnp-org:device:deviceType:ver for standard * device type * * \li urn:domain-name:device:deviceType:ver for vendor defined * device type * * \li urn:schemas-upnp-org:service:serviceType:ver for standard * service type * * \li urn:domain-name:service:serviceType:ver for vendor defined * service type * * \sa isValid() */ HResourceType(const QString& resourceTypeAsStr); /*! * \brief Destroys the instance. */ ~HResourceType(); /*! * \brief Returns the type of the resource. * * \return The type of the resource. */ inline Type type() const { return m_type; } /*! * \brief Indicates if the object is valid. * * This method is provided for convenience. It simply checks if the * type() is HResourceType::Undefined. * * \returns \e true in case the object represents a valid resource type. */ inline bool isValid() const { return m_type != Undefined; } /*! * \brief Indicates whether or not the resource type is a device type. * * This method is provided for convenience. It checks if the type * is either HResourceType::StandardDeviceType or * HResourceType::VendorSpecifiedDeviceType. * * \return \e true in case the resource type is a device type. */ inline bool isDeviceType() const { return m_type == StandardDeviceType || m_type == VendorSpecifiedDeviceType; } /*! * \brief Indicates whether or not the resource type is a service type. * * This method is provided for convenience. It checks if the type * is either HResourceType::StandardServiceType or * HResourceType::VendorSpecifiedServiceType. * * \return \e true in case the resource type is a service type. */ inline bool isServiceType() const { return m_type == StandardServiceType || m_type == VendorSpecifiedServiceType; } /*! * \brief Indicates whether or not the resource type is a standard type defined * by the UPnP forum. * * This method is provided for convenience. It checks if the type * is either HResourceType::StandardDeviceType or * HResourceType::StandardServiceType. * * \retval true in case the resource type is defined by the UPnP forum. * \retval false in case the resource type is vendor defined. */ inline bool isStandardType() const { return m_type == StandardDeviceType || m_type == StandardServiceType; } /*! * Enumeration that specifies the tokens or parts of a resource type. * For instance, if the resource type * is defined as urn:schemas-upnp-org:device:deviceType:ver then * the tokens are the parts separated by colons. */ enum Token { /*! * This is a special value used to denote "no tokens". */ None = 0x00, /*! * The "urn:" token. */ UrnPrefix = 0x01, /*! * The domain token, e.g. "schemas-upnp-org". */ Domain = 0x02, /*! * The type of the resource, e.g. "device" or "service". */ Type = 0x04, /*! * The \e type \e suffix of the resource, e.g. "deviceType" or "serviceType". */ TypeSuffix = 0x08, /*! * The version of the resource type. Most commonly this is an integer. */ Version = 0x10, /*! * This is a special value used to denote "all tokens". */ All = 0x1f }; Q_DECLARE_FLAGS(Tokens, Token); /*! * \brief Returns the version of the resource type. * * \returns the version of the resource type if the object is valid. * In case the object is invalid -1 is returned. * * \sa isValid() */ qint32 version() const; /*! * \brief Returns a string representation of the object. * * A resource type can be broken into 5 tokens, which are depicted in the * Token enum. This function is used to retrieve an arbitrary combination * of these tokens as a string. For instance, if you would like to retrieve * the resource type, resource type suffix and the version as a string * you would issue: * * \code * QString retVal = tokens( * HResourceType::Type | HResourceType::TypeSuffix | HResourceType::Version); * \endcode * * \param tokens specifies what components of the objects are included * in the returned string. The default is to return everything. * * \return a string representation of the object as defined by the provided * tokens if the object is valid. Otherwise an empty string is returned. * * \remarks * By default the contents of the object are returned in full. */ QString toString(Tokens tokens=All) const; /*! * Compares this object to the provided object according to the specified * HResourceType::VersionMatch argument. * * \param other specifies the other \c %HResourceType object. * \param versionMatch specifies how the version information in the objects * are compared against one another. The target of the comparison is always * \e this object. Therefore if the \c versionMatch is set to * HResourceType::Inclusive, the specified \e other object defines * the upper bound for the comparison. * * \return \e true in case the two objects are considered a match * taking into account the specified HResourceType::VersionMatch argument. */ bool compare(const HResourceType& other, VersionMatch versionMatch) const; }; /*! * Compares the two objects for equality. * * \return true in case the object are logically equivalent. * * \relates HResourceType */ H_UPNP_CORE_EXPORT bool operator==(const HResourceType&, const HResourceType&); /*! * Compares the two objects for inequality. * * \return true in case the objects are not logically equivalent. * * \relates HResourceType */ inline bool operator!=(const HResourceType& obj1, const HResourceType& obj2) { return !(obj1 == obj2); } /*! * \brief Returns a value that can be used as a unique key in a hash-map identifying * the resource type object. * * \param key specifies the resource type from which the hash value is created. * * \return a value that can be used as a unique key in a hash-map identifying * the resource type object. * * \relates HResourceType */ H_UPNP_CORE_EXPORT quint32 qHash(const HResourceType& key); Q_DECLARE_OPERATORS_FOR_FLAGS(HResourceType::Tokens) } } Q_DECLARE_METATYPE(Herqq::Upnp::HResourceType) #endif /* HRESOURCE_TYPE_H_ */ herqq-1.0.0/hupnp/src/dataelements/hvaluerange_p.cpp0000644000000000000000000000221011543637310021237 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hvaluerange_p.h" namespace Herqq { namespace Upnp { bool operator==(const HValueRange& arg1, const HValueRange& arg2) { return arg1.maximum() == arg2.maximum() && arg1.minimum() == arg2.minimum() && arg1.step() == arg2.step(); } } } herqq-1.0.0/hupnp/src/dataelements/hproduct_tokens.cpp0000644000000000000000000002524711543637310021651 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hproduct_tokens.h" #include "../general/hlogger_p.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HProductToken ******************************************************************************/ HProductToken::HProductToken() : m_token(), m_productVersion() { } HProductToken::HProductToken(const QString& token, const QString& productVersion) : m_token(), m_productVersion() { HLOG(H_AT, H_FUN); QString tokenTmp(token.simplified()); QString productVersionTmp(productVersion.simplified()); if (tokenTmp.isEmpty() || productVersionTmp.isEmpty()) { HLOG_WARN(QString( "Invalid product token. Token: %1, Product Version: %2").arg( token, productVersion)); return; } m_token = tokenTmp; m_productVersion = productVersionTmp; } HProductToken::~HProductToken() { } bool HProductToken::isValid(HValidityCheckLevel checkLevel) const { bool looselyValid = !m_token.isEmpty() && !m_productVersion.isEmpty(); if (!looselyValid) { return false; } else if (checkLevel == LooseChecks) { return true; } if (token().compare("UPnP", Qt::CaseInsensitive) != 0) { return false; } QString vrs = version(); return (vrs.size() == 3 && (vrs[0] == '1') && vrs[1] == '.' && (vrs[2] == '0' || vrs[2] == '1')); } QString HProductToken::toString() const { if (!isValid(LooseChecks)) { return QString(); } return QString("%1/%2").arg(m_token, m_productVersion); } qint32 HProductToken::minorVersion() { if (!isValid(LooseChecks)) { return -1; } QString tokenVersion = version(); qint32 separatorIndex = tokenVersion.indexOf('.'); if (separatorIndex < 0) { return -1; } bool ok = false; qint32 minTmp = tokenVersion.mid( separatorIndex+1, tokenVersion.indexOf('.', separatorIndex+1)).toInt(&ok); return ok ? minTmp : -1; } qint32 HProductToken::majorVersion() { if (!isValid(LooseChecks)) { return -1; } QString tokenVersion = version(); bool ok = false; qint32 majTmp = -1; qint32 separatorIndex = tokenVersion.indexOf('.'); if (separatorIndex < 0) { majTmp = tokenVersion.toInt(&ok); return ok ? majTmp : -1; } majTmp = tokenVersion.left(separatorIndex).toInt(&ok); return ok ? majTmp : -1; } bool operator==(const HProductToken& obj1, const HProductToken& obj2) { return obj1.toString() == obj2.toString(); } bool operator!=(const HProductToken& obj1, const HProductToken& obj2) { return !(obj1 == obj2); } /******************************************************************************* * HProductTokensPrivate ******************************************************************************/ class HProductTokensPrivate : public QSharedData { H_DISABLE_COPY(HProductTokensPrivate) private: // tries to parse the string into "token/version" pairs // the pairs have to be delimited with white-space or commas // a pair can contain "trailing" data until the last delimiter after which // the token of a new pair is started. for instance, this is valid: // token/version (some data; some more data) otherToken/otherVersion finalToken/finalVersion (data) bool parse(const QString& tokens) { HLOG(H_AT, H_FUN); QVector productTokens; QString token, version, buf; qint32 i = tokens.indexOf('/'), j = 0, lastDelim = 0; if (i < 0) { return false; } token = tokens.left(i); // the first special case "token/version token/version token/version" // ^^^^^ for(i = i + 1; i < tokens.size(); ++i, ++j) { if (tokens[i] == '/') { if (lastDelim <= 0) { // there must have been at least one space between the previous '/' // and this one. it is an error otherwise. return false; } HProductToken newToken(token, buf.left(lastDelim)); if (newToken.isValid(LooseChecks)) { productTokens.append(newToken); } else { return false; } token = buf.mid(lastDelim+1); version.clear(); buf.clear(); j = -1; continue; } else if (tokens[i] == ' ') { lastDelim = j; } buf.append(tokens[i]); } HProductToken newToken(token, buf); if (newToken.isValid(LooseChecks)) { productTokens.append(newToken); } else { return false; } // at this point the provided token string is parsed into // valid token/version pairs, but it is not known if the tokens string // contained the UPnP token + we should inform the user if // non-std input was given. if (productTokens.size() < 3 || !productTokens[1].isValid(StrictChecks)) { HLOG_WARN_NONSTD(QString( "The specified token string [%1] is not formed according " "to the UDA specification").arg(tokens)); return false; } m_productTokens = productTokens; return true; } public: QString m_originalTokenString; QVector m_productTokens; public: HProductTokensPrivate() : m_originalTokenString(), m_productTokens() { } HProductTokensPrivate(const QString& tokens) : m_originalTokenString(tokens.simplified()), m_productTokens() { HLOG(H_AT, H_FUN); bool ok = parse(m_originalTokenString); if (ok) { // the string followed the UDA closely (rare, unfortunately) return; } if (m_originalTokenString.contains(',')) { // some sloppy UPnP implementations uses the comma as the delimiter. // technically, comma could be part of the "version" part of the token, // but in practice, it if is present it is used as the delimiter. ok = parse(QString(m_originalTokenString).remove(',')); if (ok) { HLOG_WARN_NONSTD(QString( "Comma should not be used as a delimiter in " "product tokens: [%1]").arg(tokens)); return; } } if (!ok) { // tokenization failed. // fall back for scanning the UPnP/version only QRegExp rexp("(\\b|\\s+)UPnP/"); qint32 index = m_originalTokenString.indexOf( rexp, Qt::CaseInsensitive); if (index >= 0) { qint32 matchedLength = rexp.matchedLength(); qint32 slash = index + matchedLength; qint32 nextDelim = m_originalTokenString.indexOf(QRegExp("\\s|,"), slash); HProductToken token( m_originalTokenString.mid(index, matchedLength-1), m_originalTokenString.mid(slash, nextDelim < 0 ? -1 : nextDelim-slash)); if (token.isValid(StrictChecks)) { m_productTokens.push_back(token); } } else { HLOG_WARN_NONSTD(QString( "Missing the mandatory UPnP token [%1]: ").arg( m_originalTokenString)); } } } }; /******************************************************************************* * HProductTokens ******************************************************************************/ HProductTokens::HProductTokens() : h_ptr(new HProductTokensPrivate()) { } HProductTokens::HProductTokens(const QString& tokens) : h_ptr(new HProductTokensPrivate(tokens)) { } HProductTokens::HProductTokens(const HProductTokens& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HProductTokens& HProductTokens::operator=(const HProductTokens& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HProductTokens::~HProductTokens() { } bool HProductTokens::isValid() const { return h_ptr->m_productTokens.size() > 0; } bool HProductTokens::isEmpty() const { return h_ptr->m_originalTokenString.isEmpty(); } HProductToken HProductTokens::osToken() const { if (h_ptr->m_productTokens.size() < 3) { return HProductToken(); } return h_ptr->m_productTokens[0]; } HProductToken HProductTokens::upnpToken() const { qint32 size = h_ptr->m_productTokens.size(); if (size <= 0) { return HProductToken(); } else if (size == 1) { return h_ptr->m_productTokens[0]; } return h_ptr->m_productTokens[1]; } HProductToken HProductTokens::productToken() const { if (h_ptr->m_productTokens.size() < 3) { return HProductToken(); } return h_ptr->m_productTokens[2]; } QVector HProductTokens::extraTokens() const { return h_ptr->m_productTokens.size() > 3 ? h_ptr->m_productTokens.mid(3) : QVector(); } bool HProductTokens::hasExtraTokens() const { return h_ptr->m_productTokens.size() > 3; } QVector HProductTokens::tokens() const { return h_ptr->m_productTokens; } QString HProductTokens::toString() const { return h_ptr->m_originalTokenString; } bool operator==(const HProductTokens& ht1, const HProductTokens& ht2) { return ht1.toString() == ht2.toString(); } } } herqq-1.0.0/hupnp/src/dataelements/hvaluerange_p.h0000644000000000000000000001144311543637310020714 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HVALUERANGE_P_H_ #define HVALUERANGE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include namespace Herqq { namespace Upnp { // // \internal // class HValueRange { private: QVariant m_maximum; QVariant m_minimum; QVariant m_step; template static bool checkValues(const HValueRange& val, QString* err = 0) { T min = val.m_minimum.value(); T max = val.m_maximum.value(); T step = val.m_step.value(); if (min > max) { if (err) { *err = "Minimum value cannot be larger than the maximum."; } return false; } if (max - min < step) { if (err) { *err = "Step value cannot be larger than the entire range."; } return false; } return true; } public: inline HValueRange (){} inline ~HValueRange(){} inline QVariant maximum() const { return m_maximum; } inline QVariant minimum() const { return m_minimum; } inline QVariant step () const { return m_step ; } inline bool isNull() const { return m_maximum.isNull(); // if any of the attributes is null, all are null ==> the object is null } static bool fromVariant( QVariant::Type dataType, const QVariant& minimum, const QVariant& maximum, const QVariant& step, HValueRange* retVal, QString* err = 0) { return fromString( dataType, minimum.toString(), maximum.toString(), step.toString(), retVal, err); } static bool fromString( QVariant::Type dataType, const QString& minimum, const QString& maximum, const QString& step, HValueRange* retVal, QString* err = 0) { HValueRange tmpRetVal; tmpRetVal.m_maximum = maximum; if (!tmpRetVal.m_maximum.convert(dataType)) { if (err) { *err = "Invalid maximum value"; } return false; } tmpRetVal.m_minimum = minimum; if (!tmpRetVal.m_minimum.convert(dataType)) { if (err) { *err = "Invalid minimum value"; } return false; } tmpRetVal.m_step = step; if (!tmpRetVal.m_step.convert(dataType)) { if (err) { *err = "Invalid step value"; } return false; } bool ok = false; switch(dataType) { case QVariant::Char : ok = checkValues(tmpRetVal, err); break; case QVariant::Int : ok = checkValues(tmpRetVal, err); break; case QVariant::LongLong : ok = checkValues(tmpRetVal, err); break; case QVariant::UInt : ok = checkValues(tmpRetVal, err); break; case QVariant::ULongLong : ok = checkValues(tmpRetVal, err); break; case QVariant::Double : ok = checkValues(tmpRetVal, err); break; default: Q_ASSERT(false); if (err) { *err = "Invalid data type"; } return false; } if (ok) { *retVal = tmpRetVal; } return ok; } }; bool operator==(const HValueRange& arg1, const HValueRange& arg2); inline bool operator!=(const HValueRange& arg1, const HValueRange& arg2) { return !(arg1 == arg2); } } } #endif /* HVALUERANGE_P_H_ */ herqq-1.0.0/hupnp/src/dataelements/hudn.h0000644000000000000000000001254711543637310017040 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUDN_H_ #define HUDN_H_ #include #include #include namespace Herqq { namespace Upnp { /*! * \brief This is a class used to depict a Unique Device Name (UDN), which is a * unique device identifier that has to remain the same over time for a * specific device instance. * * A valid UDN follows the format \c "uuid:"+"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", * where the five hex fields form up a valid UUID. * * \headerfile hudn.h HUdn * * \remarks This class is not thread-safe. * * \ingroup hupnp_common */ class H_UPNP_CORE_EXPORT HUdn { friend H_UPNP_CORE_EXPORT quint32 qHash(const HUdn&); friend H_UPNP_CORE_EXPORT bool operator==(const HUdn&, const HUdn&); private: QString m_value; public: /*! * Constructs a new, empty instance. * * Instance created by this constructor is not valid, i.e. isValid() will * return false. * * \sa isValid */ HUdn(); /*! * Constructs a new instance based on the provided value. * * \param value specifies the UUID of the UDN. If the provided UUID is invalid, * the created HUdn is invalid as well. * * \sa isValid */ HUdn(const QUuid& value); /*! * Constructs a new instance based on the provided value. * * \param value specifies the string from which the object is constructed. * The argument has to contain a valid UUID and it can be prefixed with * "uuid:". The UUID part in turn must be formatted along the requirements of \c QUuid: * the string "must be formatted as five hex fields separated * by '-', e.g., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" * where 'x' is a hex digit. The curly braces shown here are optional, * but it is normal to include them. If the argument does not form a * proper UUID, the created UDN is invalid. * * \sa isValid */ HUdn(const QString& value); /*! * \brief Destroys the instance. */ ~HUdn(); /*! * \brief Indicates if the UDN is defined or not. * * \param checkLevel specifies whether the check should be done strictly * according to the UDA specifications (1.0 & 1.1). That is, the UDN * has to contain a proper UUID. If \c checkLevel is \e false the UDN is * considered valid if it is not empty. * * \return true in case the UDN is valid considering the \c checkLevel argument. */ inline bool isValid(HValidityCheckLevel checkLevel) const { return checkLevel == StrictChecks ? !value().isNull() : !m_value.isEmpty(); } /*! * \brief Returns the UUID component of the UDN. * * \return The UUID component of the UDN. * * \remarks if the UDN is not strictly valid, i.e. isValid(true) returns * \e false, this method will return a null \c QUuid. */ QUuid value() const; /*! * \brief Returns the complete UDN value. * * \returns the complete UDN value when the UDN is valid. * For instance, \c "uuid:5d794fc2-5c5e-4460-a023-f04a51363300" is a valid UDN. * Otherwise an empty string is returned. */ QString toString() const; /*! * \brief Returns the UUID component of the UDN as string. * * \returns the UUID component of the UDN as string when the UDN is valid. For instance, * if the complete UDN is \c "uuid:5d794fc2-5c5e-4460-a023-f04a51363300", this method * will return \c "5d794fc2-5c5e-4460-a023-f04a51363300". Otherwise an * empty string is returned. */ QString toSimpleUuid() const; /*! * Creates a new strictly valid UDN. * * \return a new strictly valid UDN. */ static HUdn createUdn(); }; /*! * Compares the two objects for equality. * * \return true in case the object are logically equivalent. * * \relates HUdn */ H_UPNP_CORE_EXPORT bool operator==(const HUdn&, const HUdn&); /*! * Compares the two objects for inequality. * * \return true in case the objects are not logically equivalent. * * \relates HUdn */ inline bool operator!=(const HUdn& obj1, const HUdn& obj2) { return !(obj1 == obj2); } /*! * \brief Returns a value that can be used as a unique key in a hash-map identifying * the UDN object. * * \param key specifies the \em UDN from which the hash value is created. * * \return a value that can be used as a unique key in a hash-map identifying * the UDN object. * * \relates HUdn */ H_UPNP_CORE_EXPORT quint32 qHash(const HUdn& key); } } Q_DECLARE_METATYPE(Herqq::Upnp::HUdn) #endif /* HUDN_H_ */ herqq-1.0.0/hupnp/src/dataelements/hudn.cpp0000644000000000000000000000376311543637310017373 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hudn.h" #include "../utils/hmisc_utils_p.h" #include #include namespace Herqq { namespace Upnp { HUdn::HUdn() : m_value() { } HUdn::HUdn(const QUuid& value) : m_value(value.toString().remove('{').remove('}')) { } HUdn::HUdn(const QString& value) : m_value(value.simplified()) { } HUdn::~HUdn() { } QUuid HUdn::value() const { if (m_value.startsWith("uuid:")) { return QUuid(m_value.mid(5)); } return QUuid(m_value); } QString HUdn::toString() const { if (m_value.isEmpty()) { return m_value; } else if (m_value.startsWith("uuid:")) { return m_value; } return QString("uuid:").append(m_value); } QString HUdn::toSimpleUuid() const { if (m_value.startsWith("uuid:")) { return m_value.mid(5); } return m_value; } HUdn HUdn::createUdn() { return HUdn(QUuid::createUuid()); } bool operator==(const HUdn& udn1, const HUdn& udn2) { return udn1.toString() == udn2.toString(); } quint32 qHash(const HUdn& key) { QByteArray data = key.toString().toLocal8Bit(); return hash(data.constData(), data.size()); } } } herqq-1.0.0/hupnp/src/dataelements/hresourcetype.cpp0000644000000000000000000001102611543637310021325 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hresourcetype.h" #include "../utils/hmisc_utils_p.h" #include namespace Herqq { namespace Upnp { HResourceType::HResourceType() : m_type(Undefined), m_resourceElements() { } HResourceType::HResourceType(const QString& resourceTypeAsStr) : m_type(Undefined), m_resourceElements() { qint32 flags = 0; QStringList tmp = resourceTypeAsStr.simplified().split(":"); if (tmp.size() != 5) { return; } if (tmp[0] != "urn") { return; } tmp[1] = tmp[1].simplified(); if (tmp[1].isEmpty()) { return; } if (tmp[1].compare("schemas-upnp-org") != 0) { flags = 0x01; tmp[1] = tmp[1].replace('.', '-'); } else { flags = 0x02; } tmp[2] = tmp[2].simplified(); if (tmp[2].compare("device") == 0) { flags |= 0x04; } else if (tmp[2].compare("service") == 0) { flags |= 0x08; } else { return; } tmp[3] = tmp[3].simplified(); if (tmp[3].isEmpty()) { return; } bool ok = false; tmp[4].toInt(&ok); if (!ok) { return; } switch(flags) { case 0x05: m_type = VendorSpecifiedDeviceType; break; case 0x06: m_type = StandardDeviceType; break; case 0x09: m_type = VendorSpecifiedServiceType; break; case 0x0a: m_type = StandardServiceType; break; default: Q_ASSERT(false); return; } m_resourceElements = tmp; } HResourceType::~HResourceType() { } QString HResourceType::toString(Tokens tokens) const { if (!isValid()) { return QString(); } QString retVal; bool appendDelim = false; if (tokens & UrnPrefix) { retVal.append("urn:"); } if (tokens & Domain) { retVal.append(m_resourceElements[1]); appendDelim = true; } if (tokens & Type) { if (appendDelim) { retVal.append(':'); } retVal.append(m_resourceElements[2]); appendDelim = true; } if (tokens & TypeSuffix) { if (appendDelim) { retVal.append(':'); } retVal.append(m_resourceElements[3]); appendDelim = true; } if (tokens & Version) { if (appendDelim) { retVal.append(':'); } retVal.append(m_resourceElements[4]); } return retVal; } qint32 HResourceType::version() const { if (!isValid()) { return -1; } return m_resourceElements[4].toInt(); } bool HResourceType::compare( const HResourceType& other, VersionMatch versionMatch) const { if (other.isValid() != isValid()) { return false; } else if (!isValid()) { return true; } switch (versionMatch) { case Ignore: break; case Exact: if (other.version() != version()) { return false; } break; case Inclusive: if (version() > other.version()) { return false; } break; case EqualOrGreater: if (version() < other.version()) { return false; } break; default: Q_ASSERT(false); } for(qint32 i = 0; i < m_resourceElements.size() - 1; ++i) { if (m_resourceElements[i] != other.m_resourceElements[i]) { return false; } } return true; } bool operator==(const HResourceType& arg1, const HResourceType& arg2) { return arg1.m_resourceElements == arg2.m_resourceElements; } quint32 qHash(const HResourceType& key) { QByteArray data = key.toString().toLocal8Bit(); return hash(data.constData(), data.size()); } } } herqq-1.0.0/hupnp/src/dataelements/hserviceinfo.cpp0000644000000000000000000001017611543637310021115 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hserviceinfo.h" #include "hserviceinfo_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HServiceInfoPrivate ******************************************************************************/ HServiceInfoPrivate::HServiceInfoPrivate() : m_serviceId (), m_serviceType (), m_scpdUrl (), m_controlUrl (), m_eventSubUrl (), m_inclusionRequirement(InclusionRequirementUnknown) { } HServiceInfoPrivate::~HServiceInfoPrivate() { } /******************************************************************************* * HServiceInfo ******************************************************************************/ HServiceInfo::HServiceInfo() : h_ptr(new HServiceInfoPrivate()) { } HServiceInfo::HServiceInfo( const HServiceId& serviceId, const HResourceType& serviceType, const QUrl& controlUrl, const QUrl& eventSubUrl, const QUrl& scpdUrl, HInclusionRequirement inclusionRequirement, HValidityCheckLevel checkLevel, QString* err) : h_ptr(new HServiceInfoPrivate()) { QString errTmp; if (!serviceId.isValid(checkLevel)) { errTmp = "Invalid service ID"; } else if (!serviceType.isValid()) { errTmp = "Invalid service type"; } else if (controlUrl.isEmpty() || !controlUrl.isValid()) { errTmp = "Invalid control URL"; } else if (eventSubUrl.isEmpty() || !eventSubUrl.isValid()) { errTmp = "Invalid event sub URL"; } else if (scpdUrl.isEmpty() || !scpdUrl.isValid()) { errTmp = "Invalid SCPD URL"; } else { h_ptr->m_controlUrl = controlUrl; h_ptr->m_eventSubUrl = eventSubUrl; h_ptr->m_scpdUrl = scpdUrl; h_ptr->m_serviceId = serviceId; h_ptr->m_serviceType = serviceType; h_ptr->m_inclusionRequirement = inclusionRequirement; } if (err && !errTmp.isEmpty()) { *err = errTmp; } } HServiceInfo::HServiceInfo(const HServiceInfo& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HServiceInfo& HServiceInfo::operator=(const HServiceInfo& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HServiceInfo::~HServiceInfo() { } bool HServiceInfo::isValid(HValidityCheckLevel checkLevel) const { return h_ptr->m_serviceId.isValid(checkLevel); } const HServiceId& HServiceInfo::serviceId() const { return h_ptr->m_serviceId; } const HResourceType& HServiceInfo::serviceType() const { return h_ptr->m_serviceType; } QUrl HServiceInfo::scpdUrl() const { return h_ptr->m_scpdUrl; } QUrl HServiceInfo::controlUrl() const { return h_ptr->m_controlUrl; } QUrl HServiceInfo::eventSubUrl() const { return h_ptr->m_eventSubUrl; } HInclusionRequirement HServiceInfo::inclusionRequirement() const { return h_ptr->m_inclusionRequirement; } bool operator==(const HServiceInfo& obj1, const HServiceInfo& obj2) { return obj1.h_ptr->m_controlUrl == obj2.h_ptr->m_controlUrl && obj1.h_ptr->m_eventSubUrl == obj2.h_ptr->m_eventSubUrl && obj1.h_ptr->m_scpdUrl == obj2.h_ptr->m_scpdUrl && obj1.h_ptr->m_serviceId == obj2.h_ptr->m_serviceId && obj1.h_ptr->m_serviceType == obj2.h_ptr->m_serviceType; } } } herqq-1.0.0/hupnp/src/dataelements/hstatevariableinfo_p.h0000644000000000000000000000516711543637310022273 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSTATEVARIABLENIFO_P_H_ #define HSTATEVARIABLENIFO_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hvaluerange_p.h" #include "hstatevariableinfo.h" #include "../general/hupnp_global.h" #include "../general/hupnp_datatypes.h" #include #include #include #include namespace Herqq { namespace Upnp { // // Implementation details of HStateVariableInfo // class HStateVariableInfoPrivate : public QSharedData { public: // attributes QString m_name; HUpnpDataTypes::DataType m_dataType; QVariant::Type m_variantDataType; QVariant m_defaultValue; HStateVariableInfo::EventingType m_eventingType; QStringList m_allowedValueList; HValueRange m_allowedValueRange; HInclusionRequirement m_inclusionRequirement; qint32 m_maxRate; qint32 m_version; public: // methods HStateVariableInfoPrivate(); bool isWithinAllowedRange(const QVariant&, QString* errDescr=0); bool checkValue( const QVariant&, QVariant* acceptableValue, QString* errDescr = 0) const; bool setName(const QString& name, QString* err = 0); bool setDataType(HUpnpDataTypes::DataType arg, QString* err = 0); bool setDefaultValue(const QVariant& defVal, QString* err = 0); bool setAllowedValueList( const QStringList& allowedValueList, QString* err = 0); bool setAllowedValueRange( const QVariant& minimumValue, const QVariant& maximumValue, const QVariant& stepValue, QString* err = 0); }; } } #endif /* HSTATEVARIABLENIFO_P_H_ */ herqq-1.0.0/hupnp/src/general/0000755000000000000000000000000011543637460014675 5ustar rootrootherqq-1.0.0/hupnp/src/general/hupnp_global.h0000644000000000000000000003023011543637310017510 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUPNP_GLOBAL_H_ #define HUPNP_GLOBAL_H_ #include #include /*! * \file * This file contains public functions and enumerations. */ namespace Herqq { namespace Upnp { /*! * \brief This enumeration specifies the generic error codes that UPnP action invocation * may return. * * These values correspond to the values defined in the UDA, excluding * \c NotImplemented and \c UndefinedFailure, which are defined for the purposes * of HUPnP. * * \note These are only the generic error codes. Many UPnP devices define * and use domain specific error codes that cannot be specified here. */ enum UpnpErrorCode { /*! * \brief Action invocation succeeded. * * Action invocation succeeded. */ UpnpSuccess = 200, /*! * Invalid action. * * The specified action was not found. */ UpnpInvalidAction = 401, /*! * Action invocation failed due to: * \li not enough arguments, * \li arguments in wrong order, * \li one or more arguments have wrong data type */ UpnpInvalidArgs = 402, /*! * \brief The current state of the service prevents the action invocation. * * The current state of the service prevents the action invocation. */ UpnpActionFailed = 501, /*! * \brief Action invocation failed due to an invalid argument value. * * Action invocation failed due to an invalid argument value. */ UpnpArgumentValueInvalid = 600, /*! * Action invocation failed due to: * \li an argument value is less than the minimum of the allowed value range, * \li an argument value is more than the maximum of the allowed value range, * \li an argument value is not in the allowed value list */ UpnpArgumentValueOutOfRange = 601, /*! * Action invocation failed due to the requested action being optional * and not implemented by the device. */ UpnpOptionalActionNotImplemented = 602, /*! * Action invocation failed due to insufficient memory. * * The device does not have sufficient memory available to complete the action. * This MAY be a temporary condition; the control point MAY choose to retry the * unmodified request again later and it MAY succeed if memory is available. */ UpnpOutOfMemory = 603, /*! * The device has encountered an error condition which it cannot resolve itself * and required human intervention such as a reset or power cycle. See the device * display or documentation for further guidance. */ UpnpHumanInterventionRequired = 604, /*! * Action invocation failed due to a string argument being * too long for the device to handle properly. */ UpnpStringArgumentTooLong = 605, /*! * The action invocation is in progress. * * \remarks * This value is defined and used by HUPnP in-process only. */ UpnpInvocationInProgress = 0x00f00000, /*! * \brief Action invocation failed, but the exact cause could not be determined. * * Action invocation failed, but the exact cause could not be determined. * * \remarks * This value is defined and used by HUPnP in-process only. */ UpnpUndefinedFailure = 0x0ff00000 }; /*! * \brief Returns a string representation of the specified error code. * * \param errCode specififes the error code. * * \return a string representation of the specified error code. */ QString H_UPNP_CORE_EXPORT upnpErrorCodeToString(qint32 errCode); /*! * \brief This enumeration specifies how a device tree should be traversed given a * starting node. * * HUPnP \ref hupnp_devicemodel is organized into a tree that has a root * device, which may contain embedded devices as its children and they may contain * embedded devices as their children recursively. * * \brief This enumeration is used to specify how a device and its children are traversed. */ enum DeviceVisitType { /*! * This value is used to indicate that only the device in question is visited. */ VisitThisOnly = 0, /*! * This value is used to indicate that this device and its embedded devices * are visited. */ VisitThisAndDirectChildren, /*! * This value is used to indicate that this device and all of its child * devices are visited recursively. */ VisitThisRecursively }; /*! * \brief This enumeration specifies the device types that are considered as * \e targets of an operation. */ enum TargetDeviceType { /*! * This value is used to indicate that \b all devices, both root and * embedded are the targets of an operation. */ AllDevices, /*! * This value is used to indicate that \b only embedded devices are the * targets of an operation. */ EmbeddedDevices, /*! * This value is used to indicate that \b only root devices are the * targets of an operation. */ RootDevices }; /*! * \brief This enumeration specifies the type of a device location URL. */ enum LocationUrlType { /*! * The absolute URL for the device description. */ AbsoluteUrl, /*! * The base URL of the device. This is the URL with which the various * other URLs found in a device description are resolved. */ BaseUrl }; /*! * \brief This enumeration is used to specify the strictness of argument validation. * * \ingroup hupnp_common */ enum HValidityCheckLevel { /*! * The arguments are validated strictly according to the UDA * v1.0 and v1.1 specifications. */ StrictChecks, /*! * The validation allows slight deviations from the UDA specifications * in an attempt to improve interoperability. The accepted exceptions * have been encountered in other UPnP software that are popular enough * to warrant the exceptional behavior. */ LooseChecks }; /*! * \brief This enumeration specifies whether a component of the \ref hupnp_devicemodel is * mandatory within a specific UPnP device. * * In more detail, any component of the device model * (a device, a service, a state variable or an action) may be specified as * a mandatory or an optional part of a UPnP device; for example, * a UPnP device may have two mandatory embedded devices and one * optional embedded device. The same applies to the other components as well. * * When HUPnP builds an object model of a UPnP device, this information can be * used in validating a description document, or verifying that the provided * device tree accurately depicts a description document. * * For instance, if the author of a subclass of a HServerService has * specified that a particular action is mandatory, the user of the class, * who is the one that provides the description document, has to make sure that * the description document also contains the definition of the action. * * These types of mappings are optional, but they are highly useful in case * the component is to be used as a public part of a library. * They help to ensure that the implementation back-end reflects the used * description documents appropriately. This is important, as it is the * description documents that are transferred from servers to clients and it is * these documents that advertise what a particular UPnP device supports and * is capable of doing. * * From the client's perspective they are also useful in defining requirements * for device and service types. For instance, if you have a component that * expects a discovered UPnP device to contain certain services, state variables * and actions, HUPnP can use these requirements to filter devices that are * suitable in terms of advertised capabilities. * * \ingroup hupnp_common */ enum HInclusionRequirement { /*! * This value indicates that the inclusion requirement for the component * is not specified. * * This value is used only in error situations. */ InclusionRequirementUnknown = 0, /*! * This value indicates that the component has to be appropriately specified. * It is a critical error if the component is missing. */ InclusionMandatory, /*! * This value indicates that the component is optional and may or may not be * specified. */ InclusionOptional }; /*! * \brief This enumeration specifies the logging levels that can be used with the device host. * * \ingroup hupnp_common */ enum HLogLevel { /*! * No logs are generated. * * \remark by default, HUPnP uses this logging level. */ None = 0, /*! * Only fatal messages are logged. Most often a fatal message is * followed by termination of the application. */ Fatal = 1, /*! * Only critical and fatal messages are logged. Most often a critical message * signals a severe runtime error. */ Critical = 2, /*! * Messages with level set to warning, critical and fatal are logged. * A warning message usually signifies an error or exceptional situation * that should be noted. Most often the system stability is not at stake * when warning messages appear, but they may still indicate that some * component, internal or external, is not functioning correctly. * Usually the source of warnings should be investigated. */ Warning = 3, /*! * All but debug level messages are logged. An informational message is used * to log status information of control flow. A good example of an informational * message is when a sizable component logs the start of an initialization procedure. */ Information = 4, /*! * All up to the debug messages are output. This excludes only the function * enter and exit messages. * * \remark Enabling this level of logging has notable effect on performance. * This generally should be used only for debugging purposes. */ Debug = 5, /*! * Every log message is output. This includes even the function enters * and exits. * * \remark Enabling this level of logging has severe effect on performance. * This is very rarely needed and usually the debug level is far more helpful. */ All = 6 }; /*! * \brief Sets the logging level the HUPnP should use. * * \param level specifies the desired logging level. * * \remark * \li The new logging level will take effect immediately. * \li The function is thread-safe. * * \ingroup hupnp_common */ void H_UPNP_CORE_EXPORT SetLoggingLevel(HLogLevel level); /*! * Enables / disables warnings that relate to non-standard behavior discovered * in other UPnP software. * * Most often if non-standard behavior in other UPnP software is discovered, it * isn't fatal or critical and it may be possible to inter-operate with the software. * However, deviations from the specifications and standards are unfortunate and such * \b errors should be fixed. * * Regardless, you may not want to be notified about these warnings in which * case you can specifically disable all the warnings that relate to non-standard * behavior. * * \param arg specifies whether to output warnings that are about non-standard * behavior in other UPnP software. * * \remark by default, the non standard behavior warnings are on. * * \ingroup hupnp_common */ void H_UPNP_CORE_EXPORT EnableNonStdBehaviourWarnings(bool arg); } } #endif /* HUPNP_GLOBAL_H_ */ herqq-1.0.0/hupnp/src/general/hlogger_p.cpp0000644000000000000000000000653211543637310017347 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hlogger_p.h" #include #include #include namespace Herqq { volatile int HLogger::s_logLevel = static_cast(Critical); volatile bool HLogger::s_nonStdWarningsEnabled = true; HLogger::HLogger() : m_methodName(0), m_logPrefix(0) { } HLogger::HLogger(const char* at, const char* methodName, const char* logPrefix) : m_methodName(methodName), m_logPrefix(logPrefix) { if (traceLevel() == All) { QString stmt = (m_logPrefix ? QString(m_logPrefix) : QString()).append( QString("Entering %1 @ %2").arg(m_methodName, at)); qDebug() << stmt; } } HLogger::~HLogger() { if (traceLevel() == All) { QString stmt = (m_logPrefix ? QString(m_logPrefix) : QString()).append( QString("Exiting %1").arg(m_methodName)); qDebug() << stmt; } } namespace { inline QString stmt(const char* prefix, const QString& text) { return (prefix ? QString(prefix) : QString()).append(text); } } void HLogger::logDebug(const QString& text) { qDebug() << stmt(m_logPrefix, text); } void HLogger::logWarning(const QString& text) { qWarning() << stmt(m_logPrefix, text); } void HLogger::logWarningNonStd(const QString& text) { if (s_nonStdWarningsEnabled) { qWarning() << stmt( m_logPrefix, QString("**NON-STANDARD BEHAVIOR**: %1").arg(text)); } } void HLogger::logInformation(const QString& text) { qDebug() << stmt(m_logPrefix, text); } void HLogger::logFatal(const QString& text) { qFatal("%s", stmt(m_logPrefix, text).toLocal8Bit().data()); } void HLogger::logCritical(const QString& text) { qCritical() << stmt(m_logPrefix, text); } void HLogger::logDebug_(const QString& text) { if (traceLevel() >= Debug) { qDebug() << text; } } void HLogger::logWarning_(const QString& text) { if (traceLevel() >= Warning) { qWarning() << text; } } void HLogger::logWarningNonStd_(const QString& text) { if (traceLevel() && s_nonStdWarningsEnabled) { qWarning() << QString("**NON-STANDARD BEHAVIOR**: %1").arg(text); } } void HLogger::logInformation_(const QString& text) { if (traceLevel() >= Information) { qDebug() << text; } } void HLogger::logCritical_(const QString& text) { if (traceLevel() >= Critical) { qCritical() << text; } } void HLogger::logFatal_(const QString& text) { if (traceLevel() >= Fatal) { qFatal("%s", text.toLocal8Bit().data()); } } } herqq-1.0.0/hupnp/src/general/hupnp_defs.h0000644000000000000000000000173011543637310017174 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUPNP_DEFS_H_ #define HUPNP_DEFS_H_ #include #endif // HUPNP_DEFS_H_ herqq-1.0.0/hupnp/src/general/hupnp_fwd.h0000644000000000000000000001142311543637310017033 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUPNPFWD_H_ #define HUPNPFWD_H_ class QString; template class QList; template class QHash; namespace Herqq { namespace Upnp { /*! * \file * This file contains forward-declarations to every public class HUPnP exposes * and a few common type definitions. */ class HClientAction; class HClientDevice; class HClientService; class HClientActionOp; class HClientStateVariable; struct HNullValue; template class HClientAdapterOp; typedef HClientAdapterOp HClientAdapterOpNull; class HClientDeviceAdapter; class HClientServiceAdapter; class HServerAction; class HServerDevice; class HServerService; class HServerStateVariable; class HActionSetup; class HDeviceSetup; class HServiceSetup; class HDevicesSetupData; class HActionsSetupData; class HServicesSetupData; class HServicesSetupData; class HStateVariablesSetupData; class HActionInfo; class HDeviceInfo; class HServiceInfo; class HActionArgument; class HActionArguments; class HStateVariableInfo; class HStateVariableEvent; class HUdn; class HEndpoint; class HServiceId; class HResourceType; class HProductToken; class HDeviceStatus; class HProductTokens; class HDiscoveryType; class HSsdp; class HResourceUpdate; class HDiscoveryRequest; class HDiscoveryResponse; class HResourceAvailable; class HResourceUnavailable; class HDeviceModelCreator; class HDeviceModelValidator; class HDeviceModelInfoProvider; class HAsyncOp; class HExecArgs; class HControlPoint; class HControlPointConfiguration; class HDeviceHost; class HDeviceConfiguration; class HDeviceHostConfiguration; class HDeviceHostRuntimeStatus; /*! * This is a type definition to a list of Herqq::Upnp::HEndpoint instances. * * \ingroup hupnp_common * * \sa HEndpoint */ typedef QList HEndpoints; /*! * This is a type definition to a list of pointers to * Herqq::Upnp::HClientService instances. * * \ingroup hupnp_devicemodel * * \sa HClientService */ typedef QList HClientServices; /*! * This is a type definition to a list of pointers to * Herqq::Upnp::HServerService instances. * * \ingroup hupnp_devicemodel * * \sa HServerService */ typedef QList HServerServices; /*! * This is a type definition to a list of pointers to * Herqq::Upnp::HClientDevice instances. * * \ingroup hupnp_devicemodel * * \sa HClientDevice */ typedef QList HClientDevices; /*! * This is a type definition to a list of pointers to * Herqq::Upnp::HServerDevice instances. * * \ingroup hupnp_devicemodel * * \sa HServerDevice */ typedef QList HServerDevices; /*! * This is a type definition to a hash table of pointers to * const Herqq::Upnp::HServerStateVariable instances keyed with the * state variable names. * * \ingroup hupnp_devicemodel * * \sa HClientStateVariable */ typedef QHash HClientStateVariables; /*! * This is a type definition to a hash table of pointers to * Herqq::Upnp::HServerStateVariable instances keyed with the state variable names. * * \ingroup hupnp_devicemodel * * \sa HServerStateVariable */ typedef QHash HServerStateVariables; /*! * This is a type definition to a hash table of * Herqq::Upnp::HStateVariableInfo instances keyed with the state variable names. * * \ingroup hupnp_devicemodel * * \sa HStateVariableInfo */ typedef QHash HStateVariableInfos; /*! * This is a type definition to a hash table of pointers to * Herqq::Upnp::HClientAction instances keyed with the action names. * * \ingroup hupnp_devicemodel * * \sa HClientAction */ typedef QHash HClientActions; /*! * This is a type definition to a hash table of pointers to * Herqq::Upnp::HServerAction instances keyed with the action names. * * \ingroup hupnp_devicemodel * * \sa HServerAction */ typedef QHash HServerActions; } } #endif /* HUPNPFWD_H_ */ herqq-1.0.0/hupnp/src/general/hupnpinfo.h0000644000000000000000000000523411543637310017052 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUPNPINFO_H_ #define HUPNPINFO_H_ #include /*! * \file * This file contains information of the HUPnP core library. */ namespace Herqq { namespace Upnp { /*! * This is the major version of the HUPnP Core library with which this header * file was provided. * * This value is useful for compile time checks. * * \sa Herqq::Upnp::hupnpCoreVersion() */ #define HUPNP_CORE_MAJOR_VERSION 1 /*! * This is the minor version of the HUPnP Core library with which this header * file was provided. * * This value is useful for compile time checks. * * \sa Herqq::Upnp::hupnpCoreVersion() */ #define HUPNP_CORE_MINOR_VERSION 0 /*! * This is the patch version of the HUPnP Core library with which this header * file was provided. * * This value is useful for compile time checks. * * \sa Herqq::Upnp::hupnpCoreVersion() */ #define HUPNP_CORE_PATCH_VERSION 0 /*! * This is the version of the HUPnP Core library with which this header * file was provided. * * This value is useful for compile time checks. * * \sa Herqq::Upnp::hupnpCoreVersion() */ #define HUPNP_CORE_VERSION STRX(HUPNP_CORE_MAJOR_VERSION.HUPNP_CORE_MINOR_VERSION.HUPNP_CORE_PATCH_VERSION) /*! * \brief Returns the runtime version of the HUPnP Core library as a string. * * You can use this function to query the version of the HUPnP core library * at runtime. * * For compile time checks you may use the macros: * - HUPNP_CORE_MAJOR_VERSION, * - HUPNP_CORE_MINOR_VERSION, * - HUPNP_CORE_PATCH_VERSION and * - HUPNP_CORE_VERSION. * * \return The runtime version of the HUPnP Core library as a string. * The format is major.minor.patch. * * \remarks The returned string is statically allocated. You should never * delete or free it manually. */ H_UPNP_CORE_EXPORT const char* hupnpCoreVersion(); } } #endif /* HUPNPINFO_H_ */ herqq-1.0.0/hupnp/src/general/hupnp_global_p.h0000644000000000000000000000721411543637310020035 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUPNP_GLOBAL_P_H_ #define HUPNP_GLOBAL_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hupnp_fwd.h" #include "hupnp_defs.h" #include #include #include #include #include #include #include #include class QDomElement; namespace Herqq { namespace Upnp { // // // class HSysInfo { H_DISABLE_COPY(HSysInfo) private: HSysInfo(); static QScopedPointer s_instance; static QMutex s_initMutex; QScopedPointer m_productTokens; QList > m_localNetworks; void createProductTokens(); void createLocalNetworks(); public: ~HSysInfo(); static HSysInfo& instance(); // // // inline const HProductTokens& herqqProductTokens() { return *m_productTokens; } bool localNetwork(const QHostAddress&, quint32*) const; bool isLocalAddress(const QHostAddress&) const; bool areLocalAddresses(const QList&) const; }; // // // HEndpoints convertHostAddressesToEndpoints(const QList&); // // // QString readElementValue( const QString elementTagToSearch, const QDomElement& parentElement, bool* wasDefined = 0); // // // QString toString(const QDomElement&); // // // bool verifyName(const QString& name, QString* err=0); // // Returns the provided URLs as a string following format "#N URL\n", // where N = 0..., and URL is the N'th URL in the list. // QString urlsAsStr(const QList&); // // // inline QString peerAsStr(const QTcpSocket& sock) { return QString("%1:%2").arg( sock.peerAddress().toString(), QString::number(sock.peerPort())); } // // // QString extractBaseUrl(const QString& url); // // // inline QUrl extractBaseUrl(const QUrl& url) { QString urlAsStr = url.toString(); return extractBaseUrl(urlAsStr); } // // // inline QString extractHostPart(const QUrl& arg) { return arg.toString( QUrl::RemovePassword | QUrl::RemoveUserInfo | QUrl::StripTrailingSlash | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment); } // // Returns the part + query (== request in entirety) sections of the url // inline QString extractRequestPart(const QUrl& arg) { return arg.toString( QUrl::RemoveAuthority | QUrl::RemovePassword | QUrl::RemoveUserInfo | QUrl::RemoveScheme | QUrl::RemovePort | QUrl::RemoveFragment); } // // // QUrl resolveUri(const QUrl& baseUrl, const QUrl& relativeUrl); // // // QUrl appendUrls(const QUrl& baseUrl, const QUrl& relativeUrl); } } #endif /* HUPNP_GLOBAL_P_H_ */ herqq-1.0.0/hupnp/src/general/hlogger_p.h0000644000000000000000000001022311543637310017004 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HLOGGER_H_ #define HLOGGER_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include class QString; namespace Herqq { // // // class H_UPNP_CORE_EXPORT HLogger { H_DISABLE_COPY(HLogger) private: const char* m_methodName; const char* m_logPrefix; static volatile int s_logLevel; static volatile bool s_nonStdWarningsEnabled; public: enum HLogLevel { None = 0, Fatal = 1, Critical = 2, Warning = 3, Information = 4, Debug = 5, All = 6 }; public: HLogger (); HLogger (const char* at, const char* methodName, const char* logPrefix = 0); ~HLogger(); // the instance methods log the method name if it was specified. static // equivalents do not. void logDebug (const QString& text); void logWarning (const QString& text); void logWarningNonStd(const QString& text); void logInformation (const QString& text); void logCritical (const QString& text); void logFatal (const QString& text); inline static HLogLevel traceLevel() { return static_cast(s_logLevel); } inline static void setTraceLevel(HLogLevel level) { s_logLevel = static_cast(level); } inline static void enableNonStdWarnings(bool arg) { s_nonStdWarningsEnabled = arg; } static void logDebug_ (const QString& text); static void logWarning_ (const QString& text); static void logWarningNonStd_(const QString& text); static void logInformation_ (const QString& text); static void logCritical_ (const QString& text); static void logFatal_ (const QString& text); }; #define HLOG(at, fun) \ Herqq::HLogger herqqLog__(at, fun); #define HLOG2(at, fun, logPrefix) \ Herqq::HLogger herqqLog__(at, fun, logPrefix); #define CHECK_LEVEL(level) \ if (Herqq::HLogger::traceLevel() < Herqq::HLogger::level) ; \ else #define HLOG_WARN(text) \ CHECK_LEVEL(Warning) herqqLog__.logWarning(text); #define HLOG_WARN_AT(text, at) \ CHECK_LEVEL(Warning) herqqLog__.logWarning(text, at); #define HLOG_WARN_NONSTD(text) \ CHECK_LEVEL(Warning) herqqLog__.logWarningNonStd(text); #define HLOG_WARN_NONSTD_AT(text, at) \ CHECK_LEVEL(Warning) herqqLog__.logWarning(text, at); #define HLOG_DBG(text) \ CHECK_LEVEL(Debug) herqqLog__.logDebug(text); #define HLOG_DBG_AT(text, at) \ CHECK_LEVEL(Debug) herqqLog__.logDebug(text, at); #define HLOG_INFO(text) \ CHECK_LEVEL(Information) herqqLog__.logInformation(text); #define HLOG_INFO_AT(text, at) \ CHECK_LEVEL(Information) herqqLog__.logInformation(text, at); #define HLOG_FATAL(text) \ CHECK_LEVEL(Fatal) herqqLog__.logFatal(text); #define HLOG_FATAL_AT(text, at) \ CHECK_LEVEL(Fatal) herqqLog__.logFatal(text, at); #define HLOG_CRIT(text) \ CHECK_LEVEL(Critical) herqqLog__.logCritical(text); #define HLOG_CRIT_AT(text, at) \ CHECK_LEVEL(Critical) herqqLog__.logCritical(text, at); } #endif /* HLOGGER_H_ */ herqq-1.0.0/hupnp/src/general/general.pri0000644000000000000000000000111411543637310017015 0ustar rootroot HEADERS += \ $$SRC_LOC/general/hupnp_defs.h \ $$SRC_LOC/general/hupnp_fwd.h \ $$SRC_LOC/general/hlogger_p.h \ $$SRC_LOC/general/hupnp_global_p.h \ $$SRC_LOC/general/hupnp_global.h \ $$SRC_LOC/general/hclonable.h \ $$SRC_LOC/general/hupnpinfo.h \ $$SRC_LOC/general/hupnp_datatypes.h \ $$SRC_LOC/general/hupnp_datatypes_p.h SOURCES += \ $$SRC_LOC/general/hupnp_global.cpp \ $$SRC_LOC/general/hclonable.cpp \ $$SRC_LOC/general/hlogger_p.cpp \ $$SRC_LOC/general/hupnpinfo.cpp \ $$SRC_LOC/general/hupnp_datatypes.cpp herqq-1.0.0/hupnp/src/general/hclonable.cpp0000644000000000000000000000232011543637310017317 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hclonable.h" namespace Herqq { namespace Upnp { HClonable::HClonable() { } HClonable::~HClonable() { } void HClonable::doClone(HClonable*) const { } HClonable* HClonable::clone() const { HClonable* newClone = newInstance(); if (!newClone) { return 0; } doClone(newClone); return newClone; } } } herqq-1.0.0/hupnp/src/general/hupnp_datatypes.cpp0000644000000000000000000002542011543637310020606 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hupnp_datatypes.h" #include "hupnp_datatypes_p.h" #include #include namespace Herqq { namespace Upnp { SoapType::SoapType( const QString& name, HUpnpDataTypes::DataType dt, const QVariant& value) : QtSoapSimpleType() { Q_ASSERT(!name.isEmpty()); Q_ASSERT_X(value.isValid(), "", name.toLocal8Bit()); Q_ASSERT(dt != HUpnpDataTypes::Undefined); n = QtSoapQName(name); t = convertToSoapType(dt); if (dt == HUpnpDataTypes::uri) { // the qtsoap library handles its "anyURI" type as it does almost any other // type, as string. However, at the time of writing this (with Qt 4.5.3) // the QVariant does not support toString() for Url types. v = value.toUrl().toString(); } else { v = value; } } QtSoapType::Type convertToSoapType(HUpnpDataTypes::DataType upnpDataType) { switch (upnpDataType) { case HUpnpDataTypes::i1: return QtSoapType::Byte; case HUpnpDataTypes::i2: return QtSoapType::Short; case HUpnpDataTypes::i4: case HUpnpDataTypes::integer: return QtSoapType::Integer; case HUpnpDataTypes::ui1: return QtSoapType::UnsignedByte; case HUpnpDataTypes::ui2: return QtSoapType::UnsignedShort; case HUpnpDataTypes::ui4: return QtSoapType::UnsignedInt; case HUpnpDataTypes::r4: case HUpnpDataTypes::r8: case HUpnpDataTypes::number: case HUpnpDataTypes::fixed_14_4: return QtSoapType::Double; case HUpnpDataTypes::fp: return QtSoapType::Float; case HUpnpDataTypes::character: case HUpnpDataTypes::string: return QtSoapType::String; case HUpnpDataTypes::date: return QtSoapType::Date; case HUpnpDataTypes::dateTime: case HUpnpDataTypes::dateTimeTz: return QtSoapType::DateTime; case HUpnpDataTypes::time: case HUpnpDataTypes::timeTz: return QtSoapType::Time; case HUpnpDataTypes::boolean: return QtSoapType::Boolean; case HUpnpDataTypes::bin_base64: return QtSoapType::Base64Binary; case HUpnpDataTypes::bin_hex: return QtSoapType::HexBinary; case HUpnpDataTypes::uri: return QtSoapType::AnyURI; case HUpnpDataTypes::uuid: return QtSoapType::ID; case HUpnpDataTypes::Undefined: return QtSoapType::Other; default: Q_ASSERT(false); } Q_ASSERT(false); return QtSoapType::Other; } HUpnpDataTypes::HUpnpDataTypes() { } HUpnpDataTypes::~HUpnpDataTypes() { } HUpnpDataTypes::DataType HUpnpDataTypes::dataType(const QString& dataTypeAsStr) { if (dataTypeAsStr.compare(ui1_str()) == 0) { return ui1; } else if (dataTypeAsStr.compare(ui2_str()) == 0) { return ui2; } else if (dataTypeAsStr.compare(ui4_str()) == 0) { return ui4; } else if (dataTypeAsStr.compare(i1_str()) == 0) { return i1; } else if (dataTypeAsStr.compare(i2_str()) == 0) { return i2; } else if (dataTypeAsStr.compare(i4_str()) == 0) { return i4; } else if (dataTypeAsStr.compare(integer_str()) == 0) { return integer; } else if (dataTypeAsStr.compare(r4_str()) == 0) { return r4; } else if (dataTypeAsStr.compare(r8_str()) == 0) { return r8; } else if (dataTypeAsStr.compare(number_str()) == 0) { return number; } else if (dataTypeAsStr.compare(fixed_14_4_str()) == 0) { return fixed_14_4; } else if (dataTypeAsStr.compare(fp_str()) == 0) { return fp; } else if (dataTypeAsStr.compare(character_str()) == 0) { return character; } else if (dataTypeAsStr.compare(string_str()) == 0) { return string; } else if (dataTypeAsStr.compare(date_str()) == 0) { return date; } else if (dataTypeAsStr.compare(dateTime_str()) == 0) { return dateTime; } else if (dataTypeAsStr.compare(dateTimeTz_str()) == 0) { return dateTimeTz; } else if (dataTypeAsStr.compare(time_str()) == 0) { return time; } else if (dataTypeAsStr.compare(time_tz_str()) == 0) { return timeTz; } else if (dataTypeAsStr.compare(boolean_str()) == 0) { return boolean; } else if (dataTypeAsStr.compare(bin_base64_str()) == 0) { return bin_base64; } else if (dataTypeAsStr.compare(bin_hex_str()) == 0) { return bin_hex; } else if (dataTypeAsStr.compare(uri_str()) == 0) { return uri; } else if (dataTypeAsStr.compare(uuid_str()) == 0) { return uuid; } return Undefined; } QString HUpnpDataTypes::toString(DataType dataType) { switch(dataType) { case Undefined: return "Undefined"; case ui1: return ui1_str(); case ui2: return ui2_str(); case ui4: return ui4_str(); case i1: return i1_str(); case i2: return i2_str(); case i4: return i4_str(); case integer: return integer_str(); case r4: return r4_str(); case r8: return r8_str(); case number: return number_str(); case fixed_14_4: return fixed_14_4_str(); case fp: return fp_str(); case character: return character_str(); case string: return string_str(); case date: return date_str(); case dateTime: return dateTime_str(); case dateTimeTz: return dateTimeTz_str(); case time: return time_str(); case timeTz: return time_tz_str(); case boolean: return boolean_str(); case bin_base64: return bin_base64_str(); case bin_hex: return bin_hex_str(); case uri: return uri_str(); case uuid: return uuid_str(); default: return "Undefined"; } } QVariant::Type HUpnpDataTypes::convertToVariantType( HUpnpDataTypes::DataType upnpDataType) { switch (upnpDataType) { case HUpnpDataTypes::character: return QVariant::Char; case HUpnpDataTypes::i1: case HUpnpDataTypes::i2: case HUpnpDataTypes::i4: case HUpnpDataTypes::integer: return QVariant::Int; case HUpnpDataTypes::ui1: case HUpnpDataTypes::ui2: case HUpnpDataTypes::ui4: return QVariant::UInt; case HUpnpDataTypes::fp: case HUpnpDataTypes::r4: case HUpnpDataTypes::r8: case HUpnpDataTypes::number: case HUpnpDataTypes::fixed_14_4: return QVariant::Double; case HUpnpDataTypes::string: return QVariant::String; case HUpnpDataTypes::date: return QVariant::Date; case HUpnpDataTypes::dateTime: case HUpnpDataTypes::dateTimeTz: return QVariant::DateTime; case HUpnpDataTypes::time: case HUpnpDataTypes::timeTz: return QVariant::Time; case HUpnpDataTypes::boolean: return QVariant::Bool; case HUpnpDataTypes::bin_hex: case HUpnpDataTypes::bin_base64: return QVariant::ByteArray; case HUpnpDataTypes::uri: return QVariant::Url; case HUpnpDataTypes::uuid: return QVariant::String; default: Q_ASSERT(false); } Q_ASSERT(false); return QVariant::Invalid; } QVariant HUpnpDataTypes::convertToRightVariantType( const QString& value, HUpnpDataTypes::DataType upnpDataType) { QVariant retVal; switch (upnpDataType) { case HUpnpDataTypes::character: return !value.isEmpty() ? QChar(value[0]) : QVariant(QVariant::Char); case HUpnpDataTypes::i1: case HUpnpDataTypes::i2: case HUpnpDataTypes::i4: case HUpnpDataTypes::integer: { bool ok = false; retVal = value.toInt(&ok); break; } case HUpnpDataTypes::ui1: case HUpnpDataTypes::ui2: case HUpnpDataTypes::ui4: { bool ok = false; retVal = value.toUInt(&ok); break; } case HUpnpDataTypes::fp: case HUpnpDataTypes::r4: case HUpnpDataTypes::r8: case HUpnpDataTypes::number: case HUpnpDataTypes::fixed_14_4: { bool ok = false; retVal = value.toDouble(&ok); break; } case HUpnpDataTypes::string: return value; case HUpnpDataTypes::date: { retVal = QDate::fromString(value, Qt::ISODate); break; } case HUpnpDataTypes::dateTime: case HUpnpDataTypes::dateTimeTz: { retVal = QDateTime::fromString(value, Qt::ISODate); break; } case HUpnpDataTypes::time: case HUpnpDataTypes::timeTz: { retVal = QTime::fromString(value, Qt::ISODate); break; } case HUpnpDataTypes::boolean: { if (value.compare("true", Qt::CaseInsensitive) == 0 || value.compare("yes", Qt::CaseInsensitive) == 0 || value.compare("1") == 0) { retVal = true; } else if (value.compare("false", Qt::CaseInsensitive) == 0 || value.compare("no", Qt::CaseInsensitive) == 0 || value.compare("0") == 0) { retVal = false; } break; } case HUpnpDataTypes::bin_hex: return value;//.toUtf8().toHex(); case HUpnpDataTypes::bin_base64: return value;//.toUtf8().toBase64(); case HUpnpDataTypes::uri: { retVal = QUrl(value); break; } case HUpnpDataTypes::uuid: return value; default: Q_ASSERT(false); } return retVal; } } } herqq-1.0.0/hupnp/src/general/hupnp_global.cpp0000644000000000000000000020141011543637310020043 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hupnp_global.h" #include "hupnp_global_p.h" #include "../socket/hendpoint.h" #include "../dataelements/hproduct_tokens.h" #include "../general/hupnpinfo.h" #include "../general/hlogger_p.h" #include #include #include #include #if defined(Q_OS_LINUX) #include #endif /*! * \namespace Herqq The main namespace of Herqq libraries. This namespace contains * the global enumerations, typedefs, functions and classes that are used * and referenced throughout the Herqq libraries. * * \namespace Herqq::Upnp The namespace that contains all of the Herqq UPnP * core functionality. */ namespace Herqq { namespace Upnp { /*! \mainpage %Herqq UPnP (HUPnP) Reference Documentation for Version 1.0 * * \section introduction Introduction * * %Herqq UPnP Library (thereafter HUPnP) is a collection of reusable classes that * provide UPnP connectivity conforming to the * * UPnP Device Architecture version 1.1. * * Above everything else, HUPnP is designed to be simple to use and robust in operation. * HUPnP does its best to enable you, the user, to focus on the business logic * of your domain, rather than to the details of UPnP. However, not everything * can be hidden and some UPnP knowledge is required to fully understand * the system mechanics and the terms used in this documentation. To fill such * gaps you can check the aforementioned UDA specification and other documents * available at the UPnP Forum. * * HUPnP is tightly integrated into the Qt Framework and * follows closely the very same design principles and programming practices Qt * follows. You will get the most out of HUPnP by using it alongside with Qt. * You can use HUPnP from other environments as well, assuming the appropriate * Qt headers and libraries are available. * * \section settingup Setting Up * * First, it is important to point out that at the moment HUPnP is * officially distributed in source code only. If you * come across a binary of HUPnP, it is not made by the author of HUPnP. * Second, HUPnP uses the * QtSoap library * under the LGPLv2.1 license. * The QtSoap library is distributed along the HUPnP in * source code and the library is built into a shared library during the compilation of HUPnP. * \attention At the moment, HUPnP uses a modified version of QtSoap version 2.7. * This is because the original version 2.7 contains few severe bugs in regard * to thread-safety. Until the errors are fixed in the official QtSoap release, the users * of HUPnP \b must use the modified version distributed with HUPnP. * * In order to use HUPnP, you need to build it first. By far the simplest way to do * this is to download the Qt SDK, * install it, start QtCreator and open the HUPnP project file \b herqq.pro * located in the root of the HUPnP package. To build HUPnP from the command-line * you need to run: * - qmake -recursive herqq.pro to create the make files. You'll find the * \c herqq.pro project file under the project's root directory. * - \c make to build HUPnP and * - \c make \c install to install HUPnP. This step is optional and can be omitted * if you do not want to install the HUPnP headers and binaries anywhere. See * \ref deployment for further information. * * The build produces two shared libraries to which you need to link in order to use * HUPnP. Currently, static linking is not an option. The created libraries are * placed in \c bin directory and they are named [lib]HUPnP[-majVer.minVer.patchVer].x and * [lib]QtSolutions_SOAP-2.7.x, where \c ".x" is the platform dependent suffix * for shared libraries. In addition, your compiler * must be aware of the HUPnP includes, which can be found in the \c include * directory. It is very important that you do \b not directly include anything that * is not found in the \c include directory. In any case, once your compiler * finds the HUPnP includes and your linker finds the HUPnP shared library, * you are good to go. \attention You do \b not need to include the QtSoap includes. * HUPnP does not expose the types declared in QtSoap. * * \section importantnotes Important notes * * Before starting to use HUPnP, there are a few things you have to know. * * \subsection include \#include * * HUPnP follows similar include pattern to that of Qt. When you want to use a * a class in HUPnP, you have to use \verbatim #include \endverbatim * where HClassName matches the name of the class you wish to use exactly. * * \subsection memorymanagement Memory management * * Some of the key classes in HUPnP are always instantiated by HUPnP and the * instances are always destroyed by HUPnP. You should never delete these. * The API documentation of HUPnP is clear about object ownership and * these classes are identified in documentation. * * \subsection herqqheader The HUpnp include file * * %HUpnp introduce a number of types, functions, enums and * type definitions under the root namespace \c Herqq. For instance, all the * HUPnP core types can be found under the namespace Herqq::Upnp. * * In several occasions, you do not need to include the full %HUPnP type definitions for your * code to work. More specifically, if the compiler doesn't need to see the layout * of a %HUPnP type to compile your code, you should only forward-declare such %HUPnP * types. In that case, you can include the * \c HUpnp file, which provides forward-declarations to every public * %HUPnP type and function. * * \subsection logging Logging * * In many situations it is useful to see some log output to have some idea what is * going on under the hood, especially when something appears * to be malfunctioning. You can enable logging in HUPnP by calling the * function Herqq::Upnp::SetLoggingLevel() with a desired \e level argument. * Include \c HUpnp to use the Herqq::Upnp::SetLoggingLevel(). * * \subsection deployment Deployment * * You can run \c make \c install after compiling the project to copy the * public headers and created dynamic libraries into \c hupnp/deploy folder. More * specifically, \c hupnp/deploy/include will contain all the public headers and * \c hupnp/deploy/lib/ will contain the dynamic libraries. Alternatively, you can * run qmake -recursive "PREFIX = /usr" before running \c make \c install * to install the headers and binaries under the /usr/include * and /usr/lib respectively. This may be useful to you in case you * do not want to include the full HUPnP source tree with your software. You can * run \c make \c uninstall to remove HUPnP from the selected location. * * \subsection versioning Versioning * * Until the first stable release (1.0) is made, HUPnP follows a versioning practise * where the \e major component is always zero, the \e minor component is * incremented whenever an API or ABI breaking change is introduced and the * \e patch component is increment upon each update that preserves the * API and ABI. * * By including \c HUpnpInfo, you can call hupnpCoreVersion() to query the exact * version of a HUPnP Core library at runtime. At compile-time you can use the macros * HUPNP_CORE_MAJOR_VERSION, HUPNP_CORE_MINOR_VERSION, HUPNP_CORE_PATCH_VERSION * and HUPNP_CORE_VERSION for checking the version of the API. * * \section gettingstarted Getting Started * * Often the best explanation is demonstration. * So without further ado, the following links should get you started. * * \li \ref builddevice_tutorial shows how to build your own UPnP device using * HUPnP. * \li The API documentation of Herqq::Upnp::HControlPoint shows how to discover * and use UPnP devices on the network. * \li The API documentation of Herqq::Upnp::HDeviceHost shows how to host a Herqq::Upnp::HServerDevice. * This is how you setup a UPnP device to be found and used by UPnP control points. * * For more detailed information, you can check * * \li \ref hupnp_devicemodel for the details of the HUPnP device model and * \li \ref hupnp_devicehosting for the details of hosting a device. * * From there, the API reference is the way to go. */ /*! * \defgroup hupnp_devicemodel Device Model * \ingroup hupnp_core * * \brief This page explains the concept of HUPnP Device Model, which is the * logical object hierarchy of HUPnP representing the UPnP Device Architecture. * * \section notesaboutdesign A few notes about the design * * The main four components of the UPnP device model are * a device, a service, a state variable and * an action. These four components form a type of a tree in which * devices and services are contained by devices, and state variables * and actions are contained by services. This is called the device tree. * A device tree has a \e root \e device, which is a UPnP device that has * no parent, but may contain other UPnP devices. These contained devices * are called embedded devices. * * HUPnP's device model mimicts this design closely. At server-side the main * four components are HServerDevice, HServerService, HServerStateVariable and * HServerAction. At client-side the main four components are HClientDevice, * HClientService, HClientStateVariable and HClientAction. * * The purpose of the other classes part of the HUPnP's device model is to support the * initialization and use of the four core components both at the server and * client-side. * * \subsection The API differences between client and server sides * * The HUPnP device model is largely the same at the server and client sides. * That is, whether you are writing a custom UPnP device or * trying to interact with a UPnP device found in the network, you will be * interacting with the HUPnP device model in a similar manner. Regardless of that, * there are some important differences, which is why the server and * client-side define and use different types that do not share ancestors * provided by HUPnP. * * First and most importantly, server side contains the "businness" logic of * a UPnP device and clients only invoke or use it. This logic should not be * duplicated to the client-side, as it serves no purpose there. Having a design * that explicitly states this separation of concerns at type level should * certainly help in making the purpose of each type clear. * * Second, UPnP clients are unable to modify server-side state variables directly * and in a uniform manner. This is because UPnP Device Architecture does not * specify a mechanism for changing the value of a state variable from client-side. * Certainly the value of a state variable may be changeable, but that and the * way it is done depends of the service type in which the state variable is defined. * On the other hand, server-side has to have direct read-write access to the * state variables. This type of difference should be explicit in the design. * * Third, client-side action invocation should naturally be asynchronous * to the user, as the call most often involves network access. On the * server-side the action invocations are direct method calls and as such the * burden of running them "asynchronously" with the help of worker threads * should reside at the user code. * * \subsection lifetime_and_ownership The lifetime and ownership of objects * * Every \e device (HClientDevice and HServerDevice) has the ownership of all * of its embedded devices, services, actions and state variables and the * ownership is never released. This means that every device always manages * the memory used by the objects it owns. Hence, the owner of a \e root \e device * ultimately has the ownership of an entire device tree. * * This is a very important point to remember: the lifetime of every object * contained by the root device depends of the lifetime of the root device. * * In other words, when a root device is deleted, every * embedded device, service, state variable and action underneath it are deleted as well. * Furthermore, every \e root \e device is always owned by HUPnP and the * ownership is never released. Because of this you must never call \c delete * to any of the components of the device model that is setup by HUPnP. * Failing to follow this rule will result in undefined behavior. * * \note There are situations where you may want to instruct HUPnP to \c delete * a device. For instance, when a UPnP device is removed from the network * you may want your HControlPoint instance to remove the device that is no * longer available. This can be done through the \c %HControlPoint interface. * But note, HUPnP never deletes a device object without an explicit request from * a user. * * \section usage Usage * * Basic use is about interacting with already created objects that comprise the * device model. To get started you need to initialize either a device host or a * control point and retrieve a device or a list of devices from it. * See \ref hupnp_devicehosting for more information about device hosts and * control points. Once you have access to a device you can interact with any of its * embedded devices, services, state variables and actions until: * - you explicitly request the root device of the device tree to be deleted, * - \c delete the owner of a device tree, such as HControlPoint or HDeviceHost. * * See the corresponding classes for more information concerning their use. * * \note By default, HControlPoint keeps the state of the * state variables up-to-date. That is, using default configuration * an \c %HControlPoint automatically subscribes to events the UPnP services expose. * In such a case the state of a device tree the control point maintains reflects * the state of the corresponding device tree at server-side as accurately * as the server keeps sending events. * * If you wish to implement and host your own UPnP device things get * more involved. See \ref builddevice_tutorial to get started on building your * own UPnP devices using HUPnP. */ /*! \page builddevice_tutorial Tutorial for Building a UPnP Device * * \section settingup_descriptions Setting up the device and service descriptions * * Generally, building a UPnP device with HUPnP involves two main steps in your part. * First, you have to define a \em UPnP \em device \em description document following * the specifications set by the UPnP forum. Depending of your UPnP Device Description * document, you may need to define one or more \em UPnP \em service \em description documents * as well. Second, you may have to implement a class for your device and most often * one or more classes for each service your device contains. * * For example, if you want to implement a standard UPnP device named * \b BinaryLight:1, your device description could look something like this: * * \code * * * * 1 * 0 * * * urn:schemas-upnp-org:device:BinaryLight:1 * UPnP Binary Light * MyCompany * www.mywebsite.org * New brilliant BinaryLight * SuperWhiteLight 4000 * 1 * uuid:138d3934-4202-45d7-bf35-8b50b0208139 * * * urn:schemas-upnp-org:service:SwitchPower:1 * urn:upnp-org:serviceId:SwitchPower:1 * switchpower_scpd.xml * /control * /eventing * * * * * \endcode * * Note that the above is the standard device template for UPnP \b BinaryLight:1 filled * with imaginary information. * * Since the \b BinaryLight:1 defines a service, \b SwitchPower:1, you have to provide a * service description document that could look like this: * * \code * * * * 1 * 0 * * * * SetTarget * * * newTargetValue * Target * in * * * * * GetTarget * * * RetTargetValue * Target * out * * * * * GetStatus * * * ResultStatus * Status * out * * * * * * * Target * boolean * 0 * * * Status * boolean * 0 * * * * \endcode * * The above description is the standard service description for the * \b SwitchPower:1 without any vendor specific declarations. For more information * about description documents, see the UDA specification, sections 2.3 and 2.5. * * \section creatingclasses Creating the necessary HUPnP classes * * HUPnP doesn't require any classes to be created in order to "host" a UPnP device * (make it visible for UPnP control points), but in order to plug in custom * functionality you often have to accompany the device and service descriptions with * corresponding classes. * * In our example we have to derive a class we have to derive a class from * Herqq::Upnp::HServerService for the \b SwitchPower:1 service description and * we \b can derive a class from Herqq::Upnp::HServerDevice for the * \b BinaryLight:1 device description. Note the last point, we do \b not have to * create a class for the \b BinaryLight:1, but we can. Furthermore, * if your service has no actions you do not need to create your own * HServerService type either. * * \note Omitting the creation of custom HServerDevice classes is common if there * is no need to define a type that orchestrates the use, initialization and * control of the contained services. Furthermore, such a type can specify * information about the embedded devices and services that have to be present * for the type to be initialized properly. And of course, it can offer features * that are not present in the default HServerDevice class. * * To create a custom Herqq::Upnp::HServerDevice you only need to derive from it. * There are no abstract member functions to override, but there are a few virtual * member functions that could be very useful to override in case you are * writing a type for other people to use. For more information of this, see * \ref hupnp_devicemodel. * * To create a concrete class from Herqq::Upnp::HServerService that exposes * custom actions you can either: * - Override Herqq::Upnp::HServerService::createActionInvokes(), which * purpose is to create callable entities that will * be called when the corresponding UPnP actions are invoked. * - Define \c Q_INVOKABLE methods in your custom type derived from HServerService * using the same method names as the action definitions in the service description * document. * * The first option is much more flexible, as you have full control over * what HUPnP should call when a particular action is invoked. In addition, * callable entities aren't tied to member functions. The second option may * be more convenient, as you don't have to implement * HServerService::createActionInvokes() and create the callable entities by * yourself. Whichever option you choose, every action implementation has to * have a signature of action(const HActionArguments&, HActionArguments*) * and \c int as a return type. * * \note * - The UPnP actions of a particular UPnP service are defined in the service's * description file and your service implementation has to implement all of them. * - The callable entities are used internally by HUPnP. HUPnP does not * otherwise expose them directly in the public API for action invocation. * * To continue with the example we will create two classes, one for the * \b BinaryLight:1 and one for the \b SwitchPowerService:1. Note, the class for * the BinaryLight:1 is \b not required, but it is done here for demonstration * purposes. Also note that for this example the class declarations are put * into the same header file, although in real code you might want to separate them. * * mybinarylight.h * * \code * * #include * #include * * class MyBinaryLightDevice : * public Herqq::Upnp::HServerDevice * { * * public: * * MyBinaryLightDevice(); * virtual ~MyBinaryLightDevice(); * }; * * class MySwitchPowerService : * public Herqq::Upnp::HServerService * { * protected: * * virtual HActionInvokes createActionInvokes(); * * public: * * MySwitchPowerService(); * virtual ~MySwitchPowerService(); * }; * * \endcode * * In turn, the implementation could look something like this: * * mybinarylight.cpp * * \code * * #include "mybinarylight.h" * * using namespace Herqq::Upnp; * * MyBinaryLightDevice::MyBinaryLightDevice() * { * } * * MyBinaryLightDevice::~MyBinaryLightDevice() * { * } * * MySwitchPowerService::MySwitchPowerService() * { * } * * MySwitchPowerService::~MySwitchPowerService() * { * } * * HServerServer::HActionInvokes MySwitchPowerService::createActionInvokes() * { * HActionInvokes retVal; * return retVal; * } * * \endcode * * Those who know UPnP and paid close attention to the above example might have * noticed that something was off. Where are the actions? * * According to the UPnP Device Architecture (UDA), a service may have zero or * more actions. If a service has no actions, you don't have to create a custom * HServerService derivative in the first place, but even if you do, * similar class declaration and definition as shown above are enough. * * However, the standard \b BinaryLight:1 device type specifies the * \b SwitchPower:1 service type that has three actions defined * (look back in the service description document). * Namely these are \b SetTarget, \b GetTarget and \b GetStatus. * To make the example complete the MySwitchPowerService class * requires some additional work. Note that next example shows only one way * of making the service complete. There are a few other ways, * which will be discussed later in depth. * * The complete declaration for MySwitchPowerService: * * mybinarylight.h * * \code * * #include * * class MySwitchPowerService : * public Herqq::Upnp::HServerService * { * protected: * * virtual HActionInvokes createActionInvokes(); * * public: * * MySwitchPowerService(); * virtual ~MySwitchPowerService(); * * qint32 setTarget( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs); * * qint32 getTarget( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs); * * qint32 getStatus( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs); * }; * * \endcode * * The complete definition for MySwitchPowerService: * * mybinarylight.cpp * * \code * * #include "mybinarylight.h" * * #include * #include * #include * * MySwitchPowerService::MySwitchPowerService() * { * } * * MySwitchPowerService::~MySwitchPowerService() * { * } * * HServerService::HActionInvokes MySwitchPowerService::createActionInvokes() * { * Herqq::Upnp::HServerService::HActionInvokes retVal; * * retVal.insert( * "SetTarget", * Herqq::Upnp::HActionInvoke(this, &MySwitchPowerService::setTarget)); * * // The above lines map the MySwitchPowerService::setTarget() method to * // the action that has the name SetTarget. In essence, this mapping instructs * // HUPnP to call this method when the SetTarget action is invoked. * // However, note that HActionInvoke accepts any "callable entity", * // such as a normal function or a functor. Furthermore, if you use a * // method the method does not have to be public. * * retVal.insert( * "GetTarget", * Herqq::Upnp::HActionInvoke(this, &MySwitchPowerService::getTarget)); * * retVal.insert( * "GetStatus", * Herqq::Upnp::HActionInvoke(this, &MySwitchPowerService::getStatus)); * * return retVal; * } * * qint32 MySwitchPowerService::setTarget( * const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * Herqq::Upnp::HActionArgument newTargetValueArg = inArgs.get("newTargetValue"); * if (!newTargetValueArg.isValid()) * { * // If MySwitchPowerService class is not made for direct public use * // this check is redundant, since in that case this method is called only by * // HUPnP and HUPnP always ensures that the action arguments defined in the * // service description are present when an action is invoked. * * return Herqq::Upnp::UpnpInvalidArgs; * } * * bool newTargetValue = newTargetValueArg.value().toBool(); * stateVariables().value("Target")->setValue(newTargetValue); * * // The above line modifies the state variable "Target", which reflects the * // "target state" of a light device, i.e. if a user wants to turn off a light, the * // "target state" is the light turned off whether the light can be turned * // off or not. * * // * // Do here whatever that is required to turn on / off the light * // (set it to the target state) * // * * // * // If it succeeded, we should modify the Status state variable to reflect * // the new state of the light. * // * * stateVariables().value("Status")->setValue(newTargetValue); * * return Herqq::Upnp::UpnpSuccess; * } * * qint32 MySwitchPowerService::getTarget( * const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * if (!outArgs) * { * // See the comments in MySwitchPowerService::setTarget why this * // check is here. Basically, this check is redundant if this method * // is called only by HUPnP, as HUPnP ensures proper arguments * // are always provided when an action is invoked. * * return Herqq::Upnp::UpnpInvalidArgs; * } * * bool b = stateVariables().value("Target")->value().toBool(); * outArgs->setValue("RetTargetValue", b); * * return Herqq::Upnp::UpnpSuccess; * } * * qint32 MySwitchPowerService::getStatus( * const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * if (!outArgs) * { * // See the comments in MySwitchPowerService::getTarget(); * return UpnpInvalidArgs; * } * * bool b = stateVariables().value("Status")->value().toBool(); * outArgs->setValue("ResultStatus", b); * * return Herqq::Upnp::UpnpSuccess; * } * * \endcode * * The above example overrode the HServerService::createActionInvokes() and * did the action name - callable entity mapping. However, if you'd rather * have HUPnP do that automatically, you can mark your action implementations * as \c Q_INVOKABLE as follows: * * mybinarylight.h * * \code * * #include * * class MySwitchPowerService : * public Herqq::Upnp::HServerService * { * Q_OBJECT * * public: * * MySwitchPowerService(); * virtual ~MySwitchPowerService(); * * Q_INVOKABLE qint32 SetTarget( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs); * * Q_INVOKABLE qint32 GetTarget( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs); * * Q_INVOKABLE qint32 GetStatus( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs); * }; * * \endcode * * Apart from changing the method names to start with capital letters, * the method definitions stay otherwise the same. * * \note * Using \c Q_INVOKABLE methods as action implementations you have to * ensure that the names of the member functions correspond \b exactly to the * action names defined in the service description document. * * \subsection some_notes_about_switchpower_example Some closing notes * * First of all, you may want to skim the discussion in * \ref hupnp_devicemodel and \ref hupnp_devicehosting to fully understand * the comments in the example above. Especially the section * \ref setting_up_the_devicemodel is useful if you want to learn the details of * building a custom UPnP device using HUPnP. That being said, perhaps the * most important issues of building a custom UPnP device using HUPnP * can be summarized to: * * - Every device description has to have a corresponding Herqq::Upnp::HServerDevice * and every service description has to have a corresponding Herqq::Upnp::HServerService. * However, you don't have to create a custom HServerDevice, in which case HUPnP * will create and use a default HServerDevice type. In addition, if a service has no actions * you don't have to create a custom HServerService. On the other hand, most * commonly a service has one or more actions, so this is something you'll be * doing often. * * - It is perfectly fine to create custom HServerDevice and HServerService classes * just to be hosted in a Herqq::Upnp::HDeviceHost. Such classes exist only to * run your code when UPnP control points interact with them over the network. * These types of classes are to be used directly only by HDeviceHost. * * - You can create more advanced HServerDevice and HServerService classes perhaps * to build a higher level public API or just to provide yourself a nicer interface for * doing something. This was the case with \c MySwitchPowerService class, which * extended the HServerService interface by providing the possibility of invoking * the actions of the service through the \c setTarget(), \c getTarget() and \c getStatus() * methods. * * - HUPnP allows direct (in-process) access to the hosted * HServerDevice and HServerService classes, which means you can interact with * your classes \b while they are being hosted and possibly used from external * processes. Custom HServerDevice and HServerService interfaces may be beneficial * in such a case. * * - The type behind an Herqq::Upnp::HActionInvoke can hold any * callable entity, such as a pointer to a normal function, * functor or a pointer to a member function. * * - A public callable entity should always strictly verify the input and * respond to illegal input accordingly. A "private" callable entity that * is called only by HUPnP can rest assured that HUPnP never passes a null input * argument or an argument that has an incorrect name or data type. * * - Before implementing your own device * and service types directly from HServerDevice and HServerService, * you should check if HUPnP provides more refined classes to suit your * requirements. For instance, HUPnP provides a base class * Herqq::Upnp::Lighting::HAbstractSwitchPower for simplifying the implementation * and use of \b SwitchPower:1. * * In any case, the above example demonstrates a fully standard-compliant implementation * of \b BinaryLight:1. The next step is to publish your HServerDevice in the network * for UPnP control points to discover. You can find the instructions for that * in HDeviceHost and \ref hupnp_devicehosting. */ /*! \page setting_up_the_devicemodel Setting Up the Device Model * * \section before_we_start Before We Start * * Please note that in case you are writing client-side * software you rarely need to worry about how the device model gets built. But * if you are implementing a server-side UPnP device, this is something you * should know. In addition, you should first skim through the * \ref builddevice_tutorial if you haven't already. * * \section how_devicehost_builds_a_device How HDeviceHost builds a device tree * * When you initialize an Herqq::Upnp::HDeviceHost you have to provide it: * - one or more device descriptions that represent the UPnP device(s) you want * to host and * - a device model creator that creates the C++ classes representing the * UPnP devices and services defined in the description documents. * * You can find more information about setting up the Herqq::Upnp::HDeviceHost in * \ref hupnp_devicehosting, but what is relevant here is that you provide two * pieces of information that \b must match; the C++ classes created by the * device model creator \b must reflect the description documents and vice * versa. * * During its initialization an \c %HDeviceHost scans the provided * description document(s) and whenever it encounters a definition of a * UPnP device it invokes the device model creator you have provided to create * an instance of HServerDevice matching the device definition in the * description document. Similarly, whenever it encounters a UPnP service it invokes * the device model creator to create an instance of HServerService. * * When creating a device the \c %HDeviceHost provides an HDeviceInfo object to * the creator, which contains the information read from the description document. * And again, when creating a service an HServiceInfo object is provided to the * creator. Based on the information in the \e info objects the device model * creator is expected to create an HServerDevice or HServerService instance * if it can, or return \c null otherwise. If the device model creator returns * \c null the \c %HDeviceHost creates an instance of a default type used to * represent the encountered UPnP device or service. * * Consider an example of a simple device model creator, * * \code * * #include * * class MyCreator : public Herqq::Upnp::HDeviceModelCreator * { * * private: * * // overridden from HDeviceModelCreator * virtual MyCreator* newInstance() const * { * return new MyCreator(); * } * * public: * * // overridden from HDeviceModelCreator * virtual MyHServerDevice* createDevice(const Herqq::Upnp::HDeviceInfo& info) const * { * if (info.deviceType().toString() == "urn:herqq-org:device:MyDevice:1") * { * return new MyHServerDevice(); * } * * return 0; * } * * // overridden from HDeviceModelCreator * virtual MyHServerService* createService( * const Herqq::Upnp::HServiceInfo& serviceInfo, * const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const * { * if (serviceInfo.serviceType().toString() == "urn:herqq-org:service:MyService:1") * { * return new HMyServerService(); * } * * // Note, parentDeviceInfo is not needed in this case, but there are * // scenarios when it is mandatory to know information of the parent * // device to create the correct HServerService type. * * return 0; * } * }; * \endcode * * \note The \c %HDeviceHost takes ownership of the returned objects. However, * the \c %HDeviceHost will not destroy any of them until it is being deleted. * * \section plugging_in_custom_functionality Plugging in Custom Functionality * * In the UPnP architecture the \e actions represent the functionality of a device. * Actions are contained by services and services are contained by devices. * Thus, custom functionality means custom actions, which are logically placed * into custom services. Custom services, on the other hand, don't have to reside * inside custom devices. This is because ultimately a device is only a * container for services and that is certainly something the default device * types used by HUPnP can handle. * * So, to plug-in custom functionality you need a custom service type, which * main purpose is to map callable entities to UPnP action names. * * \note A callable entity is a C++ concept that * is used to refer to anything that can be called with the \c operator(), * such as a normal function, functor or a member function. * * There are two ways to do the mapping. You can either override * Herqq::Upnp::HServerService::createActionInvokes() in your custom HServerService * type, or you can mark member functions of your custom HServerService as * \c Q_INVOKABLE. * * Consider an example of overriding the \c createActionInvokes(), * * \code * Herqq::Upnp::HServerService::HActionInvokes MyConnectionManagerService::createActionInvokes() * { * Herqq::Upnp::HServerService::HActionInvokes retVal; * * retVal.insert("GetProtocolInfo", * HActionInvoke(this, &MyConnectionManagerService::getProtocolInfo)); * * retVal.insert("PrepareForConnection", * HActionInvoke(this, &MyConnectionManagerService::prepareForConnection)); * * retVal.insert("ConnectionComplete", * HActionInvoke(this, &MyConnectionManagerService::connectionComplete)); * * retVal.insert("GetCurrentConnectionIDs", * HActionInvoke(this, &MyConnectionManagerService::getCurrentConnectionIDs)); * * retVal.insert("GetCurrentConnectionInfo", * HActionInvoke(this, &MyConnectionManagerService::getCurrentConnectionInfo)); * * return retVal; * } * \endcode * * The above code maps five member functions of the class * \c MyConnectionManagerService to the five action names accordingly. Once the * device tree is fully set up and the HServerDevice containing the * \c MyConnectionManagerService is hosted by an HDeviceHost, * action invocations are ultimately directed to these mapped member functions. * In other words, in this case it is these member functions that have to * do whatever it is that these actions are expected to do. * * \note The callable entity concept detaches invocation logic from what is being * invoked and enables these "entities" to be handled by value. It is a very * powerful concept that allows you to map anything that can be called * following a certain signature under the same interface and copy these \e * entities around by-value. * * To give you an idea of the versatility of an callable entity, you could do * the above with normal functions too: * * \code * namespace * { * int getProtocolInfo(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * } * * int prepareForConnection(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * } * * int connectionComplete(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * } * * int getCurrentConnectionIDs(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * } * * int getCurrentConnectionInfo(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs) * { * } * } * * Herqq::Upnp::HServerService::HActionInvokes MyConnectionManagerService::createActionInvokes() * { * Herqq::Upnp::HServerService::HActionInvokes retVal; * * retVal.insert("GetProtocolInfo", Herqq::Upnp::HActionInvoke(getProtocolInfo)); * retVal.insert("PrepareForConnection", Herqq::Upnp::HActionInvoke(prepareForConnection)); * retVal.insert("ConnectionComplete", Herqq::Upnp::HActionInvoke(connectionComplete)); * retVal.insert("GetCurrentConnectionIDs", Herqq::Upnp::HActionInvoke(getCurrentConnectionIDs)); * retVal.insert("GetCurrentConnectionInfo", Herqq::Upnp::HActionInvoke(getCurrentConnectionInfo)); * * return retVal; * } * \endcode * * And it doesn't stop there. You can use functors as well. * * However, you can also let HUPnP to do the mapping and creation of the callable * entities, but to do that you need to: * * - Make sure your custom HServerService type uses the \c Q_OBJECT macro. * - Mark each member function to be used as an action implemention with \c Q_INVOKABLE * macro. * - Ensure that the member functions are named exactly as the corresponding * actions are defined in the service description document. * * Consider an example of using \c Q_INVOKABLE, * * \code * * class MyConnectionManagerService : * public HServerService * { * Q_OBJECT * * public: * * MyConnectionManagerService(); * virtual ~MyConnectionManagerService(); * * Q_INVOKABLE qint32 GetProtocolInfo( * const HActionArguments& inArgs, HActionArguments* outArgs); * * Q_INVOKABLE qint32 PrepareForConnection( * const HActionArguments& inArgs, HActionArguments* outArgs); * * Q_INVOKABLE qint32 ConnectionComplete( * const HActionArguments& inArgs, HActionArguments* outArgs); * * Q_INVOKABLE qint32 GetCurrentConnectionIDs( * const HActionArguments& inArgs, HActionArguments* outArgs); * * Q_INVOKABLE qint32 GetCurrentConnectionInfo( * const HActionArguments& inArgs, HActionArguments* outArgs); * }; * * \endcode * * Note, the method names are started with capital letters as are the * corresponding actions defined in the ConnectionManager specification. * * Once you have set up the action mappings, your custom HServerService * is ready to be used. However, there is much more you can do with * Herqq::Upnp::HDeviceModelInfoProvider::actionsSetupData() to ensure that the * service description containing the action definitions is correct. Similarly, * you can override Herqq::Upnp::HDeviceModelInfoProvider::stateVariablesSetupData() * to provide additional information to HUPnP in order to make sure that the * service description document is appropriately set up in terms of state * variables as well. This may not be important to you if you are writing a * "private" implementation of a service, but it could be very useful if you are * writing a "public" library of UPnP devices and services that have to make * sure they are appropriately used. * * \note * When implementing a custom \c %HServerService class you have to define the * implementations for the action definitions found in the corresponding * service description document. You are not required to do anything else. * However, you \b may provide additional information about the structure and * details of a UPnP service via HDeviceModelInfoProvider::actionsSetupData() and * HDeviceModelInfoProvider::stateVariablesSetupData(), but those are always optional. * * \section providing_more_info_to_model_setup Providing more information to the model setup process * * There are a few ways to provide in-depth information of a UPnP device to ensure * that a device model will get built as desired. All of the methods described * here require HDeviceModelInfoProvider. First, you can override * HDeviceModelInfoProvider::embedddedDevicesSetupData() and HDeviceModelInfoProvider::servicesSetupData() * methods to specify what embedded devices and services has to be defined in the * device description for an instance of the device type to function correctly. * Second, you can provide detailed information of expected actions and their * arguments when you override HDeviceModelInfoProvider::actionsSetupData(). Third, * you can provide detailed information of expected state variables when you override * HDeviceModelInfoProvider::stateVariablesSetupData(). * * \note All of these methods and techniques described here are optional. * * The benefit of overriding these methods is that HUPnP can ensure that the * provided description documents provide everything the respective C++ classes * expect. The validation is done by HUPnP during the build of the device model * and the build succeeds only if the provided description documents are * appropriately defined. This way you never have to validate the device model * yourself and you do not have to check everywhere if an embedded device, * a service, a required action, an action argument or a state variable is provided. * But if your device and service types are created for internal or * otherwise controlled use only, implementing your own HDeviceModelInfoProvider * may be unnecessary. * * An example of \c servicesSetupData(): * * \code * * Herqq::Upnp::HServicesSetupData MyDeviceModelInfoProvider::servicesSetupData( * const Herqq::Upnp::HDeviceInfo& info) * { * Herqq::Upnp::HServicesSetupData retVal; * * QString type = info.deviceType().toString(); * if (type == "urn:schemas-upnp-org:device:DimmableLight:1") * { * retVal.insert( * Herqq::Upnp::HServiceSetup( * Herqq::Upnp::HServiceId("urn:schemas-upnp-org:serviceId:SwitchPower"), * Herqq::Upnp::HResourceType("urn:schemas-upnp-org:service:SwitchPower:1"))); * * retVal.insert( * Herqq::Upnp::HServiceSetup( * Herqq::Upnp::HServiceId("urn:schemas-upnp-org:serviceId:Dimming"), * Herqq::Upnp::HResourceType("urn:schemas-upnp-org:service:Dimming:1"))); * } * * return retVal; * } * \endcode * * The above definition instructs HUPnP to ensure that when the \c DimmableLight:1 * device type is being initialized those two specified services are found * in the device description document provided by the user. If either one of them * is missing or contains invalid information, the device model build * is aborted, the HDeviceHost::init() fails and HDeviceHost::error() * returns HDeviceHost::InvalidDeviceDescriptionError. See the documentation of * HServiceSetup for more information of what can be validated. * * An example of \c embedddedDevicesSetupData(): * * \code * Herqq::Upnp::HDevicesSetupData MyDeviceModelInfoProvider::embedddedDevicesSetupData( * const HDeviceInfo& info) * { * Herqq::Upnp::HDevicesSetupData retVal; * * QString type = info.deviceType().toString(); * if (type == "urn:custom-domain-org:device:MyDeviceType:1") * { * retVal.insert( * Herqq::Upnp::HDeviceSetup( * Herqq::Upnp::HResourceType("urn:my-domain-org:device:MyDevice_X:1"))); * * retVal.insert( * Herqq::Upnp::HDeviceSetup( * Herqq::Upnp::HResourceType("urn:my-domain-org:device:MyDevice_Y:1"))); * } * * return retVal; * } * \endcode * * The above definition instructs HUPnP to ensure that when the \c MyDeviceType:1 * device type is being initialized those two specified embedded devices are found * in the device description document provided by the user. If either one of them * is missing or contains invalid information, the device model build * is aborted, the HDeviceHost::init() fails and HDeviceHost::error() * returns HDeviceHost::InvalidDeviceDescriptionError. See the documentation of * HDeviceSetup for more information of what can be validated. * * An example of \c stateVariablesSetupData(): * * \code * Herqq::Upnp::HStateVariablesSetupData MyDeviceModelInfoProvider::stateVariablesSetupData( * const Herqq::Upnp::HServiceInfo& serviceInfo, const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) * { * Herqq::Upnp::HStateVariablesSetupData retVal; * * if (info.serviceType().compare( * HResourceType("urn:schemas-upnp-org:service:ConnectionManager:2"), * HResourceType::Inclusive)) * { * retVal.insert(HStateVariableInfo( * "SourceProtocolInfo", HUpnpDataTypes::string)); * * retVal.insert(HStateVariableInfo( * "SinkProtocolInfo", HUpnpDataTypes::string)); * * retVal.insert(HStateVariableInfo( * "CurrentConnectionIDs", HUpnpDataTypes::string)); * * retVal.insert(HStateVariableInfo( * "A_ARG_TYPE_ConnectionStatus", HUpnpDataTypes::string)); * * retVal.insert(HStateVariableInfo( * "A_ARG_TYPE_ConnectionManager",HUpnpDataTypes::string)); * * retVal.insert(HStateVariableInfo( * "A_ARG_TYPE_ProtocolInfo", HUpnpDataTypes::string)); * * retVal.insert(HStateVariableInfo( * "A_ARG_TYPE_ConnectionID", HUpnpDataTypes::i4)); * * retVal.insert(HStateVariableInfo( * "A_ARG_TYPE_AVTransportID", HUpnpDataTypes::i4)); * * retVal.insert(HStateVariableInfo( * "A_ARG_TYPE_RcsID", HUpnpDataTypes::i4)); * } * * return retVal; * } * \endcode * * The above definition instructs HUPnP to ensure that when the \c ConnectionManager:2 * service type is being initialized all those specified state variables are found * in the service description document provided by the user. If any one of them * is missing or contains invalid information, the device model build * is aborted, the HDeviceHost::init() fails and HDeviceHost::error() * returns HDeviceHost::InvalidServiceDescriptionError. See the documentation of * HStateVariableInfo for more information of what can be validated. * * Finally, you can override HDeviceModelInfoProvider::actionsSetupData() to * provide detailed information about the action and its expected arguments. * See HActionSetup for more information of this. * * \note It is planned that in the future this same information could be used to * create instances of HUPnP's device model without description documents. * * \sa hupnp_devicehosting */ /*! * \defgroup hupnp_devicehosting Device Hosting * \ingroup hupnp_core * * \brief This page explains the concept of device hosts, which encapsulate the * technical details of UPnP networking. * * \section notesaboutdesign A few notes about the design * * The logical core of HUPnP is divided into two major modules; a collection of * classes that enable the \e hosting of UPnP device model and the collection of * classes that form up the \ref hupnp_devicemodel. The separation is very distinct. The * device hosts provide the technical foundation for the UPnP networking. They * encapsulate and implement the protocols the UPnP Device Architecture * specification details. The device model, on the other hand, is about the logical * structure of the UPnP core concepts, which is clearly independent of the * technical details of communication. Because of this HUPnP uses highly similar * device models both at the server and client side. * * HUPnP introduces two types of \e hosts. * \li The Herqq::Upnp::HDeviceHost is the class * that enables UPnP devices to be published for UPnP control points to use. * \li The Herqq::Upnp::HControlPoint is the class that enables the discovery * and use of UPnP devices that are available on the network. * * The difference between these two classes is important to notice. * You could picture an HDeviceHost as a server and an HControlPoint as a * client. The \c %HDeviceHost \e publishes instances of HServerDevice for * UPnP control points to use and the \c %HControlPoint \e uses instances of * HClientDevice to communicate with UPnP devices. But as implied, * the APIs of client and server side device models are very similar and once you * get familiar either one, using the other should be simple as well. * * \note While a Herqq::Upnp::HServerDevice published by a \c %HDeviceHost is always * usable by UPnP control points over the network, the same device can also * be accesed and used simultaneously in process. * See HDeviceHost for more information. * * \section basicuse Basic use * * The basic use of the \c %HDeviceHost is straightforward. * You only need to initialize it by providing information that enables one or * more UPnP devices to be created and hosted. * * In other words, you could create and initialize an HDeviceHost like this: * * \code * * #include * #include * * #include "my_hserverdevice.h" // your code * * namespace * { * class MyDeviceModelCreator : * public Herqq::Upnp::HDeviceModelCreator * { * private: * * // overridden from HDeviceModelCreator * virtual MyDeviceModelCreator* newInstance() const * { * return new MyDeviceModelCreator(); * } * * public: * * // overridden from HDeviceModelCreator * virtual Herqq::Upnp::HServerDevice* createDevice( * const Herqq::Upnp::HDeviceInfo& info) const * { * // You should check the info object to see what object HUPnP wants * // created and return null if your creator cannot create it. * return new MyHServerDevice(); // your class derived from HServerDevice * } * * // overridden from HDeviceModelCreator * virtual HServerService* createService( * const Herqq::Upnp::HServiceInfo& serviceInfo, * const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const * { * // You should check the info objects to see what object HUPnP wants * // created and return null if your creator cannot create it. * return new MyHServerService(); * } * }; * * Herqq::Upnp::HDeviceHost* createDeviceHost() * { * Herqq::Upnp::HDeviceHostConfiguration hostConf; * hostConf.setDeviceModelCreator(MyDeviceModelCreator()); * // This specifies the factory type that the HDeviceHost uses to create * // HServerDevice and HServerService instances. * * Herqq::Upnp::HDeviceConfiguration deviceConf; * deviceConf.setPathToDeviceDescription("my_hdevice_devicedescription.xml"); * // This is the device description for our custom UPnP device type * // the device host uses this file to build the device tree. * * hostConf.add(deviceConf); * // The same HDeviceHost can host multiple UPnP root devices at the same time. * // To do that you only need to create and add other HDeviceConfiguration * // objects to the HDeviceHostConfiguration instance as shown above. * * Herqq::Upnp::HDeviceHost* deviceHost = new HDeviceHost(); * if (!deviceHost->init(hostConf)) * { * // The initialization failed. Perhaps something should be done? * // You can call error() to check the type of the error and errorDescription() * // to get a human-readable description of the error. * } * * return deviceHost; * } * } * * \endcode * * and an HControlPoint like this: * * \code * * #include * * Herqq::Upnp::HControlPoint* createControlPoint() * { * Herqq::Upnp::HControlPoint* controlPoint = new HControlPoint(); * * if (!controlPoint->init()) * { * // The initialization failed. Perhaps something should be done? * // You can call error() to check the type of the error and errorDescription() * // to get a human-readable description of the error. * } * * return controlPoint; * } * } * * \endcode * * The above shows the simplest way to initialize an HControlPoint instance. * However, you can configure the behavior of an \c %HControlPoint instance * in various ways by providing it an HControlPointConfiguration instance upon * construction. * * \sa Herqq::Upnp::HDeviceHost, Herqq::Upnp::HControlPoint, hupnp_devicemodel */ /*! * \defgroup hupnp_core HUPnP Core * HUPnP Core is a library that provides an implementation of the * * UPnP Device Architecture version 1.1 specification. */ /*! * \defgroup hupnp_common Common * \ingroup hupnp_core */ QString upnpErrorCodeToString(qint32 errCode) { QString retVal; switch(errCode) { case UpnpSuccess: retVal = "Success"; break; case UpnpInvalidAction: retVal = "InvalidAction"; break; case UpnpInvalidArgs: retVal = "InvalidArgs"; break; case UpnpActionFailed: retVal = "ActionFailed"; break; case UpnpArgumentValueInvalid: retVal = "ArgumentValueInvalid"; break; case UpnpArgumentValueOutOfRange: retVal = "ArgumentValueOutOfRange"; break; case UpnpOptionalActionNotImplemented: retVal = "OptionalActionNotImplemented"; break; case UpnpOutOfMemory: retVal = "OutOfMemory"; break; case UpnpHumanInterventionRequired: retVal = "HumanInterventionRequired"; break; case UpnpStringArgumentTooLong: retVal = "StringArgumentTooLong"; break; case UpnpUndefinedFailure: retVal = "UndefinedFailure"; break; default: retVal = QString::number(errCode); break; } return retVal; } void SetLoggingLevel(HLogLevel level) { HLogger::setTraceLevel(static_cast(level)); } void EnableNonStdBehaviourWarnings(bool arg) { HLogger::enableNonStdWarnings(arg); } QString readElementValue( const QString elementTagToSearch, const QDomElement& parentElement, bool* wasDefined) { QDomElement element = parentElement.firstChildElement(elementTagToSearch); if (element.isNull()) { if (wasDefined) { *wasDefined = false; } return ""; } if (wasDefined) { *wasDefined = true; } return element.text(); } QString toString(const QDomElement& e) { QString buf; QTextStream ts(&buf, QIODevice::ReadWrite); e.save(ts, 0); return buf; } /******************************************************************************* * HSysInfo *******************************************************************************/ QScopedPointer HSysInfo::s_instance; QMutex HSysInfo::s_initMutex; HSysInfo::HSysInfo() { createProductTokens(); createLocalNetworks(); } HSysInfo::~HSysInfo() { } HSysInfo& HSysInfo::instance() { QMutexLocker lock(&s_initMutex); if (s_instance) { return *s_instance; } s_instance.reset(new HSysInfo()); return *s_instance; } void HSysInfo::createProductTokens() { #if defined(Q_OS_WIN) QString server = "MicrosoftWindows/"; switch(QSysInfo::WindowsVersion) { case QSysInfo::WV_2000: server.append("5.0"); break; case QSysInfo::WV_XP: server.append("5.1"); break; case QSysInfo::WV_2003: server.append("5.2"); break; case QSysInfo::WV_VISTA: server.append("6.0"); break; case QSysInfo::WV_WINDOWS7: server.append("6.1"); break; default: server.append("-1"); } #elif defined(Q_OS_DARWIN) QString server = "AppleMacOSX/"; switch(QSysInfo::MacintoshVersion) { case QSysInfo::MV_10_3: server.append("10.3"); break; case QSysInfo::MV_10_4: server.append("10.4"); break; case QSysInfo::MV_10_5: server.append("10.5"); break; case QSysInfo::MV_10_6: server.append("10.6"); break; default: server.append("-1"); } #elif defined(Q_OS_LINUX) QString server; struct utsname sysinfo; if (!uname(&sysinfo)) { server = QString("%1/%2").arg(sysinfo.sysname, sysinfo.release); } else { server = "Undefined/-1"; } #else QString server = "Undefined/-1"; #endif m_productTokens.reset( new HProductTokens(QString("%1 UPnP/1.1 HUPnP/%2.%3").arg( server, STRX(HUPNP_CORE_MAJOR_VERSION), STRX(HUPNP_CORE_MINOR_VERSION)))); } void HSysInfo::createLocalNetworks() { foreach(const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) { QList entries = iface.addressEntries(); foreach(const QNetworkAddressEntry& entry, entries) { QHostAddress ha = entry.ip(); if (ha.protocol() != QAbstractSocket::IPv4Protocol) { continue; } quint32 nm = entry.netmask().toIPv4Address(); m_localNetworks.append(qMakePair(ha.toIPv4Address() & nm, nm)); } } } bool HSysInfo::localNetwork(const QHostAddress& ha, quint32* retVal) const { Q_ASSERT(retVal); QList >::const_iterator ci; for(ci = m_localNetworks.begin(); ci != m_localNetworks.end(); ++ci) { if ((ha.toIPv4Address() & ci->second) == ci->first) { *retVal = ci->first; return true; } } return false; } bool HSysInfo::isLocalAddress(const QHostAddress& ha) const { quint32 tmp; return localNetwork(ha, &tmp); } bool HSysInfo::areLocalAddresses(const QList& addresses) const { QList localAddresses = QNetworkInterface::allAddresses(); foreach(const QHostAddress& ha, addresses) { bool matched = false; foreach(const QHostAddress& localAddress, localAddresses) { if (localAddress == ha) { matched = true; break; } } if (!matched) { return false; } } return true; } HEndpoints convertHostAddressesToEndpoints(const QList& addrs) { HEndpoints retVal; foreach(const QHostAddress& ha, addrs) { retVal.append(HEndpoint(ha)); } return retVal; } bool verifyName(const QString& name, QString* err) { HLOG(H_AT, H_FUN); if (name.isEmpty()) { if (err) { *err = "[name] cannot be empty"; } return false; } if (!name[0].isLetterOrNumber() && name[0] != '_') { if (err) { *err = QString("[name: %1] has invalid first character").arg(name); } return false; } foreach(const QChar& c, name) { if (!c.isLetterOrNumber() && c != '_' && c != '.') { if (err) { *err = QString( "[name: %1] contains invalid character(s)").arg(name); } return false; } } if (name.size() > 32) { HLOG_WARN(QString("[name: %1] longer than 32 characters").arg(name)); } return true; } QString urlsAsStr(const QList& urls) { QString retVal; for(qint32 i = 0; i < urls.size(); ++i) { retVal.append(QString("#%1 %2\n").arg( QString::number(i), urls[i].toString())); } return retVal; } QString extractBaseUrl(const QString& url) { if (url.endsWith('/')) { return url; } else if (!url.contains('/')) { return ""; } QString base = url.section('/', 0, -2, QString::SectionIncludeTrailingSep); return base; } QUrl resolveUri(const QUrl& baseUrl, const QUrl& other) { QString otherReq(extractRequestPart(other)); if (otherReq.startsWith('/')) { return QString("%1%2").arg(extractHostPart(baseUrl), otherReq); } QString basePath(baseUrl.toString()); if (!basePath.endsWith('/')) { basePath.append('/'); } if (otherReq.startsWith('/')) { otherReq.remove(0, 1); } basePath.append(otherReq); return basePath; } QUrl appendUrls(const QUrl& baseUrl, const QUrl& other) { QString otherReq(extractRequestPart(other)); QString basePath(baseUrl.toString()); if (!basePath.endsWith('/')) { basePath.append('/'); } if (otherReq.startsWith('/')) { otherReq.remove(0, 1); } basePath.append(otherReq); return basePath; } } } herqq-1.0.0/hupnp/src/general/hupnpinfo.cpp0000644000000000000000000000202311543637310017376 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hupnpinfo.h" static const char s_hupnpCoreVersion[] = HUPNP_CORE_VERSION; namespace Herqq { namespace Upnp { const char* hupnpCoreVersion() { return s_hupnpCoreVersion; } } } herqq-1.0.0/hupnp/src/general/hupnp_datatypes.h0000644000000000000000000003724411543637310020262 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUPNP_DATATYPES_H_ #define HUPNP_DATATYPES_H_ #include #include #include class QUrl; class QDate; class QTime; struct QUuid; class QDateTime; class QByteArray; namespace Herqq { namespace Upnp { /*! * An utility class for working with UPnP data types. * * \headerfile hupnp_datatypes.h HUpnpDataTypes */ class H_UPNP_CORE_EXPORT HUpnpDataTypes { H_DISABLE_COPY(HUpnpDataTypes) private: HUpnpDataTypes(); ~HUpnpDataTypes(); public: /*! * This enum type defines the UPnP data types set by the UPnP Device Architecture * v1.1 specification. */ enum DataType { /*! * Undefined, illegal data type. */ Undefined = 0, /*! * Unsigned 1 Byte int. Same format as int without leading sign. */ ui1, /*! * Unsigned 2 Byte int. Same format as int without leading sign. */ ui2, /*! * Unsigned 4 Byte int. Same format as int without leading sign. */ ui4 /*! * 1 Byte int. Same format as int. */, i1, /*! * 2 Byte int. Same format as int. */ i2, /*! * 4 Byte int. Same format as int. MUST be between -2147483648 and 2147483647. */ i4, /*! * Fixed point, integer number. */ integer, /*! * 4 Byte float. Same format as float. MUST be between 3.40282347E+38 to * 1.17549435E-38. */ r4, /*! * 8 Byte float. Same format as float. MUST be between -1.79769313486232E308 and - * 4.94065645841247E-324 for negative values, and between 4.94065645841247E-324 * and 1.79769313486232E308 for positive values, i.e., IEEE 64-bit (8-Byte) double. */ r8, /*! * Same as r8. */ number, /*! * Same as r8 but no more than 14 digits to the left of the decimal point and no more * than 4 to the right. */ fixed_14_4, /*! * Floating point number. Mantissa (left of the decimal) and/or exponent MAY have a * leading sign. Mantissa and/or exponent MAY have leading zeros, which SHOULD be * ignored by the recipient. Decimal character in mantissa is a period, i.e., whole * digits in mantissa separated from fractional digits by period ("."). Mantissa * separated from exponent by "E". */ fp, /*! * Unicode string. One character long. */ character, /*! * Unicode string. No limit on length. */ string, /*! * Date in a subset of ISO 8601 format without time data. */ date, /*! * Date in ISO 8601 format with OPTIONAL time but no time zone. */ dateTime, /*! * Date in ISO 8601 format with OPTIONAL time and OPTIONAL time zone. */ dateTimeTz, /*! * Time in a subset of ISO 8601 format with no date and no time zone. */ time, /*! * Time in a subset of ISO 8601 format with OPTIONAL time zone but no date. */ timeTz, /*! * "0" for false or "1" for true. The values "true", "yes", "false", or "no" are * deprecated and MUST NOT be sent but MUST be accepted when received. When * received, the values "true" and "yes" MUST be interpreted as true and the values * "false" and "no" MUST be interpreted as false. */ boolean, /*! * MIME-style Base64 encoded binary BLOB. Takes 3 Bytes, splits them into 4 parts, and * maps each 6 bit piece to an octet. (3 octets are encoded as 4.) No limit on size. */ bin_base64, /*! * Hexadecimal digits representing octets. Treats each nibble as a hex digit and * encodes as a separate Byte. (1 octet is encoded as 2.) No limit on size. */ bin_hex, /*! * Universal Resource Identifier. */ uri, /*! * Universally Unique ID */ uuid }; /******************************************************************************* * Data types as strings *******************************************************************************/ /*! * The string identifier for an unsigned 1 byte int. * * \sa DataType::ui1 */ const static QString& ui1_str() { static QString retVal = "ui1"; return retVal; } /*! * The string identifier for an unsigned 2 byte int. * * \sa DataType::ui2 */ const static QString& ui2_str() { static QString retVal = "ui2"; return retVal; } /*! * The string identifier for an unsigned 4 byte int. * * \sa DataType::ui4 */ const static QString& ui4_str() { static QString retVal = "ui4"; return retVal; } /*! * The string identifier for a 1 byte int. * * \sa DataType::i1 */ const static QString& i1_str() { static QString retVal = "i1"; return retVal; } /*! * The string identifier for a 2 byte int. * * \sa DataType::i2 */ const static QString& i2_str() { static QString retVal = "i2"; return retVal; } /*! * The string identifier for a 4 byte int. * * \sa DataType::i4 */ const static QString& i4_str() { static QString retVal = "i4"; return retVal; } /*! * The string identifier for a fixed point, integer number. * * \sa DataType::integer */ const static QString& integer_str() { static QString retVal = "int"; return retVal; } /*! * The string identifier for a 4 byte float. * * \sa DataType::r4 */ const static QString& r4_str() { static QString retVal = "r4"; return retVal; } /*! * The string identifier for a 8 byte float. * * \sa DataType::r8 */ const static QString& r8_str() { static QString retVal = "r8"; return retVal; } /*! * The string identifier for a 8 byte float. This is an alias for r8. * * \sa DataType::number */ const static QString& number_str() { static QString retVal = "number"; return retVal; } /*! * The string identifier for a 8 byte float that has no more than * 14 digits to the left of the decimal point and no more * than 4 to the right. * * \sa DataType::fixed_14_4 */ const static QString& fixed_14_4_str() { static QString retVal = "fixed.14.4"; return retVal; } /*! * The string identifier for a floating point number. * * \sa DataType::fp */ const static QString& fp_str() { static QString retVal = "float"; return retVal; } /*! * The string identifier for a unicode string that is one character long. * * \sa DataType::char */ const static QString& character_str() { static QString retVal = "char"; return retVal; } /*! * The string identifier for a unicode string that has no limit on length. * * \sa DataType::string */ static const QString& string_str() { static QString retVal = "string"; return retVal; } /*! * The string identifier for a date in a subset of ISO 8601 format * without time data. * * \sa DataType::date */ const static QString& date_str() { static QString retVal = "date"; return retVal; } /*! * The string identifier for a date in ISO 8601 format with OPTIONAL * time but no time zone. * * \sa DataType::dateTime */ const static QString& dateTime_str() { static QString retVal = "dateTime"; return retVal; } /*! * The string identifier for a date in ISO 8601 format with OPTIONAL * time and OPTIONAL time zone. * * \sa DataType::dateTimeTz */ const static QString& dateTimeTz_str() { static QString retVal = "dateTime.tz"; return retVal; } /*! * The string identifier for a time in a subset of ISO 8601 format * with no date and no time zone. * * \sa DataType::time */ const static QString& time_str() { static QString retVal = "time"; return retVal; } /*! * The string identifier for a time in a subset of ISO 8601 format * with OPTIONAL time zone but no date. * * \sa DataType::timeTz */ const static QString& time_tz_str() { static QString retVal = "time.tz"; return retVal; } /*! * The string identifier for a boolean. * * \sa DataType::boolean */ const static QString& boolean_str() { static QString retVal = "boolean"; return retVal; } /*! * The string identifier for a MIME-style Base64 encoded binary BLOB. * * \sa DataType::bin_base64 */ const static QString& bin_base64_str() { static QString retVal = "bin.base64"; return retVal; } /*! * The string identifier for a hexadecimal digits representing octets. * * \sa DataType::bin_hex */ const static QString& bin_hex_str() { static QString retVal = "bin.hex"; return retVal; } /*! * The string identifier for a universal Resource Identifier. * * \sa DataType::uri */ const static QString& uri_str() { static QString retVal = "uri"; return retVal; } /*! * The string identifier for a universally Unique ID. * * \sa DataType::uuid */ const static QString& uuid_str() { static QString retVal = "uuid"; return retVal; } /******************************************************************************* * Type definitions for the Upnp data types *******************************************************************************/ /*! * Type definition for a DataType::ui1. */ typedef quint8 ui1T; /*! * Type definition for a DataType::ui2. */ typedef quint16 ui2T; /*! * Type definition for a DataType::ui4. */ typedef quint32 ui4T; /*! * Type definition for a DataType::i1. */ typedef qint8 i1T; /*! * Type definition for a DataType::i2. */ typedef qint16 i2T; /*! * Type definition for a DataType::i4. */ typedef qint32 i4T; /*! * Type definition for a DataType::integer. */ typedef i4T integerT; /*! * Type definition for a DataType::r4. */ typedef float r4T; /*! * Type definition for a DataType::r8. */ typedef qreal r8T; /*! * Type definition for a DataType::number. */ typedef r8T numberT; /*! * Type definition for a DataType::fixed_14_4. */ typedef qreal fixed_14_4T; /*! * Type definition for a DataType::fp. */ typedef float fpT; /*! * Type definition for a DataType::char. */ typedef char characterT; /*! * Type definition for a DataType::string. */ typedef QString stringT; /*! * Type definition for a DataType::date */ typedef QDate dateT; /*! * Type definition for a DataType::dateTime. */ typedef QDateTime dateTimeT; /*! * Type definition for a DataType::time. */ typedef QTime timeT; /*! * Type definition for a DataType::timeTz. */ typedef QTime time_tzT; /*! * Type definition for a DataType::boolean. */ typedef bool booleanT; /*! * Type definition for a DataType::bin_base64. */ typedef QByteArray bin_base64T; /*! * Type definition for a DataType::bin_hex. */ typedef QByteArray bin_hexT; /*! * Type definition for a DataType::uri. */ typedef QUrl uriT; /*! * Type definition for a DataType::uuid. */ typedef QUuid uuidT; /*! * \brief Returns the UPnP data type enum value that matches the content * of the specified string, if any. * * \param dataTypeAsStr specifies the "name" of the UPnP data type as string. * For example, the string could contain "i4", which in the UDA v1.1 specification * is defined as 4-byte signed integer. * * \return The UPnP data type enum value that matches the content * of the specified string. If the specified string does not correspond * to any UPnP data type, HUpnpDataTypes::Undefined is returned. */ static DataType dataType(const QString& dataTypeAsStr); /*! * \brief Indicates whether or not the specified data type is numeric. * * \param datatype specifies the data type to be checked. * * \retval true if the specified data type is numeric. * \retval false in case the data type is not numeric or it is undefined. */ inline static bool isNumeric(DataType datatype) { return datatype >= ui1 && datatype <= fp; } /*! * \brief Indicates whether or not the specified data type is an integer. * * \param datatype specifies the data type to be checked. * * \retval true if the specified data type is an integer. * \retval false in case the data type is not an integer or it is undefined. */ inline static bool isInteger(DataType datatype) { return datatype >= ui1 && datatype <= integer; } /*! * \brief Indicates whether or not the specified data type is a rational number. * * \param arg specifies the data type to be checked. * * \retval true if the specified data type is a rational number. * \retval false in case the data type is not rational or it is undefined. */ inline static bool isRational(DataType arg) { switch(arg) { case r4: case r8: case number: case fp: case fixed_14_4: return true; default: return false; } } /*! * \brief Returns the UDA defined string representation of the specified data type. * * \param datatype specifies the data type which string representation is requested. * * \return The UDA defined string representation of the specified data type. */ static QString toString(DataType datatype); static QVariant::Type convertToVariantType(HUpnpDataTypes::DataType); static QVariant convertToRightVariantType( const QString& value, HUpnpDataTypes::DataType); }; } } #endif /* HUPNP_DATATYPES_H_ */ herqq-1.0.0/hupnp/src/general/hclonable.h0000644000000000000000000000620311543637310016770 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLONABLE_H_ #define HCLONABLE_H_ #include namespace Herqq { namespace Upnp { /*! * \brief This class defines an interface for cloning instances of polymorphic classes. * * \headerfile hclonable.h HClonable * * \remarks This class is thread-safe. * * \ingroup hupnp_common */ class H_UPNP_CORE_EXPORT HClonable { H_DISABLE_COPY(HClonable) protected: /*! * Clones the contents of this to the \c target object. * * Every derived class that introduces member variables that should be * copied as part of a cloning operation \b should override this method. * The implementation should be something along these lines: * * \code * void MyClonable::doClone(HClonable* target) const * { * MyClonable* myClonable = dynamic_cast(target); * if (!myClonable) * { * return; * } * * BaseClassOfMyClonable::doClone(target); * * // copy the variables introduced in *this* MyClonable * // instance to "myClonable". * } * \endcode * * \param target specifies the target object to which the contents of * \c this instance are cloned. */ virtual void doClone(HClonable* target) const; /*! * \brief Creates a new instance. * * This method is used as part of object cloning. Because of that, it is * important that every concrete (non-abstract) descendant class overrides * this method regardless of the type location in the inheritance tree: * * \code * MyClonable* MyClonable::newInstance() const * { * return new MyClonable(); * } * \endcode * * \remarks * \li the object has to be heap-allocated and * \li the ownership of the object is passed to the caller. */ virtual HClonable* newInstance() const = 0; public: /*! * \brief Creates a new instance. */ HClonable(); /*! * \brief Destroys the instance. */ virtual ~HClonable(); /*! * \brief Returns a deep copy of the instance. * * \return a deep copy of the instance. * * \remarks * \li the ownership of the returned object is transferred to the caller. */ virtual HClonable* clone() const; }; } } #endif /* HCLONABLE_H_ */ herqq-1.0.0/hupnp/src/general/hupnp_datatypes_p.h0000644000000000000000000000311111543637310020563 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HUPNP_DATATYPES_P_H_ #define HUPNP_DATATYPES_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hupnp_datatypes.h" #include #include class QString; class QVariant; namespace Herqq { namespace Upnp { // // \internal // class SoapType : public QtSoapSimpleType { public: SoapType(const QString& name, HUpnpDataTypes::DataType, const QVariant& value); }; // // \internal // QtSoapType::Type convertToSoapType(HUpnpDataTypes::DataType); } } #endif /* HUPNP_DATATYPES_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/0000755000000000000000000000000011543637460015540 5ustar rootrootherqq-1.0.0/hupnp/src/devicemodel/client/0000755000000000000000000000000011543637460017016 5ustar rootrootherqq-1.0.0/hupnp/src/devicemodel/client/hclientdevice.h0000644000000000000000000001741111543637310021773 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTDEVICE_H_ #define HCLIENTDEVICE_H_ #include #include class QUrl; class QString; namespace Herqq { namespace Upnp { class HClientDevicePrivate; /*! * \brief This is a client-side class that represents a server-side UPnP device. * * \c %HClientDevice is a core component of the HUPnP's client-side \ref hupnp_devicemodel * and it models a UPnP device, both root and embedded. As detailed in the * UPnP Device Architecture specification, a UPnP device is essentially a * container for services and possibly for other (embedded) UPnP devices. * *

Using the class

* * The most common uses of \c %HClientDevice involve reading the various device * information elements originally set in the device description file and enumerating the * exposed services. By calling info() you get an HDeviceInfo object from * which you can read all the informational elements found in the device description. * Calling services() gives you a list of HClientService instances the device * exposes. Note that it is the services that contain the functionality * and runtime status of the device. * * Some devices also contain embedded devices, which you can get by calling * embeddedDevices(). * * You can retrieve the device's description file by calling description() or * you can manually read it from any of the locations returned by locations(). If * the device is an embedded device, it always has a parent device, which you can * get by calling parentDevice(). * * \headerfile hclientdevice.h HClientDevice * * \ingroup hupnp_devicemodel * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HClientDevice : public QObject { Q_OBJECT H_DISABLE_COPY(HClientDevice) H_DECLARE_PRIVATE(HClientDevice) protected: HClientDevicePrivate* h_ptr; /*! * \brief Creates a new instance. * * \param info specifies information of the device. This is often read * from a device description document. * * \param parentDev specifies the parent device of this device, if any. */ HClientDevice(const HDeviceInfo& info, HClientDevice* parentDev = 0); public: /*! * \brief Destroys the instance. */ virtual ~HClientDevice() = 0; /*! * \brief Returns the parent device of this device, if any. * * \return The parent device of this device, if any, or a null pointer * in case the device is a root device. * * \remarks The pointer is guaranteed to be valid throughout the lifetime * of this object. */ HClientDevice* parentDevice() const; /*! * \brief Returns the root device of the device tree to which this device belongs. * * \return The root device of the device tree to which this device belongs. * * \remarks This device could be the root device of the device tree in question, * in which case a pointer to this instance is returned. */ HClientDevice* rootDevice() const; /*! * \brief Returns the service that has the specified service ID. * * \param serviceId specifies the service to be returned. * * \return The service that has the specified service ID or a null pointer * in case there is no service with the specified ID. * * \remarks The pointer is guaranteed to be valid throughout the lifetime * of this object. */ HClientService* serviceById(const HServiceId& serviceId) const; /*! * \brief Returns the services this device exports. * * \return The services this device exports. The collection is empty * if the device has no services. * * \remarks The pointers are guaranteed to be valid throughout the lifetime * of this object. */ HClientServices services() const; /*! * \brief Returns the services of a specific UPnP service type. * * \param serviceType specifies the UPnP service type of interest. * Only services matching the type are returned. * * \param versionMatch specifies how the version information in argument * \c serviceType should be used. The default is inclusive match, * which essentially means that any service with a service type version that * is \b less than or \b equal to the version specified in argument * \c serviceType is successfully matched. * * \return The services of the specified type. * * \remarks the pointers are guaranteed to be valid throughout the lifetime * of this object. */ HClientServices servicesByType( const HResourceType& serviceType, HResourceType::VersionMatch versionMatch = HResourceType::Inclusive) const; /*! * \brief Returns the embedded devices of this device. * * \return The embedded devices of this device. The collection is empty * if the device has no embedded devices. * * \remarks the pointers are guaranteed to be valid throughout the lifetime * of this object. */ HClientDevices embeddedDevices() const; /*! * \brief Returns the embedded devices of a specific UPnP device type. * * \param deviceType specifies the UPnP device type of interest. * Only devices matching the type are returned. * * \param versionMatch specifies how the version information in argument * \a deviceType should be used. The default is inclusive match, * which essentially means that any device with a device type version that * is \b less than or \b equal to the version specified in argument * \a deviceType is successfully matched. * * \return The embedded devices of the specified type. * * \remarks the pointers are guaranteed to be valid throughout the lifetime * of this object. */ HClientDevices embeddedDevicesByType( const HResourceType& deviceType, HResourceType::VersionMatch versionMatch = HResourceType::Inclusive) const; /*! * \brief Returns information about the device. * * \return information about the device. This is often read from the * device description. */ const HDeviceInfo& info() const; /*! * \brief Returns the UPnP device description of this device. * * \return The UPnP device description that is associated to this device. * * \remarks an embedded device returns the same device description as * its root device. */ QString description() const; /*! * \brief Returns a list of locations where the device is currently available. * * \param urlType specifies whether the returned * location URLs are absolute URLs for retrieving the device description. * By default absolute URLs are returned and from these URLs the device * description should be retrievable. * * \return a list of locations where the device is currently available. */ QList locations(LocationUrlType urlType=AbsoluteUrl) const; }; } } #endif /* HCLIENTDEVICE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientservice.cpp0000644000000000000000000001063211543637310022525 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hclientservice.h" #include "hclientservice_p.h" #include "hdefault_clientservice_p.h" #include "hclientaction.h" #include "hdefault_clientstatevariable_p.h" #include "../../dataelements/hactioninfo.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HClientServicePrivate ******************************************************************************/ HClientServicePrivate::HClientServicePrivate() : m_stateVariablesConst() { } HClientServicePrivate::~HClientServicePrivate() { } bool HClientServicePrivate::addStateVariable(HDefaultClientStateVariable* sv) { if (HServicePrivate::addStateVariable(sv)) { m_stateVariablesConst.insert(sv->info().name(), sv); return true; } return false; } HClientServicePrivate::ReturnValue HClientServicePrivate::updateVariables( const QList >& variables, bool sendEvent) { ReturnValue rv = HServicePrivate::updateVariables(variables); if (rv == Updated && sendEvent && m_evented) { emit q_ptr->stateChanged(q_ptr); } return rv; } /******************************************************************************* * HClientService ******************************************************************************/ HClientService::HClientService( const HServiceInfo& info, HClientDevice* parentDevice) : QObject(reinterpret_cast(parentDevice)), h_ptr(new HClientServicePrivate()) { Q_ASSERT_X(parentDevice, "", "Parent device must be defined!"); h_ptr->m_serviceInfo = info; h_ptr->q_ptr = this; } HClientService::~HClientService() { delete h_ptr; } HClientDevice* HClientService::parentDevice() const { return reinterpret_cast(parent()); } const HServiceInfo& HClientService::info() const { return h_ptr->m_serviceInfo; } QString HClientService::description() const { return h_ptr->m_serviceDescription; } const HClientActions& HClientService::actions() const { return h_ptr->m_actions; } const HClientStateVariables& HClientService::stateVariables() const { return h_ptr->m_stateVariablesConst; } void HClientService::notifyListeners() { if (h_ptr->m_evented) { emit stateChanged(this); } } bool HClientService::isEvented() const { return h_ptr->m_evented; } QVariant HClientService::value(const QString& stateVarName, bool* ok) const { return h_ptr->value(stateVarName, ok); } /******************************************************************************* * HDefaultClientService ******************************************************************************/ HDefaultClientService::HDefaultClientService( const HServiceInfo& info, HClientDevice* parentDevice) : HClientService(info, parentDevice) { } void HDefaultClientService::addAction(HClientAction* action) { Q_ASSERT(action); Q_ASSERT(!h_ptr->m_actions.contains(action->info().name())); h_ptr->m_actions.insert(action->info().name(), action); } void HDefaultClientService::addStateVariable(HDefaultClientStateVariable* sv) { h_ptr->addStateVariable(sv); } void HDefaultClientService::setDescription(const QString& description) { h_ptr->m_serviceDescription = description; } bool HDefaultClientService::updateVariables( const QList >& variables, bool sendEvent) { return h_ptr->updateVariables(variables, sendEvent) != HClientServicePrivate::Failed; } } } herqq-1.0.0/hupnp/src/devicemodel/client/hdefault_clientservice_p.h0000644000000000000000000000334711543637310024222 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEFAULT_CLIENTSERVICE_P_H_ #define HDEFAULT_CLIENTSERVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include namespace Herqq { namespace Upnp { class HDefaultClientStateVariable; // // Default implementation of HClientService // class HDefaultClientService : public HClientService { H_DISABLE_COPY(HDefaultClientService) public: HDefaultClientService(const HServiceInfo&, HClientDevice* parentDevice); void addAction(HClientAction*); void addStateVariable(HDefaultClientStateVariable*); void setDescription(const QString& description); bool updateVariables( const QList >& variables, bool sendEvent); }; } } #endif /* HDEFAULT_CLIENTSERVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientstatevariable.cpp0000644000000000000000000000544111543637310023715 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hclientstatevariable.h" #include "hdefault_clientstatevariable_p.h" #include "../hstatevariable_p.h" #include "../hstatevariable_event.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HClientStateVariable *******************************************************************************/ HClientStateVariable::HClientStateVariable( const HStateVariableInfo& info, HClientService* parent) : QObject(reinterpret_cast(parent)), h_ptr(new HStateVariablePrivate()) { Q_ASSERT_X(parent, H_AT, "Parent service must be defined."); Q_ASSERT_X(info.isValid(), H_AT, "Info object must be valid."); h_ptr->m_info = info; setValue(info.defaultValue()); } HClientStateVariable::~HClientStateVariable() { delete h_ptr; } HClientService* HClientStateVariable::parentService() const { return reinterpret_cast(parent()); } QVariant HClientStateVariable::value() const { return h_ptr->m_value; } const HStateVariableInfo& HClientStateVariable::info() const { return h_ptr->m_info; } bool HClientStateVariable::setValue(const QVariant& newValue) { QVariant oldValue = h_ptr->m_value; QString err; if (!h_ptr->setValue(newValue, &err)) { return false; } if (h_ptr->m_info.eventingType() != HStateVariableInfo::NoEvents) { HStateVariableEvent event(oldValue, newValue); emit valueChanged(this, event); } return true; } /******************************************************************************* * HDefaultClientStateVariable *******************************************************************************/ HDefaultClientStateVariable::HDefaultClientStateVariable( const HStateVariableInfo& info, HClientService* parent) : HClientStateVariable(info, parent) { } } } herqq-1.0.0/hupnp/src/devicemodel/client/hclientactionop.h0000644000000000000000000000654211543637310022353 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTACTION_OP_H_ #define HCLIENTACTION_OP_H_ #include namespace Herqq { namespace Upnp { class HClientActionOpPrivate; /*! * \brief This class is used to identify a client-side action invocation and detail * information of it. * * When you call HClientAction::beginInvoke() you get an instance of this class * that uniquely identifies the asynchronous operation within the running process. * Once the operation completes and the HClientAction::invokeComplete() * signal is sent, you get a copy of the instance that was provided by the \c beginInvoke(). * You can use either of the objects and any other copy you may have made to query * the UPnP return code of the operation by calling returnValue(). You can call * inputArguments() to get the arguments you provided to the * HClientAction::beginInvoke() and you can call outputArguments() to get any * output arguments the action invocation may have returned. * * \headerfile hclientactionop.h HClientActionOp * * \ingroup hupnp_devicemodel * * \sa HClientAction, HAsyncOp * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HClientActionOp : public HAsyncOp { H_DECLARE_PRIVATE(HClientActionOp); public: /*! * \brief Creates a new instance. */ HClientActionOp(); /*! * Creates a new instance based on the provided values. * * \param inArgs specifies the input arguments of the action invocation. */ HClientActionOp(const HActionArguments& inArgs); /*! * \brief Copy constructor. * * Copies the contents of the \c other to this. */ HClientActionOp(const HClientActionOp&); /*! * \brief Destroys the instance. */ virtual ~HClientActionOp(); /*! * Assigns the contents of the other object to this. * * \return reference to this object. */ HClientActionOp& operator=(const HClientActionOp&); /*! * \brief Returns the input arguments of the action invocation. * * \return The input arguments of the action invocation. */ const HActionArguments& inputArguments() const; /*! * \brief Returns the output arguments of the action invocation. * * \return The output arguments of the action invocation. */ const HActionArguments& outputArguments() const; /*! * \brief Sets the output arguments of the action invocation. * * \param outArgs */ void setOutputArguments(const HActionArguments& outArgs); }; } } #endif /* HCLIENTACTION_OP_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientstatevariable.h0000644000000000000000000001235511543637310023364 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENT_STATEVARIABLE_H_ #define HCLIENT_STATEVARIABLE_H_ #include #include #include namespace Herqq { namespace Upnp { class HStateVariablePrivate; /*! * \brief A client-side class that represents a server-side UPnP state variable. * * \c %HClientStateVariable is a core component of the HUPnP's client-side \ref hupnp_devicemodel * and it models a UPnP state variable. The UPnP Device Architecture specifies a * UPnP state variable as an item or aspect that models state in a service. * In a way a state variable is an abstraction to a member variable inside a * UPnP service. * * A state variable can be \e evented in which case it notifies interested listeners * of changes in its value. You can see if a state variable is evented by checking * the HStateVariableInfo object using info() and you can connect to the signal * valueChanged() to be notified when the value of the state variable changes. * Note, only evented state variables emit the valueChanged() signal. * * \headerfile hclientstatevariable.h HClientStateVariable * * \ingroup hupnp_devicemodel * * \sa HClientService * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HClientStateVariable : public QObject { Q_OBJECT H_DISABLE_COPY(HClientStateVariable) protected: HStateVariablePrivate* h_ptr; /*! * \brief Creates a new instance. * * \param info specifies information of the state variable. This is often * read from a service description document. * * \param parent specifies the UPnP service instance that contains this * state variable. */ HClientStateVariable(const HStateVariableInfo& info, HClientService* parent); /*! * Changes the value of the state variable. If the instance is evented, * the valueChanged() signal is emitted after the value has been changed. * * \param newValue specifies the new value of the state variable. The new value * must have the same underlying data type as the previous value * (and the default value). If the new value has different data type, the value * is not changed, no event is sent and false is returned. * * \retval true in case the new value was successfully set. * \retval false in case the new value could not be set. * * \remarks the new value will be set if the value: * - does not violate the defined constraints * - has the same variant type or the type of the new value can be converted * to the same variant type * - is not QVariant::Invalid */ bool setValue(const QVariant& newValue); public: /*! * \brief Destroys the instance. * * An \c %HClientStateVariable is always destroyed by the * \c %HClientService that contains it when it is being deleted. * Further, unless you hold the ownership of the \c %HClientStateVariable * instance, you should never destroy it. */ virtual ~HClientStateVariable() = 0; /*! * \brief Returns the HClientService that contains this state variable. * * \return The HClientService that contains this state variable. * * \warning the pointer is guaranteed to point to a valid object as long * as the \c %HClientStateVariable exists, which ultimately is as long as the * containing root device exists. */ HClientService* parentService() const; /*! * \brief Returns the current value of the state variable. * * \return The current value of the state variable. */ QVariant value() const; /*! * \brief Returns information about the state variable. * * \return information about the state variable. This information is often read * from a service description document. */ const HStateVariableInfo& info() const; Q_SIGNALS: /*! * \brief This signal is emitted when the value of the state variable has changed. * * \param source specifies the state variable that sent the event. * * \param event specifies information about the event that occurred. * * \remarks This signal has thread affinity to the thread where the object * resides. Do not connect to this signal from other threads. */ void valueChanged( const Herqq::Upnp::HClientStateVariable* source, const Herqq::Upnp::HStateVariableEvent& event); }; } } #endif /* HCLIENT_STATEVARIABLE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hdefault_clientstatevariable_p.h0000644000000000000000000000254311543637310025405 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEFAULTCLIENT_STATEVARIABLE_H_ #define HDEFAULTCLIENT_STATEVARIABLE_H_ #include namespace Herqq { namespace Upnp { // // Default implementation of HClientStateVariable // class HDefaultClientStateVariable : public HClientStateVariable { H_DISABLE_COPY(HDefaultClientStateVariable) public: HDefaultClientStateVariable( const HStateVariableInfo&, HClientService* parent); using HClientStateVariable::setValue; }; } } #endif /* HDEFAULTCLIENT_STATEVARIABLE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientdevice_p.h0000644000000000000000000000272111543637310022310 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTDEVICE_P_H_ #define HCLIENTDEVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hdefault_clientdevice_p.h" #include "../hdevice_p.h" namespace Herqq { namespace Upnp { class HDefaultClientDevice; // // // class HClientDevicePrivate : public HDevicePrivate { H_DISABLE_COPY(HClientDevicePrivate) public: HClientDevicePrivate(){} virtual ~HClientDevicePrivate(){} }; } } #endif /* HCLIENTDEVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientservice_p.h0000644000000000000000000000346211543637310022514 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTSERVICE_P_H_ #define HCLIENTSERVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../hservice_p.h" namespace Herqq { namespace Upnp { class HDefaultClientStateVariable; // // Implementation details of HClientService // class HClientServicePrivate : public HServicePrivate { H_DECLARE_PUBLIC(HClientService) H_DISABLE_COPY(HClientServicePrivate) public: // attributes QHash m_stateVariablesConst; public: // methods HClientServicePrivate(); virtual ~HClientServicePrivate(); bool addStateVariable(HDefaultClientStateVariable*); ReturnValue updateVariables( const QList >& variables, bool sendEvent); }; } } #endif /* HCLIENTSERVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientaction.h0000644000000000000000000001544611543637310022017 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTACTION_H_ #define HCLIENTACTION_H_ #include #include class QString; namespace Herqq { namespace Upnp { class HClientActionPrivate; /*! * \brief A client-side class that represents a server-side UPnP action. * * \c %HClientAction is a core component of the HUPnP's client-side \ref hupnp_devicemodel * and it models a UPnP action. The UPnP Device Architecture specifies a UPnP * action as a command, which takes one or more input and output arguments and that * may have a return value. * * \brief This class is used to invoke the server-side UPnP actions from the client-side. * You can get information of the action using info(), which includes the action's * input and output arguments. You can dispatch an asynchronous action invocation * to the server-side using beginInvoke(). Once the server responds, invokeComplete() * signal is sent. * * \headerfile hclientaction.h HClientAction * * \ingroup hupnp_devicemodel * * \sa HActionInfo, HClientService * * \remarks * \li This class has thread-affinity. */ class H_UPNP_CORE_EXPORT HClientAction : public QObject { Q_OBJECT H_DISABLE_COPY(HClientAction) H_DECLARE_PRIVATE(HClientAction) protected: HClientActionPrivate* h_ptr; /*! * \brief Creates a new instance. * * \param info specifies information of the action. * * \param parent specifies the UPnP service that contains this action. */ HClientAction(const HActionInfo& info, HClientService* parent); public: /*! * \brief Destroys the instance. * * An \c %HClientAction is always destroyed by the \c %HClientAction that contains * it when it is being deleted. Further, unless you hold the ownership of the * \c %HClientAction instance, you should never destroy it. */ virtual ~HClientAction() = 0; /*! * \brief Returns the parent service of the action. * * \return The parent service of the action. * * \warning the pointer is guaranteed to point to a valid object as long * as the \c %HClientAction exists, which ultimately is as long as the * containing root device exists. * * \sa HClientDevice */ HClientService* parentService() const; /*! * \brief Returns information about the action that is read from the * service description. * * \return information about the action that is read from the * service description. */ const HActionInfo& info() const; /*! * Schedules the action to be invoked. * * The method performs an asynchronous action invocation. The invocation * is placed in a queue and it will be run once it's at the head of the queue. * * Unless you specified the action to be executed as fire and forget, * the signal invokeComplete() is emitted once the invocation is complete. * * \param inArgs specifies the input arguments for the action invocation. * * \param execArgs specifies information used to control the execution of * the action invocation procedure. This is optional. * * \return an object that identifies the asynchronous operation. This object will * be sent through the invokeComplete() signal once the invocation is done. * * \sa invokeComplete() */ HClientActionOp beginInvoke( const HActionArguments& inArgs, HExecArgs* execArgs = 0); /*! * Schedules the action to be invoked. * * The method performs an asynchronous action invocation. The invocation * is placed in a queue and it will be run once it's at the head of the queue. * * Unless you specified the action to be executed as fire and forget, * the specified callback is called when the invocation is complete. * No events are sent unless that is explicitly requested by \b returning \b * true from the callback function. * * The different semantics compared to the other beginInvoke() * method are important to notice: * * \li If a completion callback is valid, no event is sent unless * the invoker explicitly requests that. * \li The callback is always invoked immediately after the invocation has * succeeded or failed. If the callback returns \e true, the invokeComplete() * signal will be emitted immediately after. * * \param inArgs specifies the input arguments for the action invocation * * \param completionCallback specifies the callable entity that is called * once the action invocation is completed or failed. If the specified callable * entity is not valid and it cannot be called, the callable entity is * ignored and the invokeComplete() signal is sent sent instead. * * \param execArgs specifies information used to control the execution of * the action invocation procedure. This is optional. * * \return an object that identifies the asynchronous operation. This object will * be sent through the callback and the invokeComplete() once the invocation is done. * * \sa invokeComplete() */ HClientActionOp beginInvoke( const HActionArguments& inArgs, const HActionInvokeCallback& completionCallback, HExecArgs* execArgs = 0); Q_SIGNALS: /*! * \brief This signal is emitted when an invocation has been successfully * completed or the invocation failed, unless the invocation was started * as fire and forget. * * \param source identifies the HClientAction that ran the operation. * * \param operation specifies information of the operation that completed. * * \sa beginInvoke() * * \remarks This signal has thread affinity to the thread where the object * resides. Do not connect to this signal from other threads. */ void invokeComplete( Herqq::Upnp::HClientAction* source, const Herqq::Upnp::HClientActionOp& operation); }; } } #endif /* HCLIENTACTION_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientservice.h0000644000000000000000000001553711543637310022203 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTSERVICE_H_ #define HCLIENTSERVICE_H_ #include #include class QUrl; namespace Herqq { namespace Upnp { class HClientServicePrivate; /*! * \brief A client-side class that represents a server-side UPnP service. * * \c %HClientService is a core component of the HUPnP's client-side \ref hupnp_devicemodel * and it models a UPnP service. The UPnP Device Architecture specifies a * UPnP service as "Logical functional unit. Smallest units of control. Exposes * actions and models the state of a physical device with state variables". * In other words, a UPnP service is the entry point for accessing * certain type of functionality and state of the containing device. * *

Using the class

* * You can retrieve the containing device, the \e parent \e device, using parentDevice(). * You can retrieve all the actions the service contains by calling actions(), * Similarly, you can retrieve all the state variables of the service by calling * stateVariables(). * * The class exposes all the details in the device description concerning a * service through info(). From the returned HServiceInfo object you can * retrieve the \e serviceId and \e serviceType along with various URLs found * in the device description, such as the: * \li \e scpdUrl, which returns the URL for fetching the service description, * \li \e controlUrl, which returns the URL to be used in action invocation and * \li \e eventSubUrl, which returns the URL used in event (un)subscriptions. * * However, the above URLs usually provide informational value only, since * HUPnP provides a simpler interface for everything those URLs expose: * \li You can retrieve the service description of a service using description(). * \li Action invocation is abstracted into the HClientAction class. * \li You can receive all the event notifications from a UPnP service by connecting * to the stateChanged() signal. You do not need to worry about UPnP eventing at all, * since HUPnP handles that for you. * * \headerfile hclientservice.h HClientService * * \ingroup hupnp_devicemodel * * \sa hupnp_devicemodel * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HClientService : public QObject { Q_OBJECT H_DISABLE_COPY(HClientService) H_DECLARE_PRIVATE(HClientService) protected: HClientServicePrivate* h_ptr; /*! * \brief Creates a new instance. * * \param info specifies information of the service. * * \param parentDevice specifies the device instance that contains this * service. * * Default constructor for derived classes. */ HClientService(const HServiceInfo& info, HClientDevice* parentDevice); public: /*! * \brief Destroys the instance. */ virtual ~HClientService() = 0; /*! * \brief Returns the parent HClientDevice that contains this service instance. * * \return The parent HClientDevice that contains this service instance. */ HClientDevice* parentDevice() const; /*! * \brief Returns information about the service. * * \return information about the service. This information is usually read * from a device description document. */ const HServiceInfo& info() const; /*! * \brief Returns the full service description. * * \return The full service description. */ QString description() const; /*! * \brief Returns the actions the service supports. * * \return The actions the service supports. * * \remarks The ownership of the returned objects is not transferred. * Do \b not delete the returned objects. */ const HClientActions& actions() const; /*! * \brief Returns the state variables of the service. * * \return The state variables of the service. * * \remarks The ownership of the returned objects is not transferred. * Do \b not delete the returned objects. */ const HClientStateVariables& stateVariables() const; /*! * \brief Indicates whether or not the service contains state variables that * are evented. * * \return \e true in case the service contains one or more state variables * that are evented. * * \remarks In case the service is not evented, the stateChanged() signal * will never be emitted and the notifyListeners() method does nothing. */ bool isEvented() const; /*! * \brief Returns the value of the specified state variable, if such exists. * * This is a convenience method for retrieving a state variable by name and * getting its value. * * \param stateVarName specifies the name of the state variable. * * \param ok specifies a pointer to a \c bool, which will contain \e true * if the specified state variable was found and its value was returned. * This is optional. * * \return The value of the specified state variable, if such exists. * If this service does not contain the specified state variable, an * invalid \c QVariant is returned. * * \remarks The value of the state variable may be represented by an * invalid \c QVariant. Because of this, if you want to be sure that the * specified state variable was found and its value was returned, you should * use the \a ok parameter. */ QVariant value(const QString& stateVarName, bool* ok = 0) const; public Q_SLOTS: /*! * Explicitly forces stateChanged() event to be emitted if the service is * evented. Otherwise this method does nothing. */ void notifyListeners(); Q_SIGNALS: /*! * \brief This signal is emitted when the state of one or more state variables * has changed. * * \param source specifies the source of the event. * * \remarks This signal has thread affinity to the thread where the object * resides. Do not connect to this signal from other threads. */ void stateChanged(const Herqq::Upnp::HClientService* source); }; } } #endif /* HCLIENTSERVICE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hdefault_clientdevice_p.h0000644000000000000000000000533411543637310024017 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEFAULT_CLIENTDEVICE_P_H_ #define HDEFAULT_CLIENTDEVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include #include namespace Herqq { namespace Upnp { class HDefaultClientService; // // // class HDefaultClientDevice : public HClientDevice { Q_OBJECT H_DISABLE_COPY(HDefaultClientDevice) private: bool m_timedout; QScopedPointer m_statusNotifier; QScopedPointer m_deviceStatus; qint32 m_configId; private Q_SLOTS: void timeout_(); public: HDefaultClientDevice( const QString& description, const QList& locations, const HDeviceInfo&, qint32 deviceTimeoutInSecs, HDefaultClientDevice* parentDev); void setServices(const QList&); void setEmbeddedDevices(const QList&); inline void setConfigId(qint32 configId) { m_configId = configId; } public: enum SearchCriteria { ThisOnly = 0, EmbeddedDevices = 1, Services = 2, All = 3 }; quint32 deviceTimeoutInSecs() const; inline HDeviceStatus* deviceStatus() const { if (!parentDevice()) { return m_deviceStatus.data(); } return static_cast(rootDevice())->deviceStatus(); } void startStatusNotifier(SearchCriteria searchCriteria); void stopStatusNotifier(SearchCriteria searchCriteria); bool addLocation(const QUrl& location); void addLocations(const QList& locations); bool isTimedout(SearchCriteria searchCriteria) const; Q_SIGNALS: void statusTimeout(HDefaultClientDevice* source); }; } } #endif /* HDEFAULT_CLIENTDEVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hdefault_clientaction_p.h0000644000000000000000000000310011543637310024022 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEFAULTCLIENTACTION_P_H_ #define HDEFAULTCLIENTACTION_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include class QNetworkAccessManager; namespace Herqq { namespace Upnp { // // Default implementation of the HClientAction // class HDefaultClientAction : public HClientAction { H_DISABLE_COPY(HDefaultClientAction) public: HDefaultClientAction( const HActionInfo&, HClientService* parent, QNetworkAccessManager&); }; } } #endif /* HDEFAULTCLIENTACTION_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientdevice.cpp0000644000000000000000000001643111543637310022327 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hclientdevice.h" #include "hclientdevice_p.h" #include "hdefault_clientdevice_p.h" #include "hdefault_clientservice_p.h" #include "../../general/hlogger_p.h" #include "../../general/hupnp_global_p.h" #include "../../dataelements/hserviceid.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hserviceinfo.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HClientDevicePrivate ******************************************************************************/ /******************************************************************************* * HClientDevice ******************************************************************************/ HClientDevice::HClientDevice( const HDeviceInfo& info, HClientDevice* parentDev) : QObject(parentDev), h_ptr(new HClientDevicePrivate()) { h_ptr->m_parentDevice = parentDev; h_ptr->m_deviceInfo.reset(new HDeviceInfo(info)); h_ptr->q_ptr = this; } HClientDevice::~HClientDevice() { delete h_ptr; } HClientDevice* HClientDevice::parentDevice() const { return h_ptr->m_parentDevice; } HClientDevice* HClientDevice::rootDevice() const { return h_ptr->rootDevice(); } HClientService* HClientDevice::serviceById(const HServiceId& serviceId) const { return h_ptr->serviceById(serviceId); } HClientServices HClientDevice::services() const { return h_ptr->m_services; } HClientServices HClientDevice::servicesByType( const HResourceType& type, HResourceType::VersionMatch versionMatch) const { return h_ptr->servicesByType(type, versionMatch); } HClientDevices HClientDevice::embeddedDevices() const { return h_ptr->m_embeddedDevices; } HClientDevices HClientDevice::embeddedDevicesByType( const HResourceType& type, HResourceType::VersionMatch versionMatch) const { return h_ptr->embeddedDevicesByType(type, versionMatch); } const HDeviceInfo& HClientDevice::info() const { return *h_ptr->m_deviceInfo; } QString HClientDevice::description() const { return h_ptr->m_deviceDescription; } QList HClientDevice::locations(LocationUrlType urlType) const { if (h_ptr->m_parentDevice) { // the root device "defines" the locations and they are the same for each // embedded device. return h_ptr->m_parentDevice->locations(urlType); } QList retVal; QList::const_iterator ci; for(ci = h_ptr->m_locations.begin(); ci != h_ptr->m_locations.end(); ++ci) { retVal.push_back(urlType == AbsoluteUrl ? *ci : extractBaseUrl(*ci)); } return retVal; } /******************************************************************************* * HDefaultClientDevice ******************************************************************************/ HDefaultClientDevice::HDefaultClientDevice( const QString& description, const QList& locations, const HDeviceInfo& info, qint32 deviceTimeoutInSecs, HDefaultClientDevice* parentDev) : HClientDevice(info, parentDev), m_timedout(false), m_statusNotifier(new QTimer(this)), m_deviceStatus(new HDeviceStatus()), m_configId(0) { h_ptr->m_deviceDescription = description; h_ptr->m_locations = locations; m_statusNotifier->setInterval(deviceTimeoutInSecs * 1000); bool ok = connect( m_statusNotifier.data(), SIGNAL(timeout()), this, SLOT(timeout_())); Q_ASSERT(ok); Q_UNUSED(ok) } void HDefaultClientDevice::setServices( const QList& services) { h_ptr->m_services.clear(); foreach(HDefaultClientService* srv, services) { h_ptr->m_services.append(srv); } } void HDefaultClientDevice::setEmbeddedDevices( const QList& devices) { h_ptr->m_embeddedDevices.clear(); foreach(HDefaultClientDevice* dev, devices) { h_ptr->m_embeddedDevices.append(dev); } } quint32 HDefaultClientDevice::deviceTimeoutInSecs() const { return m_statusNotifier->interval() / 1000; } void HDefaultClientDevice::timeout_() { HLOG(H_AT, H_FUN); m_timedout = true; stopStatusNotifier(HDefaultClientDevice::ThisOnly); emit statusTimeout(this); } void HDefaultClientDevice::startStatusNotifier(SearchCriteria searchCriteria) { HLOG(H_AT, H_FUN); m_statusNotifier->start(); if (searchCriteria & Services) { // TODO } if (searchCriteria & EmbeddedDevices) { foreach(HClientDevice* dc, h_ptr->m_embeddedDevices) { static_cast(dc)->startStatusNotifier(searchCriteria); } } m_timedout = false; } void HDefaultClientDevice::stopStatusNotifier(SearchCriteria searchCriteria) { HLOG(H_AT, H_FUN); m_statusNotifier->stop(); if (searchCriteria & Services) { // TODO } if (searchCriteria & EmbeddedDevices) { foreach(HClientDevice* dc, h_ptr->m_embeddedDevices) { static_cast(dc)->stopStatusNotifier(searchCriteria); } } } bool HDefaultClientDevice::isTimedout(SearchCriteria searchCriteria) const { if (m_timedout) { return true; } if (searchCriteria & Services) { // TODO } if (searchCriteria & EmbeddedDevices) { foreach(HClientDevice* dc, h_ptr->m_embeddedDevices) { if (static_cast(dc)->isTimedout(searchCriteria)) { return true; } } } return false; } namespace { bool shouldAdd(const HClientDevice* device, const QUrl& location) { Q_ASSERT(!device->parentDevice()); // embedded devices always query the parent device for locations QList locations = device->locations(); QList::const_iterator ci = locations.constBegin(); for(; ci != locations.constEnd(); ++ci) { if ((*ci).host() == location.host()) { return false; } } return true; } } bool HDefaultClientDevice::addLocation(const QUrl& location) { if (shouldAdd(this, location)) { h_ptr->m_locations.push_back(location); return true; } return false; } void HDefaultClientDevice::addLocations(const QList& locations) { QList::const_iterator ci = locations.constBegin(); for(; ci != locations.constEnd(); ++ci) { addLocation(*ci); } } } } herqq-1.0.0/hupnp/src/devicemodel/client/hclientaction_p.h0000644000000000000000000000776211543637310022340 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HCLIENTACTION_P_H_ #define HCLIENTACTION_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hclientactionop.h" #include "../hexecargs.h" #include "../hactionarguments.h" #include "../hactioninvoke_callback.h" #include "../../dataelements/hactioninfo.h" #include #include #include #include #include #include namespace Herqq { namespace Upnp { class HActionProxy; class HInvocationInfo; // // Implementation details of HClientAction // class HClientActionPrivate { H_DECLARE_PUBLIC(HClientAction) H_DISABLE_COPY(HClientActionPrivate) public: void invokeCompleted(int rc, const HActionArguments* outArgs = 0); public: const QByteArray m_loggingIdentifier; HClientAction* q_ptr; QScopedPointer m_info; HActionProxy* m_proxy; QQueue m_invocations; public: HClientActionPrivate(); ~HClientActionPrivate(); bool setInfo(const HActionInfo&); }; // // // class HInvocationInfo { public: HActionInvokeCallback callback; HExecArgs execArgs; HActionArguments m_inArgs; HClientActionOp m_invokeId; inline HInvocationInfo() : callback(), execArgs(), m_inArgs(), m_invokeId() { } inline ~HInvocationInfo() { } inline HInvocationInfo( const HActionArguments& inArgs, const HActionInvokeCallback& cb, const HExecArgs& eargs) : callback(cb), execArgs(eargs), m_inArgs(inArgs), m_invokeId(inArgs) { } }; // // Class for relaying action invocations across the network to the real // HClientAction objects instantiated by device hosts // class HActionProxy : public QObject { Q_OBJECT H_DISABLE_COPY(HActionProxy) private: QList m_locations; qint32 m_iNextLocationToTry; // the device locations and the index the next connection attempt should try // these are the places to which the action invocation requests are sent QNetworkAccessManager& m_nam; QNetworkReply* m_reply; HClientActionPrivate* m_owner; HActionArguments m_inArgs; private: inline void invocationDone(qint32 rc, const HActionArguments* outArgs = 0) { deleteReply(); m_owner->invokeCompleted(rc, outArgs); } inline void deleteReply() { if (m_reply) { m_reply->deleteLater(); m_reply = 0; } } private slots: void error(QNetworkReply::NetworkError); void finished(); public: HActionProxy(QNetworkAccessManager&, HClientActionPrivate* owner); virtual ~HActionProxy(); void send(); inline void setInputArgs(const HActionArguments& inArgs) { m_inArgs = inArgs; } inline bool invocationInProgress() const { return m_reply; } }; } } #endif /* HCLIENTACTION_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/client/hclientactionop.cpp0000644000000000000000000000506211543637310022702 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hclientactionop.h" #include "../hasyncop.h" #include "../hasyncop_p.h" #include "../hactionarguments.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HClientActionOpPrivate *******************************************************************************/ class HClientActionOpPrivate : public HAsyncOpPrivate { public: HActionArguments m_inArgs, m_outArgs; public: inline HClientActionOpPrivate() : HAsyncOpPrivate(HAsyncOpPrivate::genId()), m_inArgs(), m_outArgs() { } virtual ~HClientActionOpPrivate() {} }; /******************************************************************************* * HClientActionOp *******************************************************************************/ HClientActionOp::HClientActionOp() : HAsyncOp(*new HClientActionOpPrivate()) { } HClientActionOp::HClientActionOp(const HActionArguments& inArgs) : HAsyncOp(*new HClientActionOpPrivate()) { H_D(HClientActionOp); h->m_inArgs = inArgs; } HClientActionOp::HClientActionOp(const HClientActionOp& other) : HAsyncOp(other) { } HClientActionOp::~HClientActionOp() { } HClientActionOp& HClientActionOp::operator=(const HClientActionOp& other) { Q_ASSERT(&other != this); HAsyncOp::operator=(other); return *this; } const HActionArguments& HClientActionOp::inputArguments() const { const H_D(HClientActionOp); return h->m_inArgs; } const HActionArguments& HClientActionOp::outputArguments() const { const H_D(HClientActionOp); return h->m_outArgs; } void HClientActionOp::setOutputArguments(const HActionArguments& outArgs) { H_D(HClientActionOp); h->m_outArgs = outArgs; } } } herqq-1.0.0/hupnp/src/devicemodel/client/hclientaction.cpp0000644000000000000000000002556711543637310022357 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hclientaction.h" #include "hclientaction_p.h" #include "hclientdevice.h" #include "hclientservice.h" #include "hdefault_clientaction_p.h" #include "../../general/hlogger_p.h" #include "../../general/hupnp_global_p.h" #include "../../general/hupnp_datatypes_p.h" #include "../../dataelements/hudn.h" #include "../../dataelements/hactioninfo.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hserviceinfo.h" #include "../../general/hlogger_p.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HActionProxy ******************************************************************************/ HActionProxy::HActionProxy( QNetworkAccessManager& nam, HClientActionPrivate* owner) : QObject(owner->q_ptr), m_locations(), m_iNextLocationToTry(0), m_nam(nam), m_reply(0), m_owner(owner) { Q_ASSERT(m_owner); } HActionProxy::~HActionProxy() { } void HActionProxy::error(QNetworkReply::NetworkError err) { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); if (!m_reply) { return; } if (err == QNetworkReply::RemoteHostClosedError) { return; } else if (err == QNetworkReply::ConnectionRefusedError || err == QNetworkReply::HostNotFoundError) { HLOG_WARN(QString("Couldn't connect to the device [%1] @ [%2].").arg( m_owner->q_ptr->parentService()->parentDevice()->info().udn().toSimpleUuid(), m_locations[m_iNextLocationToTry].toString())); if (m_iNextLocationToTry < m_locations.size() - 1) { ++m_iNextLocationToTry; deleteReply(); send(); return; } HLOG_WARN("Action invocation failed: Couldn't connect to the device"); m_iNextLocationToTry = 0; } HLOG_WARN(QString( "Action invocation failed: [%1]").arg(m_reply->errorString())); QVariant statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); invocationDone(statusCode.isValid() ? statusCode.toInt() : UpnpUndefinedFailure); } void HActionProxy::finished() { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); if (!m_reply) { return; } bool ok = false; qint32 statusCode = m_reply->attribute( QNetworkRequest::HttpStatusCodeAttribute).toInt(&ok); if (ok && statusCode != 200) { // the status code might not be available if the remote host closed // the connection. HLOG_WARN(QString( "Action invocation failed. Server responded: [%1, %2]").arg( QString::number(statusCode), m_reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute).toString())); invocationDone(statusCode); return; } QByteArray data = m_reply->readAll(); QtSoapMessage response; if (!response.setContent(data)) { HLOG_WARN(QString( "Received an invalid SOAP message as a response to " "action invocation: [%1]").arg(QString::fromUtf8(data))); invocationDone(UpnpUndefinedFailure); return; } if (response.isFault()) { HLOG_WARN(QString( "Action invocation failed: [%1, %2]").arg( response.faultString().toString(), response.faultDetail().toString())); QtSoapType errCode = response.faultDetail()["errorCode"]; invocationDone(errCode.isValid() ? errCode.value().toInt() : UpnpUndefinedFailure); return; } if (m_owner->m_info->outputArguments().size() == 0) { // since there are not supposed to be any out arguments, this is a // valid scenario invocationDone(UpnpSuccess); return; } const QtSoapType& root = response.method(); if (!root.isValid()) { HLOG_WARN(QString( "Received an invalid response to action invocation: [%1]").arg( response.toXmlString())); invocationDone(UpnpUndefinedFailure); return; } HActionArguments outArgs = m_owner->m_info->outputArguments(); HActionArguments::const_iterator ci = outArgs.constBegin(); for(; ci != outArgs.constEnd(); ++ci) { HActionArgument oarg = *ci; const QtSoapType& arg = root[oarg.name()]; if (!arg.isValid()) { invocationDone(UpnpUndefinedFailure); return; } HActionArgument userArg = outArgs.get(oarg.name()); userArg.setValue( HUpnpDataTypes::convertToRightVariantType( arg.value().toString(), oarg.dataType())); } invocationDone(UpnpSuccess, &outArgs); } void HActionProxy::send() { HLOG2(H_AT, H_FUN, m_owner->m_loggingIdentifier); Q_ASSERT(!invocationInProgress()); if (m_locations.isEmpty()) { // store the device locations only upon action invocation, and only // if they haven't been stored yet. m_locations = m_owner->q_ptr->parentService()->parentDevice()->locations(BaseUrl); Q_ASSERT(!m_locations.isEmpty()); m_iNextLocationToTry = 0; } QtSoapNamespaces::instance().registerNamespace( "u", m_owner->q_ptr->parentService()->info().serviceType().toString()); QtSoapMessage soapMsg; soapMsg.setMethod( QtSoapQName( m_owner->m_info->name(), m_owner->q_ptr->parentService()->info().serviceType().toString())); HActionArguments::const_iterator ci = m_inArgs.constBegin(); for(; ci != m_inArgs.constEnd(); ++ci) { HActionArgument iarg = *ci; if (!m_inArgs.contains(iarg.name())) { invocationDone(UpnpInvalidArgs); return; } QtSoapType* soapArg = new SoapType(iarg.name(), iarg.dataType(), iarg.value()); soapMsg.addMethodArgument(soapArg); } QNetworkRequest req; req.setHeader( QNetworkRequest::ContentTypeHeader, QString("text/xml; charset=\"utf-8\"")); QString soapActionHdrField("\""); soapActionHdrField.append( m_owner->q_ptr->parentService()->info().serviceType().toString()); soapActionHdrField.append("#").append(m_owner->m_info->name()).append("\""); req.setRawHeader("SOAPAction", soapActionHdrField.toUtf8()); QUrl url = resolveUri( m_locations[m_iNextLocationToTry], m_owner->q_ptr->parentService()->info().controlUrl()); req.setUrl(url); m_reply = m_nam.post(req, soapMsg.toXmlString().toUtf8()); bool ok = connect( m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError))); Q_ASSERT(ok); Q_UNUSED(ok) ok = connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); Q_ASSERT(ok); } /******************************************************************************* * HClientActionPrivate ******************************************************************************/ HClientActionPrivate::HClientActionPrivate() : m_loggingIdentifier(), q_ptr(0), m_info(), m_proxy(0), m_invocations() { } HClientActionPrivate::~HClientActionPrivate() { } void HClientActionPrivate::invokeCompleted( int rc, const HActionArguments* outArgs) { Q_ASSERT(!m_invocations.isEmpty()); HInvocationInfo inv = m_invocations.dequeue(); inv.m_invokeId.setReturnValue(rc); inv.m_invokeId.setOutputArguments(outArgs ? *outArgs : HActionArguments()); if (inv.execArgs.execType() != HExecArgs::FireAndForget) { bool sendEvent = true; if (inv.callback) { sendEvent = inv.callback(q_ptr, inv.m_invokeId); } if (sendEvent) { emit q_ptr->invokeComplete(q_ptr, inv.m_invokeId); } } if (!m_invocations.isEmpty() && !m_proxy->invocationInProgress()) { const HInvocationInfo& inv = m_invocations.head(); m_proxy->setInputArgs(inv.m_inArgs); m_proxy->send(); } } bool HClientActionPrivate::setInfo(const HActionInfo& info) { if (!info.isValid()) { return false; } m_info.reset(new HActionInfo(info)); return true; } /******************************************************************************* * HClientAction ******************************************************************************/ HClientAction::HClientAction(const HActionInfo& info, HClientService* parent) : QObject(reinterpret_cast(parent)), h_ptr(new HClientActionPrivate()) { Q_ASSERT_X(parent, H_AT, "Parent service must be defined."); Q_ASSERT_X(info.isValid(), H_AT, "Action information must be defined."); h_ptr->m_info.reset(new HActionInfo(info)); h_ptr->q_ptr = this; } HClientAction::~HClientAction() { delete h_ptr; } HClientService* HClientAction::parentService() const { return reinterpret_cast(parent()); } const HActionInfo& HClientAction::info() const { return *h_ptr->m_info; } HClientActionOp HClientAction::beginInvoke( const HActionArguments& inArgs, HExecArgs* execArgs) { return beginInvoke(inArgs, HActionInvokeCallback(), execArgs); } HClientActionOp HClientAction::beginInvoke( const HActionArguments& inArgs, const HActionInvokeCallback& cb, HExecArgs* execArgs) { HInvocationInfo inv(inArgs, cb, execArgs ? *execArgs : HExecArgs()); h_ptr->m_invocations.enqueue(inv); if (!h_ptr->m_proxy->invocationInProgress()) { h_ptr->m_proxy->setInputArgs(inArgs); h_ptr->m_proxy->send(); } inv.m_invokeId.setReturnValue(UpnpInvocationInProgress); return inv.m_invokeId; } /******************************************************************************* * HDefaultClientAction ******************************************************************************/ HDefaultClientAction::HDefaultClientAction( const HActionInfo& info, HClientService* parent, QNetworkAccessManager& nam) : HClientAction(info, parent) { h_ptr->m_proxy = new HActionProxy(nam, h_ptr); } } } herqq-1.0.0/hupnp/src/devicemodel/hactioninvoke_callback.h0000644000000000000000000000635511543637310022371 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HACTIONINVOKE_CALLBACK_H_ #define HACTIONINVOKE_CALLBACK_H_ #include #include /*! * \file */ namespace Herqq { namespace Upnp { /*! * This is a type definition for a callable entity that is used * as a callback for signaling the completion of an HClientAction invocation. * * You can create \c %HActionInvokeCallback objects using normal functions, * functors and member functions that follow the signature of * * * * bool function(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&); * * * *

Parameters

* \li The first parameter is a type of an "ID" of the asynchronous action invocation. * \li The second parameter specifies the output arguments of the action invocation, * which may be empty. * *

Return value

* The return value indicates if the invoked HClientAction should emit an * HClientAction::invokeComplete() after the callback has returned. * \li \b true indicates that the HClientAction should sent the corresponding event. * * The following example demonstrates how you can instantiate the \c %HActionInvokeCallback * for a normal function, functor and a member function. * * \code * * #include * * #include "myclass.h" // your code that contains declaration for MyClass * * namespace * { * bool freefun(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&) * { * return true; * } * * class MyFunctor * { * public: * bool operator()(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&) * { * return true; * } * }; * } * * bool MyClass::memfun(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&) * { * return true; * } * * void MyClass::example() * { * Herqq::Upnp::HActionInvokeCallback usingFreeFunction(freefun); * * MyFunctor myfunc; * Herqq::Upnp::HActionInvokeCallback usingFunctor(myfunc); * * Herqq::Upnp::HActionInvokeCallback usingMemberFunction(this, &MyClass::memfun); * } * * \endcode * * You can test if the object can be invoked simply by issuing * if (actionInvokeCallbackObject) { ... } * * \headerfile hactioninvoke_callback.h HActionInvokeCallback * * \ingroup hupnp_devicemodel */ typedef Functor HActionInvokeCallback; } } #endif /* HACTIONINVOKE_CALLBACK_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hasyncop.h0000644000000000000000000001474011543637310017535 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HASYNCOP_H_ #define HASYNCOP_H_ #include class QString; namespace Herqq { namespace Upnp { class HAsyncOpPrivate; /*! * \brief This abstract class is used as a base for identifying an asynchronous * operation and detail information of it. * * Some HUPnP components provide an asynchronous interface for running possible * long-standing operations. A most notable example of this is the client-side * action invocation initiated with HClientAction::beginInvoke(). In cases * like this, the class running the operation returns a derivative of this class, * which is used to identify and describe the running operation. * * \section Usage * * The component that runs an asynchronous operation provides an instance * derived from this class when the operation is started. A copy of that instance is * provided also when the component signals the operation is complete. * The provided instance uniquely identifies the operation, carries information * whether the operation eventually succeeded or not and it may contain an error * description in case of an error. * * For example: * * \code * * HClientActionOp op = someActionObject->beginInvoke(); * * // * // The operation completes, after which you can: * // * * int retVal = op.returnValue(); * // retrieve a return value indicating whether the operation succeeded. * * QString errDescr = op.errorDescription(); * // retrieve an error description if the operation failed. * * \endcode * * \note HAsyncOp and any derivative class provided by HUPnP use \e explicit * \e sharing, which basically means that every copy of an instance references * the same underlying data and any change to that data is visible to all of the * copies. * * \headerfile hasyncop.h HAsyncOp * * \ingroup hupnp_devicemodel * * \remarks This class is not thread-safe. * * \sa HClientActionOp */ class H_UPNP_CORE_EXPORT HAsyncOp { H_DECLARE_PRIVATE(HAsyncOp) friend H_UPNP_CORE_EXPORT bool operator==(const HAsyncOp&, const HAsyncOp&); protected: HAsyncOpPrivate* h_ptr; // // \internal // HAsyncOp(HAsyncOpPrivate&); // // \internal // HAsyncOp(qint32 returnCode, const QString& errorDescription, HAsyncOpPrivate& dd); /*! * Creates a new valid instance. * * Creates a new valid instance, i.e isNull() always returns \e false. * * \sa isNull() */ HAsyncOp(); /*! * Creates a new instance, invalid instance. * * \param returnCode specifies the return code. * * \param errorDescription specifies a human-readable description of the error * that occurred. */ HAsyncOp(qint32 returnCode, const QString& errorDescription); /*! * \brief Copy constructor. * * Creates a shallow copy of \a other increasing the reference count of * \a other. */ HAsyncOp(const HAsyncOp&); /*! * \brief Assignment operator. * * Switches this instance to refer to the contents of \a other increasing the * reference count of \a other. */ HAsyncOp& operator=(const HAsyncOp&); public: /*! * \brief Destroys the instance. * * Decreases the reference count or destroys the instance once the reference * count drops to zero. */ virtual ~HAsyncOp() = 0; /*! * \brief Returns a human readable error description. * * \return a human readable error description, if any. * * \sa setErrorDescription() */ QString errorDescription() const; /*! * \brief Sets a human readable error description. * * \param arg specifies the human readable error description. * * \sa errorDescription() */ void setErrorDescription(const QString& arg); /*! * \brief Returns the return value of the asynchronous operation. * * \sa setReturnValue() */ int returnValue() const; /*! * \brief Sets the return value of the asynchronous operation. * * \param returnValue specifies the return value of the asynchronous operation. * * \sa returnValue() */ void setReturnValue(int returnValue); /*! * \brief Returns an identifier of the asynchronous operation. * * \return an identifier of the asynchronous operation. The identifier * is "unique" within the process where the library is loaded. More specifically, * the ID is monotonically incremented and it is allowed to overflow. */ unsigned int id() const; /*! * \brief Indicates whether the object identifies an asynchronous operation. * * \retval true in case the object does not identify an asynchronous operation. * This is usually the case when an operation was not successfully started. * \retval false in case the object identifies an asynchronous operation. */ bool isNull() const; /*! * \brief Indicates whether the object identifies an asynchronous operation. * * This is a convenience method and it is semantically equivalent with isNull(). * * \retval true in case the object does not identify an asynchronous operation. * This is usually the case when an operation was not successfully started. * \retval false in case the object identifies an asynchronous operation. */ inline bool operator!() const { return isNull(); } /*! * Aborts the execution of the operation. * * Aborts the execution of the operation. * * \remarks * It is up to the implementation to decide whether to implement this. The * default implementation does nothing. */ virtual void abort(); }; } } #endif /* HASYNCOP_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hactionarguments_p.h0000644000000000000000000000465711543637310021611 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HACTIONARGUMENTS_P_H_ #define HACTIONARGUMENTS_P_H_ #include "hactionarguments.h" #include #include // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // namespace Herqq { namespace Upnp { // // // class HActionArgumentsPrivate { public: // attributes QVector m_argumentsOrdered; // UDA 1.1 mandates that action arguments are always transmitted in the order // they were specified in the service description. QHash m_arguments; // for fast name-based lookups public: // functions HActionArgumentsPrivate(); explicit HActionArgumentsPrivate(const QVector& args); inline void append(const HActionArgument& arg) { Q_ASSERT_X(arg.isValid(), H_AT, "A provided action argument has to be valid"); m_argumentsOrdered.push_back(arg); m_arguments[arg.name()] = arg; } template static HActionArgumentsPrivate* copy(const T& source) { HActionArgumentsPrivate* contents = new HActionArgumentsPrivate(); for(typename T::const_iterator ci = source.constBegin(); ci != source.constEnd(); ++ci) { HActionArgument arg = *ci; arg.detach(); contents->append(arg); } return contents; } }; } } #endif /* HACTIONARGUMENTS_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hservices_setupdata.h0000644000000000000000000002170311543637310021753 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVICES_SETUPDATA_H_ #define HSERVICES_SETUPDATA_H_ #include #include #include #include #include namespace Herqq { namespace Upnp { class HServiceSetupPrivate; /*! * \brief This class is used to specify information that can be used to validate * a UPnP service. * * \headerfile hservices_setupdata.h HServiceSetup * * \ingroup hupnp_devicemodel * * \sa HServicesSetupData, HClientService, HServerService * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HServiceSetup { private: QSharedDataPointer h_ptr; public: /*! * Creates a new, invalid instance. * * \sa isValid() */ HServiceSetup(); /*! * \brief Creates a new instance. * * \param id specifies the service ID. * * \param serviceType specifies the service type. * * \param incReq specifies the \e inclusion \e requirement of the * service. * * \sa isValid() * * \remarks the version() is set to 1. */ HServiceSetup( const HServiceId& id, const HResourceType& serviceType, HInclusionRequirement incReq = InclusionMandatory); /*! * \brief Creates a new instance. * * \param id specifies the service ID. * * \param serviceType specifies the service type. * * \param version specifies the version of the UPnP device, which first * specified the service. * * \param incReq specifies the \e inclusion \e requirement of the * service. * * \sa isValid() */ HServiceSetup( const HServiceId& id, const HResourceType& serviceType, int version, HInclusionRequirement incReq = InclusionMandatory); /*! * \brief Assignment operator. * * Copies the contents of \a other to this. */ HServiceSetup& operator=(const HServiceSetup&); /*! * \brief Copy constructor. * * Creates a copy of \a other. */ HServiceSetup(const HServiceSetup&); /*! * \brief Destroys the instance. */ ~HServiceSetup(); /*! * \brief Returns the inclusion requirement. * * \return The inclusion requirement. * * \sa setInclusionRequirement() */ HInclusionRequirement inclusionRequirement() const; /*! * \brief Indicates if the object is valid. * * \param checkLevel specifies whether the validity of the object should be * checked strictly according to the UDA specification. * * \return \e true in case the object is valid, that is, the service ID, * service type, version and inclusion requirement are all properly defined * in respect to the specified \c checkLevel. */ bool isValid(HValidityCheckLevel checkLevel) const; /*! * \brief Returns the service ID. * * \return The service ID. * * \sa setServiceId() */ const HServiceId& serviceId() const; /*! * \brief Returns the service type. * * \return The service type. * * \sa setServiceType() */ const HResourceType& serviceType() const; /*! * \brief Returns the version of the UPnP device, which first specified the service. * * \return The version of the UPnP device, which first specified the service. * * \sa setVersion() */ int version() const; /*! * \brief Sets the the inclusion requirement. * * \param arg specifies the inclusion requirement. * * \sa inclusionRequirement() */ void setInclusionRequirement(HInclusionRequirement arg); /*! * \brief Sets the service ID. * * \param arg specifies the service ID. * * \sa serviceId() */ void setServiceId(const HServiceId& arg); /*! * \brief Sets the service type. * * \param arg specifies the service type. * * \sa serviceType() */ void setServiceType(const HResourceType& arg); /*! * \brief Sets the version of the UPnP device, which first specified the service. * * \param version defines the version of the UPnP device, * which first specifies the service. * * \sa version() */ void setVersion(int version); }; /*! * Compares the two objects for equality. * * \return \e true in case the provided objects are equal, false otherwise. * * \relates HServiceSetup */ H_UPNP_CORE_EXPORT bool operator==(const HServiceSetup&, const HServiceSetup&); /*! * Compares the two objects for inequality. * * \return \e true in case the provided objects are not equal, false otherwise. * * \relates HServiceSetup */ inline bool operator!=(const HServiceSetup& obj1, const HServiceSetup& obj2) { return !(obj1 == obj2); } /*! * \brief This class is used to specify information that can be used to validate * UPnP services. * * \headerfile hservices_setupdata.h HServicesSetupData * * \ingroup hupnp_devicemodel * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HServicesSetupData { friend H_UPNP_CORE_EXPORT bool operator==( const HServicesSetupData&, const HServicesSetupData&); private: QHash m_serviceSetupInfos; public: /*! * \brief Creates a new, empty instance. * * \sa isEmpty() */ HServicesSetupData(); /*! * \brief Destroys the instance. */ ~HServicesSetupData(); /*! * \brief Retrieves a service setup object. * * \param id specifies the service ID of the item. * * \return The item with the specified service ID. Note that the returned item * is invalid, i.e. HServiceSetup::isValid() returns false in case no item * with the specified service ID was found. * * \sa contains() */ HServiceSetup get(const HServiceId& id) const; /*! * \brief Indicates if the instance contains a service setup item that has the * specified service ID. * * \param id specifies the service ID of the item. * * \return \e true if the instance contains an item with the specified * service ID. * * \sa get() */ bool contains(const HServiceId& id) const; /*! * \brief Indicates if the object is empty. * * \return \e true in case the instance has no items. */ bool isEmpty() const; /*! * \brief Returns the number of contained items. * * \return The number of contained items. */ int size() const; /*! * \brief Returns the service IDs of the contained items. * * \return The service IDs of the contained items. */ QSet serviceIds() const; /*! * Inserts a new item. * * \param newItem specifies the item to be added. * * \param overWrite specifies whether to replace an already existing item * with the same service ID. The default is \c false. * * \return \e true in case the item was added. The \a newItem will not be added * if the instance already contains an item that has the same * HServiceSetup::serviceId() as the \a newItem and the \a overWrite is * \c false, or the \a newItem is invalid. */ bool insert(const HServiceSetup& newItem, bool overWrite = false); /*! * Removes an existing item. * * \param id specifies the service ID of the item to be removed. * * \return \e true in case the item was found and removed. */ bool remove(const HServiceId& id); }; /*! * Compares the two objects for equality. * * \return \e true in case the provided objects are equal, false otherwise. * * \relates HServicesSetupData */ H_UPNP_CORE_EXPORT bool operator==(const HServicesSetupData&, const HServicesSetupData&); /*! * Compares the two objects for inequality. * * \return \e true in case the provided objects are not equal, false otherwise. * * \relates HServicesSetupData */ inline bool operator!=(const HServicesSetupData& obj1, const HServicesSetupData& obj2) { return !(obj1 == obj2); } } } #endif /* HSERVICES_SETUPDATA_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hservices_setupdata.cpp0000644000000000000000000001334511543637310022311 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hservices_setupdata.h" #include "../dataelements/hserviceid.h" #include "../dataelements/hresourcetype.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HServiceSetupPrivate ******************************************************************************/ class HServiceSetupPrivate : public QSharedData { public: HServiceId m_serviceId; HResourceType m_serviceType; int m_version; HInclusionRequirement m_inclusionReq; HServiceSetupPrivate() : m_serviceId(), m_serviceType(), m_version(0), m_inclusionReq(InclusionRequirementUnknown) { } ~HServiceSetupPrivate() { } }; /******************************************************************************* * HServiceSetup ******************************************************************************/ HServiceSetup::HServiceSetup() : h_ptr(new HServiceSetupPrivate()) { } HServiceSetup::HServiceSetup( const HServiceId& id, const HResourceType& serviceType, HInclusionRequirement ireq) : h_ptr(new HServiceSetupPrivate()) { h_ptr->m_serviceId = id; h_ptr->m_serviceType = serviceType; h_ptr->m_version = 1; h_ptr->m_inclusionReq = ireq; } HServiceSetup::HServiceSetup( const HServiceId& id, const HResourceType& serviceType, int version, HInclusionRequirement ireq) : h_ptr(new HServiceSetupPrivate()) { h_ptr->m_serviceId = id; h_ptr->m_serviceType = serviceType; h_ptr->m_version = version; h_ptr->m_inclusionReq = ireq; } HServiceSetup::~HServiceSetup() { } HServiceSetup& HServiceSetup::operator=(const HServiceSetup& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HServiceSetup::HServiceSetup(const HServiceSetup& other) : h_ptr(other.h_ptr) { Q_ASSERT(this != &other); } bool HServiceSetup::isValid(HValidityCheckLevel checkLevel) const { return h_ptr->m_serviceId.isValid(checkLevel) && h_ptr->m_serviceType.isValid() && h_ptr->m_version > 0 && h_ptr->m_inclusionReq != InclusionRequirementUnknown; } HInclusionRequirement HServiceSetup::inclusionRequirement() const { return h_ptr->m_inclusionReq; } const HServiceId& HServiceSetup::serviceId() const { return h_ptr->m_serviceId; } const HResourceType& HServiceSetup::serviceType() const { return h_ptr->m_serviceType; } int HServiceSetup::version() const { return h_ptr->m_version; } void HServiceSetup::setInclusionRequirement(HInclusionRequirement arg) { h_ptr->m_inclusionReq = arg; } void HServiceSetup::setServiceId(const HServiceId& arg) { h_ptr->m_serviceId = arg; } void HServiceSetup::setServiceType(const HResourceType& arg) { h_ptr->m_serviceType = arg; } void HServiceSetup::setVersion(int version) { h_ptr->m_version = version; } bool operator==(const HServiceSetup& obj1, const HServiceSetup& obj2) { return obj1.inclusionRequirement() == obj2.inclusionRequirement() && obj1.serviceId() == obj2.serviceId() && obj1.serviceType() == obj2.serviceType() && obj1.version() == obj2.version(); } /******************************************************************************* * HServicesSetupData ******************************************************************************/ HServicesSetupData::HServicesSetupData() : m_serviceSetupInfos() { } HServicesSetupData::~HServicesSetupData() { } bool HServicesSetupData::insert(const HServiceSetup& setupInfo, bool overWrite) { if (!setupInfo.isValid(StrictChecks)) { return false; } const HServiceId& id = setupInfo.serviceId(); if (!overWrite && m_serviceSetupInfos.contains(id)) { return false; } m_serviceSetupInfos.insert(id, setupInfo); return true; } bool HServicesSetupData::remove(const HServiceId& serviceId) { if (m_serviceSetupInfos.contains(serviceId)) { m_serviceSetupInfos.remove(serviceId); return true; } return false; } HServiceSetup HServicesSetupData::get(const HServiceId& serviceId) const { return m_serviceSetupInfos.value(serviceId); } bool HServicesSetupData::contains(const HServiceId& id) const { return m_serviceSetupInfos.contains(id); } QSet HServicesSetupData::serviceIds() const { return m_serviceSetupInfos.keys().toSet(); } int HServicesSetupData::size() const { return m_serviceSetupInfos.size(); } bool HServicesSetupData::isEmpty() const { return m_serviceSetupInfos.isEmpty(); } bool operator==(const HServicesSetupData& obj1, const HServicesSetupData& obj2) { return obj1.m_serviceSetupInfos == obj2.m_serviceSetupInfos; } } } herqq-1.0.0/hupnp/src/devicemodel/hservice_p.h0000644000000000000000000001220111543637310020026 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVICE_P_H_ #define HSERVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include #include #include #include #include #include namespace Herqq { namespace Upnp { // // // template class H_UPNP_CORE_EXPORT HServicePrivate { H_DECLARE_PUBLIC(HServerService) H_DISABLE_COPY(HServicePrivate) public: // attributes HServiceInfo m_serviceInfo; QString m_serviceDescription; QString m_lastError; QHash m_actions; QHash m_stateVariables; Owner* q_ptr; QByteArray m_loggingIdentifier; bool m_evented; public: // methods HServicePrivate() : m_serviceInfo(), m_serviceDescription(), m_lastError(), m_actions(), m_stateVariables(), q_ptr(0), m_loggingIdentifier(), m_evented(false) { } virtual ~HServicePrivate() { qDeleteAll(m_actions); qDeleteAll(m_stateVariables); } bool addStateVariable(StateVariable* stateVariable) { Q_ASSERT(stateVariable); const HStateVariableInfo& info = stateVariable->info(); Q_ASSERT(info.isValid()); Q_ASSERT(!m_stateVariables.contains(info.name())); m_stateVariables.insert(info.name(), stateVariable); if (!m_evented && info.eventingType() != HStateVariableInfo::NoEvents) { m_evented = true; } return true; } bool updateVariable(const QString& stateVarName, const QVariant& value) { StateVariable* sv = m_stateVariables.value(stateVarName); return sv ? sv->setValue(value) : false; } enum ReturnValue { Failed, Ignored, Updated }; ReturnValue updateVariables(const QList >& variables) { // before modifying anything, it is better to be sure that the incoming // data is valid and it can be set completely. for (int i = 0; i < variables.size(); ++i) { StateVariable* stateVar = m_stateVariables.value(variables[i].first); if (!stateVar) { m_lastError = QString( "Cannot update state variable: no state variable [%1]").arg( variables[i].first); return Failed; } const HStateVariableInfo& info = stateVar->info(); if (!info.isValidValue( HUpnpDataTypes::convertToRightVariantType( variables[i].second, info.dataType()))) { m_lastError = QString( "Cannot update state variable [%1]. New value is invalid: [%2]"). arg(info.name(), variables[i].second); return Failed; } } bool changed = false; for (int i = 0; i < variables.size(); ++i) { StateVariable* stateVar = m_stateVariables.value(variables[i].first); Q_ASSERT(stateVar); const HStateVariableInfo& info = stateVar->info(); if (stateVar->setValue( HUpnpDataTypes::convertToRightVariantType( variables[i].second, info.dataType())) && !changed) { changed = true; } } return changed ? Updated : Ignored; } QVariant value(const QString& stateVarName, bool* ok = 0) const { if (m_stateVariables.contains(stateVarName)) { if (ok) { *ok = true; } return m_stateVariables.value(stateVarName)->value(); } if (ok) { *ok = false; } return QVariant(); } bool setValue(const QString& stateVarName, const QVariant& value) { if (m_stateVariables.contains(stateVarName)) { return m_stateVariables.value(stateVarName)->setValue(value); } return false; } }; } } #endif /* HSERVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hstatevariable_event.cpp0000644000000000000000000000533411543637310022442 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hstatevariable_event.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HStateVariableEventPrivate *******************************************************************************/ class HStateVariableEventPrivate : public QSharedData { public: QVariant m_previousValue; QVariant m_newValue; public: HStateVariableEventPrivate (); ~HStateVariableEventPrivate(); }; HStateVariableEventPrivate::HStateVariableEventPrivate() : m_previousValue(), m_newValue() { } HStateVariableEventPrivate::~HStateVariableEventPrivate() { } /******************************************************************************* * HStateVariableEvent *******************************************************************************/ HStateVariableEvent::HStateVariableEvent() : h_ptr(new HStateVariableEventPrivate()) { } HStateVariableEvent::HStateVariableEvent( const QVariant& previousValue, const QVariant& newValue) : h_ptr(new HStateVariableEventPrivate()) { h_ptr->m_previousValue = previousValue; h_ptr->m_newValue = newValue; } HStateVariableEvent::HStateVariableEvent(const HStateVariableEvent& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HStateVariableEvent::~HStateVariableEvent() { } HStateVariableEvent& HStateVariableEvent::operator=( const HStateVariableEvent& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } bool HStateVariableEvent::isEmpty() const { return h_ptr->m_previousValue.isNull() && h_ptr->m_newValue.isNull(); } QVariant HStateVariableEvent::previousValue() const { return h_ptr->m_previousValue; } QVariant HStateVariableEvent::newValue() const { return h_ptr->m_newValue; } } } herqq-1.0.0/hupnp/src/devicemodel/server/0000755000000000000000000000000011543637460017046 5ustar rootrootherqq-1.0.0/hupnp/src/devicemodel/server/hdefault_serveraction_p.h0000644000000000000000000000313611543637310024113 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEFAULT_SERVERACTION_P_H_ #define HDEFAULT_SERVERACTION_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include "../hactioninvoke.h" namespace Herqq { namespace Upnp { // // Default implementation of HServerAction // class HDefaultServerAction : public HServerAction { H_DISABLE_COPY(HDefaultServerAction) public: HDefaultServerAction( const HActionInfo&, const HActionInvoke&, HServerService* parent); bool setInfo(const HActionInfo&); }; } } #endif /* HDEFAULT_SERVERACTION_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hserverstatevariable.h0000644000000000000000000001237711543637310023450 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVER_STATEVARIABLE_H_ #define HSERVER_STATEVARIABLE_H_ #include #include #include class QStringList; namespace Herqq { namespace Upnp { class HStateVariablePrivate; /*! * \brief This is a class that represents a server-side UPnP state variable. * * \c %HServerStateVariable is a core component of the HUPnP's server-side \ref hupnp_devicemodel * and it models a UPnP state variable. The UPnP Device Architecture specifies a * UPnP state variable as an item or aspect that models state in a service. * In a way a state variable is an abstraction to a member variable inside a * UPnP service. * * A state variable can be \e evented in which case it notifies interested listeners * of changes in its value. You can see if a state variable is evented by checking * the HStateVariableInfo object using info() and you can connect to the signal * valueChanged() to be notified when the value of the state variable changes. * Note, only evented state variables emit the valueChanged() signal. * * \headerfile hserverstatevariable.h HServerStateVariable * * \ingroup hupnp_devicemodel * * \sa HServerStateVariable * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HServerStateVariable : public QObject { Q_OBJECT H_DISABLE_COPY(HServerStateVariable) protected: HStateVariablePrivate* h_ptr; /*! * \brief Creates a new instance. * * \param info specifies information of the state variable. This is usually * read from a service description document. * * \param parent specifies the UPnP service instance that contains this * state variable. */ HServerStateVariable(const HStateVariableInfo& info, HServerService* parent); public: /*! * \brief Destroys the instance. * * An \c %HServerStateVariable is always destroyed by the * \c %HServerService that contains it when it is being deleted. * Further, unless you hold the ownership of the \c %HServerStateVariable * instance, you should never destroy it. */ virtual ~HServerStateVariable() = 0; /*! * \brief Returns the HServerService that contains this state variable. * * \return The HServerService that contains this state variable. * * \warning the pointer is guaranteed to point to a valid object as long * as the \c %HServerStateVariable exists, which ultimately is as long as the * containing root device exists. */ HServerService* parentService() const; /*! * \brief Returns the current value of the state variable. * * \return The current value of the state variable. */ QVariant value() const; /*! * \brief Returns information about the state variable. * * \return information about the state variable. This information is often read * from a service description document. */ const HStateVariableInfo& info() const; /*! * Changes the value of the state variable. If the instance is evented, * the valueChanged() signal is emitted after the value has been changed. * * \param newValue specifies the new value of the state variable. The new value * must have the same underlying data type as the previous value * (and the default value). If the new value has different data type, the value * is not changed, no event is sent and false is returned. * * \retval true in case the new value was successfully set. * \retval false in case the new value could not be set. * * \remarks the new value will be set if the value: * - does not violate the defined constraints * - has the same variant type or the type of the new value can be converted * to the same variant type * - is not QVariant::Invalid */ bool setValue(const QVariant& newValue); Q_SIGNALS: /*! * \brief This signal is emitted when the value of the state variable has changed. * * \param source specifies the state variable that sent the event. * * \param event specifies information about the event that occurred. * * \remarks This signal has thread affinity to the thread where the object * resides. Do not connect to this signal from other threads. */ void valueChanged( Herqq::Upnp::HServerStateVariable* source, const Herqq::Upnp::HStateVariableEvent& event); }; } } #endif /* HSERVER_STATEVARIABLE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hdevicemodelcreator.h0000644000000000000000000000614011543637310023222 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEMODEL_CREATOR_H_ #define HDEVICEMODEL_CREATOR_H_ #include namespace Herqq { namespace Upnp { class HDeviceModelCreatorPrivate; /*! * A protocol class for creating HServerDevice and HServerService instances. * * The primary purpose of this protocol class is to build instances of the HUPnP's * \ref hupnp_devicemodel at server-side. If you wish to host a device in an * HDeviceHost you have to derive from this class and override its * abstract methods. * * \headerfile hdevicemodelcreator.h HDeviceModelCreator * * \ingroup hupnp_devicemodel * * \sa hupnp_devicehosting, HServerDevice, HServerService */ class H_UPNP_CORE_EXPORT HDeviceModelCreator : public HClonable { H_DISABLE_COPY(HDeviceModelCreator) public: /*! * \brief Creates a new instance. */ HDeviceModelCreator(); /*! * \brief Destroys the instance. */ virtual ~HDeviceModelCreator(); /*! * Creates a device matching the provided device information. * * \param info specifies information of the device type the creator is asked * to create. * * \return a heap allocated device matching the provided device information * or \c null in case the creator does not recognize the specified device type. * * \remarks The ownership of the created device is transferred to the caller. */ virtual HServerDevice* createDevice(const HDeviceInfo& info) const; /*! * Creates a service matching the provided service information. * * \param serviceInfo specifies information of the service type the * creator is asked to create. * * \param parentDeviceInfo specifies information about the parent UPnP device * that contains this service. * * \return a heap allocated service matching the provided service information * or \c null in case the creator does not recognize the specified service type. * * \remarks The ownership of the created service is transferred to the caller. */ virtual HServerService* createService( const HServiceInfo& serviceInfo, const HDeviceInfo& parentDeviceInfo) const = 0; // // Documented in HClonable virtual HDeviceModelCreator* clone() const; }; } } #endif /* HDEVICEMODEL_CREATOR_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hdefault_serverdevice_p.h0000644000000000000000000000304711543637310024076 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEFAULT_SERVERDEVICE_P_H_ #define HDEFAULT_SERVERDEVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include namespace Herqq { namespace Upnp { // // This is the default implementation of HServerDevice // class HDefaultServerDevice : public HServerDevice { H_DISABLE_COPY(HDefaultServerDevice) public: HDefaultServerDevice(); // HServerDevice is complete, but due to design issues it is also abstract. }; } } #endif /* HDEFAULT_SERVERDEVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hserverservice.cpp0000644000000000000000000001437611543637310022616 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hserverservice.h" #include "hserverservice_p.h" #include "../../general/hlogger_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HServerServicePrivate ******************************************************************************/ HServerServicePrivate::HServerServicePrivate() { } HServerServicePrivate::~HServerServicePrivate() { } HServerServicePrivate::ReturnValue HServerServicePrivate::updateVariables( const QList >& variables, bool sendEvent) { ReturnValue rv = HServicePrivate::updateVariables(variables); if (rv == Updated && sendEvent && m_evented) { emit q_ptr->stateChanged(q_ptr); } return rv; } /******************************************************************************* * HServerService ******************************************************************************/ HServerService::HServerService() : h_ptr(new HServerServicePrivate()) { } HServerService::HServerService(HServerServicePrivate& dd) : h_ptr(&dd) { } HServerService::~HServerService() { delete h_ptr; } bool HServerService::init( const HServiceInfo& info, HServerDevice* parentDevice) { if (h_ptr->q_ptr) { return false; } Q_ASSERT_X(parentDevice, "parentDevice", "Parent device has to be defined."); setParent(reinterpret_cast(parentDevice)); h_ptr->m_serviceInfo = info; h_ptr->q_ptr = this; return true; } namespace { class MetaMethodInvoker { private: const char* m_typeName; HServerService* m_methodOwner; QMetaMethod m_mm; public: MetaMethodInvoker( HServerService* methodOwner, const QMetaMethod& mm, const char* typeName) : m_typeName(typeName), m_methodOwner(methodOwner), m_mm(mm) { Q_ASSERT(methodOwner); } int operator()( const HActionArguments& inArgs, HActionArguments* outArgs) { int retVal = UpnpSuccess; bool ok = m_mm.invoke( m_methodOwner, Qt::DirectConnection, //Q_RETURN_ARG(int, retVal), QGenericReturnArgument(m_typeName, static_cast(&retVal)), Q_ARG(Herqq::Upnp::HActionArguments, inArgs), Q_ARG(Herqq::Upnp::HActionArguments*, outArgs)); Q_ASSERT(ok); Q_UNUSED(ok) // Q_RETURN_ARG is not used above, because it cannot handle typedefs // and in this case it is perfectly reasonable for the user to // use "int" or "qint32" as the return type. Certainly other typedefs // besides "qint32" should be valid too, but for now the typeName has to // be either "int" or "qint32". The restriction is enforced in the // createActionInvokes() method below. // For instance, a user could have one action defined as: // qint32 myAction(const HActionArguments&, HActionArguments*); // and another as: // int myAction2(const HActionArguments&, HActionArguments*); return retVal; } }; } HServerService::HActionInvokes HServerService::createActionInvokes() { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); HActionInvokes retVal; const QMetaObject* mob = metaObject(); for(int i = mob->methodOffset(); i < mob->methodCount(); ++i) { QMetaMethod mm = mob->method(i); QString typeName = mm.typeName(); if (typeName != "int" && typeName != "qint32") { continue; } QList parTypes = mm.parameterTypes(); if (parTypes.size() != 2) { continue; } QString firstPar = parTypes.at(0); if (firstPar != "Herqq::Upnp::HActionArguments" && firstPar != "HActionArguments") { continue; } QString secondPar = parTypes.at(1); if (secondPar != "Herqq::Upnp::HActionArguments*" && secondPar != "HActionArguments*") { continue; } QString signature = mm.signature(); signature = signature.left(signature.indexOf('(')); Q_ASSERT(!retVal.contains(signature)); retVal.insert(signature, MetaMethodInvoker(this, mm, mm.typeName())); // See the comment in MetaMethodInvoker why the typeName() is passed // there as well. } return retVal; } bool HServerService::finalizeInit(QString*) { // intentionally empty. return true; } HServerDevice* HServerService::parentDevice() const { return reinterpret_cast(parent()); } const HServiceInfo& HServerService::info() const { return h_ptr->m_serviceInfo; } const QString& HServerService::description() const { return h_ptr->m_serviceDescription; } const HServerActions& HServerService::actions() const { return h_ptr->m_actions; } const HServerStateVariables& HServerService::stateVariables() const { return h_ptr->m_stateVariables; } void HServerService::notifyListeners() { if (h_ptr->m_evented) { emit stateChanged(this); } } bool HServerService::isEvented() const { return h_ptr->m_evented; } QVariant HServerService::value(const QString& stateVarName, bool* ok) const { return h_ptr->value(stateVarName, ok); } bool HServerService::setValue(const QString& stateVarName, const QVariant& value) { return h_ptr->setValue(stateVarName, value); } } } herqq-1.0.0/hupnp/src/devicemodel/server/hserveraction.h0000644000000000000000000001101411543637310022062 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERACTION_H_ #define HSERVERACTION_H_ #include #include class QString; namespace Herqq { namespace Upnp { class HServerActionPrivate; /*! * \brief A class that represents a server-side UPnP action. * * \c %HServerAction is a core component of the HUPnP's server-side \ref hupnp_devicemodel * and it models a UPnP action. The UPnP Device Architecture specifies a UPnP * action as command, which takes one or more input or output arguments and that * may have a return value. * * \brief This class is used to invoke the server-side UPnP actions directly in process. * You can get information of the action using info(), which includes the action's * input and output arguments. You can invoke an action synchronously using * invoke(). * * \headerfile hserveraction.h HServerAction * * \ingroup hupnp_devicemodel * * \sa HActionInfo, HServerService * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HServerAction : public QObject { Q_OBJECT H_DISABLE_COPY(HServerAction) H_DECLARE_PRIVATE(HServerAction) protected: HServerActionPrivate* h_ptr; /*! * \brief Creates a new instance. * * \param info specifies information of the action. This is usually read * from a service description document. * * \param parentService specifies the UPnP service instance that contains * this action. */ HServerAction(const HActionInfo& info, HServerService* parentService); public: /*! * \brief Destroys the instance. * * An \c %HServerAction is always destroyed by the \c %HServerService that * contains it when it is being deleted. Further, unless you hold the * ownership of the \c %HServerAction instance, you should never destroy it. */ virtual ~HServerAction() = 0; /*! * \brief Returns the parent service of the action. * * \return The parent service of the action. * * \warning the pointer is guaranteed to point to a valid object as long * as the \c %HServerAction exists, which ultimately is as long as the * containing root device exists. * * \sa HServerDevice */ HServerService* parentService() const; /*! * \brief Returns information about the action that is read from the * service description. * * \return information about the action that is read from the * service description. */ const HActionInfo& info() const; /*! * Invokes the action synchronously. * * For example, * * \code * * Herqq::Upnp::HActionArguments inArgs = action->info().inputArguments(); * inArgs.setValue("EchoInArgument", "Ping"); * * Herqq::Upnp::HActionArguments outArgs; * * qint32 retVal = action->invoke(inArgs, &outArgs); * if (retVal == Herqq::Upnp::HServerAction::Success) * { * qDebug() << outArgs.value("EchoOutArgument").toString(); * } * * \endcode * * \param inArgs specifies the input arguments for the action. * * \param outArgs specifies a pointer to HActionArguments instance created * by the user. This can be null in which case the output arguments will not * be set even if the action has output arguments. If the parameter is specified * and the action has output arguments, the values of the arguments will be * set accordingly. If the action doesn't have output arguments, * the parameter is ignored. * * \return UpnpSuccess on success. Any other value indicates * that an error occurred. */ qint32 invoke( const HActionArguments& inArgs, HActionArguments* outArgs = 0); }; } } #endif /* HSERVERACTION_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hserverstatevariable.cpp0000644000000000000000000000544111543637310023775 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hserverstatevariable.h" #include "hdefault_serverstatevariable_p.h" #include "../hstatevariable_p.h" #include "../hstatevariable_event.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HServerStateVariable *******************************************************************************/ HServerStateVariable::HServerStateVariable( const HStateVariableInfo& info, HServerService* parent) : QObject(reinterpret_cast(parent)), h_ptr(new HStateVariablePrivate()) { Q_ASSERT_X(parent, H_AT, "Parent service must be defined."); Q_ASSERT_X(info.isValid(), H_AT, "Info object must be valid."); h_ptr->m_info = info; setValue(info.defaultValue()); } HServerStateVariable::~HServerStateVariable() { delete h_ptr; } HServerService* HServerStateVariable::parentService() const { return reinterpret_cast(parent()); } QVariant HServerStateVariable::value() const { return h_ptr->m_value; } const HStateVariableInfo& HServerStateVariable::info() const { return h_ptr->m_info; } bool HServerStateVariable::setValue(const QVariant& newValue) { QVariant oldValue = h_ptr->m_value; QString err; if (!h_ptr->setValue(newValue, &err)) { return false; } if (h_ptr->m_info.eventingType() != HStateVariableInfo::NoEvents) { HStateVariableEvent event(oldValue, newValue); emit valueChanged(this, event); } return true; } /******************************************************************************* * HDefaultServerStateVariable *******************************************************************************/ HDefaultServerStateVariable::HDefaultServerStateVariable( const HStateVariableInfo& info, HServerService* parent) : HServerStateVariable(info, parent) { } } } herqq-1.0.0/hupnp/src/devicemodel/server/hserverservice.h0000644000000000000000000002571411543637310022261 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERSERVICE_H_ #define HSERVERSERVICE_H_ #include #include #include #include class QUrl; class QString; namespace Herqq { namespace Upnp { class HServerServicePrivate; /*! * \brief This is an abstract base class for server-side UPnP services. * * \c %HServerService is a core component of the HUPnP's server-side \ref hupnp_devicemodel * and it models a UPnP service. The UPnP Device Architecture specifies a * UPnP service as "Logical functional unit. Smallest units of control. Exposes * actions and models the state of a physical device with state variables". * In other words, a UPnP service is the entry point for accessing * certain type of functionality and state of the containing device. * *

Using the class

* * You can retrieve the containing device, the \e parent \e device, using parentDevice(). * You can retrieve all the actions the service contains by calling actions(), * Similarly, you can retrieve all the state variables of the service by calling * stateVariables(). * * The class exposes all the details in the device description concerning a * service through info(). From the returned HServiceInfo object you can * retrieve the \e serviceId and \e serviceType along with various URLs found * in the device description, such as the: * \li \e scpdUrl, which returns the URL for fetching the service description, * \li \e controlUrl, which returns the URL to be used in action invocation and * \li \e eventSubUrl, which returns the URL used in event (un)subscriptions. * * However, the above URLs usually provide informational value only, since * HUPnP provides a simpler interface for everything those URLs expose: * \li You can retrieve the service description of a service using description(). * \li Action invocation is abstracted into the HServerAction class. * \li You can receive all the event notifications from a UPnP service by connecting * to the stateChanged() signal. * *

Sub-classing

* * Writing a custom \c %HServerService is simple, because you only have to * provide the implementations of the actions the service exposes. You can do this * by overriding createActionInvokes() in which you create the \e callable * \e entities that will be called upon action invocation. You can also mark * member functions implementing actions of a service as \c Q_INVOKABLE, which * enables HUPnP to automatically create the previsously mentioned \e callable * \e entities for you. See \ref builddevice_tutorial and * \ref setting_up_the_devicemodel for more information about creating your * own HServerService types with custom functionality. * * \headerfile hserverservice.h HServerService * * \ingroup hupnp_devicemodel * * \sa hupnp_devicemodel * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HServerService : public QObject { Q_OBJECT H_DISABLE_COPY(HServerService) H_DECLARE_PRIVATE(HServerService) friend class HServerModelCreator; protected: /*! * This is a type definition for a hash table containing HActionInvoke objects * keyed with strings representing the names of the actions. * * \ingroup hupnp_devicemodel * * \sa HActionInvoke */ typedef QHash HActionInvokes; /*! * Creates and returns the "action implementations" of the actions the * service exposes. * * It is very important to note that the overrides of this method * should always call the implementation of the super class too. For instance, * * \code * * void HServerService::HActionInvokes MyServiceType::createActionInvokes() * { * HActionInvokes retVal = SuperClass::createActionInvokes(); * * // create and add the actions of this class to the "retVal" variable * * return retVal; * } * * \endcode * * \return The implementations of the actions this \c %HServerService exposes. */ virtual HActionInvokes createActionInvokes(); /*! * Provides an opportunity to do post-construction initialization routines * in derived classes. * * As \c %HServerService is part of the HUPnP's server-side \ref hupnp_devicemodel, * its initialization process is usually driven by HUPnP. If this is the case, * at the time of instantiation of a descendant \c %HServerService the base * \c %HServerService sub-object is not yet fully set up. In other words, * at that time it is not guaranteed that every private or protected member * of a \c %HServerService are set to their "final" values that are used * once the object is fully initialized and ready to be used. * * Because of the above, descendants of \c %HServerService should not * reference or rely on values of \c %HServerService at * the time of construction. If the initialization of a \c %HServerService * descendant needs to do something that rely on \c %HServerService being fully * set up, you can override this method. This method is called \b once * right after the base \c %HServerService is fully initialized. * * \param errDescription * * \return \e true in case the initialization succeeded. * * \note It is advisable to keep the constructors of the descendants of * \c %HServerService small and fast, and do more involved initialization routines * here. */ virtual bool finalizeInit(QString* errDescription); protected: HServerServicePrivate* h_ptr; /*! * \brief Creates a new instance. * * You have to call init() to fully initialize the instance. * * \sa init() */ HServerService(); // // \internal // // Creates a new instance and re-uses the h_ptr. // HServerService(HServerServicePrivate& dd); /*! * Initializes the instance. * * This method will succeed only once after construction. Subsequent * calls will do nothing. * * \param info specifies information of the service. This is usually read * from a device description document. * * \param parentDevice specifies the UPnP device instance that contains * this service. */ bool init(const HServiceInfo& info, HServerDevice* parentDevice); public: /*! * \brief Destroys the instance. */ virtual ~HServerService() = 0; /*! * \brief Returns the parent HServerDevice that contains this service instance. * * \return The parent HServerDevice that contains this service instance. */ HServerDevice* parentDevice() const; /*! * \brief Returns information about the service. * * \return information about the service. This information is usually read * from a device description document. */ const HServiceInfo& info() const; /*! * \brief Returns the full service description. * * \return The full service description. */ const QString& description() const; /*! * \brief Returns the actions the service contains. * * \return The actions the service contains. * * \remarks The ownership of the returned objects is not transferred. * Do \b not delete the returned objects. */ const HServerActions& actions() const; /*! * \brief Returns the state variables of the service. * * \return The state variables of the service. * * \remarks The ownership of the returned objects is not transferred. * Do \b not delete the returned objects. */ const HServerStateVariables& stateVariables() const; /*! * \brief Indicates whether or not the service contains state variables that * are evented. * * \return \e true in case the service contains one or more state variables * that are evented. * * \remarks In case the service is not evented, the stateChanged() signal * will never be emitted and the notifyListeners() method does nothing. */ bool isEvented() const; /*! * \brief Returns the value of the specified state variable, if such exists. * * This is a convenience method for retrieving a state variable by name and * getting its value. * * \param stateVarName specifies the name of the state variable. * * \param ok specifies a pointer to a \c bool, which will contain \e true * if the specified state variable was found and its value was returned. * This is optional. * * \return The value of the specified state variable, if such exists. * If this service does not contain the specified state variable, an * invalid \c QVariant is returned. * * \remarks The value of the state variable may be represented by an * invalid \c QVariant. Because of this, if you want to be sure that the * specified state variable was found and its value was returned, you should * use the \a ok parameter. */ QVariant value(const QString& stateVarName, bool* ok = 0) const; /*! * \brief Sets the value of the specified state variable, if such exists. * * This is a convenience method for retrieving a state variable by name and * setting its value. * * \param stateVarName specifies the name of the state variable. * * \param value specifies the new value of the state variable. * * \return \e true in case the specified state variable was found and its * value was changed. */ bool setValue(const QString& stateVarName, const QVariant& value); public Q_SLOTS: /*! * Explicitly forces stateChanged() event to be emitted if the service is * evented. Otherwise this method does nothing. */ void notifyListeners(); Q_SIGNALS: /*! * \brief This signal is emitted when the state of one or more state variables * has changed. * * \param source specifies the source of the event. * * \remarks This signal has thread affinity to the thread where the object * resides. Do not connect to this signal from other threads. */ void stateChanged(const Herqq::Upnp::HServerService* source); }; } } #endif /* HSERVERSERVICE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hserverservice_p.h0000644000000000000000000000340211543637310022566 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERSERVICE_P_H_ #define HSERVERSERVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include #include #include namespace Herqq { namespace Upnp { // // Implementation details of HServerService // class H_UPNP_CORE_EXPORT HServerServicePrivate : public HServicePrivate { H_DECLARE_PUBLIC(HServerService) H_DISABLE_COPY(HServerServicePrivate) public: // methods HServerServicePrivate(); virtual ~HServerServicePrivate(); ReturnValue updateVariables( const QList >& variables, bool sendEvent); }; } } #endif /* HSERVERSERVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hserveraction.cpp0000644000000000000000000000574211543637310022430 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hserveraction.h" #include "hserveraction_p.h" #include "hdefault_serveraction_p.h" #include "../hactionarguments.h" #include "../../general/hlogger_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HServerActionPrivate ******************************************************************************/ HServerActionPrivate::HServerActionPrivate() : q_ptr(0), m_info(), m_actionInvoke() { } HServerActionPrivate::~HServerActionPrivate() { } bool HServerActionPrivate::setInfo(const HActionInfo& info) { if (!info.isValid()) { return false; } m_info.reset(new HActionInfo(info)); return true; } /******************************************************************************* * HServerAction ******************************************************************************/ HServerAction::HServerAction(const HActionInfo& info, HServerService* parent) : QObject(reinterpret_cast(parent)), h_ptr(new HServerActionPrivate()) { Q_ASSERT_X(parent, H_AT, "Parent service must be defined."); Q_ASSERT_X(info.isValid(), H_AT, "Action information must be defined."); h_ptr->m_info.reset(new HActionInfo(info)); h_ptr->q_ptr = this; } HServerAction::~HServerAction() { delete h_ptr; } HServerService* HServerAction::parentService() const { return reinterpret_cast(parent()); } const HActionInfo& HServerAction::info() const { return *h_ptr->m_info; } qint32 HServerAction::invoke( const HActionArguments& inArgs, HActionArguments* outArgs) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); *outArgs = h_ptr->m_info->outputArguments(); return h_ptr->m_actionInvoke(inArgs, outArgs); } /******************************************************************************* * HDefaultServerAction ******************************************************************************/ HDefaultServerAction::HDefaultServerAction( const HActionInfo& info, const HActionInvoke& inv, HServerService* parent) : HServerAction(info, parent) { Q_ASSERT(inv); h_ptr->m_actionInvoke = inv; } } } herqq-1.0.0/hupnp/src/devicemodel/server/hserverdevice_p.h0000644000000000000000000000272411543637310022373 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERDEVICE_P_H_ #define HSERVERDEVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include namespace Herqq { namespace Upnp { // // // class H_UPNP_CORE_EXPORT HServerDevicePrivate : public HDevicePrivate { H_DISABLE_COPY(HServerDevicePrivate) public: HServerDevicePrivate(){} virtual ~HServerDevicePrivate(){} }; } } #endif /* HSERVERDEVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hserverdevice.cpp0000644000000000000000000001026211543637310022403 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hserverdevice.h" #include "hserverdevice_p.h" #include "hserverservice.h" #include "hdefault_serverdevice_p.h" #include "../../dataelements/hserviceid.h" #include "../../dataelements/hdeviceinfo.h" #include "../../dataelements/hserviceinfo.h" #include "../../general/hupnp_global_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HServerDevicePrivate ******************************************************************************/ /******************************************************************************* * HServerDevice ******************************************************************************/ HServerDevice::HServerDevice() : QObject(), h_ptr(new HServerDevicePrivate()) { } HServerDevice::HServerDevice(HServerDevicePrivate& dd) : QObject(), h_ptr(&dd) { } HServerDevice::~HServerDevice() { delete h_ptr; } bool HServerDevice::finalizeInit(QString*) { // intentionally empty Q_ASSERT(h_ptr->q_ptr); return true; } bool HServerDevice::init(const HDeviceInfo& info, HServerDevice* parentDevice) { if (h_ptr->q_ptr) { return false; } if (parentDevice) { setParent(parentDevice); } h_ptr->m_parentDevice = parentDevice; h_ptr->m_deviceInfo.reset(new HDeviceInfo(info)); h_ptr->q_ptr = this; return true; } HServerDevice* HServerDevice::parentDevice() const { return h_ptr->m_parentDevice; } HServerDevice* HServerDevice::rootDevice() const { return h_ptr->rootDevice(); } HServerService* HServerDevice::serviceById(const HServiceId& serviceId) const { return h_ptr->serviceById(serviceId); } const HServerServices& HServerDevice::services() const { return h_ptr->m_services; } HServerServices HServerDevice::servicesByType( const HResourceType& type, HResourceType::VersionMatch versionMatch) const { return h_ptr->servicesByType(type, versionMatch); } const HServerDevices& HServerDevice::embeddedDevices() const { return h_ptr->m_embeddedDevices; } HServerDevices HServerDevice::embeddedDevicesByType( const HResourceType& type, HResourceType::VersionMatch versionMatch) const { return h_ptr->embeddedDevicesByType(type, versionMatch); } const HDeviceInfo& HServerDevice::info() const { return *h_ptr->m_deviceInfo; } QString HServerDevice::description() const { return h_ptr->m_deviceDescription; } QList HServerDevice::locations(LocationUrlType urlType) const { if (h_ptr->m_parentDevice) { // the root device "defines" the locations and they are the same for each // embedded device. return h_ptr->m_parentDevice->locations(urlType); } QList retVal; QList::const_iterator ci; for(ci = h_ptr->m_locations.begin(); ci != h_ptr->m_locations.end(); ++ci) { retVal.push_back(urlType == AbsoluteUrl ? *ci : extractBaseUrl(*ci)); } return retVal; } const HDeviceStatus& HServerDevice::deviceStatus() const { const HServerDevice* rootDev = rootDevice(); return *rootDev->h_ptr->m_deviceStatus; } /******************************************************************************* * HDefaultServerDevice ******************************************************************************/ HDefaultServerDevice::HDefaultServerDevice() : HServerDevice() { } } } herqq-1.0.0/hupnp/src/devicemodel/server/hdevicemodelcreator.cpp0000644000000000000000000000251211543637310023554 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicemodelcreator.h" #include "hdefault_serverdevice_p.h" namespace Herqq { namespace Upnp { HDeviceModelCreator::HDeviceModelCreator() { } HDeviceModelCreator::~HDeviceModelCreator() { } HServerDevice* HDeviceModelCreator::createDevice(const HDeviceInfo&) const { return new HDefaultServerDevice(); } HDeviceModelCreator* HDeviceModelCreator::clone() const { return static_cast(HClonable::clone()); } } } herqq-1.0.0/hupnp/src/devicemodel/server/hserveraction_p.h0000644000000000000000000000337711543637310022416 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERACTION_P_H_ #define HSERVERACTION_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../hactioninvoke.h" #include "../../dataelements/hactioninfo.h" #include #include #include namespace Herqq { namespace Upnp { // // Implementation details of HAction // class HServerActionPrivate { H_DISABLE_COPY(HServerActionPrivate) public: const QByteArray m_loggingIdentifier; HServerAction* q_ptr; QScopedPointer m_info; HActionInvoke m_actionInvoke; public: HServerActionPrivate(); ~HServerActionPrivate(); bool setInfo(const HActionInfo&); }; } } #endif /* HSERVERACTION_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hdefault_serverstatevariable_p.h0000644000000000000000000000247111543637310025465 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEFAULTSERVER_STATEVARIABLE_H_ #define HDEFAULTSERVER_STATEVARIABLE_H_ #include namespace Herqq { namespace Upnp { // // Default implementation of HServerStateVariable // class HDefaultServerStateVariable : public HServerStateVariable { H_DISABLE_COPY(HDefaultServerStateVariable) public: HDefaultServerStateVariable( const HStateVariableInfo&, HServerService* parent); }; } } #endif /* HDEFAULTSERVER_STATEVARIABLE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/server/hserverdevice.h0000644000000000000000000002467311543637310022063 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSERVERDEVICE_H_ #define HSERVERDEVICE_H_ #include #include class QUrl; class QString; namespace Herqq { namespace Upnp { class HServerDevicePrivate; /*! * \brief This is an abstract base class for server-side UPnP devices hosted * by HDeviceHost. * * \c %HServerDevice is a core component of the HUPnP's server-side \ref hupnp_devicemodel * and it models a UPnP device, both root and embedded. * * \note As detailed in the UPnP Device Architecture specification, * a UPnP device is essentially a container for services and possibly for other * (embedded) UPnP devices. * *

Using the class

* * The most common uses of \c %HServerDevice involve reading the various device * information elements originally set in the device description file and enumerating the * exposed services. By calling info() you get an HDeviceInfo object from * which you can read all the informational elements found in the device description. * Calling services() gives you a list of HServerService instances the device * exposes. Note that it is the services that contain the functionality * and runtime status of the device. * * Some devices also contain embedded devices, which you can get by calling * embeddedDevices(). * * You can retrieve the device's description file by calling description() or * you can manually read it from any of the locations returned by locations(). If * the device is an embedded device, it always has a parent device, which you can * get by calling parentDevice(). * *

Sub-classing

* * First of all, if you want to implement a custom UPnP device using HUPnP, note * that you do not have to subclass HServerDevice. But you can and there are valid * reasons to do so. * * Subclassing HServerDevice is extremely simple, as you are not required to override * anything. However, if you choose to subclass HServerDevice, it is most likely * because: * - you want HUPnP to run strict validation routines on the description * documents provided by users, * - you want a custom HServerDevice type to do some additional initialization * routines, * - you want to extend the HServerDevice API in some way or * - you want to create a custom type for design purposes. * * See \ref setting_up_the_devicemodel for more information of this topic. * * \headerfile HServerDevice.h HServerDevice * * \ingroup hupnp_devicemodel * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HServerDevice : public QObject { Q_OBJECT H_DISABLE_COPY(HServerDevice) H_DECLARE_PRIVATE(HServerDevice) friend class HServerModelCreator; protected: /*! * Provides the opportunity to do post-construction initialization routines * in derived classes. * * As \c %HServerDevice is part of the HUPnP's server-side \ref hupnp_devicemodel, * its initialization process is usually driven by HUPnP. If this is the case, * at the time of instantiation of a descendant \c %HServerDevice the base * \c %HServerDevice sub-object is not yet fully set up. In other words, * at that time it is not guaranteed that every private or protected member * of a \c %HServerDevice are set to their "final" values that are used * once the object is fully initialized and ready to be used. * * Because of the above, descendants of \c %HServerDevice should not * reference or rely on values of \c %HServerDevice at * the time of construction. If the initialization of a \c %HServerDevice * descendant needs to do things that rely on \c %HServerDevice being fully * set up, you can override this method. This method is called \b once * right after the base \c %HServerDevice is fully initialized. * * \param errDescription * * \return \e true in case the initialization succeeded. * * \note It is advisable to keep the constructors of the descendants of * \c %HServerDevice small and fast, and do more involved initialization * routines here. */ virtual bool finalizeInit(QString* errDescription); protected: HServerDevicePrivate* h_ptr; // // \internal // // Constructor for derived classes for re-using the h_ptr. // HServerDevice(HServerDevicePrivate& dd); /*! * \brief Creates a new instance. */ HServerDevice(); /*! * Initializes the instance. * * This method will succeed only once after construction. Subsequent * calls will do nothing. * * \param info specifies information of the device. This is usually read * from a device description document. * * \param parentDevice specifies parent UPnP device, if any. */ bool init(const HDeviceInfo& info, HServerDevice* parentDevice = 0); public: /*! * \brief Destroys the instance. */ virtual ~HServerDevice() = 0; /*! * \brief Returns the parent device of this device, if any. * * \return The parent device of this device, if any, or a null pointer * in case the device is a root device. * * \remarks The pointer is guaranteed to be valid throughout the lifetime * of this object. */ HServerDevice* parentDevice() const; /*! * \brief Returns the root device of the device tree to which this device belongs. * * \return The root device of the device tree to which this device belongs. * * \remarks This device could be the root device of the device tree in question, * in which case a pointer to this instance is returned. */ HServerDevice* rootDevice() const; /*! * \brief Returns the service that has the specified service ID. * * \param serviceId specifies the service to be returned. * * \return The service that has the specified service ID or a null pointer * in case there is no service with the specified ID. * * \remarks The pointer is guaranteed to be valid throughout the lifetime * of this object. */ HServerService* serviceById(const HServiceId& serviceId) const; /*! * \brief Returns the services this device exports. * * \return The services this device exports. The collection is empty * if the device has no services. * * \remarks the pointers are guaranteed to be valid throughout the lifetime * of this object. */ const HServerServices& services() const; /*! * \brief Returns the services of a specific UPnP service type. * * \param serviceType specifies the UPnP service type of interest. * Only services matching the type are returned. * * \param versionMatch specifies how the version information in argument * \c serviceType should be used. The default is inclusive match, * which essentially means that any service with a service type version that * is \b less than or \b equal to the version specified in argument * \c serviceType is successfully matched. * * \return The services of the specified type. * * \remarks the pointers are guaranteed to be valid throughout the lifetime * of this object. */ HServerServices servicesByType( const HResourceType& serviceType, HResourceType::VersionMatch versionMatch = HResourceType::Inclusive) const; /*! * \brief Returns the embedded devices of this device. * * \return The embedded devices of this device. The collection is empty * if the device has no embedded devices. * * \remarks the pointers are guaranteed to be valid throughout the lifetime * of this object. */ const HServerDevices& embeddedDevices() const; /*! * \brief Returns the embedded devices of a specific UPnP device type. * * \param deviceType specifies the UPnP device type of interest. * Only devices matching the type are returned. * * \param versionMatch specifies how the version information in argument * \a deviceType should be used. The default is inclusive match, * which essentially means that any device with a device type version that * is \b less than or \b equal to the version specified in argument * \a deviceType is successfully matched. * * \return The embedded devices of the specified type. * * \remarks the pointers are guaranteed to be valid throughout the lifetime * of this object. */ HServerDevices embeddedDevicesByType( const HResourceType& deviceType, HResourceType::VersionMatch versionMatch = HResourceType::Inclusive) const; /*! * \brief Returns information about the device. * * \return information about the device. This is often read from the * device description. */ const HDeviceInfo& info() const; /*! * \brief Returns the UPnP device description of this device. * * \return The UPnP device description that is associated to this device. * * \remarks an embedded device returns the same device description as * its root device. */ QString description() const; /*! * \brief Returns a list of locations where the device is currently available. * * \param urlType specifies whether the returned * location URLs are absolute URLs for retrieving the device description. * By default absolute URLs are returned and from these URLs the device * description should be retrievable. * * \return a list of locations where the device is currently available. */ QList locations(LocationUrlType urlType=AbsoluteUrl) const; /*! * \return */ const HDeviceStatus& deviceStatus() const; }; } } #endif /* HSERVERDEVICE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hdevicemodel_infoprovider.cpp0000644000000000000000000000370611543637310023462 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevicemodel_infoprovider.h" #include "hdevices_setupdata.h" #include "hactions_setupdata.h" #include "hservices_setupdata.h" #include "hstatevariables_setupdata.h" namespace Herqq { namespace Upnp { HDeviceModelInfoProvider::HDeviceModelInfoProvider() { } HDeviceModelInfoProvider::~HDeviceModelInfoProvider() { } HServicesSetupData HDeviceModelInfoProvider::servicesSetupData( const HDeviceInfo&) const { return HServicesSetupData(); } HDevicesSetupData HDeviceModelInfoProvider::embedddedDevicesSetupData( const HDeviceInfo&) const { return HDevicesSetupData(); } HActionsSetupData HDeviceModelInfoProvider::actionsSetupData( const HServiceInfo&, const HDeviceInfo&) const { return HActionsSetupData(); } HStateVariablesSetupData HDeviceModelInfoProvider::stateVariablesSetupData( const HServiceInfo&, const HDeviceInfo&) const { return HStateVariablesSetupData(); } HDeviceModelInfoProvider* HDeviceModelInfoProvider::clone() const { return static_cast(HClonable::clone()); } } } herqq-1.0.0/hupnp/src/devicemodel/hstatevariable_event.h0000644000000000000000000000576511543637310022117 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSTATEVARIABLE_EVENT_H_ #define HSTATEVARIABLE_EVENT_H_ #include #include #include namespace Herqq { namespace Upnp { class HStateVariableEventPrivate; /*! * \brief This is a class used to transfer state variable event information. * * \headerfile hstatevariable_event.h HStateVariableEvent * * \ingroup hupnp_devicemodel * * \sa HClientStateVariable, HServerStateVariable * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HStateVariableEvent { private: QSharedDataPointer h_ptr; public: /*! * \brief Creates a new, empty instance. * * \sa isEmpty() */ HStateVariableEvent(); /*! * Creates a new instance based on the provided values. * * \param previousValue specifies the value before the change. * * \param newValue specifies the value of the state variable at the time * the event was generated. * * \sa isEmpty() */ HStateVariableEvent( const QVariant& previousValue, const QVariant& newValue); /*! * \brief Copy constructor. * * Copies the contents of the \c other to this. */ HStateVariableEvent(const HStateVariableEvent&); /*! * \brief Destroys the instance. */ ~HStateVariableEvent(); /*! * Assigns the contents of the other object to this. * * \return reference to this object. */ HStateVariableEvent& operator=(const HStateVariableEvent&); /*! * \brief Indicates if the instance is empty. * * \return \e true if the instance is empty, which means that none of its * attributes contain a valid non-empty value. */ bool isEmpty() const; /*! * \brief Returns the previous value of the state variable. * * \return The previous value of the state variable. */ QVariant previousValue() const; /*! * \brief Returns the new, changed value of the state variable. * * \return The new, changed value of the state variable. */ QVariant newValue() const; }; } } #endif /* HSTATEVARIABLE_EVENT_H_ */ herqq-1.0.0/hupnp/src/devicemodel/devicemodel.pri0000644000000000000000000000636311543637310020536 0ustar rootroot HEADERS += \ $$SRC_LOC/devicemodel/hactions_setupdata.h \ $$SRC_LOC/devicemodel/hasyncop.h \ $$SRC_LOC/devicemodel/hexecargs.h \ $$SRC_LOC/devicemodel/hactioninvoke.h \ $$SRC_LOC/devicemodel/hactioninvoke_callback.h \ $$SRC_LOC/devicemodel/hactionarguments.h \ $$SRC_LOC/devicemodel/hactionarguments_p.h \ $$SRC_LOC/devicemodel/hdevicestatus.h \ $$SRC_LOC/devicemodel/hservice_p.h \ $$SRC_LOC/devicemodel/hdevice_p.h \ $$SRC_LOC/devicemodel/hdevices_setupdata.h \ $$SRC_LOC/devicemodel/hservices_setupdata.h \ $$SRC_LOC/devicemodel/hstatevariable_event.h \ $$SRC_LOC/devicemodel/hstatevariable_p.h \ $$SRC_LOC/devicemodel/hdevicemodel_infoprovider.h \ $$SRC_LOC/devicemodel/hstatevariables_setupdata.h \ $$SRC_LOC/devicemodel/client/hclientaction.h \ $$SRC_LOC/devicemodel/client/hclientactionop.h \ $$SRC_LOC/devicemodel/client/hclientaction_p.h \ $$SRC_LOC/devicemodel/client/hclientdevice.h \ $$SRC_LOC/devicemodel/client/hclientdevice_p.h \ $$SRC_LOC/devicemodel/client/hclientservice.h \ $$SRC_LOC/devicemodel/client/hclientservice_p.h \ $$SRC_LOC/devicemodel/client/hclientstatevariable.h \ $$SRC_LOC/devicemodel/client/hdefault_clientaction_p.h \ $$SRC_LOC/devicemodel/client/hdefault_clientdevice_p.h \ $$SRC_LOC/devicemodel/client/hdefault_clientservice_p.h \ $$SRC_LOC/devicemodel/client/hdefault_clientstatevariable_p.h \ $$SRC_LOC/devicemodel/server/hserveraction.h \ $$SRC_LOC/devicemodel/server/hserverdevice.h \ $$SRC_LOC/devicemodel/server/hserverdevice_p.h \ $$SRC_LOC/devicemodel/server/hserverservice.h \ $$SRC_LOC/devicemodel/server/hserverservice_p.h \ $$SRC_LOC/devicemodel/server/hserverstatevariable.h \ $$SRC_LOC/devicemodel/server/hdevicemodelcreator.h \ $$SRC_LOC/devicemodel/server/hdefault_serverdevice_p.h \ $$SRC_LOC/devicemodel/server/hdefault_serveraction_p.h \ $$SRC_LOC/devicemodel/server/hdefault_serverstatevariable_p.h EXPORTED_PRIVATE_HEADERS += \ $$SRC_LOC/devicemodel/hservice_p.h \ $$SRC_LOC/devicemodel/hdevice_p.h \ $$SRC_LOC/devicemodel/server/hserverdevice_p.h \ $$SRC_LOC/devicemodel/server/hserverservice_p.h SOURCES += \ $$SRC_LOC/devicemodel/hactions_setupdata.cpp \ $$SRC_LOC/devicemodel/hasyncop.cpp \ $$SRC_LOC/devicemodel/hexecargs.cpp \ $$SRC_LOC/devicemodel/hactionarguments.cpp \ $$SRC_LOC/devicemodel/hdevices_setupdata.cpp \ $$SRC_LOC/devicemodel/hservices_setupdata.cpp \ $$SRC_LOC/devicemodel/hstatevariable_event.cpp \ $$SRC_LOC/devicemodel/hstatevariables_setupdata.cpp \ $$SRC_LOC/devicemodel/hdevicemodel_infoprovider.cpp \ $$SRC_LOC/devicemodel/client/hclientdevice.cpp \ $$SRC_LOC/devicemodel/client/hclientaction.cpp \ $$SRC_LOC/devicemodel/client/hclientactionop.cpp \ $$SRC_LOC/devicemodel/client/hclientservice.cpp \ $$SRC_LOC/devicemodel/client/hclientstatevariable.cpp \ $$SRC_LOC/devicemodel/server/hserveraction.cpp \ $$SRC_LOC/devicemodel/server/hserverdevice.cpp \ $$SRC_LOC/devicemodel/server/hserverservice.cpp \ $$SRC_LOC/devicemodel/server/hserverstatevariable.cpp \ $$SRC_LOC/devicemodel/server/hdevicemodelcreator.cpp herqq-1.0.0/hupnp/src/devicemodel/hexecargs.h0000644000000000000000000000660711543637310017665 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HEXECARGS_H_ #define HEXECARGS_H_ #include namespace Herqq { namespace Upnp { /*! * \brief This class is used to specify information used to control the execution of * an asynchronous operation and the notification of its completion. * * \headerfile hexecargs.h HExecArgs * * \ingroup hupnp_devicemodel * * \remarks This class is thread-safe. */ class H_UPNP_CORE_EXPORT HExecArgs { friend H_UPNP_CORE_EXPORT bool operator==(const HExecArgs&, const HExecArgs&); public: /*! * \brief This enumeration specifies how the asynchronous operation should be run. */ enum ExecType { /*! * This value indicates that the operation should be run normally and * its completion or failure should be signaled normally. */ Normal, /*! * This value indicates that the operation should be dispatched to be run, * but its completion or failure isn't signaled. * * This value is useful in situations where the result of the operation * isn't interesting. */ FireAndForget }; private: volatile ExecType m_execType; public: /*! * \brief Creates a new instance. * * \param type */ explicit HExecArgs(ExecType type=Normal); /*! * \brief Destroys the instance. * * \brief Destroys the instance. */ ~HExecArgs(); /*! * \brief Indicates how the operation should be run and its completion or failure * be signaled. * * \return a value indicating how the operation should be run and its * completion or failure be signaled. * * \sa setExecType() */ inline ExecType execType() const { return m_execType; } /*! * \brief Sets the value indicating how the operation should be run and its * completion or failure be signaled. * * \param type specifies the value indicating how the operation should be * run and its completion or failure be signaled. * * \sa execType() */ inline void setExecType(ExecType type) { m_execType = type; } }; /*! * Compares the two objects for equality. * * \return \e true in case the object are logically equivalent. * * \relates HExecArgs */ H_UPNP_CORE_EXPORT bool operator==(const HExecArgs&, const HExecArgs&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HExecArgs */ inline bool operator!=(const HExecArgs& obj1, const HExecArgs& obj2) { return !(obj1 == obj2); } } } #endif /* HEXECARGS_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hasyncop_p.h0000644000000000000000000000335311543637310020052 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HASYNCOP_P_H_ #define HASYNCOP_P_H_ #include #include namespace Herqq { namespace Upnp { // // Implementation details of HAsyncOp // class H_UPNP_CORE_EXPORT HAsyncOpPrivate { H_DISABLE_COPY(HAsyncOpPrivate) private: const unsigned int m_id; public: int m_refCount; int m_returnValue; void* m_userData; QString* m_errorDescription; inline HAsyncOpPrivate() : m_id(0), m_refCount(1), m_returnValue(0), m_userData(0), m_errorDescription(0) { } inline HAsyncOpPrivate(int id) : m_id(id), m_refCount(1), m_returnValue(0), m_userData(0), m_errorDescription(0) { } static unsigned int genId(); virtual ~HAsyncOpPrivate(); inline unsigned int id() const { return m_id; } }; } } #endif /* HASYNCOP_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hstatevariables_setupdata.h0000644000000000000000000001203511543637310023137 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSTATEVARIABLES_SETUPDATA_H_ #define HSTATEVARIABLES_SETUPDATA_H_ #include #include #include #include template class QSet; namespace Herqq { namespace Upnp { /*! * \brief This class is used to specify information that can be used to validate * UPnP state variables. * * \headerfile hstatevariables_setupdata.h HStateVariablesSetupData * * \ingroup hupnp_devicemodel * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HStateVariablesSetupData { public: /*! * \brief This enumeration specifies the actions the HUPnP device model builder * should take when it encounters an unknown state variable definition in a * service description file. */ enum DefaultInclusionPolicy { /*! * The unknown state variable should be accepted. */ Accept, /*! * The unknown state variable should be rejected. In this case the build * of a device tree is aborted. */ Deny }; private: QHash m_setupData; DefaultInclusionPolicy m_defaultInclusionPolicy; public: /*! * \brief Creates a new, empty instance. * * \param defIncPol specifies the default inclusion policy for state variables * that are \b not contained in this instance. * * \sa isEmpty(), defaultInclusionPolicy() */ HStateVariablesSetupData(DefaultInclusionPolicy defIncPol = Accept); /*! * \brief Returns the default inclusion policy. * * The default inclusion policy specifies the action to take when a * state variable definition in a service description file does not map * to any HStateVariableInfo object contained within this instance. * * \return The default inclusion policy. */ DefaultInclusionPolicy defaultInclusionPolicy() const; /*! * \brief Indicates if the instance contains an item that has the * specified name. * * \param name specifies the name of the item. * * \return \e true when the instance contains an item that * has the specified name. * * \sa get(), isEmpty() */ bool contains(const QString& name) const; /*! * \brief Retrieves an item. * * \param name specifies the name of the item to be retrieved. * * \return The item with the specified name. Note that the returned item * is invalid, i.e. HStateVariableInfo::isValid() returns false in case no item * with the specified name was found. * * \sa contains(), isEmpty() */ HStateVariableInfo get(const QString& name) const; /*! * \brief Indicates if the object is empty. * * \return \e true in case the instance has no items. */ bool isEmpty() const; /*! * \brief Returns the names of the contained items. * * \return The names of the contained items. */ QSet names() const; /*! * \brief Returns the number of contained items. * * \return The number of contained items. */ qint32 size() const; /*! * Inserts a new item. * * \param newItem specifies the item to be added. * * \return \e true in case the item was added. The item will not be added * if the instance already contains an item that has the * same name as the \c newItem. * * \sa remove() */ bool insert(const HStateVariableInfo& newItem); /*! * Removes an existing item. * * \param name specifies the name of the item to be removed. * * \return \e true in case the item was found and removed. * * \sa insert() */ bool remove(const QString& name); /*! * \brief Sets the inclusion requirement element of an item. * * \param name specifies the name of the item. * * \param incReq specifies the inclusion requirement value. * * \return \e true when the item was found and the inclusion requirement * element was set. */ bool setInclusionRequirement( const QString& name, HInclusionRequirement incReq); }; } } #endif /* HSTATEVARIABLES_SETUPDATA_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hdevice_p.h0000644000000000000000000000757111543637310017643 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICE_P_H_ #define HDEVICE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include #include #include #include #include #include #include namespace Herqq { namespace Upnp { // // // template class HDevicePrivate { H_DISABLE_COPY(HDevicePrivate) public: // attributes QScopedPointer m_deviceInfo; // The static device information read from a device description. QList m_embeddedDevices; // The embedded devices this instance contains. QList m_services; // The services this instance contains. Device* m_parentDevice; // ^^ this is not the "QObject" parent, but rather the parent in the // device tree. Device* q_ptr; // The "parent" QObject QList m_locations; // The URLs at which this device is available QString m_deviceDescription; // The full device description. // CONSIDER: would it be better to load this into memory only when needed? QScopedPointer m_deviceStatus; public: // methods HDevicePrivate() : m_deviceInfo(0), m_embeddedDevices(), m_services(), m_parentDevice(0), q_ptr(0), m_locations(), m_deviceDescription(), m_deviceStatus(0) { } virtual ~HDevicePrivate(){} inline bool isValid() const { return m_deviceInfo.data(); } Device* rootDevice() const { Device* root = q_ptr; while(root->parentDevice()) { root = root->parentDevice(); } return root; } Service* serviceById(const HServiceId& serviceId) const { foreach(Service* sc, m_services) { if (sc->info().serviceId() == serviceId) { return sc; } } return 0; } QList servicesByType( const HResourceType& type, HResourceType::VersionMatch versionMatch) const { if (!type.isValid()) { return QList(); } QList retVal; foreach(Service* sc, m_services) { if (sc->info().serviceType().compare(type, versionMatch)) { retVal.push_back(sc); } } return retVal; } QList embeddedDevicesByType( const HResourceType& type, HResourceType::VersionMatch versionMatch) const { if (!type.isValid()) { return QList(); } QList retVal; foreach(Device* dev, m_embeddedDevices) { if (dev->info().deviceType().compare(type, versionMatch)) { retVal.push_back(dev); } } return retVal; } }; } } #endif /* HDEVICE_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hactions_setupdata.h0000644000000000000000000002216711543637310021575 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HACTIONS_SETUPDATA_H_ #define HACTIONS_SETUPDATA_H_ #include #include #include #include namespace Herqq { namespace Upnp { class HActionSetupPrivate; /*! * \brief This class is used to specify information that can be used to setup * an HServerAction or validate a UPnP action. * * \headerfile hactions_setupdata.h HActionSetup * * \ingroup hupnp_devicemodel * * \sa HActionsSetupData, HClientAction, HServerAction * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HActionSetup { private: QSharedDataPointer h_ptr; public: /*! * Creates a new, invalid instance. * * \sa isValid() */ HActionSetup(); /*! * \brief Creates a new instance. * * \param name specifies the name of the action. If the name value contains * special characters other than hyphens or dots the instance will be * invalid and name() will be empty. * * \param incReq specifies the \e inclusion \e requirement of the action. * * \sa isValid() * * \remarks the version() is set to 1. */ explicit HActionSetup( const QString& name, HInclusionRequirement incReq = InclusionMandatory); /*! * \brief Creates a new instance. * * \param name specifies the name of the action. If the name value contains * special characters other than hyphens or dots the instance will be * invalid and name() will be empty. * * \param version specifies the UPnP service version in which the action * was first specified. * * \param incReq specifies the \e inclusion \e requirement of the action. * * \sa isValid() */ HActionSetup( const QString& name, int version, HInclusionRequirement incReq = InclusionMandatory); /*! * \brief Copy constructor. * * Creates a copy of \a other. */ HActionSetup(const HActionSetup&); /*! * \brief Assignment operator. * * Copies the contents of \a other to this. */ HActionSetup& operator=(const HActionSetup&); /*! * \brief Destroys the instance. */ ~HActionSetup(); /*! * \brief Returns the setup information of the action's input arguments. * * \return The setup information of the action's input arguments. * * \sa setInputArguments() */ const HActionArguments& inputArguments() const; /*! * \brief Returns the setup information of the action's output arguments. * * \return The setup information of the action's output arguments. * * \sa setOutputArguments() */ const HActionArguments& outputArguments() const; /*! * \brief Returns the inclusion requirement of the action. * * \return The inclusion requirement of the action. * * \sa setInclusionRequirement() */ HInclusionRequirement inclusionRequirement() const; /*! * \brief Indicates if the object is valid. * * \return \e true in case the object is valid, that is, * the name(), version() and the inclusionRequirement() are properly defined. */ bool isValid() const; /*! * \brief Returns the name of the action. * * \return The name of the action. * * \sa setName() */ QString name() const; /*! * \brief Returns the UPnP service version in which the action * was first specified. * * \return The UPnP service version in which the action * was first specified. * * \sa setVersion() */ int version() const; /*! * \brief Specifies the action's input arguments. * * \param args specifies the setup information for the action's input arguments. * * \sa inputArguments() */ void setInputArguments(const HActionArguments& args); /*! * \brief Specifies the action's output arguments. * * \param args specifies the setup information for the action's output arguments. * * \sa outputArguments() */ void setOutputArguments(const HActionArguments& args); /*! * \brief Sets the name of the action. * * \param name specifies the name of the action. * * \param err is a pointer to a \c QString that contains an error description * in case the name could not be set. This is an optional parameter. * * \return \e true in case the specified name was successfully set. * * \sa name() */ bool setName(const QString& name, QString* err = 0); /*! * \brief Sets the inclusion requirement of the action. * * \param arg specifies the inclusion requirement of the action. * * \sa inclusionRequirement() */ void setInclusionRequirement(HInclusionRequirement arg); /*! * \brief Specifies the UPnP service version in which the action * was first specified. * * \param version specifies the UPnP service version in which the action * was first specified. * * \sa version() */ void setVersion(int version); }; /*! * \brief This class is used to specify information that can be used to setup * HServerAction instances or generally validate the actions of a UPnP service. * * \headerfile hactions_setupdata.h HActionsSetupData * * \ingroup hupnp_devicemodel * * \remarks This class is not thread-safe. * * \sa HActionSetup */ class H_UPNP_CORE_EXPORT HActionsSetupData { private: QHash m_actionSetupInfos; public: /*! * \brief Creates a new, empty instance. * * \sa isEmpty() */ HActionsSetupData(); /*! * Inserts a new item. * * \param newItem specifies the item to be added. * * \return \e true in case the item was added. The item will not be added * if the instance already contains an item with the * same name as \a newItem or the \a newItem is invalid. * * \sa remove() */ bool insert(const HActionSetup& newItem); /*! * Removes an existing item. * * \param name specifies the name of the item to be removed. * * \return \e true in case the item was found and removed. * * \sa insert() */ bool remove(const QString& name); /*! * \brief Retrieves an action setup object. * * \param name specifies the name of the item to be retrieved. * * \return The item with the specified name. Note that the returned item * is invalid, i.e. HActionSetup::isValid() returns false in case no item * with the specified name was found. * * \sa contains() */ HActionSetup get(const QString& name) const; /*! * This is a convenience method for setting the inclusion requirement * element of an item. * * \param name specifies the name of the item. * * \param incReq specifies the inclusion requirement value. * * \return \e true when the item was found and the inclusion requirement * element was set. */ bool setInclusionRequirement( const QString& name, HInclusionRequirement incReq); /*! * \brief Indicates if the instance contains an item with the specified name. * * \param name specifies the name of the item. * * \return \e true when the instance contains an item with the specified name. * * \sa get() */ inline bool contains(const QString& name) const { return m_actionSetupInfos.contains(name); } /*! * \brief Returns the names of the contained items. * * \return The names of the contained items. */ QSet names() const; /*! * \brief Returns the number of contained items. * * \return The number of contained items. */ inline qint32 size() const { return m_actionSetupInfos.size(); } /*! * \brief Indicates if the object is empty. * * \return \e true in case the instance has no items. */ inline bool isEmpty() const { return m_actionSetupInfos.isEmpty(); } /*! * Removes every contained object. */ inline void clear() { m_actionSetupInfos.clear(); } }; } } #endif /* HACTIONS_SETUPDATA_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hactionarguments.h0000644000000000000000000004731611543637310021271 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HACTIONARGUMENTS_H_ #define HACTIONARGUMENTS_H_ #include #include #include #include #include template class QHash; template class QVector; namespace Herqq { namespace Upnp { class HActionArgumentPrivate; /*! * \brief This is a class that represents an argument used in a UPnP action invocation. * * A UPnP argument is defined in the UPnP service description within * an action. If you picture a UPnP action as a function, then an * action argument is a parameter to the function. In that sense a UPnP * \e input \e argument is a single \b constant parameter that provides * input for the function. An input argument is never modified during action * invocation. On the other hand, a UPnP \e output \e argument relays information * back from the callee to the caller and thus it is often modified during * action invocation. * * \section actionargument_basicuse Basic Use * * A UPnP argument has an unique name() within the definition * of the action that contains it. A UPnP argument contains a value, which you * can retrieve using value() and which you can set using setValue(). Note, the * value of a UPnP argument is bound by its dataType(). * * A somewhat unusual aspect of a UPnP argument is the concept of a * related state variable. According to the UDA specification, a * UPnP argument is \b always associated with a state variable, even if the * state variable does not serve any other purpose besides that. * This type of a state variable is used to describe the data type of a * UPnP argument and thus the value of a UPnP argument is bound by the * data type of its related state variable. The dataType() method introduced * in this class is equivalent for calling relatedStateVariable()->dataType(). * * \note * relatedStateVariable() returns a const reference to an HStateVariableInfo * object, rather than a reference or a pointer to an actual state variable. * HStateVariableInfo is an object with value semantics that details information * of a state variable. * * Due to the strict typing of UPnP arguments, HUPnP attempts to make sure that * invalid values are not entered into a UPnP argument. Because of this, you can * call isValidValue() to check if a value you wish to set using setValue() * will be accepted. In addition, setValue() returns \e false in case the value * was not accepted. It is advised that you make sure your values are properly * set before attempting to invoke an action, because the invocation may fail * in case any of the provided arguments is invalid. * * Finally, you can use isValid() to check if the object itself is valid, which * is true if the object was constructed with a proper name and valid related state * variable information. * * \note Since it is common for actions to use both input and output arguments * that are defined only for the duration of the action invocation, * there are bound to be numerous state variables that exist only for * UPnP action invocation. It is defined in the UDA specification * that these types of state variables have to have a name that includes the * prefix \b A_ARG_TYPE. * * \section actionargument_copysemantics Copy Semantics * * HActionArgument is designed to be used by value. However, the class uses * \e explicit \e sharing, which essentially means that every copy of an * HActionArgument instance accesses and modifies the same data until detach() * is called. The detach() function effectively modifies an HActionArgument instance to use * a "private" copy of the underlying data until the instance is copied * via a copy constructor or an assignment operator. * * \remarks This class is not thread-safe. * * \headerfile hactionarguments.h HActionArgument * * \ingroup hupnp_devicemodel * * \sa HActionArguments */ class H_UPNP_CORE_EXPORT HActionArgument { friend H_UPNP_CORE_EXPORT bool operator==( const HActionArgument&, const HActionArgument&); private: QExplicitlySharedDataPointer h_ptr; public: /*! * Constructs a new, empty instance. * * \remarks Object constructed using this method is always invalid. * * \sa isValid() */ HActionArgument(); /*! * Initializes a new instance with the specified name and related state variable. * * \param name specifies the name of the argument. * * \param stateVariableInfo specifies the related state variable. * * \param err specifies a pointer to a \c QString, which will contain an * error description in case the provided arguments were not valid. This * is optional * * \remarks in case the name parameter fails the criteria specified for * UPnP action arguments in UPnP Device Architecture 1.1 specification * or the stateVariable is null, the object is constructed as "invalid"; * isValid() always returns false. * * \sa isValid() */ HActionArgument( const QString& name, const HStateVariableInfo& stateVariableInfo, QString* err = 0); /*! * \brief Copy constructor. * * Creates a copy of \c other. */ HActionArgument(const HActionArgument&); /*! * \brief Assignment operator. * * Copies the contents of \c other to this. */ HActionArgument& operator=(const HActionArgument&); /*! * \brief Destroys the instance. */ ~HActionArgument(); /*! * Creates a deep copy of the instance, if necessary. * * If the underlying reference count of this instance is greater than one, * this function creates a deep copy of the shared data and modifies this * instance to refer to the copied data. */ void detach(); /*! * \brief Returns the name of the argument. * * \return The name of the argument. The return value is an empty string in * case the object is invalid. * * \sa isValid() */ QString name() const; /*! * \brief Returns information about the state variable that is associated * with this action argument. * * \return information about the state variable that is associated * with this action argument or a null pointer in case the object is invalid. * * \sa isValid() */ const HStateVariableInfo& relatedStateVariable() const; /*! * Helper method for accessing the data type of the related state variable * info object directly. * * \return The data type of the state variable. The data type is * HUpnpDataTypes::Undefined in case the object is invalid. * * \sa isValid() */ HUpnpDataTypes::DataType dataType() const; /*! * \brief Returns the value of the argument. * * \return The value of the argument. The returned \c QVariant has a type of * \c QVariant::Invalid in case the object is invalid. * * \sa isValid() */ QVariant value() const; /*! * \brief Sets the value of the argument if the object is valid and the new value is * of right type. * * \param value specifies the new value of the argument. * * \return \e true in case the new value was successfully set. */ bool setValue(const QVariant& value); /*! * \brief Indicates if the object is constructed with a proper name and a state * variable. * * \return \e true in case the object has a proper name and the object refers * to a valid state variable. */ bool isValid() const; /*! * \brief Indicates whether or not the object is considered as invalid. * * This is the opposite for calling isValid(). * * \return \e true in case the object is invalid. * * \sa isValid() */ bool operator!() const; /*! * \brief Returns a string representation of the object. * * The format of the return value is \c "name: theValue". * * \return a string representation of the object. An empty string is returned * if the object is invalid. */ QString toString() const; /*! * \brief Indicates if the provided value can be set into this input argument * successfully. * * A value is considered \e valid, when: * \li the argument object is valid, i.e. isValid() returns true and * \li the data type of the provided value matches the data type of the argument or * \li the data type of the provided value can be converted to the data type * of the argument. * * \param value specifies the value to be checked. * * \return \e true in case the provided value can be set into this input argument * successfully. */ bool isValidValue(const QVariant& value); }; /*! * Compares the two objects for equality. * * \return \e true in case the object are logically equivalent. * * \relates HActionArgument */ H_UPNP_CORE_EXPORT bool operator==( const HActionArgument&, const HActionArgument&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HActionArgument */ H_UPNP_CORE_EXPORT bool operator!=( const HActionArgument&, const HActionArgument&); class HActionArgumentsPrivate; /*! * A storage class for HActionArgument instances. * * Instances of this class are used to contain the input and output arguments * for an action invocation. * * \note * The class provides iterative and keyed access to the stored HActionArgument * instances. The order of action arguments during iteration is the order * in which the HActionArgument objects are provided to the instance. * If the class is instantiated by HUPnP, the order of the contained arguments * during iteration is the order in which they are defined in the service * description document. * * \headerfile hactionarguments.h HActionArguments * * \ingroup hupnp_devicemodel * * \sa HActionArgument * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HActionArguments { friend H_UPNP_CORE_EXPORT bool operator==( const HActionArguments&, const HActionArguments&); private: HActionArgumentsPrivate* h_ptr; public: typedef HActionArgument* iterator; typedef const HActionArgument* const_iterator; /*! * Swaps the contents of the two containers. * * Swaps the contents of the two containers. * * \relates HActionArguments */ friend H_UPNP_CORE_EXPORT void swap(HActionArguments&, HActionArguments&); /*! * \brief Creates a new, empty instance. * * \sa isEmpty() */ HActionArguments(); /*! * Creates a new instance from the specified input arguments. * * \param args specifies the action argument objects this instance will * contain. * * \sa isEmpty() */ HActionArguments(const QVector& args); /*! * \brief Copy constructor. * * Creates a copy of \c other. */ HActionArguments(const HActionArguments&); /*! * \brief Destroys the instance. */ ~HActionArguments(); /*! * \brief Assignment operator. * * Copies the contents of \c other to this. * * \return a reference to this object. */ HActionArguments& operator=(const HActionArguments&); /*! * \brief Indicates if the object contains an argument with the specified name. * * \param argumentName specifies the name of the action argument. * * \return \e true in case the object contains an argument with the specified name. * * \remarks This is a \e constant-time operation. */ bool contains(const QString& argumentName) const; /*! * \brief Returns an action argument with the specified name. * * \param argumentName specifies the name of the argument to be retrieved. * * \return an action argument with the specified name. If no argument is found * with the specified name, the returned instance is invalid, i.e. * HActionArgument::isValid() returns \e false. * * \remarks This is a \e constant-time operation. */ HActionArgument get(const QString& argumentName) const; /*! * \brief Returns an action argument at the specified index. * * \param index specifies the index of the action argument to return. The * index has to be valid position in the container, i.e. it must be * 0 <= i < size(). * * \return an action argument at the specified \a index. * * \remarks This is a \e constant-time operation. */ HActionArgument get(qint32 index) const; /*! * \brief Returns a const STL-style iterator pointing to the first item. * * \return a const STL-style iterator pointing to the first item. */ HActionArguments::const_iterator constBegin() const; /*! * \brief Returns a const STL-style iterator pointing to the * imaginary item after the last item. * * \return a const STL-style iterator pointing to the * imaginary item after the last item. */ HActionArguments::const_iterator constEnd() const; /*! * \brief Returns an STL-style iterator pointing to the first item. * * \return an STL-style iterator pointing to the first item. */ HActionArguments::iterator begin(); /*! * \overload * * \return an STL-style iterator pointing to the first item. */ HActionArguments::const_iterator begin() const; /*! * \brief Returns an STL-style iterator pointing to the imaginary item * after the last item. * * \return an STL-style iterator pointing to the imaginary item * after the last item. */ HActionArguments::iterator end(); /*! * \overload * * \return an STL-style iterator pointing to the imaginary item * after the last item. */ HActionArguments::const_iterator end() const; /*! * \brief Returns the number of contained action arguments. * * \return The number of contained action arguments. */ qint32 size() const; /*! * \brief Returns an action argument at the specified index. * * This is the same as calling get() with the specified index. This method is * provided for convenience. * * \param index specifies the index of the action argument to return. The * index has to be valid position in the container, i.e. it must be * 0 <= i < size(). * * \return an action argument at the specified index. */ HActionArgument operator[](qint32 index) const; /*! * \brief Returns an action argument with the specified name. * * This is the same as calling get() with the specified argument name. * This method is provided for convenience. * * \param argName specifies the name of the argument to be retrieved. * * \return an action argument with the specified name. If no argument is found * with the specified name, the returned instance is invalid, i.e. * HActionArgument::isValid() returns \e false. * * \remarks This is a \e constant-time operation. */ HActionArgument operator[](const QString& argName) const; /*! * \brief Returns the names of all the contained action arguments. * * \return The names of all the contained action arguments. */ QStringList names() const; /*! * \brief Indicates if the object is empty, i.e. it has no action arguments. * * \return \e true when the object has no action arguments. */ bool isEmpty() const; /*! * Removes every contained HActionArgument from this instance. * * \remarks * A call to this function makes active iterators invalid and */ void clear(); /*! * Removes an HActionArgument with the specified name. * * \param name specifies the name of the HActionArgument to be removed. * * \return \e true if an HActionArgument was found and removed. * * \remarks * A call to this function makes active iterators invalid and */ bool remove(const QString& name); /*! * Inserts an HActionArgument to this instance. * * \param arg specifies the HActionArgument to be added. * * \return \e true if the specified argument was added. The action argument * will not be added if the instance already contains an action argument * instance with the same name or the provided instance is invalid. * * \remarks * A call to this function makes active iterators invalid and */ bool append(const HActionArgument& arg); /*! * \brief Returns the value of the specified state variable, if such exists. * * This is a convenience method for retrieving the value of the specified * state variable. Semantically this call is comparable to * get("stateVariable_name").value(). * * \param name specifies the name of the state variable. * * \param ok specifies a pointer to \c bool, which will be \e true if * the specified state variable was found. This parameter is optional. * * \return The value of the specified state variable, if such exists. * Otherwise the returned \c QVariant is invalid. */ QVariant value(const QString& name, bool* ok = 0) const; /*! * Attempts to set the value of the specified state variable. * * This is a convenience method for setting the value of the specified * state variable. Semantically this call is comparable to * get("stateVariable_name").setValue(value). * * \param name specifies the name of the state variable. * * \param value specifies the value of the state variable. * * \return \e true in case the value of the specified state variable was * found and its value was changed. */ bool setValue(const QString& name, const QVariant& value); /*! * \brief Returns a string representation of the object. * * \return a string representation of the object. The * returned string contains all the arguments represented as strings and * separated from each other by a new-line. The string representation of * an argument is retrieved using HActionArgument::toString(). * * \remarks * An empty string is returned if the object is invalid. */ QString toString() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the object are logically equivalent. * * \relates HActionArguments */ H_UPNP_CORE_EXPORT bool operator==( const HActionArguments&, const HActionArguments&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HActionArguments */ inline bool operator!=( const HActionArguments& obj1, const HActionArguments& obj2) { return !(obj1 == obj2); } } } #endif /* HACTIONARGUMENTS_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hdevices_setupdata.cpp0000644000000000000000000001124411543637310022104 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdevices_setupdata.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HDeviceSetupPrivate ******************************************************************************/ class HDeviceSetupPrivate : public QSharedData { public: HResourceType m_deviceType; int m_version; HInclusionRequirement m_inclusionReq; HDeviceSetupPrivate() : m_deviceType(), m_version(0), m_inclusionReq(InclusionRequirementUnknown) { } ~HDeviceSetupPrivate() { } }; /******************************************************************************* * HDeviceSetup ******************************************************************************/ HDeviceSetup::HDeviceSetup() : h_ptr(new HDeviceSetupPrivate()) { } HDeviceSetup::HDeviceSetup( const HResourceType& type, HInclusionRequirement incReq) : h_ptr(new HDeviceSetupPrivate()) { h_ptr->m_deviceType = type; h_ptr->m_version = 1; h_ptr->m_inclusionReq = incReq; } HDeviceSetup::HDeviceSetup( const HResourceType& type, int version, HInclusionRequirement incReq) : h_ptr(new HDeviceSetupPrivate()) { h_ptr->m_deviceType = type; h_ptr->m_version = version; h_ptr->m_inclusionReq = incReq; } HDeviceSetup::~HDeviceSetup() { } HDeviceSetup& HDeviceSetup::operator=(const HDeviceSetup& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HDeviceSetup::HDeviceSetup(const HDeviceSetup& other) : h_ptr(other.h_ptr) { Q_ASSERT(this != &other); } const HResourceType& HDeviceSetup::deviceType() const { return h_ptr->m_deviceType; } HInclusionRequirement HDeviceSetup::inclusionRequirement() const { return h_ptr->m_inclusionReq; } bool HDeviceSetup::isValid() const { return h_ptr->m_deviceType.isValid() && h_ptr->m_version > 0 && h_ptr->m_inclusionReq != InclusionRequirementUnknown; } int HDeviceSetup::version() const { return h_ptr->m_version; } void HDeviceSetup::setInclusionRequirement(HInclusionRequirement arg) { h_ptr->m_inclusionReq = arg; } void HDeviceSetup::setDeviceType(const HResourceType& arg) { h_ptr->m_deviceType = arg; } void HDeviceSetup::setVersion(int version) { h_ptr->m_version = version; } /******************************************************************************* * HDevicesSetupData ******************************************************************************/ HDevicesSetupData::HDevicesSetupData() : m_deviceSetupInfos() { } HDevicesSetupData::~HDevicesSetupData() { } bool HDevicesSetupData::insert(const HDeviceSetup& setupInfo) { if (!setupInfo.isValid()) { return false; } HResourceType id = setupInfo.deviceType(); if (m_deviceSetupInfos.contains(id)) { return false; } m_deviceSetupInfos.insert(id, setupInfo); return true; } bool HDevicesSetupData::remove(const HResourceType& deviceType) { if (m_deviceSetupInfos.contains(deviceType)) { m_deviceSetupInfos.remove(deviceType); return true; } return false; } HDeviceSetup HDevicesSetupData::get(const HResourceType& deviceType) const { return m_deviceSetupInfos.value(deviceType); } bool HDevicesSetupData::contains(const HResourceType& id) const { return m_deviceSetupInfos.contains(id); } QSet HDevicesSetupData::deviceTypes() const { return m_deviceSetupInfos.keys().toSet(); } int HDevicesSetupData::size() const { return m_deviceSetupInfos.size(); } bool HDevicesSetupData::isEmpty() const { return m_deviceSetupInfos.isEmpty(); } } } herqq-1.0.0/hupnp/src/devicemodel/hdevicestatus.h0000644000000000000000000000360711543637310020564 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICESTATUS_H_ #define HDEVICESTATUS_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include namespace Herqq { namespace Upnp { /*! * */ class HDeviceStatus { private: qint32 m_bootId; qint32 m_configId; qint32 m_searchPort; bool m_online; public: HDeviceStatus() : m_bootId(0), m_configId(0), m_searchPort(0), m_online(true) { } inline qint32 bootId() const { return m_bootId; } inline void setBootId(qint32 arg) { m_bootId = arg; } inline qint32 configId() const { return m_configId; } inline void setConfigId(qint32 arg) { m_configId = arg; } inline qint32 searchPort() const { return m_searchPort; } inline void setSearchPort(qint32 arg) { m_searchPort = arg; } inline bool online() const { return m_online; } inline void setOnline(bool arg) { m_online = arg; } }; } } #endif /* HDEVICESTATUS_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hactionarguments.cpp0000644000000000000000000002307111543637310021614 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hactionarguments.h" #include "hactionarguments_p.h" #include "../general/hupnp_global_p.h" #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HActionArgumentPrivate *******************************************************************************/ class HActionArgumentPrivate : public QSharedData { public: QString m_name; HStateVariableInfo m_stateVariableInfo; QVariant m_value; HActionArgumentPrivate(); }; HActionArgumentPrivate::HActionArgumentPrivate() : m_name(), m_stateVariableInfo(), m_value() { } /******************************************************************************* * HActionArgument *******************************************************************************/ HActionArgument::HActionArgument() : h_ptr(new HActionArgumentPrivate()) { } HActionArgument::HActionArgument( const QString& name, const HStateVariableInfo& stateVariableInfo, QString* err) : h_ptr(new HActionArgumentPrivate()) { if (!verifyName(name, err)) { return; } else if (!stateVariableInfo.isValid()) { if (err) { *err = "The provided state variable information object was not valid"; } return; } h_ptr->m_name = name; h_ptr->m_value = stateVariableInfo.defaultValue(); h_ptr->m_stateVariableInfo = stateVariableInfo; } HActionArgument::HActionArgument(const HActionArgument& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HActionArgument& HActionArgument::operator=(const HActionArgument& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HActionArgument::~HActionArgument() { } void HActionArgument::detach() { h_ptr.detach(); } QString HActionArgument::name() const { return h_ptr->m_name; } const HStateVariableInfo& HActionArgument::relatedStateVariable() const { return h_ptr->m_stateVariableInfo; } HUpnpDataTypes::DataType HActionArgument::dataType() const { return h_ptr->m_stateVariableInfo.dataType(); } QVariant HActionArgument::value() const { return h_ptr->m_value; } bool HActionArgument::setValue(const QVariant& value) { QVariant convertedValue; if (isValid() && h_ptr->m_stateVariableInfo.isValidValue(value, &convertedValue)) { h_ptr->m_value = convertedValue; return true; } return false; } bool HActionArgument::isValid() const { return !h_ptr->m_name.isEmpty(); } bool HActionArgument::operator!() const { return !isValid(); } QString HActionArgument::toString() const { if (!isValid()) { return ""; } return QString("%1: %2").arg( name(), dataType() == HUpnpDataTypes::uri ? value().toUrl().toString() : value().toString()); } bool HActionArgument::isValidValue(const QVariant& value) { return isValid() && h_ptr->m_stateVariableInfo.isValidValue(value); } bool operator==(const HActionArgument& arg1, const HActionArgument& arg2) { return arg1.h_ptr->m_name == arg2.h_ptr->m_name && arg1.h_ptr->m_value == arg2.h_ptr->m_value && arg1.h_ptr->m_stateVariableInfo == arg2.h_ptr->m_stateVariableInfo; } bool operator!=(const HActionArgument& arg1, const HActionArgument& arg2) { return !(arg1 == arg2); } /******************************************************************************* * HActionArgumentsPrivate *******************************************************************************/ HActionArgumentsPrivate::HActionArgumentsPrivate() { } HActionArgumentsPrivate::HActionArgumentsPrivate( const QVector& args) { QVector::const_iterator ci = args.constBegin(); for (; ci != args.constEnd(); ++ci) { append(*ci); } } /******************************************************************************* * HActionArguments *******************************************************************************/ HActionArguments::HActionArguments() : h_ptr(new HActionArgumentsPrivate()) { } HActionArguments::HActionArguments(const QVector& args) : h_ptr(HActionArgumentsPrivate::copy(args)) { } HActionArguments::~HActionArguments() { delete h_ptr; } HActionArguments::HActionArguments(const HActionArguments& other) : h_ptr(HActionArgumentsPrivate::copy(other)) { Q_ASSERT(&other != this); } HActionArguments& HActionArguments::operator=(const HActionArguments& other) { Q_ASSERT(&other != this); delete h_ptr; h_ptr = HActionArgumentsPrivate::copy(other); return *this; } bool HActionArguments::contains(const QString& argumentName) const { return h_ptr->m_arguments.contains(argumentName); } HActionArgument HActionArguments::get(qint32 index) const { return h_ptr->m_argumentsOrdered.at(index); } HActionArgument HActionArguments::get(const QString& argumentName) const { return h_ptr->m_arguments.value(argumentName); } HActionArguments::const_iterator HActionArguments::constBegin() const { return h_ptr->m_argumentsOrdered.constBegin(); } HActionArguments::const_iterator HActionArguments::constEnd() const { return h_ptr->m_argumentsOrdered.constEnd(); } HActionArguments::iterator HActionArguments::begin() { return h_ptr->m_argumentsOrdered.begin(); } HActionArguments::iterator HActionArguments::end() { return h_ptr->m_argumentsOrdered.end(); } HActionArguments::const_iterator HActionArguments::begin() const { return h_ptr->m_argumentsOrdered.begin(); } HActionArguments::const_iterator HActionArguments::end() const { return h_ptr->m_argumentsOrdered.end(); } qint32 HActionArguments::size() const { return h_ptr->m_argumentsOrdered.size(); } HActionArgument HActionArguments::operator[](qint32 index) const { return h_ptr->m_argumentsOrdered.at(index); } HActionArgument HActionArguments::operator[](const QString& argName) const { return h_ptr->m_arguments.value(argName); } QStringList HActionArguments::names() const { return h_ptr->m_arguments.keys(); } bool HActionArguments::isEmpty() const { return h_ptr->m_argumentsOrdered.isEmpty(); } void HActionArguments::clear() { h_ptr->m_arguments.clear(); h_ptr->m_argumentsOrdered.clear(); } bool HActionArguments::remove(const QString& name) { if (h_ptr->m_arguments.contains(name)) { h_ptr->m_arguments.remove(name); HActionArguments::iterator it = h_ptr->m_argumentsOrdered.begin(); for(; it != h_ptr->m_argumentsOrdered.end(); ++it) { if (it->name() == name) { h_ptr->m_argumentsOrdered.erase(it); return true; } } } return false; } bool HActionArguments::append(const HActionArgument& arg) { if (!arg.isValid()) { return false; } else if (h_ptr->m_arguments.contains(arg.name())) { return false; } h_ptr->m_arguments.insert(arg.name(), arg); h_ptr->m_argumentsOrdered.append(arg); return true; } QVariant HActionArguments::value(const QString& name, bool* ok) const { QVariant retVal; if (h_ptr->m_arguments.contains(name)) { retVal = h_ptr->m_arguments.value(name).value(); if (ok) { *ok = true; } } else { if (ok) { *ok = false; } } return retVal; } bool HActionArguments::setValue(const QString& name, const QVariant& value) { if (h_ptr->m_arguments.contains(name)) { return h_ptr->m_arguments[name].setValue(value); } return false; } QString HActionArguments::toString() const { QString retVal; HActionArguments::const_iterator ci = constBegin(); for (; ci != constEnd(); ++ci) { retVal.append(ci->toString()).append("\n"); } return retVal; } void swap(HActionArguments& a, HActionArguments& b) { std::swap(a.h_ptr, b.h_ptr); } bool operator==(const HActionArguments& arg1, const HActionArguments& arg2) { if (arg1.h_ptr->m_argumentsOrdered.size() != arg2.h_ptr->m_argumentsOrdered.size()) { return false; } qint32 size = arg1.h_ptr->m_argumentsOrdered.size(); for(qint32 i = 0; i < size; ++i) { if (arg1.h_ptr->m_argumentsOrdered.at(i) != arg2.h_ptr->m_argumentsOrdered.at(i)) { return false; } } return true; } } } herqq-1.0.0/hupnp/src/devicemodel/hactioninvoke.h0000644000000000000000000000606311543637310020551 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HACTIONINVOKE_H_ #define HACTIONINVOKE_H_ #include #include /*! * \file * This file contains the type definition and usage documentation for the functor * used in action invocation. */ namespace Herqq { namespace Upnp { /*! * This is a type definition for a callable entity that is used * for HServerAction invocation. * * You can create \c %HActionInvoke objects using normal functions, functors and * member functions that follow the signature of * * * * qint32 function(const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs = 0); * * * * The following example demonstrates how you can instantiate the \c %HActionInvoke * for a normal function, functor and a member function. * * \code * * #include * #include * * #include "myclass.h" // your code that contains declaration for MyClass * * namespace * { * qint32 freefun( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs) * { * return 0; * } * * class MyFunctor * { * public: * qint32 operator()( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs) * { * return 0; * } * }; * } * * qint32 MyClass::memfun( * const Herqq::Upnp::HActionArguments& inArgs, * Herqq::Upnp::HActionArguments* outArgs = 0) * { * } * * void MyClass::example() * { * Herqq::Upnp::HActionInvoke usingFreeFunction(freefun); * * MyFunctor myfunc; * Herqq::Upnp::HActionInvoke usingFunctor(myfunc); * * Herqq::Upnp::HActionInvoke usingMemberFunction(this, &MyClass::memfun); * } * * \endcode * * You can test if the object can be invoked simply by issuing * if (actionInvokeObject) { ... } * * \headerfile hactioninvoke.h HActionInvoke * * \ingroup hupnp_devicemodel */ typedef Functor HActionInvoke; } } #endif /* HACTIONINVOKE_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hexecargs.cpp0000644000000000000000000000222211543637310020205 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hexecargs.h" namespace Herqq { namespace Upnp { HExecArgs::HExecArgs(ExecType etype) : m_execType(etype) { } HExecArgs::~HExecArgs() { } bool operator==(const HExecArgs& arg1, const HExecArgs& arg2) { return arg1.m_execType == arg2.m_execType; } } } herqq-1.0.0/hupnp/src/devicemodel/hasyncop.cpp0000644000000000000000000000624011543637310020064 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hasyncop.h" #include "hasyncop_p.h" #include static unsigned int s_lastInt = 0; static QMutex s_lastIntMutex; namespace Herqq { namespace Upnp { namespace { inline unsigned int getNextId() { unsigned int retVal; s_lastIntMutex.lock(); retVal = ++s_lastInt; s_lastIntMutex.unlock(); return retVal; } } unsigned int HAsyncOpPrivate::genId() { return getNextId(); } HAsyncOpPrivate::~HAsyncOpPrivate() { delete m_errorDescription; } HAsyncOp::HAsyncOp() : h_ptr(new HAsyncOpPrivate(getNextId())) { } HAsyncOp::HAsyncOp(HAsyncOpPrivate& dd) : h_ptr(&dd) { } HAsyncOp::HAsyncOp( qint32 returnCode, const QString& errorDescription, HAsyncOpPrivate& dd) : h_ptr(&dd) { h_ptr->m_returnValue = returnCode; h_ptr->m_errorDescription = new QString(errorDescription); } HAsyncOp::HAsyncOp(int rc, const QString& errorDescription) : h_ptr(new HAsyncOpPrivate()) { h_ptr->m_returnValue = rc; h_ptr->m_errorDescription = new QString(errorDescription); } HAsyncOp::~HAsyncOp() { if (--h_ptr->m_refCount == 0) { delete h_ptr; } } HAsyncOp::HAsyncOp(const HAsyncOp& op) : h_ptr(op.h_ptr) { Q_ASSERT(this != &op); ++h_ptr->m_refCount; } HAsyncOp& HAsyncOp::operator=(const HAsyncOp& op) { Q_ASSERT(this != &op); if (--h_ptr->m_refCount == 0) { delete h_ptr; } h_ptr = op.h_ptr; ++h_ptr->m_refCount; return *this; } QString HAsyncOp::errorDescription() const { return h_ptr->m_errorDescription ? QString(*h_ptr->m_errorDescription) : QString(); } void HAsyncOp::setErrorDescription(const QString& arg) { if (h_ptr->m_errorDescription) { delete h_ptr->m_errorDescription; h_ptr->m_errorDescription = 0; } h_ptr->m_errorDescription = new QString(arg); } int HAsyncOp::returnValue() const { return h_ptr->m_returnValue; } void HAsyncOp::setReturnValue(int returnValue) { h_ptr->m_returnValue = returnValue; } unsigned int HAsyncOp::id() const { return h_ptr->id(); } bool HAsyncOp::isNull() const { return h_ptr->id() == 0; } void HAsyncOp::abort() { // The default implementation does nothing. } } } herqq-1.0.0/hupnp/src/devicemodel/hdevices_setupdata.h0000644000000000000000000001566011543637310021557 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICES_SETUPDATA_H_ #define HDEVICES_SETUPDATA_H_ #include #include #include #include #include namespace Herqq { namespace Upnp { class HDeviceSetupPrivate; /*! * \brief This class is used to specify information that can be used to validate * a UPnP device. * * \headerfile hdevices_setupdata.h HDeviceSetup * * \ingroup hupnp_devicemodel * * \sa HDevicesSetupData, HClientDevice, HServerDevice * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HDeviceSetup { private: QSharedDataPointer h_ptr; public: /*! * Creates a new, invalid instance. * * \sa isValid() */ HDeviceSetup(); /*! * \brief Creates a new instance. * * \param type specifies the device type. * * \param incReq specifies inclusion requirement of the device. * * \sa isValid() * * \remarks the version() is set to 1. */ HDeviceSetup( const HResourceType& type, HInclusionRequirement incReq = InclusionMandatory); /*! * \brief Creates a new instance. * * \param type specifies the device type. * * \param version specifies the version of the UPnP device, * which first specified the embedded device. * * \param incReq specifies inclusion requirement of the device. * * \sa isValid() */ HDeviceSetup( const HResourceType& type, int version, HInclusionRequirement incReq = InclusionMandatory); /*! * \brief Destroys the instance. */ ~HDeviceSetup(); /*! * \brief Copy constructor. * * Creates a copy of \a other. */ HDeviceSetup& operator=(const HDeviceSetup&); /*! * \brief Assignment operator. * * Copies the contents of \a other to this. */ HDeviceSetup(const HDeviceSetup&); /*! * \brief Returns the device type. * * \return The device type. * * \sa setDeviceType() */ const HResourceType& deviceType() const; /*! * \brief Returns the inclusion requirement. * * \return The inclusion requirement. * * \sa setInclusionRequirement() */ HInclusionRequirement inclusionRequirement() const; /*! * \brief Indicates if the object is valid. * * \return \e true in case the object is valid, that is, the device type, * version and inclusion requirement are properly defined. * * \sa version(), deviceType(), inclusionRequirement() */ bool isValid() const; /*! * \brief Returns the version of the UPnP device, which first specified the * embedded device. * * \return The version of the UPnP device, which first specified the * embedded device. * * \sa setVersion() */ int version() const; /*! * \brief Sets the the inclusion requirement. * * \param arg specifies the inclusion requirement. * * \sa inclusionRequirement() */ void setInclusionRequirement(HInclusionRequirement arg); /*! * \brief Sets the device type. * * \param arg specifies the device type. * * \sa deviceType() */ void setDeviceType(const HResourceType& arg); /*! * \brief Specifies the version of the UPnP device, which first specified the * embedded device. * * \param version specifies the version of the UPnP device, * which first specified the embedded device. * * \sa version() */ void setVersion(int version); }; /*! * \brief This class is used to specify information that can be used to validate * UPnP devices. * * \headerfile hdevices_setupdata.h HDevicesSetupData * * \ingroup hupnp_devicemodel * * \remarks This class is not thread-safe. * * \sa HDeviceSetup */ class H_UPNP_CORE_EXPORT HDevicesSetupData { private: QHash m_deviceSetupInfos; public: /*! * \brief Creates a new, empty instance. * * \sa isEmpty() */ HDevicesSetupData(); /*! * \brief Destroys the instance. */ ~HDevicesSetupData(); /*! * \brief Indicates if the instance contains an item with the * specified device type. * * \param deviceType specifies the device type of the searched item. * * \return \e true when the instance contains an item with the specified * device type. * * \sa get() */ bool contains(const HResourceType& deviceType) const; /*! * \brief Returns the device types of the contained items. * * \return The device types of the contained items. */ QSet deviceTypes() const; /*! * \brief Retrieves an item. * * \param type specifies the device type of the item. * * \return The item with the specified device type. The returned item is * invalid in case no item with the specified device type was found. * * \sa contains() */ HDeviceSetup get(const HResourceType& type) const; /*! * \brief Indicates if the object is empty. * * \return \e true in case the instance has no items. */ bool isEmpty() const; /*! * \brief Returns the number of contained items. * * \return The number of contained items. */ int size() const; /*! * Inserts a new item. * * \param newItem specifies the item to be added. * * \return \e true in case the item was added. The \a newItem will not be added * if the instance already contains an item that has the * same HDeviceSetup::deviceType() as the \a newItem or the \a newItem is * invalid. */ bool insert(const HDeviceSetup& newItem); /*! * Removes an existing item. * * \param type specifies the device type of the item to be removed. * * \return \e true in case the item was found and removed. */ bool remove(const HResourceType& type); }; } } #endif /* HDEVICES_SETUPDATA_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hstatevariables_setupdata.cpp0000644000000000000000000000555011543637310023476 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hstatevariables_setupdata.h" #include "../general/hupnp_global_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HStateVariablesSetupData ******************************************************************************/ HStateVariablesSetupData::HStateVariablesSetupData( DefaultInclusionPolicy policy) : m_setupData(), m_defaultInclusionPolicy(policy) { } bool HStateVariablesSetupData::insert(const HStateVariableInfo& setupData) { if (m_setupData.contains(setupData.name())) { return false; } m_setupData.insert(setupData.name(), setupData); return true; } bool HStateVariablesSetupData::remove(const QString& stateVarName) { if (m_setupData.contains(stateVarName)) { m_setupData.remove(stateVarName); return true; } return false; } HStateVariablesSetupData::DefaultInclusionPolicy HStateVariablesSetupData::defaultInclusionPolicy() const { return m_defaultInclusionPolicy; } bool HStateVariablesSetupData::setInclusionRequirement( const QString& name, HInclusionRequirement incReq) { if (m_setupData.contains(name)) { HStateVariableInfo setupInfo = m_setupData.value(name); setupInfo.setInclusionRequirement(incReq); m_setupData.insert(name, setupInfo); return true; } return false; } HStateVariableInfo HStateVariablesSetupData::get( const QString& stateVarName) const { return m_setupData.value(stateVarName); } bool HStateVariablesSetupData::contains(const QString& name) const { return m_setupData.contains(name); } QSet HStateVariablesSetupData::names() const { return m_setupData.keys().toSet(); } qint32 HStateVariablesSetupData::size() const { return m_setupData.size(); } bool HStateVariablesSetupData::isEmpty() const { return m_setupData.isEmpty(); } } } herqq-1.0.0/hupnp/src/devicemodel/hdevicemodel_infoprovider.h0000644000000000000000000001177611543637310023135 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDEVICEMODEL_INFOPROVIDER_H_ #define HDEVICEMODEL_INFOPROVIDER_H_ #include namespace Herqq { namespace Upnp { class HDeviceModelInfoProviderPrivate; /*! * A protocol class for providing information that is used to validate * components of UPnP's device architecture and to setup components of * HUPnP's device model. * * The main purpose of this class is to define an interface that enables the * users to provide information that HUPnP can use for verification and * validation purposes. Although optional, this information can be especially * useful when provided to HDeviceHost via HDeviceHostConfiguration. This enables * HUPnP to use the information to verify that device and service descriptions * are setup according to the specified information. * * The benefit of this is that your custom device model components can rest * assured that all the required state variables, actions, services and * embedded devices are properly defined and initialized before the instantiation * of the HUPnP's device model (device tree) is published for control points to use. * * The benefits of this may be somewhat difficult to realize at first, since most * of the time it is you, the user, who provides the implementation and * the description documents. Apart from inadvertent mistakes, you usually * get those right. However, when someone else provides the implementation of * the HUPnP's device model or the description documents, mismatches can easily * occur and this is where the benefits of this additional information are truly * useful. Remember, in UPnP architecture the description documents are used to * marshal device model information from servers to clients. If the description * documents do not accurately reflect the server-side implementation, the * client-side may not be able to correctly invoke the server-side. * * \headerfile hdevicemodel_infoprovider.h HDeviceModelInfoProvider * * \ingroup hupnp_devicemodel * * \sa hupnp_devicehosting, HDeviceHostConfiguration */ class H_UPNP_CORE_EXPORT HDeviceModelInfoProvider : public HClonable { H_DISABLE_COPY(HDeviceModelInfoProvider) public: /*! * \brief Creates a new instance. */ HDeviceModelInfoProvider(); /*! * \brief Destroys the instance. */ virtual ~HDeviceModelInfoProvider() = 0; /*! * \brief Returns information of the services the specified device type may contain. * * \param info specifies the device type. * * \return information of the services the specified device type may contain. */ virtual HServicesSetupData servicesSetupData(const HDeviceInfo& info) const; /*! * \brief Returns information of the embedded devices the specified device type may contain. * * \param info specifies the device type. * * \return information of the embedded devices the specified device type may contain. */ virtual HDevicesSetupData embedddedDevicesSetupData( const HDeviceInfo& info) const; /*! * \brief Returns information of the actions the specified service type may contain. * * \param serviceInfo specifies the service type. * * \param parentDeviceInfo specifies information about the parent UPnP device * that contains this service. * * \return information of the actions the specified service type may contain. */ virtual HActionsSetupData actionsSetupData( const HServiceInfo& serviceInfo, const HDeviceInfo& parentDeviceInfo) const; /*! * \brief Returns information of the state variables the specified service type * may contain. * * \param serviceInfo specifies the service type. * * \param parentDeviceInfo specifies information about the parent UPnP device * that contains this service. * * \return information of the state variables the specified service type * may contain. */ virtual HStateVariablesSetupData stateVariablesSetupData( const HServiceInfo& serviceInfo, const HDeviceInfo& parentDeviceInfo) const; // // Documented in HClonable virtual HDeviceModelInfoProvider* clone() const; }; } } #endif /* HDEVICEMODEL_INFOPROVIDER_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hstatevariable_p.h0000644000000000000000000000422311543637310021221 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSTATEVARIABLE_P_H_ #define HSTATEVARIABLE_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../dataelements/hstatevariableinfo.h" #include #include #include namespace Herqq { namespace Upnp { // // Implementation details of HStateVariable // class HStateVariablePrivate { H_DISABLE_COPY(HStateVariablePrivate) public: HStateVariableInfo m_info; QVariant m_value; public: HStateVariablePrivate() : m_info(), m_value() {} ~HStateVariablePrivate(){} bool setValue(const QVariant& value, QString* err) { if (value == m_value) { if (err) { *err = QString("The new and the old value are equal: [%1]").arg( value.toString()); } return false; } QVariant convertedValue; if (m_info.isValidValue(value, &convertedValue, err)) { m_value = convertedValue; return true; } return false; } }; } } #endif /* UPNP_ACTION_P_H_ */ herqq-1.0.0/hupnp/src/devicemodel/hactions_setupdata.cpp0000644000000000000000000001234211543637310022122 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hactions_setupdata.h" #include "hactionarguments.h" #include "../general/hupnp_global_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HActionSetupPrivate ******************************************************************************/ class HActionSetupPrivate : public QSharedData { public: QString m_name; int m_version; HInclusionRequirement m_inclusionRequirement; HActionArguments m_inputArgs; HActionArguments m_outputArgs; HActionSetupPrivate() : m_name(), m_version(0), m_inclusionRequirement(InclusionRequirementUnknown), m_inputArgs(), m_outputArgs() { } }; /******************************************************************************* * HActionSetup ******************************************************************************/ HActionSetup::HActionSetup() : h_ptr(new HActionSetupPrivate()) { } HActionSetup::HActionSetup(const QString& name, HInclusionRequirement ireq) : h_ptr(new HActionSetupPrivate()) { setName(name); h_ptr->m_version = 1; h_ptr->m_inclusionRequirement = ireq; } HActionSetup::HActionSetup( const QString& name, int version, HInclusionRequirement ireq) : h_ptr(new HActionSetupPrivate()) { setName(name); h_ptr->m_version = version; h_ptr->m_inclusionRequirement = ireq; } HActionSetup::~HActionSetup() { } HActionSetup::HActionSetup(const HActionSetup& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HActionSetup& HActionSetup::operator=(const HActionSetup& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } const HActionArguments& HActionSetup::inputArguments() const { return h_ptr->m_inputArgs; } const HActionArguments& HActionSetup::outputArguments() const { return h_ptr->m_outputArgs; } HInclusionRequirement HActionSetup::inclusionRequirement() const { return h_ptr->m_inclusionRequirement; } bool HActionSetup::isValid() const { return !h_ptr->m_name.isEmpty() && h_ptr->m_version > 0 && h_ptr->m_inclusionRequirement != InclusionRequirementUnknown; } QString HActionSetup::name() const { return h_ptr->m_name; } int HActionSetup::version() const { return h_ptr->m_version; } void HActionSetup::setInputArguments(const HActionArguments& args) { h_ptr->m_inputArgs = args; } void HActionSetup::setOutputArguments(const HActionArguments& args) { h_ptr->m_outputArgs = args; } void HActionSetup::setInclusionRequirement(HInclusionRequirement arg) { h_ptr->m_inclusionRequirement = arg; } void HActionSetup::setVersion(int version) { h_ptr->m_version = version; } bool HActionSetup::setName(const QString& name, QString* err) { if (verifyName(name, err)) { h_ptr->m_name = name; return true; } return false; } /******************************************************************************* * HActionsSetupData ******************************************************************************/ HActionsSetupData::HActionsSetupData() : m_actionSetupInfos() { } bool HActionsSetupData::insert(const HActionSetup& setupInfo) { if (m_actionSetupInfos.contains(setupInfo.name()) || !setupInfo.isValid()) { return false; } m_actionSetupInfos.insert(setupInfo.name(), setupInfo); return true; } bool HActionsSetupData::remove(const QString& actionName) { if (m_actionSetupInfos.contains(actionName)) { m_actionSetupInfos.remove(actionName); return true; } return false; } HActionSetup HActionsSetupData::get(const QString& actionName) const { return m_actionSetupInfos.value(actionName); } bool HActionsSetupData::setInclusionRequirement( const QString& actionName, HInclusionRequirement incReq) { if (m_actionSetupInfos.contains(actionName)) { HActionSetup setupInfo = m_actionSetupInfos.value(actionName); setupInfo.setInclusionRequirement(incReq); m_actionSetupInfos.insert(actionName, setupInfo); return true; } return false; } QSet HActionsSetupData::names() const { return m_actionSetupInfos.keys().toSet(); } } } herqq-1.0.0/hupnp/src/http/0000755000000000000000000000000011543637460014237 5ustar rootrootherqq-1.0.0/hupnp/src/http/hhttp_utils_p.cpp0000644000000000000000000000375611543637310017636 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hhttp_utils_p.h" #include #include #include #include namespace Herqq { namespace Upnp { QString HHttpUtils::callbackAsStr(const QList& callbacks) { QString retVal; foreach(const QUrl& cb, callbacks) { retVal.append(QString("<%1>").arg(cb.toString())); } return retVal; } bool HHttpUtils::readLines( QTcpSocket& socket, QByteArray& target, qint32 lineCount) { char readChar = 0; qint32 linesRead = 0; while(linesRead < lineCount && socket.getChar(&readChar)) { target.push_back(readChar); if (readChar != '\r') { if (linesRead > 0) { linesRead = 0; } continue; } if (socket.getChar(&readChar)) { target.push_back(readChar); if (readChar == '\n') { ++linesRead; } else if (linesRead > 0) { linesRead = 0; } } } return linesRead >= lineCount; } } } herqq-1.0.0/hupnp/src/http/hhttp_p.h0000644000000000000000000000310111543637310016043 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HHTTP_P_H_ #define HHTTP_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // namespace Herqq { namespace Upnp { enum ContentType { Undefined, // "text/xml; charset=\"utf-8\"" TextXml, // "application/octet-stream" OctetStream }; enum StatusCode { Ok, BadRequest, // UDA IncompatibleHeaderFields, // Unauthorized, Forbidden, NotFound, MethotNotAllowed, PreconditionFailed, InternalServerError, ServiceUnavailable }; } } #endif /* HHTTP_P_H_ */ herqq-1.0.0/hupnp/src/http/hhttp_messagecreator_p.cpp0000644000000000000000000003124111543637310021470 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hhttp_messagecreator_p.h" #include "hhttp_messaginginfo_p.h" #include "hhttp_header_p.h" #include "hhttp_utils_p.h" #include "../dataelements/hactioninfo.h" #include "../general/hlogger_p.h" #include "../general/hupnp_global_p.h" #include namespace Herqq { namespace Upnp { HHttpMessageCreator::HHttpMessageCreator() { } HHttpMessageCreator::~HHttpMessageCreator() { } QByteArray HHttpMessageCreator::setupData( HHttpHeader& hdr, const HMessagingInfo& mi) { return setupData(hdr, QByteArray(), mi); } QByteArray HHttpMessageCreator::setupData( HHttpHeader& reqHdr, const QByteArray& body, const HMessagingInfo& mi, ContentType ct) { HLOG(H_AT, H_FUN); Q_ASSERT(reqHdr.isValid()); reqHdr.setValue( "DATE", QDateTime::currentDateTime().toString(HHttpUtils::rfc1123DateFormat())); switch(ct) { case TextXml: reqHdr.setContentType("text/xml; charset=\"utf-8\""); break; case OctetStream: reqHdr.setContentType("application/octet-stream"); break; default: ; } if (!mi.keepAlive() && reqHdr.minorVersion() == 1) { reqHdr.setValue("Connection", "close"); } reqHdr.setValue("HOST", mi.hostInfo()); bool chunked = false; if (mi.chunkedInfo().max() > 0 && body.size() > mi.chunkedInfo().max()) { chunked = true; reqHdr.setValue("Transfer-Encoding", "chunked"); } else { reqHdr.setContentLength(body.size()); } QByteArray msg(reqHdr.toString().toUtf8()); msg.append(body); return msg; } QByteArray HHttpMessageCreator::createResponse( StatusCode sc, const HMessagingInfo& mi, const QByteArray& body, ContentType ct) { qint32 statusCode = 0; QString reasonPhrase = ""; switch(sc) { case Ok: statusCode = 200; reasonPhrase = "OK"; break; case BadRequest: statusCode = 400; reasonPhrase = "Bad Request"; break; case IncompatibleHeaderFields: statusCode = 400; reasonPhrase = "Incompatible header fields"; break; case Unauthorized: statusCode = 401; reasonPhrase = "Unauthorized"; break; case Forbidden: statusCode = 403; reasonPhrase = "Forbidden"; break; case NotFound: statusCode = 404; reasonPhrase = "Not Found"; break; case MethotNotAllowed: statusCode = 405; reasonPhrase = "Method Not Allowed"; break; case PreconditionFailed: statusCode = 412; reasonPhrase = "Precondition Failed"; break; case InternalServerError: statusCode = 500; reasonPhrase = "Internal Server Error"; break; case ServiceUnavailable: statusCode = 503; reasonPhrase = "Service Unavailable"; break; default: Q_ASSERT(false); } HHttpResponseHeader responseHdr(statusCode, reasonPhrase); return setupData(responseHdr, body, mi, ct); } namespace { void checkForActionError( qint32 actionRetVal, QtSoapMessage::FaultCode* soapFault, qint32* httpStatusCode, QString* httpReasonPhrase) { HLOG(H_AT, H_FUN); Q_ASSERT(httpStatusCode); Q_ASSERT(httpReasonPhrase); Q_ASSERT(soapFault); if (actionRetVal == UpnpInvalidArgs) { *httpStatusCode = 402; *httpReasonPhrase = "Invalid Args"; *soapFault = QtSoapMessage::Client; } else if (actionRetVal == UpnpActionFailed) { *httpStatusCode = 501; *httpReasonPhrase = "Action Failed"; *soapFault = QtSoapMessage::Client; } else if (actionRetVal == UpnpArgumentValueInvalid) { *httpStatusCode = 600; *httpReasonPhrase = "Argument Value Invalid"; *soapFault = QtSoapMessage::Client; } else if (actionRetVal == UpnpArgumentValueOutOfRange) { *httpStatusCode = 601; *httpReasonPhrase = "Argument Value Out of Range"; *soapFault = QtSoapMessage::Client; } else if (actionRetVal == UpnpOptionalActionNotImplemented) { *httpStatusCode = 602; *httpReasonPhrase = "Optional Action Not Implemented"; *soapFault = QtSoapMessage::Client; } else if (actionRetVal == UpnpOutOfMemory) { *httpStatusCode = 603; *httpReasonPhrase = "Out of Memory"; *soapFault = QtSoapMessage::Client; } else if (actionRetVal == UpnpHumanInterventionRequired) { *httpStatusCode = 604; *httpReasonPhrase = "Human Intervention Required"; *soapFault = QtSoapMessage::Client; } else if (actionRetVal == UpnpStringArgumentTooLong) { *httpStatusCode = 605; *httpReasonPhrase = "String Argument Too Long"; *soapFault = QtSoapMessage::Client; } else { *httpStatusCode = actionRetVal; *httpReasonPhrase = QString::number(actionRetVal); *soapFault = QtSoapMessage::Client; } } } QByteArray HHttpMessageCreator::setupData( const HMessagingInfo& mi, qint32 statusCode, const QString& reasonPhrase, const QString& body, ContentType ct) { HHttpResponseHeader responseHdr(statusCode, reasonPhrase); return setupData(responseHdr, body.toUtf8(), mi, ct); } QByteArray HHttpMessageCreator::createResponse( const HMessagingInfo& mi, qint32 actionErrCode, const QString& description) { QtSoapMessage::FaultCode soapFault; qint32 httpStatusCode; QString httpReasonPhrase; checkForActionError( actionErrCode, &soapFault, &httpStatusCode, &httpReasonPhrase); QtSoapMessage soapFaultResponse; soapFaultResponse.setFaultCode(soapFault); soapFaultResponse.setFaultString("UPnPError"); QtSoapStruct* detail = new QtSoapStruct(QtSoapQName("UPnPError")); detail->insert(new QtSoapSimpleType(QtSoapQName("errorCode"), actionErrCode)); detail->insert(new QtSoapSimpleType(QtSoapQName("errorDescription"), description)); soapFaultResponse.addFaultDetail(detail); return setupData( mi, httpStatusCode, httpReasonPhrase, soapFaultResponse.toXmlString()); } QByteArray HHttpMessageCreator::create( const HNotifyRequest& req, HMessagingInfo* mi) { Q_ASSERT(req.isValid(true)); HHttpRequestHeader reqHdr; reqHdr.setContentType("Content-type: text/xml; charset=\"utf-8\""); reqHdr.setRequest( "NOTIFY", extractRequestPart(req.callback().toString())); mi->setHostInfo(req.callback()); reqHdr.setValue("SID", req.sid().toString()); reqHdr.setValue("SEQ", QString::number(req.seq())); reqHdr.setValue("NT" , "upnp:event"); reqHdr.setValue("NTS", "upnp:propchange"); return setupData(reqHdr, req.data(), *mi); } QByteArray HHttpMessageCreator::create( const HSubscribeRequest& req, const HMessagingInfo& mi) { Q_ASSERT(req.isValid(false)); HHttpRequestHeader requestHdr( "SUBSCRIBE", extractRequestPart(req.eventUrl())); requestHdr.setValue("TIMEOUT", req.timeout().toString()); if (!req.isRenewal()) { if (req.hasUserAgent()) { requestHdr.setValue("USER-AGENT", req.userAgent().toString()); } requestHdr.setValue("CALLBACK", HHttpUtils::callbackAsStr(req.callbacks())); requestHdr.setValue("NT", req.nt().typeToString()); } else { requestHdr.setValue("SID", req.sid().toString()); } return setupData(requestHdr, mi); } QByteArray HHttpMessageCreator::create( const HUnsubscribeRequest& req, HMessagingInfo* mi) { Q_ASSERT(req.isValid(false)); HHttpRequestHeader requestHdr( "UNSUBSCRIBE", extractRequestPart(req.eventUrl())); mi->setHostInfo(req.eventUrl()); requestHdr.setValue("SID", req.sid().toString()); return setupData(requestHdr, *mi); } QByteArray HHttpMessageCreator::create( const HSubscribeResponse& response, const HMessagingInfo& mi) { Q_ASSERT(response.isValid(true)); HHttpResponseHeader responseHdr(200, "OK"); responseHdr.setContentLength(0); responseHdr.setValue("SID" , response.sid().toString()); responseHdr.setValue("TIMEOUT", response.timeout().toString()); responseHdr.setValue("SERVER" , response.server().toString()); return setupData(responseHdr, mi); } HNotifyRequest::RetVal HHttpMessageCreator::create( const HHttpRequestHeader& reqHdr, const QByteArray& body, HNotifyRequest& req) { HLOG(H_AT, H_FUN); QString nt = reqHdr.value("NT" ); QString nts = reqHdr.value("NTS"); QString sid = reqHdr.value("SID"); QString seqStr = reqHdr.value("SEQ"); QString host = reqHdr.value("HOST").trimmed(); QString deliveryPath = reqHdr.path().trimmed(); if (!deliveryPath.startsWith('/')) { deliveryPath.insert(0, '/'); } QUrl callbackUrl(QString("http://%1%2").arg(host, deliveryPath)); HNotifyRequest nreq; HNotifyRequest::RetVal retVal = nreq.setContents(callbackUrl, nt, nts, sid, seqStr, body); switch(retVal) { case HNotifyRequest::Success: break; case HNotifyRequest::PreConditionFailed: break; case HNotifyRequest::InvalidContents: case HNotifyRequest::InvalidSequenceNr: break; default: Q_ASSERT(false); retVal = HNotifyRequest::BadRequest; } req = nreq; return retVal; } HSubscribeRequest::RetVal HHttpMessageCreator::create( const HHttpRequestHeader& reqHdr, HSubscribeRequest& req) { HLOG(H_AT, H_FUN); QString nt = reqHdr.value("NT"); QString callback = reqHdr.value("CALLBACK").trimmed(); QString timeoutStr = reqHdr.value("TIMEOUT"); QString sid = reqHdr.value("SID"); QString userAgent = reqHdr.value("USER-AGENT"); QString host = reqHdr.value("HOST"); QUrl servicePath = reqHdr.path().trimmed(); HSubscribeRequest sreq; HSubscribeRequest::RetVal retVal = sreq.setContents( nt, appendUrls("http://"+host, servicePath), sid, callback, timeoutStr, userAgent); switch(retVal) { case HSubscribeRequest::Success: break; case HSubscribeRequest::PreConditionFailed: break; case HSubscribeRequest::IncompatibleHeaders: break; case HSubscribeRequest::BadRequest: break; default: Q_ASSERT(false); retVal = HSubscribeRequest::BadRequest; } req = sreq; return retVal; } HUnsubscribeRequest::RetVal HHttpMessageCreator::create( const HHttpRequestHeader& reqHdr, HUnsubscribeRequest& req) { HLOG(H_AT, H_FUN); QString sid = reqHdr.value("SID"); QUrl callback = reqHdr.value("CALLBACK").trimmed(); QString hostStr = reqHdr.value("HOST").trimmed(); if (!callback.isEmpty()) { return HUnsubscribeRequest::IncompatibleHeaders; } HUnsubscribeRequest usreq; HUnsubscribeRequest::RetVal retVal = usreq.setContents( appendUrls("http://"+hostStr, reqHdr.path().trimmed()), sid); switch(retVal) { case HUnsubscribeRequest::Success: break; case HUnsubscribeRequest::PreConditionFailed: break; default: Q_ASSERT(false); retVal = HUnsubscribeRequest::BadRequest; } req = usreq; return retVal; } bool HHttpMessageCreator::create( const HHttpResponseHeader& respHdr, HSubscribeResponse& resp) { HLOG(H_AT, H_FUN); if (!respHdr.isValid() || respHdr.statusCode() != 200) { return false; } HSid sid = HSid(respHdr.value("SID")); HTimeout timeout = HTimeout(respHdr.value("TIMEOUT")); QString server = respHdr.value("SERVER"); QDateTime date = QDateTime::fromString(respHdr.value("DATE"), HHttpUtils::rfc1123DateFormat()); resp = HSubscribeResponse(sid, HProductTokens(server), timeout, date); return resp.isValid(false); } } } herqq-1.0.0/hupnp/src/http/hhttp_asynchandler_p.cpp0000644000000000000000000004662511543637310021153 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hhttp_asynchandler_p.h" #include "hhttp_messagecreator_p.h" #include "hhttp_utils_p.h" #include "../general/hupnp_global_p.h" #include #include namespace Herqq { namespace Upnp { HHttpAsyncOperation::HHttpAsyncOperation( const QByteArray& loggingIdentifier, unsigned int id, HMessagingInfo* mi, bool waitingRequest, QObject* parent) : QObject(parent), m_mi(mi), m_dataToSend(), m_dataSend(0), m_dataSent(0), m_state(Internal_NotStarted), m_headerRead(0), m_dataRead(), m_dataToRead(0), m_id(id), m_loggingIdentifier(loggingIdentifier), m_opType(waitingRequest ? ReceiveRequest : ReceiveResponse) { bool ok = connect( &m_mi->socket(), SIGNAL(readyRead()), this, SLOT(readyRead())); Q_ASSERT(ok); Q_UNUSED(ok) ok = connect( &m_mi->socket(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); Q_ASSERT(ok); } HHttpAsyncOperation::HHttpAsyncOperation( const QByteArray& loggingIdentifier, unsigned int id, HMessagingInfo* mi, const QByteArray& data, bool sendOnly, QObject* parent) : QObject(parent), m_mi(mi), m_dataToSend(data), m_dataSend(0), m_dataSent(0), m_state(Internal_NotStarted), m_headerRead(0), m_dataRead(), m_dataToRead(0), m_id(id), m_loggingIdentifier(loggingIdentifier), m_opType(sendOnly ? SendOnly : MsgIO) { bool ok = connect( &m_mi->socket(), SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWritten(qint64))); Q_ASSERT(ok); Q_UNUSED(ok) ok = connect( &m_mi->socket(), SIGNAL(readyRead()), this, SLOT(readyRead())); Q_ASSERT(ok); ok = connect( &m_mi->socket(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); Q_ASSERT(ok); } HHttpAsyncOperation::~HHttpAsyncOperation() { delete m_mi; delete m_headerRead; } void HHttpAsyncOperation::sendChunked() { static const char crlf[] = {"\r\n"}; // then start sending the data in chunks qint64 bytesWritten = 0; if (m_dataSent < m_dataToSend.size()) { qint32 dataToSendSize = m_dataSend > 0 ? m_dataSend : qMin(m_dataToSend.size() - m_dataSent, static_cast(m_mi->chunkedInfo().max())); if (m_state == Internal_WritingChunkedSizeLine) { // write the size line of the next chunk QByteArray sizeLine; sizeLine.setNum(dataToSendSize, 16); sizeLine.append(crlf, 2); bytesWritten = m_mi->socket().write(sizeLine); if (bytesWritten != sizeLine.size()) { m_mi->setLastErrorDescription("failed to send chunked data"); done_(Internal_Failed); return; } m_state = Internal_WritingChunk; } // write the chunk bytesWritten = m_mi->socket().write(m_dataToSend.data() + m_dataSent, dataToSendSize); if (bytesWritten < 0) { m_mi->setLastErrorDescription("failed to send chunked data"); done_(Internal_Failed); return; } m_dataSent += bytesWritten; if (bytesWritten != dataToSendSize) { m_dataSend = dataToSendSize - bytesWritten; // wait for bytesWritten() and then attempt to send the data remaining // in the chunk return; } else { m_dataSend = 0; } // and after the chunk, write the trailing crlf and start again if there's // chunks left bytesWritten = m_mi->socket().write(crlf, 2); if (bytesWritten != 2) { m_mi->setLastErrorDescription("failed to send chunked data"); done_(Internal_Failed); return; } m_state = Internal_WritingChunkedSizeLine; } if (m_dataSent >= m_dataToSend.size()) { // write the "eof" == zero + crlf const char eof[] = "0\r\n"; m_mi->socket().write(&eof[0], 3); m_mi->socket().flush(); if (m_opType == SendOnly) { done_(Internal_FinishedSuccessfully); return; } m_state = Internal_ReadingHeader; } } void HHttpAsyncOperation::readBlob() { QByteArray buf; buf.resize(m_dataToRead+1); do { qint64 retVal = m_mi->socket().read( buf.data(), qMin(static_cast(buf.size()), m_dataToRead)); if (retVal < 0) { m_mi->setLastErrorDescription( QString("failed to read data: %1").arg( m_mi->socket().errorString())); done_(Internal_Failed); return; } else if (retVal > 0) { m_dataToRead -= retVal; m_dataRead.append(QByteArray(buf.data(), retVal)); } else { break; } } while(m_dataToRead > 0); if (m_dataToRead <= 0) { done_(Internal_FinishedSuccessfully); } } bool HHttpAsyncOperation::readChunkedSizeLine() { if (m_mi->socket().bytesAvailable() <= 0) { return false; } QByteArray buf; if (!HHttpUtils::readLines(m_mi->socket(), buf, 1)) { // No size line. It should be available at this point. m_mi->setLastErrorDescription("missing chunk-size line"); done_(Internal_Failed); return false; } qint32 endOfSize = buf.indexOf(';'); if (endOfSize < 0) { // no extensions endOfSize = buf.size() - 2; // 2 == crlf } QByteArray sizeLine = buf.left(endOfSize); bool ok = false; qint32 chunkSize = sizeLine.toInt(&ok, 16); if (!ok || chunkSize < 0) { m_mi->setLastErrorDescription( QString("invalid chunk-size line: %1").arg( QString::fromUtf8(sizeLine))); done_(Internal_Failed); return false; } if (chunkSize == 0) { // the last chunk, ignore possible trailers done_(Internal_FinishedSuccessfully); return false; } m_dataToRead = chunkSize; m_state = Internal_ReadingChunk; return true; } bool HHttpAsyncOperation::readChunk() { QByteArray tmp; tmp.resize(m_dataToRead); qint32 read = m_mi->socket().read(tmp.data(), tmp.size()); if (read < 0) { m_mi->setLastErrorDescription(QString( "failed to read chunk: %1").arg(m_mi->socket().errorString())); done_(Internal_Failed); return false; } else if (read == 0) { // couldn't read the entire chunk in one pass return false; } tmp.resize(read); m_dataRead.append(tmp); m_dataToRead -= read; if (m_dataToRead > 0) { // couldn't read the entire chunk in one pass return false; } // if here, the entire chunk data is read. // clear the remaining crlf and move to the next chunk char c; m_mi->socket().getChar(&c); m_mi->socket().getChar(&c); m_state = Internal_ReadingChunkSizeLine; return true; } bool HHttpAsyncOperation::readHeader() { if (!HHttpUtils::readLines(m_mi->socket(), m_dataRead, 2)) { m_mi->setLastErrorDescription(QString( "failed to read HTTP header: %1").arg(m_mi->socket().errorString())); done_(Internal_Failed); return false; } if (m_opType == ReceiveRequest) { m_headerRead = new HHttpRequestHeader(QString::fromUtf8(m_dataRead)); } else { m_headerRead = new HHttpResponseHeader(QString::fromUtf8(m_dataRead)); } m_dataRead.clear(); if (!m_headerRead->isValid()) { m_mi->setLastErrorDescription("read invalid HTTP header"); done_(Internal_Failed); return false; } m_mi->setKeepAlive(HHttpUtils::keepAlive(*m_headerRead)); if (m_headerRead->hasContentLength()) { m_dataToRead = m_headerRead->contentLength(); if (m_dataToRead == 0) { done_(Internal_FinishedSuccessfully); return false; } } else if (m_headerRead->value("TRANSFER-ENCODING") != "chunked") { done_(Internal_FinishedSuccessfully); return false; } m_state = Internal_ReadingData; return true; } bool HHttpAsyncOperation::readData() { if (!m_mi->socket().bytesAvailable()) { return false; } bool chunked = m_headerRead->value("TRANSFER-ENCODING") == "chunked"; if (chunked) { if (m_headerRead->hasContentLength()) { m_mi->setLastErrorDescription("read invalid HTTP header where both " "TRANSFER-ENCODING and CONTENT-LENGTH where defined"); done_(Internal_Failed); return false; } m_state = Internal_ReadingChunkSizeLine; } else { if (m_headerRead->hasContentLength()) { readBlob(); } else { // not chunked and content length is not specified ==> // no way to know what to expect ==> read all that is available QByteArray body = m_mi->socket().readAll(); m_dataRead.append(body); done_(Internal_FinishedSuccessfully); return false; } } return true; } bool HHttpAsyncOperation::run() { if (m_dataToSend.isEmpty()) { m_mi->setLastErrorDescription("no data to send"); m_state = Internal_ReadingHeader; return true; } if (m_mi->socket().state() != QTcpSocket::ConnectedState) { m_mi->setLastErrorDescription("socket is not connected"); return false; } qint32 indexOfData = m_dataToSend.indexOf("\r\n\r\n"); Q_ASSERT(indexOfData > 0); if (m_mi->chunkedInfo().max() > 0 && m_dataToSend.size() - indexOfData > m_mi->chunkedInfo().max()) { // send the http header first (it is expected that the header has been // properly setup for chunked transfer, as it should be, since this is // private stuff not influenced by public input) qint32 endOfHdr = m_dataToSend.indexOf("\r\n\r\n") + 4; m_dataSent = m_mi->socket().write(m_dataToSend.data(), endOfHdr); if (m_dataSent != endOfHdr) { m_mi->setLastErrorDescription(QString( "failed to send HTTP header %1").arg( m_mi->socket().errorString())); done_(Internal_Failed, false); return false; } m_state = Internal_WritingChunkedSizeLine; sendChunked(); } else { m_dataSent = m_mi->socket().write(m_dataToSend); if (m_dataSent < 0) { m_mi->setLastErrorDescription( QString("failed to send data: %1").arg( m_mi->socket().errorString())); done_(Internal_Failed, false); return false; } m_state = Internal_WritingBlob; if (m_mi->sendWait() > 0) { if (m_mi->socket().waitForBytesWritten(m_mi->sendWait())) { bytesWritten(-1); } else { m_mi->setLastErrorDescription(QString( "failed to send data %1").arg(m_mi->socket().errorString())); done_(Internal_Failed, false); return false; } } } return true; } void HHttpAsyncOperation::done_(InternalState state, bool emitSignal) { m_mi->socket().disconnect(this); Q_ASSERT((state == Internal_FinishedSuccessfully && (headerRead() || m_opType == SendOnly)) || state != Internal_FinishedSuccessfully); m_state = state; if (emitSignal) { emit done(m_id); } } void HHttpAsyncOperation::bytesWritten(qint64) { if (m_state == Internal_WritingBlob) { if (m_dataSent < m_dataToSend.size()) { qint64 dataSent = m_mi->socket().write( m_dataToSend.data() + m_dataSent, m_dataToSend.size() - m_dataSent); if (dataSent < 0) { m_mi->setLastErrorDescription( QString("failed to send data: %1").arg( m_mi->socket().errorString())); done_(Internal_Failed); return; } m_dataSent += dataSent; } if (m_dataSent >= m_dataToSend.size()) { if (m_opType == SendOnly) { done_(Internal_FinishedSuccessfully); } else { m_state = Internal_ReadingHeader; } } } else if (m_state == Internal_WritingChunk || m_state == Internal_WritingChunkedSizeLine) { sendChunked(); } } void HHttpAsyncOperation::readyRead() { if (m_state == Internal_ReadingHeader) { if (!readHeader()) { return; } } if (m_state == Internal_ReadingData) { if (!readData()) { return; } } for(; m_state == Internal_ReadingChunkSizeLine || m_state == Internal_ReadingChunk;) { // the request contained chunked data if (m_state == Internal_ReadingChunkSizeLine) { if (!readChunkedSizeLine()) { // no more data available at the moment return; } } if (m_state == Internal_ReadingChunk) { if (!readChunk()) { // no more data available at the moment return; } } } } void HHttpAsyncOperation::error(QAbstractSocket::SocketError err) { if (err != QAbstractSocket::RemoteHostClosedError) { done_(Internal_Failed); return; } else if (m_state >= Internal_Failed && m_state < Internal_ReadingHeader) { done_(Internal_Failed); return; } else if (m_dataToRead > 0) { m_mi->setLastErrorDescription( "remote host closed connection before all data could be read"); done_(Internal_Failed); return; } else if (m_state == Internal_ReadingHeader) { if (m_dataRead.size() <= 0) { m_mi->setLastErrorDescription("failed to read HTTP header"); done_(Internal_Failed); return; } if (m_opType == ReceiveRequest) { m_headerRead = new HHttpRequestHeader(QString::fromUtf8(m_dataRead)); } else { m_headerRead = new HHttpResponseHeader(QString::fromUtf8(m_dataRead)); } if (!m_headerRead->isValid()) { m_mi->setLastErrorDescription("read invalid HTTP header"); done_(Internal_Failed); return; } } // at this point a header is successfully read and possibly some data ==> // it is up to the user to check the contents of the data to determine was the // operation "really" successful done_(Internal_FinishedSuccessfully); } HHttpAsyncOperation::State HHttpAsyncOperation::state() const { switch(m_state) { case Internal_Failed: return Failed; case Internal_NotStarted: return NotStarted; case Internal_WritingBlob: case Internal_WritingChunkedSizeLine: case Internal_WritingChunk: return Writing; case Internal_ReadingHeader: case Internal_ReadingData: case Internal_ReadingChunkSizeLine: case Internal_ReadingChunk: return Reading; case Internal_FinishedSuccessfully: return Succeeded; default: Q_ASSERT(false); return Failed; } } /******************************************************************************* * HHttpAsyncHandler ******************************************************************************/ HHttpAsyncHandler::HHttpAsyncHandler( const QByteArray& loggingIdentifier, QObject* parent) : QObject(parent), m_loggingIdentifier(loggingIdentifier), m_operations(), m_lastIdUsed(0) { } HHttpAsyncHandler::~HHttpAsyncHandler() { } void HHttpAsyncHandler::done(unsigned int id) { HHttpAsyncOperation* ao = m_operations.value(id); Q_ASSERT(ao); Q_ASSERT(ao->state() != HHttpAsyncOperation::NotStarted); bool ok = ao->disconnect(this); Q_ASSERT(ok); Q_UNUSED(ok) m_operations.remove(id); emit msgIoComplete(ao); } HHttpAsyncOperation* HHttpAsyncHandler::msgIo( HMessagingInfo* mi, const QByteArray& req) { Q_ASSERT(mi); Q_ASSERT(!req.isEmpty()); HHttpAsyncOperation* ao = new HHttpAsyncOperation( m_loggingIdentifier, ++m_lastIdUsed, mi, req, false, this); bool ok = connect(ao, SIGNAL(done(unsigned int)), this, SLOT(done(unsigned int))); Q_ASSERT(ok); Q_UNUSED(ok) m_operations.insert(ao->id(), ao); if (!ao->run()) { m_operations.remove(ao->id()); delete ao; return 0; } return ao; } HHttpAsyncOperation* HHttpAsyncHandler::msgIo( HMessagingInfo* mi, HHttpRequestHeader& reqHdr, const QtSoapMessage& soapMsg) { QByteArray dataToSend = HHttpMessageCreator::setupData( reqHdr, soapMsg.toXmlString().toUtf8(), *mi, TextXml); return msgIo(mi, dataToSend); } HHttpAsyncOperation* HHttpAsyncHandler::send( HMessagingInfo* mi, const QByteArray& data) { Q_ASSERT(mi); Q_ASSERT(!data.isEmpty()); HHttpAsyncOperation* ao = new HHttpAsyncOperation( m_loggingIdentifier, ++m_lastIdUsed, mi, data, true, this); bool ok = connect(ao, SIGNAL(done(unsigned int)), this, SLOT(done(unsigned int))); Q_ASSERT(ok); Q_UNUSED(ok) m_operations.insert(ao->id(), ao); if (!ao->run()) { m_operations.remove(ao->id()); delete ao; return 0; } return ao; } HHttpAsyncOperation* HHttpAsyncHandler::receive( HMessagingInfo* mi, bool waitingRequest) { Q_ASSERT(mi); HHttpAsyncOperation* ao = new HHttpAsyncOperation( m_loggingIdentifier, ++m_lastIdUsed, mi, waitingRequest, this); bool ok = connect(ao, SIGNAL(done(unsigned int)), this, SLOT(done(unsigned int))); Q_ASSERT(ok); Q_UNUSED(ok) m_operations.insert(ao->id(), ao); if (!ao->run()) { m_operations.remove(ao->id()); delete ao; return 0; } return ao; } } } herqq-1.0.0/hupnp/src/http/hhttp_messagecreator_p.h0000644000000000000000000000604711543637310021143 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HHTTP_MESSAGECREATOR_H_ #define HHTTP_MESSAGECREATOR_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hhttp_p.h" #include "../devicehosting/messages/hevent_messages_p.h" class QString; class QByteArray; namespace Herqq { namespace Upnp { class HHttpHeader; class HMessagingInfo; class HHttpRequestHeader; class HHttpResponseHeader; // // // class H_UPNP_CORE_EXPORT HHttpMessageCreator { H_FORCE_SINGLETON(HHttpMessageCreator) private: static QByteArray setupData( const HMessagingInfo&, qint32 statusCode, const QString& reasonPhrase, const QString& body, ContentType ct = Undefined); public: static QByteArray setupData(HHttpHeader& hdr, const HMessagingInfo&); static QByteArray setupData( HHttpHeader& hdr, const QByteArray& body, const HMessagingInfo&, ContentType = Undefined); inline static QByteArray createResponse( StatusCode sc, const HMessagingInfo& mi) { return createResponse(sc, mi, QByteArray()); } static QByteArray createResponse( StatusCode, const HMessagingInfo&, const QByteArray& body, ContentType = Undefined); static QByteArray createResponse( const HMessagingInfo&, qint32 actionErrCode, const QString& msg=""); static QByteArray create(const HNotifyRequest& , HMessagingInfo*); static QByteArray create(const HSubscribeRequest& , const HMessagingInfo&); static QByteArray create(const HUnsubscribeRequest&, HMessagingInfo*); static QByteArray create(const HSubscribeResponse& , const HMessagingInfo&); static HNotifyRequest::RetVal create( const HHttpRequestHeader& reqHdr, const QByteArray& body, HNotifyRequest& req); static HSubscribeRequest::RetVal create( const HHttpRequestHeader& reqHdr, HSubscribeRequest& req); static HUnsubscribeRequest::RetVal create( const HHttpRequestHeader& reqHdr, HUnsubscribeRequest& req); static bool create( const HHttpResponseHeader& respHdr, HSubscribeResponse& resp); }; } } #endif /* HHTTP_MESSAGECREATOR_H_ */ herqq-1.0.0/hupnp/src/http/hhttp_server_p.h0000644000000000000000000001025711543637310017443 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HHTTP_SERVER_H_ #define HHTTP_SERVER_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_defs.h" #include "hhttp_asynchandler_p.h" #include "hhttp_messaginginfo_p.h" #include class QUrl; class QString; class QTcpSocket; namespace Herqq { namespace Upnp { class HEndpoint; class HNotifyRequest; class HSubscribeRequest; class HUnsubscribeRequest; class HInvokeActionRequest; class HHttpHeader; class HHttpRequestHeader; class HHttpResponseHeader; // // Private class for handling HTTP server duties needed in UPnP messaging // class H_UPNP_CORE_EXPORT HHttpServer : public QObject { Q_OBJECT H_DISABLE_COPY(HHttpServer) friend class Server; private: class Server : public QTcpServer { H_DISABLE_COPY(Server) private: HHttpServer* m_owner; protected: virtual void incomingConnection(qint32 socketDescriptor); public: Server(HHttpServer* owner); }; private Q_SLOTS: void msgIoComplete(HHttpAsyncOperation* op); private: QList m_servers; protected: const QByteArray m_loggingIdentifier; HHttpAsyncHandler* m_httpHandler; HChunkedInfo m_chunkedInfo; private: void processRequest(HHttpAsyncOperation*); void processResponse(HHttpAsyncOperation*); void processRequest(qint32 socketDescriptor); void processNotifyMessage( HMessagingInfo*, const HHttpRequestHeader&, const QByteArray& body); void processGet ( HMessagingInfo*, const HHttpRequestHeader&); void processHead( HMessagingInfo*, const HHttpRequestHeader&); void processPost( HMessagingInfo*, const HHttpRequestHeader&, const QByteArray& body); void processSubscription( HMessagingInfo*, const HHttpRequestHeader&); void processUnsubscription( HMessagingInfo*, const HHttpRequestHeader&); bool setupIface(const HEndpoint&); protected: virtual void incomingSubscriptionRequest( HMessagingInfo*, const HSubscribeRequest&); virtual void incomingUnsubscriptionRequest( HMessagingInfo*, const HUnsubscribeRequest&); virtual void incomingControlRequest( HMessagingInfo*, const HInvokeActionRequest&); virtual void incomingNotifyMessage( HMessagingInfo*, const HNotifyRequest&); virtual void incomingUnknownHeadRequest( HMessagingInfo*, const HHttpRequestHeader&); virtual void incomingUnknownGetRequest( HMessagingInfo*, const HHttpRequestHeader&); virtual void incomingUnknownPostRequest( HMessagingInfo*, const HHttpRequestHeader&, const QByteArray& body); virtual void incomingResponse(HHttpAsyncOperation*); virtual bool sendComplete(HHttpAsyncOperation*); public: HHttpServer( const QByteArray& loggingIdentifier, QObject* parent = 0); virtual ~HHttpServer(); QList rootUrls() const; QUrl rootUrl(const QHostAddress&) const; QList endpoints() const; inline qint32 endpointCount() const { return m_servers.size(); } bool init(); bool init(const HEndpoint&); bool init(const QList&); bool isInitialized() const; void close(); }; } } #endif /* HHTTP_SERVER_H_ */ herqq-1.0.0/hupnp/src/http/hhttp_asynchandler_p.h0000644000000000000000000001410111543637310020600 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HTTP_ASYNCHANDLER_P_H_ #define HTTP_ASYNCHANDLER_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_defs.h" #include "hhttp_p.h" #include "hhttp_header_p.h" #include "hhttp_messaginginfo_p.h" #include "../devicehosting/messages/hevent_messages_p.h" #include #include #include #include class QtSoapMessage; namespace Herqq { namespace Upnp { class HHttpAsyncHandler; // // // class HHttpAsyncOperation : public QObject { Q_OBJECT H_DISABLE_COPY(HHttpAsyncOperation) friend class HHttpAsyncHandler; public: enum OpType { MsgIO, SendOnly, ReceiveRequest, ReceiveResponse }; private: enum InternalState { Internal_Failed, Internal_NotStarted, Internal_WritingBlob, Internal_WritingChunkedSizeLine, Internal_WritingChunk, Internal_ReadingHeader, Internal_ReadingData, Internal_ReadingChunkSizeLine, Internal_ReadingChunk, Internal_FinishedSuccessfully }; HMessagingInfo* m_mi; QByteArray m_dataToSend; // the data which will be sent to the target socket qint64 m_dataSend; // used only with chunked encoding when a chunk cannot be sent in full and // the operation needs to be continued later qint64 m_dataSent; // the amount of data that has been successfully sent InternalState m_state; // the current state of this "state machine" HHttpHeader* m_headerRead; // the http reader read from the target socket // (request / response, depends of the setup) QByteArray m_dataRead; // the response data that is currently read from the target socket qint64 m_dataToRead; // the amount of data that should be available (once the operation is // successfully completed) unsigned int m_id; // id for the operation const QByteArray m_loggingIdentifier; OpType m_opType; // what the operation is supposed to do private: void sendChunked(); void readBlob(); bool readChunkedSizeLine(); bool readChunk(); // the return value of these two methods indicate if it is okay to continue // the operation. when returned false, the operation has signaled completion // and thus must be aborted immediately. bool readHeader(); bool readData(); bool run(); void done_(InternalState state, bool emitSignal = true); private Q_SLOTS: void bytesWritten(qint64); void readyRead(); void error(QAbstractSocket::SocketError); public: enum State { Failed, NotStarted, Writing, Reading, Succeeded }; HHttpAsyncOperation( const QByteArray& loggingIdentifier, unsigned int id, HMessagingInfo* mi, bool waitingRequest, QObject* parent); HHttpAsyncOperation( const QByteArray& loggingIdentifier, unsigned int id, HMessagingInfo* mi, const QByteArray& data, bool sendOnly, QObject* parent); virtual ~HHttpAsyncOperation(); State state() const; inline unsigned int id() const { return m_id; } // the data of the response inline QByteArray dataRead() const { return m_dataRead; } // the header of the response inline const HHttpHeader* headerRead() const { return m_headerRead; } inline HMessagingInfo* messagingInfo() const { return m_mi; } inline HMessagingInfo* takeMessagingInfo() { HMessagingInfo* retVal = m_mi; m_mi = 0; return retVal; } inline OpType opType() const { return m_opType; } Q_SIGNALS: void done(unsigned int); }; // // Performs async messaging utilizing the event loop. // This class is not thread-safe. // class H_UPNP_CORE_EXPORT HHttpAsyncHandler : public QObject { Q_OBJECT H_DISABLE_COPY(HHttpAsyncHandler) friend class HHttpAsyncOperation; private: const QByteArray m_loggingIdentifier; QHash m_operations; unsigned int m_lastIdUsed; private Q_SLOTS: void done(unsigned int); Q_SIGNALS: // user is expected to delete the transferred object void msgIoComplete(HHttpAsyncOperation*); public: HHttpAsyncHandler(const QByteArray& loggingIdentifier, QObject* parent); virtual ~HHttpAsyncHandler(); // // \param mi // \param data contains an entire HTTP message, including headers. // // \return an object that contains state data for the operation. // once the operation is done, user is expected to delete the object, but // NOT any sooner! HHttpAsyncOperation* msgIo(HMessagingInfo* mi, const QByteArray& data); // // Helper overload // HHttpAsyncOperation* msgIo( HMessagingInfo*, HHttpRequestHeader&, const QtSoapMessage&); // // // HHttpAsyncOperation* send(HMessagingInfo*, const QByteArray& data); // // waitingRequest == expecting to receive HHttpRequestHeader, otherwise // expecting to receive HHttpResponseHeader // HHttpAsyncOperation* receive(HMessagingInfo*, bool waitingRequest); }; } } #endif /* HTTP_ASYNCHANDLER_P_H_ */ herqq-1.0.0/hupnp/src/http/hhttp_header_p.h0000644000000000000000000001212011543637310017354 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HHTTP_HEADER_H #define HHTTP_HEADER_H // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_defs.h" #include #include #include namespace Herqq { namespace Upnp { // // The design and implementation of this class were heavily influenced by // the Qt's QHttpHeader. The main reason this class exists is that Qt // has deprecated QHttpHeader. // class H_UPNP_CORE_EXPORT HHttpHeader { private: bool parseLine(const QString&); virtual bool parseFirstLine(const QString&) = 0; protected: QList > m_values; bool m_valid; int m_majorVersion; int m_minorVersion; bool parse(const QString&); inline void addValue(const QString& key, const QString& value) { m_values.append(qMakePair(key, value)); } HHttpHeader(const HHttpHeader&); HHttpHeader& operator=(const HHttpHeader&); public: HHttpHeader(); virtual ~HHttpHeader() = 0; void setValue(const QString& key, const QString& value); bool hasKey(const QString&) const; QString value(const QString&) const; inline bool hasContentLength() const { return hasKey("content-length"); } inline uint contentLength() const { return value("content-length").toUInt(); } inline void setContentLength(int len) { setValue("content-length", QString::number(len)); } inline bool hasContentType() const { return hasKey("content-type"); } QString contentType(bool includeCharset=false) const; inline void setContentType(const QString& type) { setValue("content-type", type); } virtual QString toString() const; inline bool isValid() const { return m_valid; } inline int majorVersion() const { return m_majorVersion; } inline int minorVersion() const { return m_minorVersion; } }; // // The design and implementation of this class were heavily influenced by // the Qt's QHttpResponseHeader. The main reason this class exists is // that Qt has deprecated QHttpResponseHeader. // class H_UPNP_CORE_EXPORT HHttpResponseHeader : public HHttpHeader { private: virtual bool parseFirstLine(const QString& line); protected: int m_statusCode; QString m_reasonPhrase; public: HHttpResponseHeader(); HHttpResponseHeader(const QString &str); HHttpResponseHeader( int code, const QString& text = QString(), int majorVer = 1, int minorVer = 1); HHttpResponseHeader(const HHttpResponseHeader&); HHttpResponseHeader& operator=(const HHttpResponseHeader&); bool setStatusLine( int code, const QString& text, int majorVer = 1, int minorVer = 1); inline int statusCode() const { return m_statusCode; } inline QString reasonPhrase() const { return m_reasonPhrase; } virtual QString toString() const; }; // // The design and implementation of this class were heavily influenced by // the Qt's QHttpRequestHeader. The main reason this class exists is // that Qt has deprecated QHttpRequestHeader. // class H_UPNP_CORE_EXPORT HHttpRequestHeader : public HHttpHeader { private: virtual bool parseFirstLine(const QString&); protected: QString m_method; QString m_path; public: HHttpRequestHeader(); HHttpRequestHeader( const QString& method, const QString& path, int majorVer = 1, int minorVer = 1); HHttpRequestHeader(const QString&); HHttpRequestHeader(const HHttpRequestHeader&); HHttpRequestHeader& operator=(const HHttpRequestHeader&); bool setRequest( const QString& method, const QString& path, int majorVer = 1, int minorVer = 1); inline QString method() const { return m_method; } inline QString path() const { return m_path; } virtual QString toString() const; }; } } #endif // HHTTP_HEADER_H herqq-1.0.0/hupnp/src/http/hhttp_server_p.cpp0000644000000000000000000004157111543637310020001 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hhttp_server_p.h" #include "hhttp_utils_p.h" #include "hhttp_header_p.h" #include "hhttp_messaginginfo_p.h" #include "hhttp_messagecreator_p.h" #include "../general/hlogger_p.h" #include "../utils/hmisc_utils_p.h" #include "../socket/hendpoint.h" #include "../general/hupnp_global_p.h" #include "../devicehosting/messages/hcontrol_messages_p.h" #include "../devicehosting/messages/hevent_messages_p.h" #include #include #include #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HHttpServer::Server ******************************************************************************/ HHttpServer::Server::Server(HHttpServer* owner) : QTcpServer(owner), m_owner(owner) { } void HHttpServer::Server::incomingConnection(qint32 socketDescriptor) { m_owner->processRequest(socketDescriptor); } /******************************************************************************* * HHttpServer ******************************************************************************/ HHttpServer::HHttpServer(const QByteArray& loggingIdentifier, QObject* parent) : QObject(parent), m_servers(), m_loggingIdentifier(loggingIdentifier), m_httpHandler(new HHttpAsyncHandler(m_loggingIdentifier, this)), m_chunkedInfo() { bool ok = connect( m_httpHandler, SIGNAL(msgIoComplete(HHttpAsyncOperation*)), this, SLOT(msgIoComplete(HHttpAsyncOperation*))); Q_ASSERT(ok); Q_UNUSED(ok) } HHttpServer::~HHttpServer() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); close(); qDeleteAll(m_servers); } void HHttpServer::processRequest(HHttpAsyncOperation* op) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HMessagingInfo* mi = op->messagingInfo(); const HHttpRequestHeader* hdr = static_cast(op->headerRead()); if (!hdr->isValid()) { m_httpHandler->send( op->takeMessagingInfo(), HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } QString host = hdr->value("HOST"); if (host.isEmpty()) { m_httpHandler->send( op->takeMessagingInfo(), HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } mi->setHostInfo(host); mi->setKeepAlive(HHttpUtils::keepAlive(*hdr)); QString method = hdr->method(); if (method.compare("GET", Qt::CaseInsensitive) == 0) { processGet(op->takeMessagingInfo(), *hdr); } else if (method.compare("HEAD"), Qt::CaseInsensitive) { processHead(op->takeMessagingInfo(), *hdr); } else if (method.compare("POST", Qt::CaseInsensitive) == 0) { processPost(op->takeMessagingInfo(), *hdr, op->dataRead()); } else if (method.compare("NOTIFY", Qt::CaseInsensitive) == 0) { processNotifyMessage(op->takeMessagingInfo(), *hdr, op->dataRead()); } else if (method.compare("SUBSCRIBE", Qt::CaseInsensitive) == 0) { processSubscription(op->takeMessagingInfo(), *hdr); } else if (method.compare("UNSUBSCRIBE", Qt::CaseInsensitive) == 0) { processUnsubscription(op->takeMessagingInfo(), *hdr); } else { m_httpHandler->send( op->takeMessagingInfo(), HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } } void HHttpServer::processResponse(HHttpAsyncOperation* op) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); if (op->state() == HHttpAsyncOperation::Failed) { HLOG_DBG(QString("HTTP failure: [%1]").arg( op->messagingInfo()->lastErrorDescription())); } incomingResponse(op); } void HHttpServer::msgIoComplete(HHttpAsyncOperation* op) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); op->deleteLater(); HMessagingInfo* mi = op->messagingInfo(); if (op->state() == HHttpAsyncOperation::Failed) { HLOG_DBG(QString("HTTP failure: [%1]").arg(mi->lastErrorDescription())); return; } switch(op->opType()) { case HHttpAsyncOperation::SendOnly: if (sendComplete(op)) { if (mi->keepAlive() && mi->socket().state() == QTcpSocket::ConnectedState) { if (!m_httpHandler->receive(op->takeMessagingInfo(), true)) { HLOG_WARN(QString( "Failed to read data from: [%1]. Disconnecting.").arg( peerAsStr(mi->socket()))); } } } break; case HHttpAsyncOperation::ReceiveRequest: processRequest(op); break; case HHttpAsyncOperation::MsgIO: case HHttpAsyncOperation::ReceiveResponse: processResponse(op); break; default: Q_ASSERT(false); } } void HHttpServer::processRequest(qint32 socketDescriptor) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QTcpSocket* client = new QTcpSocket(this); client->setSocketDescriptor(socketDescriptor); QString peer = peerAsStr(*client); HLOG_DBG(QString("Incoming connection from [%1]").arg(peer)); HMessagingInfo* mi = new HMessagingInfo(qMakePair(client, true)); mi->setChunkedInfo(m_chunkedInfo); if (!m_httpHandler->receive(mi, true)) { HLOG_WARN(QString( "Failed to read data from: [%1]. Disconnecting.").arg(peer)); } } void HHttpServer::processNotifyMessage( HMessagingInfo* mi, const HHttpRequestHeader& hdr, const QByteArray& body) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HNotifyRequest nreq; HNotifyRequest::RetVal retVal = HHttpMessageCreator::create(hdr, body, nreq); switch(retVal) { case HNotifyRequest::Success: break; case HNotifyRequest::PreConditionFailed: mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(PreconditionFailed, *mi)); return; case HNotifyRequest::InvalidContents: case HNotifyRequest::InvalidSequenceNr: mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; default: retVal = HNotifyRequest::BadRequest; mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } HLOG_DBG("Dispatching event notification."); incomingNotifyMessage(mi, nreq); } void HHttpServer::processGet( HMessagingInfo* mi, const HHttpRequestHeader& requestHdr) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG("Dispatching unknown GET request."); incomingUnknownGetRequest(mi, requestHdr); } void HHttpServer::processHead( HMessagingInfo* mi, const HHttpRequestHeader& requestHdr) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_DBG("Dispatching unknown HEAD request."); incomingUnknownHeadRequest(mi, requestHdr); } void HHttpServer::processPost( HMessagingInfo* mi, const HHttpRequestHeader& requestHdr, const QByteArray& body) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QString soapAction = requestHdr.value("SOAPACTION"); if (soapAction.indexOf("#") <= 0) { HLOG_DBG("Dispatching unknown POST request."); incomingUnknownPostRequest(mi, requestHdr, body); return; } QString actionName = soapAction.mid(soapAction.indexOf("#")); if (actionName.isEmpty()) { HLOG_DBG("Dispatching unknown POST request."); incomingUnknownPostRequest(mi, requestHdr, body); return; } QtSoapMessage soapMsg; if (!soapMsg.setContent(body)) { mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } QString controlUrl = requestHdr.path().simplified(); if (controlUrl.isEmpty()) { mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } HInvokeActionRequest iareq(soapAction, soapMsg, controlUrl); HLOG_DBG("Dispatching control request."); incomingControlRequest(mi, iareq); } void HHttpServer::processSubscription( HMessagingInfo* mi, const HHttpRequestHeader& hdr) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HSubscribeRequest sreq; HSubscribeRequest::RetVal retVal = HHttpMessageCreator::create(hdr, sreq); switch(retVal) { case HSubscribeRequest::Success: break; case HSubscribeRequest::PreConditionFailed: mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(PreconditionFailed, *mi)); break; case HSubscribeRequest::IncompatibleHeaders: mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(IncompatibleHeaderFields, *mi)); return; case HSubscribeRequest::BadRequest: default: mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } HLOG_DBG("Dispatching subscription request."); incomingSubscriptionRequest(mi, sreq); } void HHttpServer::processUnsubscription( HMessagingInfo* mi, const HHttpRequestHeader& hdr) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HUnsubscribeRequest usreq; HUnsubscribeRequest::RetVal retVal = HHttpMessageCreator::create(hdr, usreq); switch(retVal) { case HUnsubscribeRequest::Success: break; case HUnsubscribeRequest::IncompatibleHeaders: mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(IncompatibleHeaderFields, *mi)); return; case HUnsubscribeRequest::PreConditionFailed: mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(PreconditionFailed, *mi)); return; default: mi->setKeepAlive(false); m_httpHandler->send( mi, HHttpMessageCreator::createResponse(BadRequest, *mi)); return; } HLOG_DBG("Dispatching unsubscription request."); incomingUnsubscriptionRequest(mi, usreq); } bool HHttpServer::setupIface(const HEndpoint& ep) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QHostAddress ha = ep.hostAddress(); if (ha == QHostAddress::Null || ha == QHostAddress::Any || ha == QHostAddress::Broadcast) { return false; } QScopedPointer server(new Server(this)); bool b = server->listen(ha, ep.portNumber()); if (b) { HLOG_INFO(QString("HTTP server bound to %1:%2").arg( server->serverAddress().toString(), QString::number(server->serverPort()))); m_servers.append(server.take()); } else { HLOG_INFO(QString("Failed to bind HTTP server to %1").arg( ep.hostAddress().toString())); } return b; } void HHttpServer::incomingSubscriptionRequest( HMessagingInfo* mi, const HSubscribeRequest&) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingSubscriptionRequest] implementation, which does nothing."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } void HHttpServer::incomingUnsubscriptionRequest( HMessagingInfo* mi, const HUnsubscribeRequest&) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingUnsubscriptionRequest] implementation, which does nothing."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } void HHttpServer::incomingControlRequest( HMessagingInfo* mi, const HInvokeActionRequest&) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingControlRequest] implementation, which does nothing."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } void HHttpServer::incomingNotifyMessage( HMessagingInfo* mi, const HNotifyRequest&) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingNotifyMessage] implementation, which does nothing."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } void HHttpServer::incomingUnknownHeadRequest( HMessagingInfo* mi, const HHttpRequestHeader&) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingUnknownHeadRequest] implementation, which does nothing."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } void HHttpServer::incomingUnknownGetRequest( HMessagingInfo* mi, const HHttpRequestHeader&) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingUnknownGetRequest] implementation, which does nothing."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } void HHttpServer::incomingUnknownPostRequest( HMessagingInfo* mi, const HHttpRequestHeader&, const QByteArray&) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingUnknownGetRequest] implementation, which does nothing."); mi->setKeepAlive(false); m_httpHandler->send(mi, HHttpMessageCreator::createResponse(MethotNotAllowed, *mi)); } void HHttpServer::incomingResponse( HHttpAsyncOperation* op) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HLOG_WARN("Calling default [incomingResponse] implementation, which does nothing."); op->messagingInfo()->setKeepAlive(false); } bool HHttpServer::sendComplete(HHttpAsyncOperation*) { return true; } QList HHttpServer::rootUrls() const { QList retVal; foreach(const Server* server, m_servers) { QUrl url(QString("http://%1:%2").arg( server->serverAddress().toString(), QString::number(server->serverPort()))); retVal.append(url); } return retVal; } QUrl HHttpServer::rootUrl(const QHostAddress& ha) const { foreach(const Server* server, m_servers) { if (ha == server->serverAddress()) { QUrl url(QString("http://%1:%2").arg( server->serverAddress().toString(), QString::number(server->serverPort()))); return url; } } return QUrl(); } QList HHttpServer::endpoints() const { QList retVal; foreach(const Server* server, m_servers) { retVal.append(HEndpoint(server->serverAddress(), server->serverPort())); } return retVal; } bool HHttpServer::init() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); if (isInitialized()) { return false; } QHostAddress ha = findBindableHostAddress(); return setupIface(HEndpoint(ha)); } bool HHttpServer::init(const HEndpoint& ep) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); if (isInitialized()) { return false; } return setupIface(ep); } bool HHttpServer::init(const QList& eps) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(thread() == QThread::currentThread()); if (isInitialized()) { return false; } bool b = false; foreach(const HEndpoint& ep, eps) { b = setupIface(ep); if (!b) { qDeleteAll(m_servers); m_servers.clear(); return false; } } return true; } bool HHttpServer::isInitialized() const { return m_servers.size(); } void HHttpServer::close() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT_X( thread() == QThread::currentThread(), H_AT, "The HTTP Server has to be shutdown in the thread in which " "it is currently located."); foreach(Server* server, m_servers) { if (server->isListening()) { server->close(); } } } } } herqq-1.0.0/hupnp/src/http/hhttp_header_p.cpp0000644000000000000000000002223711543637310017721 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hhttp_header_p.h" #include namespace { int searchKey( const QString& key, const QList >& values) { QString lowCaseKey = key.toLower(); for (int i = 0; i < values.size(); ++i) { if (values[i].first.toLower() == lowCaseKey) { return i; } } return -1; } bool parseVersion(const QString& version, int* major, int* minor) { if (version.length() >= 8 && version.left(5) == "HTTP/" && version[5].isDigit() && version[6] == '.' && version[7].isDigit()) { *major = version[5].toLatin1() - '0'; *minor = version[7].toLatin1() - '0'; return true; } return false; } } namespace Herqq { namespace Upnp { /******************************************************************************* * HHttpHeader ******************************************************************************/ HHttpHeader::HHttpHeader() : m_values(), m_valid(false), m_majorVersion(0), m_minorVersion(0) { } HHttpHeader::~HHttpHeader() { } HHttpHeader::HHttpHeader(const HHttpHeader& other) : m_values(), m_valid(false), m_majorVersion(0), m_minorVersion(0) { Q_ASSERT(this != &other); m_values = other.m_values; m_valid = other.m_valid; m_majorVersion = other.m_majorVersion; m_minorVersion = other.m_minorVersion; } HHttpHeader& HHttpHeader::operator=(const HHttpHeader& other) { Q_ASSERT(this != &other); m_majorVersion = other.m_majorVersion; m_minorVersion = other.m_minorVersion; m_valid = other.m_valid; m_values = other.m_values; return *this; } bool HHttpHeader::parse(const QString& str) { QStringList lines = str.trimmed().split("\r\n"); if (lines.isEmpty()) { return false; } parseFirstLine(lines[0]); lines.removeFirst(); foreach(const QString& line, lines) { if (line.isEmpty()) { break; } else if (!parseLine(line)) { m_valid = false; return false; } } return true; } QString HHttpHeader::value(const QString& key) const { int index = searchKey(key, m_values); return index >= 0 ? m_values[index].second : QString(); } bool HHttpHeader::hasKey(const QString& key) const { return searchKey(key, m_values) >= 0; } void HHttpHeader::setValue(const QString& key, const QString& value) { int index = searchKey(key, m_values); if (index >= 0) { m_values[index].second = value; } else { addValue(key, value); } } bool HHttpHeader::parseLine(const QString& line) { int i = line.indexOf(QLatin1Char(':')); if (i == -1) { return false; } addValue(line.left(i).trimmed(), line.mid(i + 1).trimmed()); return true; } QString HHttpHeader::toString() const { if (!isValid()) { return ""; } QString retVal; QList >::const_iterator it = m_values.constBegin(); for (; it != m_values.constEnd(); ++it) { retVal.append((*it).first) .append(": ") .append((*it).second) .append("\r\n"); } return retVal; } QString HHttpHeader::contentType(bool includeCharset) const { QString type = value("content-type"); if (type.isEmpty()) { return type; } if (includeCharset) { return type.trimmed(); } int pos = type.indexOf(';'); if (pos == -1) { return type; } return type.left(pos).trimmed(); } /******************************************************************************* * HHttpResponseHeader ******************************************************************************/ HHttpResponseHeader::HHttpResponseHeader() : HHttpHeader(), m_statusCode(0), m_reasonPhrase() { } HHttpResponseHeader::HHttpResponseHeader(const QString& str) : HHttpHeader(), m_statusCode(0), m_reasonPhrase() { if (parse(str)) { m_valid = true; } } HHttpResponseHeader::HHttpResponseHeader( int code, const QString& text, int majorVer, int minorVer) : HHttpHeader(), m_statusCode(0), m_reasonPhrase() { setStatusLine(code, text, majorVer, minorVer); } HHttpResponseHeader::HHttpResponseHeader(const HHttpResponseHeader& other) : HHttpHeader(other), m_statusCode(other.m_statusCode), m_reasonPhrase(other.m_reasonPhrase) { } HHttpResponseHeader& HHttpResponseHeader::operator=( const HHttpResponseHeader& other) { HHttpHeader::operator=(other); m_reasonPhrase = other.m_reasonPhrase; m_statusCode = other.m_statusCode; return *this; } bool HHttpResponseHeader::setStatusLine( int code, const QString& text, int majorVer, int minorVer) { if (code < 0 || text.simplified().isEmpty()) { return false; } m_statusCode = code; m_reasonPhrase = text.simplified(); m_majorVersion = majorVer; m_minorVersion = minorVer; m_valid = true; return true; } bool HHttpResponseHeader::parseFirstLine(const QString& constLine) { QString line = constLine.simplified(); if (line.length() < 10) { return false; } if (!parseVersion(line, &m_majorVersion, &m_minorVersion)) { return false; } if (line[8] == ' ' && line[9].isDigit()) { int pos = line.indexOf(' ', 9); if (pos != -1) { m_reasonPhrase = line.mid(pos + 1); m_statusCode = line.mid(9, pos - 9).toInt(); } else { m_statusCode = line.mid(9).toInt(); m_reasonPhrase.clear(); } return true; } return false; } QString HHttpResponseHeader::toString() const { if (!isValid()) { return ""; } return QString("HTTP/%1.%2 %3 %4\r\n%5\r\n").arg(m_majorVersion).arg( m_minorVersion).arg(m_statusCode).arg(m_reasonPhrase).arg( HHttpHeader::toString()); } /******************************************************************************* * HHttpRequestHeader ******************************************************************************/ HHttpRequestHeader::HHttpRequestHeader() : HHttpHeader(), m_method(), m_path() { } HHttpRequestHeader::HHttpRequestHeader( const QString& method, const QString& path, int majorVer, int minorVer) : HHttpHeader(), m_method(), m_path() { setRequest(method, path, majorVer, minorVer); } HHttpRequestHeader::HHttpRequestHeader(const QString& str) : HHttpHeader(), m_method(), m_path() { if (parse(str)) { m_valid = true; } } HHttpRequestHeader::HHttpRequestHeader(const HHttpRequestHeader& other) : HHttpHeader(other), m_method(other.m_method), m_path(other.m_path) { } HHttpRequestHeader& HHttpRequestHeader::operator=( const HHttpRequestHeader& other) { HHttpHeader::operator=(other); m_method = other.m_method; m_path = other.m_path; return *this; } bool HHttpRequestHeader::setRequest( const QString& method, const QString& path, int majorVer, int minorVer) { if (method.simplified().isEmpty()) { return false; } m_method = method; m_path = path; m_majorVersion = majorVer; m_minorVersion = minorVer; m_valid = true; return true; } bool HHttpRequestHeader::parseFirstLine(const QString& line) { QStringList list = line.simplified().split(" "); if (list.size() > 0) { m_method = list[0]; if (list.size() > 1) { m_path = list[1]; if (list.size() > 2) { return parseVersion(list[2], &m_majorVersion, &m_minorVersion); } } } return false; } QString HHttpRequestHeader::toString() const { if (!isValid()) { return ""; } return QString("%1 %2 HTTP/%3.%4\r\n%5\r\n").arg( m_method, m_path, QString::number(m_majorVersion), QString::number(m_minorVersion), HHttpHeader::toString()); } } } herqq-1.0.0/hupnp/src/http/hhttp_utils_p.h0000644000000000000000000000454111543637310017274 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HTTP_UTILS_H_ #define HTTP_UTILS_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_defs.h" #include class QUrl; template class QList; class QTcpSocket; class QByteArray; namespace Herqq { namespace Upnp { // // // class HHttpUtils { H_DISABLE_COPY(HHttpUtils) HHttpUtils(); public: template static bool keepAlive(const Hdr& hdr) { QString connection = hdr.value("CONNECTION"); if (hdr.minorVersion() == 1) { return connection.compare("close", Qt::CaseInsensitive) != 0; } return connection.compare("Keep-Alive", Qt::CaseInsensitive) == 0; } // returns the URLs as a string inside brackets. This is the format used in // UPnP eventing when subscribing to events. static QString callbackAsStr(const QList& callbacks); // the date format used in UPnP inline static QString rfc1123DateFormat() { QString retVal = "ddd, dd MMM yyyy HH:mm:ss"; return retVal; } // // reads byte by byte to the target bytearray until \r\n\r\n is found, // in which case true is returned static bool readLines(QTcpSocket&, QByteArray& target, qint32 lineCount = 2); }; } } #endif /* HTTP_UTILS_H_ */ herqq-1.0.0/hupnp/src/http/hhttp_messaginginfo_p.cpp0000644000000000000000000000636211543637310021323 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hhttp_messaginginfo_p.h" #include #include #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HMessagingInfo ******************************************************************************/ HMessagingInfo::HMessagingInfo( QPair sock, qint32 receiveTimeoutForNoData) : m_sock(), m_keepAlive(false), m_receiveTimeoutForNoData(receiveTimeoutForNoData), m_chunkedInfo(), m_msecsToWaitOnSend(-1) { m_sock = qMakePair(QPointer(sock.first), sock.second); } HMessagingInfo::HMessagingInfo( QTcpSocket& sock, qint32 receiveTimeoutForNoData) : m_sock(), m_keepAlive(false), m_receiveTimeoutForNoData(receiveTimeoutForNoData), m_chunkedInfo(), m_msecsToWaitOnSend(-1) { m_sock = qMakePair(QPointer(&sock), false); } HMessagingInfo::HMessagingInfo( QPair sock, bool keepAlive, qint32 receiveTimeoutForNoData) : m_sock(), m_keepAlive(keepAlive), m_receiveTimeoutForNoData(receiveTimeoutForNoData), m_msecsToWaitOnSend(-1) { m_sock = qMakePair(QPointer(sock.first), sock.second); } HMessagingInfo::HMessagingInfo( QTcpSocket& sock, bool keepAlive, qint32 receiveTimeoutForNoData) : m_sock(), m_keepAlive(keepAlive), m_receiveTimeoutForNoData(receiveTimeoutForNoData), m_msecsToWaitOnSend(-1) { m_sock = qMakePair(QPointer(&sock), false); } HMessagingInfo::~HMessagingInfo() { if (m_sock.second) { Q_ASSERT(!m_sock.first.isNull()); m_sock.first->deleteLater(); } } void HMessagingInfo::setHostInfo(const QUrl& hostInfo) { QString tmp(hostInfo.host()); if (hostInfo.port(0) > 0) { tmp.append(':').append(QString::number(hostInfo.port())); } m_hostInfo = tmp; } QString HMessagingInfo::hostInfo() const { if (m_hostInfo.isEmpty()) { // fall back to the ip address if no host information was provided. return QString("%1:%2").arg( socket().peerName(), QString::number(socket().peerPort())); } return m_hostInfo; } QString HMessagingInfo::lastErrorDescription() const { return m_lastErrorDescription.isEmpty() ? socket().errorString() : m_lastErrorDescription; } } } herqq-1.0.0/hupnp/src/http/hhttp_messaginginfo_p.h0000644000000000000000000001122011543637310020755 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HHTTP_MESSAGINGINFO_P_H_ #define HHTTP_MESSAGINGINFO_P_H_ #include "../general/hupnp_defs.h" #include #include #include #include class QUrl; // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // namespace Herqq { namespace Upnp { // // // class H_UPNP_CORE_EXPORT HChunkedInfo { private: volatile int m_maxChunkSize; // if this is non-zero, it means that chunked-encoding should be used // if the data to be sent is larger than that of the specified max chunk size // and that the max chunk size is this volatile int m_minChunkSize; // if this is non-zero, it means that when the size of the data to be sent // is not known in advance, how big _at least_ each chunk must be in size. public: inline HChunkedInfo(int max = 0) : m_maxChunkSize(max), m_minChunkSize(0) { } inline HChunkedInfo(int min, int max) : m_maxChunkSize(max), m_minChunkSize(min) { } inline int max() const { return m_maxChunkSize; } inline int min() const { return m_minChunkSize; } inline void setMax(int arg) { m_maxChunkSize = arg; } inline void setMin(int arg) { m_minChunkSize = arg; } }; // // // class H_UPNP_CORE_EXPORT HMessagingInfo { H_DISABLE_COPY(HMessagingInfo) private: QPair, bool> m_sock; bool m_keepAlive; qint32 m_receiveTimeoutForNoData; HChunkedInfo m_chunkedInfo; QString m_hostInfo; QString m_lastErrorDescription; qint32 m_msecsToWaitOnSend; public: // // The default timeout in milliseconds that is waited before a read operation // is terminated unless _some_ data is received (not necessarily the desired amount). // static inline qint32 defaultReceiveTimeoutForNoData() { const qint32 retVal = 5000; return retVal; } explicit HMessagingInfo( QPair sock, qint32 receiveTimeoutForNoData = defaultReceiveTimeoutForNoData()); explicit HMessagingInfo( QTcpSocket& sock, qint32 receiveTimeoutForNoData = defaultReceiveTimeoutForNoData()); HMessagingInfo( QPair, bool keepAlive, qint32 receiveTimeoutForNoData = defaultReceiveTimeoutForNoData()); HMessagingInfo( QTcpSocket&, bool keepAlive, qint32 receiveTimeoutForNoData = defaultReceiveTimeoutForNoData()); ~HMessagingInfo(); inline QTcpSocket& socket() const { Q_ASSERT(!m_sock.first.isNull()); return *m_sock.first; } inline void setKeepAlive(bool arg) { m_keepAlive = arg; } inline bool keepAlive() const { return m_keepAlive; } void setHostInfo(const QUrl& hostInfo); inline void setHostInfo(const QString& hostInfo) { m_hostInfo = hostInfo.trimmed(); } QString hostInfo() const; inline void setReceiveTimeoutForNoData(qint32 arg) { m_receiveTimeoutForNoData = arg; } inline qint32 receiveTimeoutForNoData() const { return m_receiveTimeoutForNoData; } inline const HChunkedInfo& chunkedInfo() const { return m_chunkedInfo; } inline void setChunkedInfo(const HChunkedInfo& arg) { m_chunkedInfo = arg; } inline void setLastErrorDescription(const QString& errDescr) { m_lastErrorDescription = errDescr; } inline void setSendWait(qint32 msecsToWait) { m_msecsToWaitOnSend = msecsToWait; } inline qint32 sendWait() const { return m_msecsToWaitOnSend; } QString lastErrorDescription() const; }; } } #endif /* HHTTP_MESSAGINGINFO_P_H_ */ herqq-1.0.0/hupnp/src/http/http.pri0000644000000000000000000000110211543637310015716 0ustar rootrootHEADERS += \ $$SRC_LOC/http/hhttp_p.h \ $$SRC_LOC/http/hhttp_header_p.h \ $$SRC_LOC/http/hhttp_utils_p.h \ $$SRC_LOC/http/hhttp_server_p.h \ $$SRC_LOC/http/hhttp_asynchandler_p.h \ $$SRC_LOC/http/hhttp_messaginginfo_p.h \ $$SRC_LOC/http/hhttp_messagecreator_p.h SOURCES += \ $$SRC_LOC/http/hhttp_utils_p.cpp \ $$SRC_LOC/http/hhttp_header_p.cpp \ $$SRC_LOC/http/hhttp_server_p.cpp \ $$SRC_LOC/http/hhttp_asynchandler_p.cpp \ $$SRC_LOC/http/hhttp_messaginginfo_p.cpp \ $$SRC_LOC/http/hhttp_messagecreator_p.cpp herqq-1.0.0/hupnp/src/ssdp/0000755000000000000000000000000011543637460014231 5ustar rootrootherqq-1.0.0/hupnp/src/ssdp/hssdp_messagecreator_p.h0000644000000000000000000000336211543637310021124 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSSDP_MESSAGECREATOR_P_H_ #define HSSDP_MESSAGECREATOR_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_defs.h" #include "../general/hupnp_fwd.h" namespace Herqq { namespace Upnp { // // // class HSsdpMessageCreator { H_DISABLE_COPY(HSsdpMessageCreator) private: HSsdpMessageCreator(); ~HSsdpMessageCreator(); public: static QByteArray create(const HResourceUpdate&); static QByteArray create(const HDiscoveryRequest&); static QByteArray create(const HDiscoveryResponse&); static QByteArray create(const HResourceAvailable&); static QByteArray create(const HResourceUnavailable&); }; } } #endif /* HSSDP_MESSAGECREATOR_P_H_ */ herqq-1.0.0/hupnp/src/ssdp/hssdp.cpp0000644000000000000000000005624411543637310016063 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hssdp.h" #include "hssdp_p.h" #include "hdiscovery_messages.h" #include "hssdp_messagecreator_p.h" #include "../dataelements/hdiscoverytype.h" #include "../dataelements/hproduct_tokens.h" #include "../socket/hendpoint.h" #include "../general/hlogger_p.h" #include "../utils/hmisc_utils_p.h" #include #include #include #include #include /*! * \defgroup hupnp_ssdp Ssdp * \ingroup hupnp_core * * \brief This page provides information about the HUPnP's classes that provide the * SSDP functionality required for the discovery phase of the UPnP Device Architecture. * * According to the UPnP Device Architecture specification version 1.1, * When a device is added to the network, the UPnP discovery protocol allows that * device to advertise its services to control points on the network. Similarly, * when a control point is added to the network, the UPnP discovery protocol allows * that control point to search for devices of interest on the network (p. 19). * * The mentioned discovery protocol is SSDP and it is about exchanging * HTTP messages over UDP. * * \note As mentioned in the Herqq::Upnp::HSsdp, these classes implement the SSDP * as it is required by the UDA specification. The IETF SSDP draft is not * implemented in full. * * To send or receive SSDP messages, you need to use Herqq::Upnp::HSsdp * class. You can either derive from it or use it directly. In either case, * sending messages is straightforward: * * \code * * Herqq::Upnp::HSsdp ssdp; * * Herqq::Upnp::HResourceAvailable deviceAvailable( * 1800, // how long the advertisement is valid in seconds * QUrl("127.0.0.1:1900/mydevice"), // where the device description can be downloaded * Herqq::Upnp::HProductTokens("unix/5.1 UPnP/1.1 MyProduct/1.0"), // some information about the host and product * Herqq::Upnp::HDiscoveryType("uuid:5d724fc2-5c5e-4760-a123-f04a9136b300::upnp:rootdevice")); // universally unique identifier * * ssdp.announcePresence(deviceAvailable); * * \endcode * * The above example sends a single ssdp:alive message indicating that a * UPnP root device is now available. * * \note All SSDP classes validate the provided information during * object construction. For instance, if the argument to the Herqq::Upnp::HDiscoveryType * is invalid, the constructed object will be invalid as well, * e.g Herqq::Upnp::HDiscoveryType::isValid() returns false. In such a case, the creation * of Herqq::Upnp::HResourceAvailable will fail and consequenlty, the \c %HSsdp will * not send anything. * * Receiving messages is almost as simple. You can use the class directly in which * case you have to connect to the exposed signals. For instance, to receive signals * when resource available messages are received, you should do: * * \code * * MyClass::MyClass(QObject* parent) : * QObject(parent), m_ssdp(new Herqq::Upnp::HSsdp()) * { * connect( * m_ssdp, SIGNAL(resourceAvailableReceived(Herqq::Upnp::HResourceAvailable)), * this , SLOT (resourceAvailableReceived(Herqq::Upnp::HResourceAvailable))); * } * * MyClass::resourceAvailableReceived(const Herqq::Upnp::HResourceAvailable&) * { * // do something * } * * \endcode * * Note the used signature with the SIGNAL and SLOT macros. You can also derive * from \c %HSsdp in which case you can override the various \c protected \c virtual * methods that will be called upon message reception. * * \attention * Usually you have no need to use the classes in this module directly. These classes * may be useful in case you are writing your own device host or control point. * Otherwise, the Herqq::Upnp::HControlPoint and Herqq::Upnp::HDeviceHost classes * may suit your needs better. */ namespace Herqq { namespace Upnp { namespace { inline QHostAddress multicastAddress() { static QHostAddress retVal("239.255.255.250"); return retVal; } inline qint16 multicastPort() { static qint16 retVal = 1900; return retVal; } inline HEndpoint multicastEndpoint() { static HEndpoint retVal = HEndpoint("239.255.255.250:1900"); return retVal; } } /******************************************************************************* * HSsdpPrivate ******************************************************************************/ HSsdpPrivate::HSsdpPrivate( HSsdp* qptr, const QByteArray& loggingIdentifier) : m_loggingIdentifier(loggingIdentifier), m_multicastSocket(0), m_unicastSocket (0), q_ptr (qptr), m_allowedMessages(HSsdp::All), m_lastError() { } HSsdpPrivate::~HSsdpPrivate() { clear(); } bool HSsdpPrivate::parseCacheControl(const QString& str, qint32* retVal) { bool ok = false; QString cacheControl = str.simplified(); QStringList slist = cacheControl.split('='); if (slist.size() != 2 || slist[0].simplified() != "max-age") { m_lastError = QString("Invalid Cache-Control field value: %1").arg(str); return false; } qint32 maxAge = slist[1].simplified().toInt(&ok); if (!ok) { m_lastError = QString("Invalid Cache-Control field value: %1").arg(str); return false; } *retVal = maxAge; return true; } bool HSsdpPrivate::checkHost(const QString& host) { QStringList slist = host.split(':'); if (slist.size() < 1 || slist[0].simplified() != "239.255.255.250") { m_lastError = QString("HOST header field is invalid: %1").arg(host); return false; } return true; } bool HSsdpPrivate::parseDiscoveryResponse( const HHttpResponseHeader& hdr, HDiscoveryResponse* retVal) { QString cacheControl = hdr.value("CACHE-CONTROL"); QDateTime date = QDateTime::fromString(hdr.value("DATE")); QUrl location = hdr.value("LOCATION"); QString server = hdr.value("SERVER"); //QString st = hdr.value("ST"); QString usn = hdr.value("USN"); QString bootIdStr = hdr.value("BOOTID.UPNP.ORG"); QString configIdStr = hdr.value("CONFIGID.UPNP.ORG"); QString searchPortStr = hdr.value("SEARCHPORT.UPNP.ORG"); if (!hdr.hasKey("EXT")) { m_lastError = QString("EXT field is missing:\n%1").arg( hdr.toString()); return false; } else if (!hdr.value("EXT").isEmpty()) { m_lastError = QString("EXT field is not empty, although it should be:\n%1"). arg(hdr.toString()); return false; } qint32 maxAge; if (!parseCacheControl(cacheControl, &maxAge)) { return false; } bool ok = false; qint32 bootId = bootIdStr.toInt(&ok); if (!ok) { bootId = -1; } qint32 configId = configIdStr.toInt(&ok); if (!ok) { configId = -1; } qint32 searchPort = searchPortStr.toInt(&ok); if (!ok) { searchPort = -1; } *retVal = HDiscoveryResponse( maxAge, date, location, HProductTokens(server), HDiscoveryType(usn, LooseChecks), bootId, hdr.hasKey("CONFIGID.UPNP.ORG") ? configId : 0, // ^^ configid is optional even in UDA v1.1 ==> cannot provide -1 // unless the header field is specified and the value is invalid searchPort); return retVal->isValid(LooseChecks); } bool HSsdpPrivate::parseDiscoveryRequest( const HHttpRequestHeader& hdr, HDiscoveryRequest* retVal) { QString host = hdr.value("HOST"); QString man = hdr.value("MAN").simplified(); bool ok = false; qint32 mx = hdr.value("MX").toInt(&ok); if (!ok) { m_lastError = QString("MX is not specified."); return false; } QString st = hdr.value("ST"); QString ua = hdr.value("USER-AGENT"); checkHost(host); if (man.compare(QString("\"ssdp:discover\""), Qt::CaseInsensitive) != 0) { m_lastError = QString("MAN header field is invalid: [%1].").arg(man); return false; } *retVal = HDiscoveryRequest( mx, HDiscoveryType(st, LooseChecks), HProductTokens(ua)); return retVal->isValid(LooseChecks); } bool HSsdpPrivate::parseDeviceAvailable( const HHttpRequestHeader& hdr, HResourceAvailable* retVal) { QString host = hdr.value("HOST"); QString server = hdr.value("SERVER"); QString usn = hdr.value("USN"); //QString nt = hdr.value("NT"); QUrl location = hdr.value("LOCATION"); QString cacheControl = hdr.value("CACHE-CONTROL"); QString bootIdStr = hdr.value("BOOTID.UPNP.ORG"); QString configIdStr = hdr.value("CONFIGID.UPNP.ORG"); QString searchPortStr = hdr.value("SEARCHPORT.UPNP.ORG"); qint32 maxAge; if (!parseCacheControl(cacheControl, &maxAge)) { return false; } bool ok = false; qint32 bootId = bootIdStr.toInt(&ok); if (!ok) { bootId = -1; } qint32 configId = configIdStr.toInt(&ok); if (!ok) { configId = -1; } checkHost(host); qint32 searchPort = searchPortStr.toInt(&ok); if (!ok) { searchPort = -1; } *retVal = HResourceAvailable( maxAge, location, HProductTokens(server), HDiscoveryType(usn, LooseChecks), bootId, configId, searchPort); return retVal->isValid(LooseChecks); } bool HSsdpPrivate::parseDeviceUnavailable( const HHttpRequestHeader& hdr, HResourceUnavailable* retVal) { QString host = hdr.value("HOST"); //QString nt = hdr.value("NT"); QString usn = hdr.value("USN"); QString bootIdStr = hdr.value("BOOTID.UPNP.ORG"); QString configIdStr = hdr.value("CONFIGID.UPNP.ORG"); bool ok = false; qint32 bootId = bootIdStr.toInt(&ok); if (!ok) { bootId = -1; } qint32 configId = configIdStr.toInt(&ok); if (!ok) { configId = -1; } checkHost(host); *retVal = HResourceUnavailable( HDiscoveryType(usn, LooseChecks), bootId, configId); return retVal->isValid(LooseChecks); } bool HSsdpPrivate::parseDeviceUpdate( const HHttpRequestHeader& hdr, HResourceUpdate* retVal) { QString host = hdr.value("HOST"); QUrl location = hdr.value("LOCATION"); //QString nt = hdr.value("NT"); QString usn = hdr.value("USN"); QString bootIdStr = hdr.value("BOOTID.UPNP.ORG"); QString configIdStr = hdr.value("CONFIGID.UPNP.ORG"); QString nextBootIdStr = hdr.value("NEXTBOOTID.UPNP.ORG"); QString searchPortStr = hdr.value("SEARCHPORT.UPNP.ORG"); bool ok = false; qint32 bootId = bootIdStr.toInt(&ok); if (!ok) { bootId = -1; } qint32 configId = configIdStr.toInt(&ok); if (!ok) { configId = -1; } qint32 nextBootId = nextBootIdStr.toInt(&ok); if (!ok) { nextBootId = -1; } qint32 searchPort = searchPortStr.toInt(&ok); if (!ok) { searchPort = -1; } checkHost(host); *retVal = HResourceUpdate( location, HDiscoveryType(usn, LooseChecks), bootId, configId, nextBootId, searchPort); return retVal->isValid(LooseChecks); } bool HSsdpPrivate::send(const QByteArray& data, const HEndpoint& receiver) { Q_ASSERT(isInitialized()); quint16 port = receiver.portNumber(); if (!port) { port = 1900; } qint64 retVal = m_unicastSocket->writeDatagram( data, receiver.hostAddress(), port); return retVal == data.size(); } void HSsdpPrivate::processResponse(const QString& msg, const HEndpoint& source) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HHttpResponseHeader hdr(msg); if (!hdr.isValid()) { HLOG_WARN("Ignoring a malformed HTTP response."); return; } if (m_allowedMessages & HSsdp::DiscoveryResponse) { HDiscoveryResponse rcvdMsg; if (!parseDiscoveryResponse(hdr, &rcvdMsg)) { HLOG_WARN(QString("Ignoring invalid message from [%1]: %2").arg( source.toString(), msg)); } else if (!q_ptr->incomingDiscoveryResponse(rcvdMsg, source)) { emit q_ptr->discoveryResponseReceived(rcvdMsg, source); } } } void HSsdpPrivate::processNotify(const QString& msg, const HEndpoint& source) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HHttpRequestHeader hdr(msg); if (!hdr.isValid()) { HLOG_WARN("Ignoring an invalid HTTP NOTIFY request."); return; } QString nts = hdr.value("NTS"); if (nts.compare(QString("ssdp:alive"), Qt::CaseInsensitive) == 0) { if (m_allowedMessages & HSsdp::DeviceAvailable) { HResourceAvailable rcvdMsg; if (!parseDeviceAvailable(hdr, &rcvdMsg)) { HLOG_WARN(QString( "Ignoring an invalid ssdp:alive announcement:\n%1").arg(msg)); } else if (!q_ptr->incomingDeviceAvailableAnnouncement(rcvdMsg, source)) { emit q_ptr->resourceAvailableReceived(rcvdMsg, source); } } } else if (nts.compare(QString("ssdp:byebye"), Qt::CaseInsensitive) == 0) { if (m_allowedMessages & HSsdp::DeviceUnavailable) { HResourceUnavailable rcvdMsg; if (!parseDeviceUnavailable(hdr, &rcvdMsg)) { HLOG_WARN(QString( "Ignoring an invalid ssdp:byebye announcement:\n%1").arg(msg)); } else if (!q_ptr->incomingDeviceUnavailableAnnouncement(rcvdMsg, source)) { emit q_ptr->resourceUnavailableReceived(rcvdMsg, source); } } } else if (nts.compare(QString("ssdp:update"), Qt::CaseInsensitive) == 0) { if (m_allowedMessages & HSsdp::DeviceUpdate) { HResourceUpdate rcvdMsg; if (!parseDeviceUpdate(hdr, &rcvdMsg)) { HLOG_WARN(QString( "Ignoring invalid ssdp:update announcement:\n%1").arg(msg)); } else if (!q_ptr->incomingDeviceUpdateAnnouncement(rcvdMsg, source)) { emit q_ptr->deviceUpdateReceived(rcvdMsg, source); } } } else { HLOG_WARN(QString( "Ignoring an invalid SSDP presence announcement: [%1].").arg(nts)); } } void HSsdpPrivate::processSearch( const QString& msg, const HEndpoint& source, const HEndpoint& destination) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); HHttpRequestHeader hdr(msg); if (!hdr.isValid()) { HLOG_WARN("Ignoring an invalid HTTP M-SEARCH request."); return; } if (m_allowedMessages & HSsdp::DiscoveryRequest) { HSsdp::DiscoveryRequestMethod type = destination.isMulticast() ? HSsdp::MulticastDiscovery : HSsdp::UnicastDiscovery; HDiscoveryRequest rcvdMsg; if (!parseDiscoveryRequest(hdr, &rcvdMsg)) { HLOG_WARN(QString("Ignoring invalid message from [%1]: %2").arg( source.toString(), msg)); } else if (!q_ptr->incomingDiscoveryRequest(rcvdMsg, source, type)) { emit q_ptr->discoveryRequestReceived(rcvdMsg, source, type); } } } void HSsdpPrivate::clear() { HLOG2(H_AT, H_FUN, m_loggingIdentifier); if (m_multicastSocket && m_multicastSocket->state() == QUdpSocket::BoundState) { m_multicastSocket->leaveMulticastGroup( multicastAddress(), m_unicastSocket->localAddress()); } delete m_unicastSocket; m_unicastSocket = 0; delete m_multicastSocket; m_multicastSocket = 0; } bool HSsdpPrivate::init(const QHostAddress& addressToBind) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); Q_ASSERT(!isInitialized()); m_multicastSocket = new HMulticastSocket(q_ptr); m_unicastSocket = new QUdpSocket(q_ptr); bool ok = QObject::connect( m_multicastSocket, SIGNAL(readyRead()), q_ptr, SLOT(multicastMessageReceived())); Q_ASSERT(ok); Q_UNUSED(ok) ok = QObject::connect( m_unicastSocket, SIGNAL(readyRead()), q_ptr, SLOT(unicastMessageReceived())); Q_ASSERT(ok); if (!m_multicastSocket->bind(1900)) { HLOG_WARN("Failed to bind multicast socket for listening"); return false; } if (!m_multicastSocket->joinMulticastGroup( multicastAddress(), addressToBind)) { HLOG_WARN(QString("Could not join %1").arg( multicastAddress().toString())); //return false; } HLOG_DBG(QString( "Attempting to use address [%1] for SSDP communications").arg( addressToBind.toString())); // always attempt to bind to the 1900 first if (!m_unicastSocket->bind(addressToBind, 1900)) { HLOG_DBG("Could not bind UDP unicast socket to port 1900"); // the range is specified by the UDA 1.1 standard for(qint32 i = 49152; i < 65535; ++i) { if (m_unicastSocket->bind(addressToBind, i)) { HLOG_DBG(QString("Unicast UDP socket bound to port [%1].").arg( QString::number(i))); break; } } } else { HLOG_DBG("Unicast UDP socket bound to port 1900"); } if (m_unicastSocket->state() != QUdpSocket::BoundState) { HLOG_WARN(QString( "Failed to bind UDP unicast socket on address.").arg( addressToBind.toString())); clear(); return false; } return true; } void HSsdpPrivate::messageReceived(QUdpSocket* socket, const HEndpoint* dest) { HLOG2(H_AT, H_FUN, m_loggingIdentifier); QHostAddress ha; quint16 port; QByteArray buf; buf.resize(socket->pendingDatagramSize() + 1); qint64 read = socket->readDatagram(buf.data(), buf.size(), &ha, &port); if (read < 0) { HLOG_WARN(QString("Read failed: %1").arg(socket->errorString())); Q_ASSERT(false); return; } QString msg(QString::fromUtf8(buf, read)); HEndpoint source(ha, port); HEndpoint destination( dest ? *dest : HEndpoint(socket->localAddress(), socket->localPort())); if (msg.startsWith("NOTIFY * HTTP/1.1", Qt::CaseInsensitive)) { // Possible presence announcement processNotify(msg, source); } else if (msg.startsWith("M-SEARCH * HTTP/1.1", Qt::CaseInsensitive)) { // Possible discovery request. processSearch(msg, source, destination); } else { // Possible discovery response processResponse(msg, source); } } /******************************************************************************* * HSsdp ******************************************************************************/ HSsdp::HSsdp(QObject* parent) : QObject(parent), h_ptr(new HSsdpPrivate(this)) { } HSsdp::HSsdp(const QByteArray& loggingIdentifier, QObject* parent) : QObject(parent), h_ptr(new HSsdpPrivate(this, loggingIdentifier)) { } HSsdp::~HSsdp() { delete h_ptr; } void HSsdp::unicastMessageReceived() { h_ptr->messageReceived(h_ptr->m_unicastSocket); } void HSsdp::multicastMessageReceived() { HEndpoint ep = multicastEndpoint(); h_ptr->messageReceived(h_ptr->m_multicastSocket, &ep); } void HSsdp::setFilter(AllowedMessages allowedMessages) { h_ptr->m_allowedMessages = allowedMessages; } HSsdp::AllowedMessages HSsdp::filter() const { return h_ptr->m_allowedMessages; } bool HSsdp::init() { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (isInitialized()) { return false; } QHostAddress ha(findBindableHostAddress()); return h_ptr->init(ha); } bool HSsdp::init(const QHostAddress& unicastAddress) { HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier); if (isInitialized()) { return false; } return h_ptr->init(unicastAddress); } bool HSsdp::isInitialized() const { return h_ptr->isInitialized(); } HEndpoint HSsdp::unicastEndpoint() const { return HEndpoint( h_ptr->m_unicastSocket->localAddress(), h_ptr->m_unicastSocket->localPort()); } bool HSsdp::incomingDiscoveryRequest( const HDiscoveryRequest&, const HEndpoint& /*source*/, DiscoveryRequestMethod /*requestType*/) { return false; } bool HSsdp::incomingDiscoveryResponse( const HDiscoveryResponse&, const HEndpoint& /*source*/) { return false; } bool HSsdp::incomingDeviceAvailableAnnouncement( const HResourceAvailable&, const HEndpoint& /*source*/) { return false; } bool HSsdp::incomingDeviceUnavailableAnnouncement( const HResourceUnavailable&, const HEndpoint& /*source*/) { return false; } bool HSsdp::incomingDeviceUpdateAnnouncement( const HResourceUpdate&, const HEndpoint& /*source*/) { return false; } namespace { template qint32 send(HSsdpPrivate* hptr, const Msg& msg, const HEndpoint& receiver, qint32 count) { HLOG(H_AT, H_FUN); if (!msg.isValid(StrictChecks) || receiver.isNull() || count < 0 || !hptr->isInitialized()) { return -1; } qint32 sent = 0; for (qint32 i = 0; i < count; ++i) { QByteArray data = HSsdpMessageCreator::create(msg); Q_ASSERT(!data.isEmpty()); if (hptr->send(data, receiver)) { ++sent; } else { HLOG_DBG(hptr->m_unicastSocket->errorString()); } } return sent; } } qint32 HSsdp::announcePresence(const HResourceAvailable& msg, qint32 count) { return send(h_ptr, msg, multicastEndpoint(), count); } qint32 HSsdp::announcePresence(const HResourceUnavailable& msg, qint32 count) { return send(h_ptr, msg, multicastEndpoint(), count); } qint32 HSsdp::announceUpdate(const HResourceUpdate& msg, qint32 count) { return send(h_ptr, msg, multicastEndpoint(), count); } qint32 HSsdp::sendDiscoveryRequest(const HDiscoveryRequest& msg, qint32 count) { return send(h_ptr, msg, multicastEndpoint(), count); } qint32 HSsdp::sendDiscoveryRequest( const HDiscoveryRequest& msg, const HEndpoint& endpoint, qint32 count) { return send(h_ptr, msg, endpoint, count); } qint32 HSsdp::sendDiscoveryResponse( const HDiscoveryResponse& msg, const HEndpoint& destination, qint32 count) { return send(h_ptr, msg, destination, count); } } } herqq-1.0.0/hupnp/src/ssdp/hdiscovery_messages.h0000644000000000000000000006757011543637310020461 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HDISCOVERY_MSGS_H_ #define HDISCOVERY_MSGS_H_ #include #include class QUrl; class QString; class QDateTime; namespace Herqq { namespace Upnp { class HResourceAvailablePrivate; /*! * \brief This is a class that represents the resource available (ssdp:alive) message. * * According to the UDA, When a device is added to the network, * it MUST multicast discovery messages to advertise its root device, any embedded devices, * and any services. In HUPnP this class represents such an advertisement. * * Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, * or you receive instances of this class from the Herqq::Upnp::HSsdp. * * \headerfile hdiscovery_messages.h HResourceAvailable * * \ingroup hupnp_ssdp * * \remarks the class provides an assignment operator, which is not thread-safe. * * \sa HSsdp */ class H_UPNP_CORE_EXPORT HResourceAvailable { friend H_UPNP_CORE_EXPORT bool operator==( const HResourceAvailable&, const HResourceAvailable&); private: QSharedDataPointer h_ptr; public: /*! * Constructs a new, empty instance. The constructed object is not valid, * i.e isValid() returns false. * * \sa isValid() */ HResourceAvailable(); /*! * Constructs a new instance using the specified parameters. * * \param cacheControlMaxAge specifies the number of seconds the * advertisement is valid. * * \param location specifies the URL to the UPnP description of the root device. * If the location is invalid or empty the created object will be invalid. * * \param serverTokens specifies information about the host, the UPnP version * used and of the product. Note that if this parameter specifies * UPnP version 1.1 or later, \c bootId and \c configId have to be properly defined. * Otherwise the created object will be invalid. * * \note Although server tokens are mandatory according to the UDA, * this is not enforced by this class for interoperability reasons. * * \param usn specifies the Unique Service Name. The created object is valid * only if the provided USN is valid. * * \param bootId specifies the \c BOOTID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0. Because of this the class requires a valid value (>= 0) only in case * the \c serverTokens identify UPnP v1.1 or later. * * \param configId specifies the \c CONFIGID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0. Because of this the class requires a valid value (>= 0) only in case * the \c serverTokens identify UPnP v1.1 or later. * * \param searchPort specifies the \c SEARCHPORT.UPNP.ORG header value. Note that * this is optional in UDA v1.1, whereas it is not specified at all in UDA v1.0. * If specified, this is the port at which the device must listen for unicast * \c M-SEARCH messages. Otherwise the port is by default \c 1900. * This parameter is optional. * * \remarks * \li if cacheControlMaxAge is smaller than 5 it it set to 5, or if it is * larger than 60 * 60 * 24 (a day in seconds) it is set to a day measured in seconds. * * \li if searchPort is smaller than 49152 or larger than 65535 it is set to -1. * The range is specified in UDA v1.1. * * \sa isValid() */ HResourceAvailable( qint32 cacheControlMaxAge, const QUrl& location, const HProductTokens& serverTokens, const HDiscoveryType& usn, qint32 bootId = -1, qint32 configId = -1, qint32 searchPort = -1); /*! * \brief Destroys the instance. */ ~HResourceAvailable(); /*! * \brief Copy constructor. * * Copies the contents of the other object instance to this. */ HResourceAvailable(const HResourceAvailable&); /*! * Assigns the contents of the other object instance to this. * * \remarks This is not thread-safe. */ HResourceAvailable& operator=(const HResourceAvailable&); /*! * \brief Indicates whether or not the object contains valid announcement information. * * \param level indicates whether the check should be strictly according * to the UDA specification. If set to false some checks are omitted that * are known to be poorly implemented in some UPnP software. * * \return \e true in case the objects contains valid announcement * information in terms of the requested strictness. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Returns the server tokens. * * \return The server tokens. The returned object is invalid if this * object is invalid. * * \sa isValid() */ const HProductTokens& serverTokens() const; /*! * \brief Returns the location of the announced device. * * \return The location of the announced device. This is the URL where * the device description can be retrieved. The returned object * is empty if this object is invalid. * * \sa isValid() */ QUrl location() const; /*! * \brief Returns the Unique Service Name. * * The Unique Service Name identifies a unique \e device or \e service instance. * * \return The Unique Service Name. The returned object is invalid if this * object is invalid. * * \sa isValid() */ const HDiscoveryType& usn() const; /*! * \brief Returns the number of seconds the advertisement is valid. * * \return The number of seconds the advertisement is valid. If the object * is valid the return value is never smaller than 5. */ qint32 cacheControlMaxAge() const; /*! * \brief Returns the value of \c BOOTID.UPNP.ORG. * * \return The value of \c BOOTID.UPNP.ORG. If the value is not * specified -1 is returned. */ qint32 bootId() const; /*! * \brief Returns the value of \c CONFIGID.UPNP.ORG. * * \return The value of \c CONFIGID.UPNP.ORG. If the value is not * specified -1 is returned. */ qint32 configId() const; /*! * \brief Returns the value of \c SEARCHPORT.UPNP.ORG header field. * * \return The value of \c SEARCHPORT.UPNP.ORG header field. If the value is not * specified -1 is returned. */ qint32 searchPort() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically equivalent. * * \relates HResourceAvailable */ H_UPNP_CORE_EXPORT bool operator==( const HResourceAvailable&, const HResourceAvailable&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HResourceAvailable */ inline bool operator!=( const HResourceAvailable& obj1, const HResourceAvailable& obj2) { return !(obj1 == obj2); } class HResourceUnavailablePrivate; /*! * Class that represents the device unavailable (ssdp:byebye) message. * * According to the UDA, When a device and its services are going to be * removed from the network, the device SHOULD multicast an ssdp:byebye message * corresponding to each of the ssdp:alive messages it multicasted that have not * already expired. In HUPnP this class represents such a message. * * Usually you create instances of this class to be sent by the Herqq::Upnp::HSsdp, * or you receive instances of this class from the Herqq::Upnp::HSsdp. * * \headerfile hdiscovery_messages.h HResourceUnavailable * * \ingroup hupnp_ssdp * * \remarks the class provides an assignment operator, which is not thread-safe. * * \sa HSsdp */ class H_UPNP_CORE_EXPORT HResourceUnavailable { friend H_UPNP_CORE_EXPORT bool operator==( const HResourceUnavailable&, const HResourceUnavailable&); private: QSharedDataPointer h_ptr; public: /*! * Constructs a new, empty instance. The constructed object is not valid, * i.e isValid() returns false. * * \sa isValid() */ HResourceUnavailable(); /*! * \brief Creates a new instance. * * \param usn specifies the Unique Service Name. The created object is invalid * if the provided USN is invalid. * * \param bootId specifies the \c BOOTID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0. * * \param configId specifies the \c CONFIGID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0. * * \sa isValid() */ HResourceUnavailable( const HDiscoveryType& usn, qint32 bootId = -1, qint32 configId = -1); /*! * \brief Destroys the instance. */ ~HResourceUnavailable(); /*! * \brief Copy constructor. * * Copies the contents of the other to this object. */ HResourceUnavailable(const HResourceUnavailable&); /*! * Assigns the contents of the other to this. * * \return a reference to this object. */ HResourceUnavailable& operator=(const HResourceUnavailable&); /*! * \brief Indicates whether or not the object contains valid announcement information. * * \param level indicates whether the check should be strictly according * to the UDA specification. If set to false some checks are omitted that * are known to be poorly implemented in some UPnP software. * * \return \e true in case the objects contains valid announcement * information in terms of the requested strictness. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Returns the Unique Service Name. * * The Unique Service Name identifies a unique \e device or \e service instance. * * \return The Unique Service Name. The returned object is invalid if this * object is invalid. * * \sa isValid() */ const HDiscoveryType& usn() const; /*! * \brief Returns the value of \c BOOTID.UPNP.ORG. * * \return The value of \c BOOTID.UPNP.ORG. If the value is not * specified -1 is returned. */ qint32 bootId() const; /*! * \brief Returns the value of \c CONFIGID.UPNP.ORG. * * \return The value of \c CONFIGID.UPNP.ORG. If the value is not * specified -1 is returned. */ qint32 configId() const; /*! * \brief Returns the IP endpoint of the device that went offline. * * \return The IP endpoint of the device that went offline. */ HEndpoint location() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically equivalent. * * \relates HResourceUnavailable */ H_UPNP_CORE_EXPORT bool operator==( const HResourceUnavailable&, const HResourceUnavailable&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HResourceUnavailable */ inline bool operator!=( const HResourceUnavailable& obj1, const HResourceUnavailable& obj2) { return !(obj1 == obj2); } class HResourceUpdatePrivate; /*! * Class representing the device update (ssdp:update) message. * * Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, * or you receive instances of this class from the Herqq::Upnp::HSsdp. * * \headerfile hdiscovery_messages.h HResourceUpdate * * \ingroup hupnp_ssdp * * \remarks the class provides an assignment operator, which is not thread-safe. * * \sa HSsdp */ class H_UPNP_CORE_EXPORT HResourceUpdate { friend H_UPNP_CORE_EXPORT bool operator==( const HResourceUpdate&, const HResourceUpdate&); private: QSharedDataPointer h_ptr; public: /*! * Constructs a new, empty instance. The constructed object is not valid, * i.e isValid() returns false. * * \sa isValid() */ HResourceUpdate(); /*! * Constructs a new instance using the specified parameters. * * \param location specifies the URL to the UPnP description of the root device. * If the location is invalid or empty the created object will be invalid. * * \param usn specifies the Unique Service Name. The created object is invalid * if the provided USN is invalid. * * \param bootId specifies the \c BOOTID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0. * * \param configId specifies the \c CONFIGID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0 * * \param nextBootId * * \param searchPort specifies the \c SEARCHPORT.UPNP.ORG header value. Note that * this is optional in UDA v1.1, whereas it is not specified at all in UDA v1.0. * If specified, this is the port at which the device must listen for unicast * \c M-SEARCH messages. Otherwise the port is by default \c 1900. * This parameter is optional. * * \remarks if searchPort is smaller than 49152 or larger than 65535 it is set to -1. * This is specified in the UDA v1.1. */ HResourceUpdate( const QUrl& location, const HDiscoveryType& usn, qint32 bootId = -1, qint32 configId = -1, qint32 nextBootId = -1, qint32 searchPort = -1); /*! * \brief Destroys the instance. */ ~HResourceUpdate(); /*! * \brief Copy constructor. * * Copies the contents of the other to this. */ HResourceUpdate(const HResourceUpdate&); /*! * Assigns the contents of the other to this. * * \return a reference to this object. */ HResourceUpdate& operator=(const HResourceUpdate&); /*! * \brief Indicates whether or not the object contains valid announcement information. * * \param level indicates whether the check should be strictly according * to the UDA specification. If set to false some checks are omitted that * are known to be poorly implemented in some UPnP software. * * \return \e true in case the objects contains valid announcement * information in terms of the requested strictness. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Returns the location of the announced device. * * \return The location of the announced device. This is the URL where * the device description can be retrieved. The returned object * will be empty if this object is invalid. * * \sa isValid() */ QUrl location() const; /*! * \brief Returns the Unique Service Name. * * \return The Unique Service Name. */ const HDiscoveryType& usn() const; /*! * \brief Returns the value of \c BOOTID.UPNP.ORG. * * \return The value of \c BOOTID.UPNP.ORG. * If the value is not specified -1 is returned. */ qint32 bootId() const; /*! * \brief Returns the value of \c CONFIGID.UPNP.ORG. * * \return The value of \c CONFIGID.UPNP.ORG. * If the value is not specified -1 is returned. */ qint32 configId() const; /*! * \return * If the value is not specified -1 is returned. */ qint32 nextBootId() const; /*! * \brief Returns the value of \c SEARCHPORT.UPNP.ORG header field. * * \return The value of \c SEARCHPORT.UPNP.ORG header field. * If the value is not specified -1 is returned. */ qint32 searchPort() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically equivalent. * * \relates HResourceUpdate */ H_UPNP_CORE_EXPORT bool operator==( const HResourceUpdate&, const HResourceUpdate&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HResourceUpdate */ inline bool operator!=( const HResourceUpdate& obj1, const HResourceUpdate& obj2) { return !(obj1 == obj2); } class HDiscoveryRequestPrivate; /*! * Class representing an M-SEARCH (ssdp:discover) message. * * Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, * or you receive instances of this class from the Herqq::Upnp::HSsdp. * * \headerfile hdiscovery_messages.h HDiscoveryRequest * * \ingroup hupnp_ssdp * * \remarks the class provides an assignment operator, which is not thread-safe. * * \sa HSsdp */ class H_UPNP_CORE_EXPORT HDiscoveryRequest { friend H_UPNP_CORE_EXPORT bool operator==( const HDiscoveryRequest&, const HDiscoveryRequest&); private: QSharedDataPointer h_ptr; public: /*! * Constructs a new, empty instance. The constructed object is not valid, * i.e isValid() returns false. * * \sa isValid() */ HDiscoveryRequest(); /*! * Creates a new instance based on the provided parameters. The constructed * object will be invalid, i.e. isValid() returns false in case the provided * information is invalid. * * \param mx specifies the maximum wait time in seconds. * * \param resource specifies the Search Target (ST). If the object is invalid, * the created object will be invalid. * * \param userAgent specifies information about the requester. * * \remarks * - if userAgent identifies a UPnP v1.1 requester: * - if mx is smaller than 1 it is set to 1 and * - if mx is larger than 5 it it set to 5. * - if userAgent does not specify UPnP version (it always should however) or * the userAgent identifies a UPnP v1.0 requester: * - if mx is smaller than 0 it is set to 0 and * - if mx is larger than 120 it it set to 120. * * \sa isValid(), mx(), searchTarget(), userAgent() */ HDiscoveryRequest( qint32 mx, const HDiscoveryType& resource, const HProductTokens& userAgent); /*! * \brief Destroys the instance. */ ~HDiscoveryRequest(); /*! * \brief Copy constructor. * * Copies the contents of \c other to this. */ HDiscoveryRequest(const HDiscoveryRequest&); /*! * Assigns the contents of the other to this. * * \return a reference to this. */ HDiscoveryRequest& operator=(const HDiscoveryRequest&); /*! * \brief Indicates whether or not the object contains valid announcement information. * * \param level indicates whether the check should be strictly according * to the UDA specification. If set to false some checks are omitted that * are known to be poorly implemented in some UPnP software. * * \return \e true in case the objects contains valid announcement * information in terms of the requested strictness. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Returns the Search Target of the request. * * \return The Search Target of the request. */ const HDiscoveryType& searchTarget() const; /*! * \brief Returns the maximum wait time in seconds. * * According to UDA, * Device responses SHOULD be delayed a random duration between 0 and * this many seconds to balance load for the control point when it * processes responses. * * \return The maximum wait time in seconds. */ qint32 mx() const; /*! * \brief Returns information about the maker of the request. * * \return information about the maker of the request. */ const HProductTokens& userAgent() const; }; /*! * Compares the two objects for equality. * * \return true in case the objects are logically equivalent. * * \relates HDiscoveryRequest */ H_UPNP_CORE_EXPORT bool operator==( const HDiscoveryRequest&, const HDiscoveryRequest&); /*! * Compares the two objects for inequality. * * \return true in case the objects are not logically equivalent. * * \relates HDiscoveryRequest */ inline bool operator!=( const HDiscoveryRequest& obj1, const HDiscoveryRequest& obj2) { return !(obj1 == obj2); } class HDiscoveryResponsePrivate; /*! * \brief This is a class that represents a response to a HDiscoveryRequest. * * Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, * or you receive instances of this class from the Herqq::Upnp::HSsdp. * * \headerfile hdiscovery_messages.h HDiscoveryResponse * * \ingroup hupnp_ssdp * * \remarks the class provides an assignment operator, which is not thread-safe. * * \sa HSsdp */ class H_UPNP_CORE_EXPORT HDiscoveryResponse { friend H_UPNP_CORE_EXPORT bool operator==( const HDiscoveryResponse&, const HDiscoveryResponse&); private: QSharedDataPointer h_ptr; public: /*! * Constructs a new, empty instance. The constructed object is not valid, * i.e isValid() returns false. * * \sa isValid() */ HDiscoveryResponse(); /*! * Constructs a new instance using the specified parameters. The constructed * object will be invalid, i.e. isValid() returns false in case the provided * information is invalid. * * \param cacheControlMaxAge specifies the number of seconds the * advertisement is valid. * * \param date * * \param location specifies the URL to the UPnP description of the root device. * If the location is invalid or empty the created object will be invalid. * * \param serverTokens specifies information about the host, the UPnP version * used and of the product. Note that if this parameter specifies * UPnP version 1.1 or later, \c bootId and \c configId have to be properly defined. * Otherwise the created object will be invalid. * * \note Although server tokens are mandatory according to the UDA, * this is not enforced by this class for interoperability reasons. * * \param usn specifies the Unique Service Name. The created object is valid * only if the provided USN is valid. * * \param bootId specifies the \c BOOTID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0. Because of this the class requires a valid value (>= 0) only in case * the \c serverTokens identify UPnP v1.1 or later. * * \param configId specifies the \c CONFIGID.UPNP.ORG header value. Note that * this is mandatory in UDA v1.1, whereas it is not specified at all in * UDA v1.0. Because of this, the class requires a valid value (>= 0) only in case * the \c serverTokens identify UPnP v1.1 or later. * * \param searchPort specifies the \c SEARCHPORT.UPNP.ORG header value. Note that * this is optional in UDA v1.1, whereas it is not specified at all in UDA v1.0. * If specified, this is the port at which the device must listen for unicast * \c M-SEARCH messages. Otherwise the port is the default \c 1900. * This parameter is optional. * * \remarks * \li if cacheControlMaxAge is smaller than 5, it it set to 5 or if it is * larger than 60 * 60 * 24 (a day in seconds), it is set to a day measured in seconds. * * \li if searchPort is smaller than 49152 or larger than 65535 it is set to -1. * The range is specified in UDA v1.1. * * \sa isValid() */ HDiscoveryResponse( qint32 cacheControlMaxAge, const QDateTime& date, const QUrl& location, const HProductTokens& serverTokens, const HDiscoveryType& usn, qint32 bootId = -1, qint32 configId = 0, qint32 searchPort = -1); /*! * \brief Copy constructor. * * Copies the contents of \c other to this. */ HDiscoveryResponse(const HDiscoveryResponse&); /*! * Assigns the contents of the other to this. Makes a deep copy. * * \return reference to this object. */ HDiscoveryResponse& operator=(const HDiscoveryResponse&); /*! * \brief Destroys the instance. */ ~HDiscoveryResponse(); /*! * \brief Indicates whether or not the object contains valid announcement information. * * \param level indicates whether the check should be strictly according * to the UDA specification. If set to false some checks are omitted that * are known to be poorly implemented in some UPnP software. * * \return \e true in case the objects contains valid announcement * information in terms of the requested strictness. */ bool isValid(HValidityCheckLevel level) const; /*! * \brief Returns the server tokens. * * \return The server tokens. */ const HProductTokens& serverTokens() const; /*! * \brief Returns the date when the response was generated. * * \return The date when the response was generated. */ QDateTime date() const; /*! * \brief Returns the Unique Service Name. * * The Unique Service Name identifies a unique \e device or \e service instance. * * \return The Unique Service Name. The returned object is invalid if this * object is invalid. * * \sa isValid() */ const HDiscoveryType& usn() const; /*! * \brief Returns the location of the announced device. * * \return The location of the announced device. This is the URL where * the device description can be retrieved. The returned object * will be empty if this object is invalid. * * \sa isValid() */ QUrl location() const; /*! * \brief Returns the number of seconds the advertisement is valid. * * \return The number of seconds the advertisement is valid. */ qint32 cacheControlMaxAge() const; /*! * \brief Returns the value of \c BOOTID.UPNP.ORG. * * \return The value of \c BOOTID.UPNP.ORG. * If the value is not specified -1 is returned. */ qint32 bootId() const; /*! * \brief Returns the value of \c CONFIGID.UPNP.ORG. * * \return The value of \c CONFIGID.UPNP.ORG. * If the value is not specified -1 is returned. */ qint32 configId() const; /*! * \brief Returns the value of \c SEARCHPORT.UPNP.ORG header field. * * \return The value of \c SEARCHPORT.UPNP.ORG header field. * If the value is not specified -1 is returned. */ qint32 searchPort() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the objects are logically the equivalent. * * \relates HDiscoveryResponse */ H_UPNP_CORE_EXPORT bool operator==( const HDiscoveryResponse&, const HDiscoveryResponse&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically the equivalent. * * \relates HDiscoveryResponse */ inline bool operator!=( const HDiscoveryResponse& obj1, const HDiscoveryResponse& obj2) { return !(obj1 == obj2); } } } #endif /* HDISCOVERY_MSGS_H_ */ herqq-1.0.0/hupnp/src/ssdp/hssdp.h0000644000000000000000000003774211543637310015532 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSSDP_H_ #define HSSDP_H_ #include #include class QUrl; class QString; class QHostAddress; namespace Herqq { namespace Upnp { class HSsdpPrivate; /*! * \brief This class is used for sending and receiving SSDP messages defined by the * UPnP Device Architecture specification. * * Simple Service Discovery Protocol (SSDP) is an expired IETF Internet draft * on which the UPnP discovery mechanism is built. This class implements only the * SSDP functionality mandated by the UPnP Device Architecture specification. * \brief This class does not implement the SSDP draft in full. * * To use this class, you only need to instantiate it and connect to the * exposed signals to receive events when SSDP messages are received. You can also * derive a sub-class and override the various virtual member functions to handle * the received messages. * * \headerfile hssdp.h HSsdp * * \ingroup hupnp_ssdp * * \remarks * \li this class requires an event loop for listening incoming messages * \li this class has thread-affinity, which mandates that the instances of this * class has to be used in the thread in which they are located at the time. */ class H_UPNP_CORE_EXPORT HSsdp : public QObject { Q_OBJECT H_DISABLE_COPY(HSsdp) H_DECLARE_PRIVATE(HSsdp) public: /*! * \brief This enumeration specifies the different discovery methods the * HSsdp class can run. */ enum DiscoveryRequestMethod { /*! * This is the default multicast discovery supported both UDA v1.0 and * UDA v1.1. */ MulticastDiscovery, /*! * The unicast discovery specified in UDA v1.1. */ UnicastDiscovery }; private Q_SLOTS: void unicastMessageReceived(); void multicastMessageReceived(); protected: HSsdpPrivate* h_ptr; HSsdp(const QByteArray& loggingIdentifier, QObject* parent = 0); protected: /*! * This method is called immediately after receiving a discovery request. * * Override this method if you want to handle the message. You can also connect * to the discoveryRequestReceived() signal. * * \param msg specifies the incoming message. * \param source specifies the source TCP/IP endpoint that sent the * message. * \param requestType specifies the type of the incoming discovery request. * * \retval true in case the message was handled successfully and the * discoveryRequestReceived() signal should not be sent. * * \retval false in case the message was not handled and the * discoveryRequestReceived() signal should be sent. * * \sa discoveryRequestReceived() */ virtual bool incomingDiscoveryRequest( const HDiscoveryRequest& msg, const HEndpoint& source, DiscoveryRequestMethod requestType); /*! * This method is called immediately after receiving a discovery response. * Override this method if you want to handle message. You can also connect * to the discoveryResponseReceived() signal. * * \param msg specifies the incoming message. * \param source specifies the source TCP/IP endpoint that sent the * message. * * \retval true in case the message was handled successfully and the * discoveryResponseReceived() signal should not be sent. * * \retval false in case the message was not handled and the * discoveryResponseReceived() signal should be sent. * * \sa discoveryResponseReceived() */ virtual bool incomingDiscoveryResponse( const HDiscoveryResponse& msg, const HEndpoint& source); /*! * This method is called immediately after receiving a device available announcement. * Override this method if you want to handle message. You can also connect * to the discoveryRequestReceived() signal. * * \param msg specifies the incoming message. * \param source specifies the source TCP/IP endpoint that sent the * message. * * \retval true in case the message was handled successfully and the * resourceAvailableReceived() signal should not be sent. * * \retval false in case the message was not handled and the * resourceAvailableReceived() signal should be sent. * * \sa resourceAvailableReceived() */ virtual bool incomingDeviceAvailableAnnouncement( const HResourceAvailable& msg, const HEndpoint& source); /*! * This method is called immediately after receiving a device unavailable announcement. * Override this method if you want to handle message. You can also connect * to the resourceUnavailableReceived() signal. * * \param msg specifies the incoming message. * \param source specifies the source TCP/IP endpoint that sent the * message. * * \retval true in case the message was handled successfully and the * resourceUnavailableReceived() signal should not be sent. * * \retval false in case the message was not handled and the * resourceUnavailableReceived() signal should be sent. * * \sa resourceUnavailableReceived() */ virtual bool incomingDeviceUnavailableAnnouncement( const HResourceUnavailable& msg, const HEndpoint& source); /*! * This method is called immediately after receiving a device update announcement. * Override this method if you want to handle message. You can also connect * to the deviceUpdateRecieved() signal. * * \param msg specifies the incoming message. * \param source specifies the source TCP/IP endpoint that sent the * message. * * \retval true in case the message was handled successfully and the * deviceUpdateRecieved() signal should not be sent. * * \retval false in case the message was not handled and the * deviceUpdateRecieved() signal should be sent. * * \sa deviceUpdateRecieved() */ virtual bool incomingDeviceUpdateAnnouncement( const HResourceUpdate& msg, const HEndpoint& source); public: /*! * \brief Creates a new instance. * * \param parent specifies the parent \c QObject. */ HSsdp(QObject* parent=0); /*! * \brief Destroys the instance. */ virtual ~HSsdp(); /*! * This enum is used to define a "filter", which specifies which message * types are to be processed when encountered. * * \sa filter(), setFilter() */ enum AllowedMessage { /*! * No messages are processed. */ None = 0x00, /*! * Device available messages are processed. */ DeviceAvailable = 0x01, /*! * Device update messages are processed. */ DeviceUpdate = 0x02, /*! * Device unavailable messages are processed. */ DeviceUnavailable = 0x04, /*! * Discovery request messages are processed. */ DiscoveryRequest = 0x08, /*! * Discovery response messages are processed. */ DiscoveryResponse = 0x10, /*! * Discovery response messages are processed. */ All = 0x1f }; Q_DECLARE_FLAGS(AllowedMessages, AllowedMessage); /*! * \brief Sets the filter of what message types are accepted for processing. * * The default is HSsdp::All. * * \param allowedMessages defines the message types the instance should * accept for further processing. Other message types will be silently ignored. * * \sa filter() */ void setFilter(AllowedMessages allowedMessages); /*! * \brief Returns the message types that are currently accepted for processing. * * Default is HSsdp::All. * * \return The message types that are currently accepted for processing. * * \sa setFilter() */ AllowedMessages filter() const; /*! * \brief Sets the instance to listen the network for SSDP messages and and attempts to * init the unicast socket of the instance to the address of the first * found network address that is up and that is not loopback. If no such * interface is found the loopback address is used. * * \retval true in case the instances was successfully bound to some address. * \retval false in case the instance could not be bound or the instance * was already bound. * * \remarks \c %HSsdp has to be bound to receive messages of any type. */ bool init(); /*! * \brief Sets the instance to listen the network for SSDP messages and attempts to * init a unicast socket of the instance to the specified address. * * \param unicastAddress specifies the address that should be used for * unicast messaging. * * \retval true in case the instance was successfully bound to the * specified address. * * \retval false in case the instance could not be bound or the instance * was already bound to the specified address. * * \remarks \c %HSsdp has to be bound to receive messages of any type. */ bool init(const QHostAddress& unicastAddress); /*! * \brief Indicates if the instance is bound to listen for messages using one * or more network interfaces. * * \return \e true in case the instance is bound to listen for messages * using one or more network interfaces. */ bool isInitialized() const; /*! * \brief Returns the UDP endpoint that is used for unicast communication. * * \return The UDP endpoint that is used for unicast communication. */ HEndpoint unicastEndpoint() const; /*! * Sends the specified device availability announcement. * * \param msg specifies the announcement to send. * \param count specifies how many times the announcement is send. * The default is 1. * * \return The number of messages sent, 0 in case no messages was sent or * -1 in case the provided message is not valid. */ qint32 announcePresence(const HResourceAvailable& msg, qint32 count = 1); /*! * Sends the specified device availability announcement. * * \param msg specifies the announcement to send. * \param count specifies how many times the announcement is send. * The default is 1. * * \return The number of messages sent, 0 in case no messages was sent or * -1 in case the provided message is not valid. */ qint32 announcePresence(const HResourceUnavailable& msg, qint32 count = 1); /*! * Sends the specified device update announcement. * * \param msg specifies the message to send. * \param count specifies how many times the announcement is send. * The default is 1. * * \return The number of messages sent, 0 in case no messages was sent or * -1 in case the provided message is not valid. */ qint32 announceUpdate(const HResourceUpdate& msg, qint32 count = 1); /*! * Sends the specified discovery request. * * Sends the specified discovery request to a multicast address * 239.255.255.250. * * \param msg specifies the announcement to send. * \param count specifies how many times the announcement is send. * The default is 1. * * \return The number of messages sent, 0 in case no messages was sent or * -1 in case the provided message is not valid. */ qint32 sendDiscoveryRequest(const HDiscoveryRequest& msg, qint32 count = 1); /*! * Sends the specified discovery request. * * Sends the specified discovery request to a specified address. The * address can be an unicast address or a multicast address. * * \param msg specifies the announcement to send. * \param destination specifies the target UDP endpoint of the message. * If the port of the specified endpoint is set to zero the message is sent * to the specified host address using the default port 1900. * \param count specifies how many times the announcement is send. * The default is 1. * * \return The number of messages sent, 0 in case no messages was sent or * -1 in case the provided message or the destination is not valid. */ qint32 sendDiscoveryRequest( const HDiscoveryRequest& msg, const HEndpoint& destination, qint32 count = 1); /*! * Sends the specified discovery response. * * \param msg specifies the announcement to send. * * \param destination specifies the target of the response. * If the port of the specified endpoint is set to zero the message is sent * to the specified host address using the default port 1900. * \param count specifies how many times the announcement is send. * The default is 1. * * \return The number of messages sent, 0 in case no messages was sent or * -1 in case the provided message is not valid. */ qint32 sendDiscoveryResponse( const HDiscoveryResponse& msg, const HEndpoint& destination, qint32 count = 1); //// //////////////////////////////////////////////////////////////////////////////// Q_SIGNALS: /*! * \brief This signal is emitted when a discovery request is received. * * \param msg specifies the received discovery request message. * \param source specifies the location where the message came. * \param requestType specifies the type of the incoming discovery request. */ void discoveryRequestReceived( const Herqq::Upnp::HDiscoveryRequest& msg, const Herqq::Upnp::HEndpoint& source, Herqq::Upnp::HSsdp::DiscoveryRequestMethod requestType); /*! * \brief This signal is emitted when a discovery response is received. * * \param msg specifies the received discovery response message. * \param source specifies the location where the message came. */ void discoveryResponseReceived( const Herqq::Upnp::HDiscoveryResponse& msg, const Herqq::Upnp::HEndpoint& source); /*! * \brief This signal is emitted when a device announcement is received. * * \param msg specifies the device announcement message. * \param source specifies the location where the message came. */ void resourceAvailableReceived( const Herqq::Upnp::HResourceAvailable& msg, const Herqq::Upnp::HEndpoint& source); /*! * \brief This signal is emitted when a device update is received. * * \param msg specifies the device update message. * \param source specifies the location where the message came. */ void deviceUpdateReceived( const Herqq::Upnp::HResourceUpdate& msg, const Herqq::Upnp::HEndpoint& source); /*! * \brief This signal is emitted when a device announcement is received. * * \param msg specifies the device announcement message. * \param source specifies the location where the message came. */ void resourceUnavailableReceived( const Herqq::Upnp::HResourceUnavailable& msg, const Herqq::Upnp::HEndpoint& source); }; Q_DECLARE_OPERATORS_FOR_FLAGS(HSsdp::AllowedMessages) } } #endif /* HSSDP_H_ */ herqq-1.0.0/hupnp/src/ssdp/hssdp_messagecreator_p.cpp0000644000000000000000000001415311543637310021457 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hssdp_messagecreator_p.h" #include "hdiscovery_messages.h" #include "../dataelements/hresourcetype.h" #include "../dataelements/hdiscoverytype.h" #include "../dataelements/hproduct_tokens.h" #include "../socket/hendpoint.h" #include "../general/hlogger_p.h" #include #include namespace Herqq { namespace Upnp { namespace { HEndpoint multicastEndpoint() { static HEndpoint retVal(QHostAddress("239.255.255.250"), 1900); return retVal; } QString getTarget(const HDiscoveryType& ri) { switch(ri.type()) { case HDiscoveryType::Undefined: return ""; case HDiscoveryType::All: case HDiscoveryType::RootDevices: case HDiscoveryType::SpecificDevice: return ri.toString(); case HDiscoveryType::SpecificRootDevice: return "upnp:rootdevice"; default: return ri.resourceType().toString(); } return QString(); } } HSsdpMessageCreator::HSsdpMessageCreator() { } HSsdpMessageCreator::~HSsdpMessageCreator() { } QByteArray HSsdpMessageCreator::create(const HResourceUpdate& msg) { if (!msg.isValid(StrictChecks)) { return QByteArray(); } QString retVal; QTextStream ts(&retVal); ts << "NOTIFY * HTTP/1.1\r\n" << "HOST: " << multicastEndpoint().toString() << "\r\n" << "LOCATION: " << msg.location().toString() << "\r\n" << "NT: " << getTarget(msg.usn()) << "\r\n" << "NTS: " << "ssdp:update\r\n" << "USN: " << msg.usn().toString() << "\r\n"; if (msg.bootId() >= 0) { ts << "BOOTID.UPNP.ORG: " << msg.bootId() << "\r\n" << "CONFIGID.UPNP.ORG: " << msg.configId() << "\r\n" << "NEXTBOOTID.UPNP.ORG: " << msg.nextBootId() << "\r\n"; if (msg.searchPort() >= 0) { ts << "SEARCHPORT.UPNP.ORG: " << msg.searchPort() << "\r\n"; } } ts << "\r\n"; return retVal.toUtf8(); } QByteArray HSsdpMessageCreator::create(const HDiscoveryRequest& msg) { if (!msg.isValid(StrictChecks)) { return QByteArray(); } QString retVal; QTextStream out(&retVal); out << "M-SEARCH * HTTP/1.1\r\n" << "HOST: " << multicastEndpoint().toString() << "\r\n" << "MAN: " << "\"ssdp:discover\"\r\n" << "MX: " << msg.mx() << "\r\n" << "ST: " << getTarget(msg.searchTarget()) << "\r\n" << "USER-AGENT: " << msg.userAgent().toString()<< "\r\n\r\n"; return retVal.toUtf8(); } QByteArray HSsdpMessageCreator::create(const HDiscoveryResponse& msg) { if (!msg.isValid(StrictChecks)) { return QByteArray(); } QString retVal; QTextStream out(&retVal); out << "HTTP/1.1 200 OK\r\n" << "CACHE-CONTROL: max-age=" << msg.cacheControlMaxAge() << "\r\n" << "EXT:\r\n" << "LOCATION: " << msg.location().toString() << "\r\n" << "SERVER: " << msg.serverTokens().toString() << "\r\n" << "ST: " << getTarget(msg.usn()) << "\r\n" << "USN: " << msg.usn().toString() << "\r\n"; if (msg.bootId() >= 0) { out << "BOOTID.UPNP.ORG: " << msg.bootId() << "\r\n" << "CONFIGID.UPNP.ORG: " << msg.configId() <<"\r\n"; if (msg.searchPort() >= 0) { out << "SEARCHPORT.UPNP.ORG: " << msg.searchPort() << "\r\n"; } } out << "\r\n"; return retVal.toUtf8(); } QByteArray HSsdpMessageCreator::create(const HResourceAvailable& msg) { if (!msg.isValid(StrictChecks)) { return QByteArray(); } QString retVal; QTextStream ts(&retVal); ts << "NOTIFY * HTTP/1.1\r\n" << "HOST: " << multicastEndpoint().toString() << "\r\n" << "CACHE-CONTROL: max-age=" << msg.cacheControlMaxAge() << "\r\n" << "LOCATION: " << msg.location().toString() << "\r\n" << "NT: " << getTarget(msg.usn()) << "\r\n" << "NTS: " << "ssdp:alive\r\n" << "SERVER: " << msg.serverTokens().toString() << "\r\n" << "USN: " << msg.usn().toString() << "\r\n"; if (msg.serverTokens().upnpToken().minorVersion() > 0) { ts << "BOOTID.UPNP.ORG: " << msg.bootId() << "\r\n" << "CONFIGID.UPNP.ORG: " << msg.configId() << "\r\n"; if (msg.searchPort() >= 0) { ts << "SEARCHPORT.UPNP.ORG: " << msg.searchPort() << "\r\n"; } } ts << "\r\n"; return retVal.toUtf8(); } QByteArray HSsdpMessageCreator::create(const HResourceUnavailable& msg) { if (!msg.isValid(StrictChecks)) { return QByteArray(); } QString retVal; QTextStream ts(&retVal); ts << "NOTIFY * HTTP/1.1\r\n" << "HOST: " << multicastEndpoint().toString()<< "\r\n" << "NT: " << getTarget(msg.usn()) << "\r\n" << "NTS: " << "ssdp:byebye\r\n" << "USN: " << msg.usn().toString() << "\r\n"; if (msg.bootId() >= 0) { ts << "BOOTID.UPNP.ORG: " << msg.bootId () << "\r\n" << "CONFIGID.UPNP.ORG: " << msg.configId() << "\r\n"; } ts << "\r\n"; return retVal.toUtf8(); } } } herqq-1.0.0/hupnp/src/ssdp/hdiscovery_messages.cpp0000644000000000000000000005047311543637310021006 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hdiscovery_messages.h" #include "../dataelements/hudn.h" #include "../dataelements/hresourcetype.h" #include "../dataelements/hdiscoverytype.h" #include "../dataelements/hproduct_tokens.h" #include "../socket/hendpoint.h" #include "../general/hlogger_p.h" #include #include #include #include namespace Herqq { namespace Upnp { /******************************************************************************* * HResourceAvailablePrivate ******************************************************************************/ class HResourceAvailablePrivate : public QSharedData { HResourceAvailablePrivate& operator=(const HResourceAvailablePrivate&); public: // attributes HProductTokens m_serverTokens; HDiscoveryType m_usn; QUrl m_location; qint32 m_cacheControlMaxAge; qint32 m_bootId; qint32 m_configId; qint32 m_searchPort; public: // methods HResourceAvailablePrivate(); ~HResourceAvailablePrivate(); }; HResourceAvailablePrivate::HResourceAvailablePrivate() : m_serverTokens(), m_usn(), m_location(), m_cacheControlMaxAge(0), m_bootId(0), m_configId(0), m_searchPort(0) { } HResourceAvailablePrivate::~HResourceAvailablePrivate() { } /******************************************************************************* * HResourceAvailable ******************************************************************************/ HResourceAvailable::HResourceAvailable() : h_ptr(new HResourceAvailablePrivate()) { } HResourceAvailable::HResourceAvailable( qint32 cacheControlMaxAge, const QUrl& location, const HProductTokens& serverTokens, const HDiscoveryType& usn, qint32 bootId, qint32 configId, qint32 searchPort) : h_ptr(new HResourceAvailablePrivate()) { HLOG(H_AT, H_FUN); if (cacheControlMaxAge < 5) { cacheControlMaxAge = 5; } else if (cacheControlMaxAge > 60 * 60 * 24) { cacheControlMaxAge = 60* 60 * 24; } if (usn.type() == HDiscoveryType::Undefined) { HLOG_WARN("USN is not defined"); return; } if (!location.isValid() || location.isEmpty()) { HLOG_WARN(QString("Location is not defined")); return; } if (!serverTokens.isValid()) { HLOG_WARN_NONSTD(QString("Server tokens are not defined")); // although mandatory according to UDA, some UPnP software // do not define this ==> cannot require it } if (serverTokens.upnpToken().minorVersion() > 0) { if (bootId < 0 || configId < 0) { HLOG_WARN("bootId and configId must both be >= 0."); return; } if (searchPort < 49152 || searchPort > 65535) { searchPort = -1; } } else { searchPort = -1; } h_ptr->m_serverTokens = serverTokens; h_ptr->m_usn = usn; h_ptr->m_location = location; h_ptr->m_cacheControlMaxAge = cacheControlMaxAge; h_ptr->m_configId = configId; h_ptr->m_bootId = bootId; h_ptr->m_searchPort = searchPort; } HResourceAvailable::HResourceAvailable(const HResourceAvailable& other) : h_ptr(other.h_ptr) { } HResourceAvailable& HResourceAvailable::operator=( const HResourceAvailable& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HResourceAvailable::~HResourceAvailable() { } bool HResourceAvailable::isValid(HValidityCheckLevel level) const { return (h_ptr->m_usn.type() != HDiscoveryType::Undefined) && (level == StrictChecks ? h_ptr->m_serverTokens.isValid() : true); } const HProductTokens& HResourceAvailable::serverTokens() const { return h_ptr->m_serverTokens; } const HDiscoveryType& HResourceAvailable::usn() const { return h_ptr->m_usn; } QUrl HResourceAvailable::location() const { return h_ptr->m_location; } qint32 HResourceAvailable::cacheControlMaxAge() const { return h_ptr->m_cacheControlMaxAge; } qint32 HResourceAvailable::bootId() const { return h_ptr->m_bootId; } qint32 HResourceAvailable::configId() const { return h_ptr->m_configId; } qint32 HResourceAvailable::searchPort() const { return h_ptr->m_searchPort; } bool operator==(const HResourceAvailable& obj1, const HResourceAvailable& obj2) { return obj1.h_ptr->m_serverTokens == obj2.h_ptr->m_serverTokens && obj1.h_ptr->m_usn == obj2.h_ptr->m_usn && obj1.h_ptr->m_location == obj2.h_ptr->m_location && obj1.h_ptr->m_cacheControlMaxAge == obj2.h_ptr->m_cacheControlMaxAge && obj1.h_ptr->m_bootId == obj2.h_ptr->m_bootId && obj1.h_ptr->m_configId == obj2.h_ptr->m_configId && obj1.h_ptr->m_searchPort == obj2.h_ptr->m_searchPort; } /******************************************************************************* * HResourceUnavailablePrivate ******************************************************************************/ class HResourceUnavailablePrivate : public QSharedData { HResourceUnavailablePrivate& operator=(const HResourceUnavailablePrivate&); public: // attributes HDiscoveryType m_usn; qint32 m_bootId; qint32 m_configId; HEndpoint m_sourceLocation; public: // methods HResourceUnavailablePrivate(); ~HResourceUnavailablePrivate(); }; HResourceUnavailablePrivate::HResourceUnavailablePrivate() : m_usn(), m_bootId(0), m_configId(0), m_sourceLocation(0) { } HResourceUnavailablePrivate::~HResourceUnavailablePrivate() { } /******************************************************************************* * HResourceUnavailable ******************************************************************************/ HResourceUnavailable::HResourceUnavailable() : h_ptr(new HResourceUnavailablePrivate()) { } HResourceUnavailable::HResourceUnavailable( const HDiscoveryType& usn, qint32 bootId, qint32 configId) : h_ptr(new HResourceUnavailablePrivate()) { HLOG(H_AT, H_FUN); if (usn.type() == HDiscoveryType::Undefined) { HLOG_WARN("USN is not defined"); return; } if ((bootId < 0 && configId >= 0) || (configId < 0 && bootId >= 0)) { HLOG_WARN("If either bootId or configId is specified they both must be >= 0"); return; } if (bootId < 0) { bootId = -1; configId = -1; } h_ptr->m_usn = usn; h_ptr->m_configId = configId; h_ptr->m_bootId = bootId; } HResourceUnavailable::HResourceUnavailable(const HResourceUnavailable& other) : h_ptr(other.h_ptr) { } HResourceUnavailable& HResourceUnavailable::operator=( const HResourceUnavailable& other) { Q_ASSERT(this != &other); h_ptr = other.h_ptr; return *this; } HResourceUnavailable::~HResourceUnavailable() { } HEndpoint HResourceUnavailable::location() const { return h_ptr->m_sourceLocation; } bool HResourceUnavailable::isValid(HValidityCheckLevel level) const { Q_UNUSED(level) return h_ptr->m_usn.type() != HDiscoveryType::Undefined; // if the object is valid, the USN is valid } const HDiscoveryType& HResourceUnavailable::usn() const { return h_ptr->m_usn; } qint32 HResourceUnavailable::bootId() const { return h_ptr->m_bootId; } qint32 HResourceUnavailable::configId() const { return h_ptr->m_configId; } bool operator==(const HResourceUnavailable& obj1, const HResourceUnavailable& obj2) { return obj1.h_ptr->m_usn == obj2.h_ptr->m_usn && obj1.h_ptr->m_bootId == obj2.h_ptr->m_bootId && obj1.h_ptr->m_configId == obj2.h_ptr->m_configId; } /******************************************************************************* * HResourceUpdatePrivate ******************************************************************************/ class HResourceUpdatePrivate : public QSharedData { HResourceUpdatePrivate& operator=(const HResourceUpdatePrivate&); public: // attributes HDiscoveryType m_usn; QUrl m_location; qint32 m_bootId; qint32 m_configId; qint32 m_nextBootId; qint32 m_searchPort; public: // methods HResourceUpdatePrivate(); ~HResourceUpdatePrivate(); }; HResourceUpdatePrivate::HResourceUpdatePrivate() : m_usn(), m_location(), m_bootId(0), m_configId(0), m_nextBootId(0), m_searchPort(0) { } HResourceUpdatePrivate::~HResourceUpdatePrivate() { } /******************************************************************************* * HResourceUpdate ******************************************************************************/ HResourceUpdate::HResourceUpdate() : h_ptr(new HResourceUpdatePrivate()) { } HResourceUpdate::HResourceUpdate( const QUrl& location, const HDiscoveryType& usn, qint32 bootId, qint32 configId, qint32 nextBootId, qint32 searchPort) : h_ptr(new HResourceUpdatePrivate()) { HLOG(H_AT, H_FUN); if (usn.type() == HDiscoveryType::Undefined) { HLOG_WARN("USN is not defined"); return; } if (!location.isValid()) { HLOG_WARN("Location is not defined"); return; } if ((bootId < 0 && (configId >= 0 || nextBootId >= 0)) || (configId < 0 && (bootId >= 0 || nextBootId >= 0)) || (nextBootId < 0 && (bootId >= 0 || configId >= 0))) { HLOG_WARN("If bootId, configId or nextBootId is specified, " \ "they all must be >= 0."); return; } if (bootId < 0) { bootId = -1; configId = -1; nextBootId = -1; searchPort = -1; } else if (searchPort < 49152 || searchPort > 65535) { searchPort = -1; } h_ptr->m_usn = usn; h_ptr->m_location = location; h_ptr->m_configId = configId; h_ptr->m_bootId = bootId; h_ptr->m_nextBootId = nextBootId; h_ptr->m_searchPort = searchPort; } HResourceUpdate::HResourceUpdate(const HResourceUpdate& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HResourceUpdate& HResourceUpdate::operator=(const HResourceUpdate& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HResourceUpdate::~HResourceUpdate() { } bool HResourceUpdate::isValid(HValidityCheckLevel level) const { Q_UNUSED(level) return h_ptr->m_usn.type() != HDiscoveryType::Undefined; // if the object is valid, the USN is valid } const HDiscoveryType& HResourceUpdate::usn() const { return h_ptr->m_usn; } QUrl HResourceUpdate::location() const { return h_ptr->m_location; } qint32 HResourceUpdate::bootId() const { return h_ptr->m_bootId; } qint32 HResourceUpdate::configId() const { return h_ptr->m_configId; } qint32 HResourceUpdate::nextBootId() const { return h_ptr->m_nextBootId; } qint32 HResourceUpdate::searchPort() const { return h_ptr->m_searchPort; } bool operator==(const HResourceUpdate& obj1, const HResourceUpdate& obj2) { return obj1.h_ptr->m_usn == obj2.h_ptr->m_usn && obj1.h_ptr->m_location == obj2.h_ptr->m_location && obj1.h_ptr->m_bootId == obj2.h_ptr->m_bootId && obj1.h_ptr->m_configId == obj2.h_ptr->m_configId && obj1.h_ptr->m_searchPort == obj2.h_ptr->m_searchPort; } /******************************************************************************* * HDiscoveryRequestPrivate ******************************************************************************/ class HDiscoveryRequestPrivate : public QSharedData { HDiscoveryRequestPrivate& operator=(const HDiscoveryRequestPrivate&); public: // attributes HDiscoveryType m_st; qint32 m_mx; HProductTokens m_userAgent; public: // methods HDiscoveryRequestPrivate() : m_st(), m_mx(0), m_userAgent() {} bool init(const HDiscoveryType& st, qint32 mx, const HProductTokens& userAgent) { HLOG(H_AT, H_FUN); if (st.type() == HDiscoveryType::Undefined) { HLOG_WARN("Search Target is not specified"); return false; } bool treatAsUpnp1_0 = true; if (!userAgent.isValid()) { HLOG_WARN_NONSTD(QString("Invalid user agent: [%1]").arg( userAgent.toString())); } else if (userAgent.upnpToken().minorVersion() >= 1) { treatAsUpnp1_0 = false; } if (treatAsUpnp1_0) { if (mx < 0) { HLOG_WARN("MX cannot be negative"); return false; } else if (mx < 1) { HLOG_WARN("MX should be between 1 and 120 inclusive"); } else if (mx > 120) { HLOG_WARN("MX should be between 1 and 120 inclusive, using 120"); mx = 120; // UDA 1.0 instructs to treat MX values larger than 120 as 120 } } else { if (mx < 1) { HLOG_WARN("MX cannot be smaller than 1"); return false; } else if (mx > 5) { HLOG_WARN("MX should be less than 5 inclusive, setting it to 5"); mx = 5; // UDA 1.1 instructs to treat MX values larger than 5 as 5 } } m_st = st; m_mx = mx; m_userAgent = userAgent; return true; } }; /******************************************************************************* * HDiscoveryRequest ******************************************************************************/ HDiscoveryRequest::HDiscoveryRequest() : h_ptr(new HDiscoveryRequestPrivate()) { } HDiscoveryRequest::HDiscoveryRequest( qint32 mx, const HDiscoveryType& st, const HProductTokens& userAgent) : h_ptr(new HDiscoveryRequestPrivate()) { h_ptr->init(st, mx, userAgent); } HDiscoveryRequest::HDiscoveryRequest(const HDiscoveryRequest& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HDiscoveryRequest& HDiscoveryRequest::operator=(const HDiscoveryRequest& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HDiscoveryRequest::~HDiscoveryRequest() { } bool HDiscoveryRequest::isValid(HValidityCheckLevel level) const { return (h_ptr->m_st.type() != HDiscoveryType::Undefined) && (level == StrictChecks ? h_ptr->m_userAgent.isValid() : true); } const HDiscoveryType& HDiscoveryRequest::searchTarget() const { return h_ptr->m_st; } qint32 HDiscoveryRequest::mx() const { return h_ptr->m_mx; } const HProductTokens& HDiscoveryRequest::userAgent() const { return h_ptr->m_userAgent; } bool operator==(const HDiscoveryRequest& obj1, const HDiscoveryRequest& obj2) { return obj1.h_ptr->m_mx == obj2.h_ptr->m_mx && obj1.h_ptr->m_st == obj2.h_ptr->m_st && obj1.h_ptr->m_userAgent == obj2.h_ptr->m_userAgent; } /******************************************************************************* * HDiscoveryResponsePrivate ******************************************************************************/ class HDiscoveryResponsePrivate : public QSharedData { HDiscoveryResponsePrivate& operator=(const HDiscoveryResponsePrivate&); public: // attributes HProductTokens m_serverTokens; HDiscoveryType m_usn; QUrl m_location; QDateTime m_date; qint32 m_cacheControlMaxAge; qint32 m_bootId; qint32 m_configId; qint32 m_searchPort; public: // methods HDiscoveryResponsePrivate() : m_serverTokens(), m_usn(), m_location(), m_date(), m_cacheControlMaxAge(0), m_bootId(0), m_configId(0), m_searchPort(0) { } }; /******************************************************************************* * HDiscoveryResponse ******************************************************************************/ HDiscoveryResponse::HDiscoveryResponse() : h_ptr(new HDiscoveryResponsePrivate()) { } HDiscoveryResponse::HDiscoveryResponse( qint32 cacheControlMaxAge, const QDateTime& /*date*/, const QUrl& location, const HProductTokens& serverTokens, const HDiscoveryType& usn, qint32 bootId, qint32 configId, qint32 searchPort) : h_ptr(new HDiscoveryResponsePrivate()) { HLOG(H_AT, H_FUN); if (cacheControlMaxAge < 5) { cacheControlMaxAge = 5; } else if (cacheControlMaxAge > 60 * 60 * 24) { cacheControlMaxAge = 60* 60 * 24; } if (usn.type() == HDiscoveryType::Undefined) { HLOG_WARN("Unique Service Name (USN) is not defined"); return; } else if (!usn.udn().isValid(LooseChecks)) { // TODO should this be a parameter? HLOG_WARN(QString("Unique Service Name (USN) is missing the " "Unique Device Name (UDN): [%1]").arg(usn.toString())); return; } if (!location.isValid()) { HLOG_WARN("Invalid resource location"); return; } if (!serverTokens.isValid()) { HLOG_WARN_NONSTD(QString("Invalid server tokens: %1").arg( serverTokens.toString())); } if (serverTokens.upnpToken().minorVersion() > 0) { if (bootId < 0 || configId < 0) { HLOG_WARN("bootId and configId must both be positive."); return; } } h_ptr->m_serverTokens = serverTokens; h_ptr->m_usn = usn; h_ptr->m_location = location; h_ptr->m_date = QDateTime::currentDateTime(); h_ptr->m_cacheControlMaxAge = cacheControlMaxAge; h_ptr->m_bootId = bootId; h_ptr->m_configId = configId; h_ptr->m_searchPort = searchPort; } HDiscoveryResponse::HDiscoveryResponse(const HDiscoveryResponse& other) : h_ptr(other.h_ptr) { Q_ASSERT(&other != this); } HDiscoveryResponse& HDiscoveryResponse::operator=(const HDiscoveryResponse& other) { Q_ASSERT(&other != this); h_ptr = other.h_ptr; return *this; } HDiscoveryResponse::~HDiscoveryResponse() { } bool HDiscoveryResponse::isValid(HValidityCheckLevel level) const { return (h_ptr->m_usn.type() != HDiscoveryType::Undefined) && (level == StrictChecks ? h_ptr->m_serverTokens.isValid() : true); } const HProductTokens& HDiscoveryResponse::serverTokens() const { return h_ptr->m_serverTokens; } QDateTime HDiscoveryResponse::date() const { return h_ptr->m_date; } const HDiscoveryType& HDiscoveryResponse::usn() const { return h_ptr->m_usn; } QUrl HDiscoveryResponse::location() const { return h_ptr->m_location; } qint32 HDiscoveryResponse::cacheControlMaxAge() const { return h_ptr->m_cacheControlMaxAge; } qint32 HDiscoveryResponse::bootId() const { return h_ptr->m_bootId; } qint32 HDiscoveryResponse::configId() const { return h_ptr->m_configId; } qint32 HDiscoveryResponse::searchPort() const { return h_ptr->m_searchPort; } bool operator==(const HDiscoveryResponse& obj1, const HDiscoveryResponse& obj2) { return obj1.h_ptr->m_serverTokens == obj2.h_ptr->m_serverTokens && obj1.h_ptr->m_usn == obj2.h_ptr->m_usn && obj1.h_ptr->m_location == obj2.h_ptr->m_location && obj1.h_ptr->m_cacheControlMaxAge == obj2.h_ptr->m_cacheControlMaxAge && obj1.h_ptr->m_bootId == obj2.h_ptr->m_bootId && obj1.h_ptr->m_configId == obj2.h_ptr->m_configId && obj1.h_ptr->m_searchPort == obj2.h_ptr->m_searchPort;// && //obj1.h_ptr->m_date == obj2.h_ptr->m_date; // the date isn't used in comparison due to something that seems to be a bug // in Qt. A datetime object created using the currentDateTime() function // copy constructed to another datetime object seems to result a logically // different object. } } } herqq-1.0.0/hupnp/src/ssdp/hssdp_p.h0000644000000000000000000000603511543637310016040 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HSSDP_P_H_ #define HSSDP_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hssdp.h" #include "hdiscovery_messages.h" #include "../socket/hendpoint.h" #include "../general/hupnp_defs.h" #include "../http/hhttp_header_p.h" #include "../socket/hmulticast_socket.h" #include class QUrl; class QString; class QHostAddress; namespace Herqq { namespace Upnp { class HSsdp; // // Implementation details of HSsdp // class HSsdpPrivate { H_DISABLE_COPY(HSsdpPrivate) private: bool parseCacheControl(const QString&, qint32*); bool checkHost(const QString& host); bool parseDiscoveryResponse(const HHttpResponseHeader&, HDiscoveryResponse*); bool parseDiscoveryRequest (const HHttpRequestHeader&, HDiscoveryRequest*); bool parseDeviceAvailable (const HHttpRequestHeader&, HResourceAvailable*); bool parseDeviceUnavailable(const HHttpRequestHeader&, HResourceUnavailable*); bool parseDeviceUpdate (const HHttpRequestHeader&, HResourceUpdate*); void clear(); public: // attributes QByteArray m_loggingIdentifier; HMulticastSocket* m_multicastSocket; // for listening multicast messages QUdpSocket* m_unicastSocket; // for sending datagrams and listening messages directed to this instance HSsdp* q_ptr; HSsdp::AllowedMessages m_allowedMessages; QString m_lastError; public: // methods HSsdpPrivate( HSsdp* qptr, const QByteArray& loggingIdentifier = QByteArray()); ~HSsdpPrivate(); bool init(const QHostAddress& addressToBind); inline bool isInitialized() const { return m_unicastSocket && m_multicastSocket; } void processNotify(const QString& msg, const HEndpoint& source); void processSearch(const QString& msg, const HEndpoint& source, const HEndpoint& destination); void processResponse(const QString& msg, const HEndpoint& source); bool send(const QByteArray& data, const HEndpoint& receiver); void messageReceived(QUdpSocket*, const HEndpoint* = 0); }; } } #endif /* HSSDP_P_H_ */ herqq-1.0.0/hupnp/src/ssdp/ssdp.pri0000644000000000000000000000045411543637310015713 0ustar rootrootHEADERS += \ $$SRC_LOC/ssdp/hssdp.h \ $$SRC_LOC/ssdp/hssdp_p.h \ $$SRC_LOC/ssdp/hdiscovery_messages.h \ $$SRC_LOC/ssdp/hssdp_messagecreator_p.h SOURCES += \ $$SRC_LOC/ssdp/hssdp.cpp \ $$SRC_LOC/ssdp/hdiscovery_messages.cpp \ $$SRC_LOC/ssdp/hssdp_messagecreator_p.cpp herqq-1.0.0/hupnp/src/socket/0000755000000000000000000000000011543637460014550 5ustar rootrootherqq-1.0.0/hupnp/src/socket/hmulticast_socket.cpp0000644000000000000000000001311111543637310020770 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hmulticast_socket.h" #include "../general/hlogger_p.h" #ifdef Q_OS_WIN #include #include #else #include #endif #include namespace Herqq { namespace Upnp { // // // class HMulticastSocketPrivate { }; HMulticastSocket::HMulticastSocket(QObject* parent) : QUdpSocket(parent), h_ptr(new HMulticastSocketPrivate()) { setProxy(QNetworkProxy::NoProxy); } HMulticastSocket::~HMulticastSocket() { delete h_ptr; } HMulticastSocket::HMulticastSocket( HMulticastSocketPrivate& dd, QObject* parent) : QUdpSocket(parent), h_ptr(&dd) { setProxy(QNetworkProxy::NoProxy); } bool HMulticastSocket::bind(quint16 port) { return QUdpSocket::bind( port, QUdpSocket::ReuseAddressHint | QUdpSocket::ShareAddress); } bool HMulticastSocket::joinMulticastGroup(const QHostAddress& groupAddress) { return joinMulticastGroup(groupAddress, QHostAddress()); } bool HMulticastSocket::joinMulticastGroup( const QHostAddress& groupAddress, const QHostAddress& localAddress) { HLOG(H_AT, H_FUN); if (groupAddress.protocol() != QAbstractSocket::IPv4Protocol) { // TODO: IPv6 multicast HLOG_WARN("IPv6 is not supported."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } if (proxy().type() != QNetworkProxy::NoProxy) { // TODO: Proxied multicast HLOG_WARN("Proxied multicast is not supported."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } if (socketDescriptor() == -1) { HLOG_WARN("Socket descriptor is invalid."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } struct ip_mreq mreq; memset(&mreq, 0, sizeof(ip_mreq)); mreq.imr_multiaddr.s_addr = inet_addr(groupAddress.toString().toUtf8()); if (!localAddress.isNull()) { mreq.imr_interface.s_addr = inet_addr(localAddress.toString().toUtf8()); } else { mreq.imr_interface.s_addr = htonl(INADDR_ANY); } if (setsockopt( socketDescriptor(), IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast(&mreq), sizeof(mreq)) < 0) { HLOG_WARN(QString( "Failed to join the group [%1] using local address: [%2].").arg( groupAddress.toString(), localAddress.toString())); setSocketError(QAbstractSocket::UnknownSocketError); return false; } return true; } bool HMulticastSocket::leaveMulticastGroup(const QHostAddress& groupAddress) { return leaveMulticastGroup(groupAddress, QHostAddress()); } bool HMulticastSocket::leaveMulticastGroup( const QHostAddress& groupAddress, const QHostAddress& localAddress) { HLOG(H_AT, H_FUN); if (groupAddress.protocol() != QAbstractSocket::IPv4Protocol) { // TODO: IPv6 multicast HLOG_WARN("IPv6 is not supported."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } if (proxy().type() != QNetworkProxy::NoProxy) { // TODO: Proxied multicast HLOG_WARN("Proxied multicast is not supported."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } if (socketDescriptor() == -1) { HLOG_WARN("Socket descriptor is invalid."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } struct ip_mreq mreq; memset(&mreq, 0, sizeof(ip_mreq)); mreq.imr_multiaddr.s_addr = inet_addr(groupAddress.toString().toUtf8()); if (localAddress.isNull()) { mreq.imr_interface.s_addr = htons(INADDR_ANY); } else { mreq.imr_interface.s_addr = inet_addr(localAddress.toString().toUtf8()); } if (setsockopt( socketDescriptor(), IPPROTO_IP, IP_DROP_MEMBERSHIP, reinterpret_cast(&mreq), sizeof(mreq)) < 0) { HLOG_WARN("Failed to leave the specified group."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } return true; } bool HMulticastSocket::setMulticastTtl(quint8 ttl) { HLOG(H_AT, H_FUN); if (socketDescriptor() == -1) { HLOG_WARN("Socket descriptor is invalid."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } if (setsockopt( socketDescriptor(), IPPROTO_IP, IP_MULTICAST_TTL, reinterpret_cast(&ttl), sizeof(ttl)) < 0) { HLOG_WARN("Could not set multicast TTL to the specified value."); setSocketError(QAbstractSocket::UnknownSocketError); return false; } return true; } } } herqq-1.0.0/hupnp/src/socket/socket.pri0000644000000000000000000000027611543637310016553 0ustar rootrootHEADERS += \ $$SRC_LOC/socket/hmulticast_socket.h \ $$SRC_LOC/socket/hendpoint.h SOURCES += \ $$SRC_LOC/socket/hendpoint.cpp \ $$SRC_LOC/socket/hmulticast_socket.cpp herqq-1.0.0/hupnp/src/socket/hendpoint.cpp0000644000000000000000000000572011543637310017242 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hendpoint.h" #include "../utils/hmisc_utils_p.h" #include namespace Herqq { namespace Upnp { /******************************************************************************* * HEndpoint ******************************************************************************/ HEndpoint::HEndpoint(const QHostAddress& hostAddress, quint16 portNumber) : m_hostAddress(hostAddress), m_portNumber(hostAddress == QHostAddress::Null ? (quint16)0 : portNumber) { } HEndpoint::HEndpoint(const QHostAddress& hostAddress) : m_hostAddress(hostAddress), m_portNumber(0) { } HEndpoint::HEndpoint() : m_hostAddress(QHostAddress::Null), m_portNumber(0) { } HEndpoint::HEndpoint(const QUrl& url) : m_hostAddress(QHostAddress(url.host())), m_portNumber(m_hostAddress == QHostAddress::Null ? (quint16)0 : url.port()) { } HEndpoint::HEndpoint(const QString& arg) : m_hostAddress(), m_portNumber(0) { qint32 delim = arg.indexOf(':'); if (delim < 0) { m_hostAddress = arg; } else { m_hostAddress = arg.left(delim); if (m_hostAddress == QHostAddress::Null) { m_portNumber = 0; } else { m_portNumber = arg.mid(delim+1).toUShort(); } } } HEndpoint::~HEndpoint() { } bool HEndpoint::isMulticast() const { quint32 ipaddr = m_hostAddress.toIPv4Address(); return ((ipaddr & 0xe0000000) == 0xe0000000) || ((ipaddr & 0xe8000000) == 0xe8000000) || ((ipaddr & 0xef000000) == 0xef000000); } QString HEndpoint::toString() const { return isNull() ? QString() : m_hostAddress.toString().append(":").append(QString::number(m_portNumber)); } bool operator==(const HEndpoint& ep1, const HEndpoint& ep2) { return ep1.m_hostAddress == ep2.m_hostAddress && ep1.m_portNumber == ep2.m_portNumber; } quint32 qHash(const HEndpoint& key) { quint32 tmp = key.m_hostAddress.toIPv4Address() ^ key.portNumber(); return hash(reinterpret_cast(&tmp), sizeof(tmp)); } } } herqq-1.0.0/hupnp/src/socket/hendpoint.h0000644000000000000000000001174411543637310016712 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HENDPOINT_H #define HENDPOINT_H #include #include class QUrl; namespace Herqq { namespace Upnp { /*! * Class that represents a network endpoint, which is a combination of * a host address and a port number. * * \headerfile hendpoint.h HEndpoint * * \remarks This class is not thread-safe. */ class H_UPNP_CORE_EXPORT HEndpoint { friend H_UPNP_CORE_EXPORT bool operator==( const HEndpoint&, const HEndpoint&); friend H_UPNP_CORE_EXPORT quint32 qHash(const HEndpoint&); private: QHostAddress m_hostAddress; quint16 m_portNumber; public: /*! * Creates a new instance with host address set to \c QHostAddress::Null * and port set to "0". * * \sa isNull() */ HEndpoint(); /*! * Creates a new instance with the specified host address and port set to zero. * * \param hostAddress specifies the host address. * * \sa isNull() */ HEndpoint(const QHostAddress& hostAddress); /*! * Creates a new instance with the specified host address and port. * * \param hostAddress specifies the host address. If the host address * is null the port number is set to zero. * \param portNumber specifies the port number. * * \sa isNull() */ HEndpoint(const QHostAddress& hostAddress, quint16 portNumber); /*! * Creates a new instance from the specified url. * * \param url specifies the url from which the endpoint and port information * is extracted (if present). If the URL does not contain a valid host information * the port number is set to zero. * * \sa isNull() */ HEndpoint(const QUrl& url); /*! * Creates a new instance from the specified string. following format * "hostAddress:portNumber", where [:portNumber] is optional. * * \param arg specifies the string following format * "hostAddress:portNumber", where [:portNumber] is optional. * If the hostAddress is \c QHostAddress::Null the port number is set to * zero. * * \sa isNull() */ HEndpoint(const QString& arg); /*! * \brief Destroys the instance. */ ~HEndpoint(); /*! * \brief Indicates whether or not the end point is properly defined. * * \return \e true in case the end point is not defined. */ inline bool isNull() const { return m_hostAddress.isNull(); } /*! * \brief Returns the host address of the endpoint. * * \return The host address of the endpoint. */ inline QHostAddress hostAddress() const { return m_hostAddress; } /*! * \brief Returns the port number of the endpoint. * * \return The port number of the endpoint. */ inline quint16 portNumber() const { return m_portNumber; } /*! * \brief Indicates whether or not the end point refers to a multicast address. * * \return \e true in case the end point refers to a multicast address. */ bool isMulticast() const; /*! * \brief Returns a string representation of the endpoint. * * \return The address and port number together separated by a ":". E.g * \c "192.168.0.1:80". If the instance is null, i.e. isNull() returns true * then an empty string is returned. */ QString toString() const; }; /*! * Compares the two objects for equality. * * \return \e true in case the object are logically equivalent. * * \relates HEndpoint */ H_UPNP_CORE_EXPORT bool operator==(const HEndpoint&, const HEndpoint&); /*! * Compares the two objects for inequality. * * \return \e true in case the objects are not logically equivalent. * * \relates HEndpoint */ inline bool operator!=(const HEndpoint& obj1, const HEndpoint& obj2) { return !(obj1 == obj2); } /*! * \brief Returns a value that can be used as a unique key in a hash-map identifying * the object. * * \param key specifies the object from which the hash value is created. * * \return a value that can be used as a unique key in a hash-map identifying * the object. * * \relates HEndpoint */ H_UPNP_CORE_EXPORT quint32 qHash(const HEndpoint& key); } } #endif // HENDPOINT_H herqq-1.0.0/hupnp/src/socket/hmulticast_socket.h0000644000000000000000000001067311543637310020447 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef MULTICAST_SOCKET_H_ #define MULTICAST_SOCKET_H_ #include #include namespace Herqq { namespace Upnp { class HMulticastSocketPrivate; /*! * \brief This is a class for multicast communication. * * \headerfile hmulticast_socket.h HMulticastSocket * * \remark this class has thread-affinity, which mandates that the instances of this * class has to be used in the thread in which they are located at the time. */ class H_UPNP_CORE_EXPORT HMulticastSocket : public QUdpSocket { H_DISABLE_COPY(HMulticastSocket) H_DECLARE_PRIVATE(HMulticastSocket) protected: HMulticastSocketPrivate* h_ptr; HMulticastSocket(HMulticastSocketPrivate& dd, QObject* parent = 0); public: /*! * Constructs a new instance. * * \param parent specifies the parent \c QObject. */ explicit HMulticastSocket(QObject* parent = 0); /*! * \brief Destroys the instance. */ virtual ~HMulticastSocket(); /*! * Attempts to joins into the specified multicast group address. * * \param groupAddress specifies the multicast group address. * * \retval true in case the operation succeeded. * * \retval false in case the operation failed. For instance, * this happens when the socket is not bound to a port. */ bool joinMulticastGroup(const QHostAddress& groupAddress); /*! * Attempts to joins into the specified multicast group address using * the specified local address. * * \param groupAddress specifies the multicast group address. * \param localAddress specifies the local addresses from which the join * message is sent. * * \retval true in case the operation succeeded. * * \retval false in case the operation failed. For instance, * this happens when the socket is not bound to a port. */ bool joinMulticastGroup( const QHostAddress& groupAddress, const QHostAddress& localAddress); /*! * Attempts to leave from the specified multicast group address. * * \param groupAddress specifies the multicast group address. * * \retval true in case the operation succeeded. * * \retval false in case the operation failed. For example, this happens * when the socket has not joined to the specified multicast address. */ bool leaveMulticastGroup(const QHostAddress& groupAddress); /*! * Attempts to leave from the specified multicast group address using the * specified local address. * * \param groupAddress specifies the multicast group address. * \param localAddress specifies the local addresses from which the leave * message is sent. * * \retval true in case the operation succeeded. * * \retval false in case the operation failed. For example, this happens * when the socket has not joined to the specified multicast address. */ bool leaveMulticastGroup( const QHostAddress& groupAddress, const QHostAddress& localAddress); /*! * Attempts to set the Time To Live attribute for each message. * * \param arg specifies the value for Time To Live. * * \return \e true in case the operation succeeded. */ bool setMulticastTtl(quint8 arg); /*! * Attempts to bind the socket into the specified port using BindMode flags * and a QHostAddress value that are suitable for a multicast socket. * * \param port specifies the port to which to bind. * * \return \e true in case the operation succeeded. */ bool bind(quint16 port = 0); }; } } #endif /* MULTICAST_SOCKET_H_ */ herqq-1.0.0/hupnp/src/utils/0000755000000000000000000000000011543637460014420 5ustar rootrootherqq-1.0.0/hupnp/src/utils/hfunctor.h0000644000000000000000000003226511543637310016423 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ /* ----------------------------------------------------------------------------- * -----------------------------PLEASE NOTE------------------------------------- * ----------------------------------------------------------------------------- * * The generalized functor presented in this file is largely based on * the work of Mr. Andrei Alexandrescu. Below is the copyright notice and * permission to use found in the Loki library. */ //////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Wesley Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// /* * The functor template presented in this file is simpler (but not faster), less general and * less useful than the one Andrei has implemented in his Loki library, but it * suffices well for the purposes of Herqq libraries. In fact, it is _made_ for * Herqq libraries. * * For more information, check out the web page of the Loki library @ * http://loki-lib.sourceforge.net/ and Andrei's book Modern C++ Design. */ #ifndef HFUNCTOR_H_ #define HFUNCTOR_H_ #include namespace Herqq { // // \internal // struct EmptyType { }; // // \internal // struct NullType { }; // // \internal // template struct Typelist { typedef T Head; typedef U Tail; }; #define H_TYPELIST_1(T1) ::Herqq::Typelist #define H_TYPELIST_2(T1, T2) ::Herqq::Typelist #define H_TYPELIST_3(T1, T2, T3) ::Herqq::Typelist #define H_TYPELIST_4(T1, T2, T3, T4) ::Herqq::Typelist #define H_TYPELIST_5(T1, T2, T3, T4, T5) ::Herqq::Typelist // // \internal // template class FunctorImplBase { template friend class Functor; private: virtual FunctorImplBase* doClone() const = 0; template static T* clone(T* pObj) { if (!pObj) return 0; T* pClone = static_cast(pObj->doClone()); return pClone; } public: typedef R ReturnValue; typedef EmptyType Parameter1; typedef EmptyType Parameter2; typedef EmptyType Parameter3; typedef EmptyType Parameter4; typedef EmptyType Parameter5; FunctorImplBase(){} virtual ~FunctorImplBase() {} }; // // \internal // template class FunctorImpl; // // \internal // template class FunctorImpl : public FunctorImplBase { public: typedef R ReturnValue; virtual R operator()() = 0; }; // // \internal // template class FunctorImpl : public FunctorImplBase { public: typedef R ReturnValue; typedef P1 Parameter1; virtual R operator()(Parameter1) = 0; }; // // \internal // template class FunctorImpl : public FunctorImplBase { public: typedef R ReturnValue; typedef P1 Parameter1; typedef P2 Parameter2; virtual R operator()(Parameter1, Parameter2) = 0; }; // // \internal // template class FunctorImpl : public FunctorImplBase { public: typedef R ReturnValue; typedef P1 Parameter1; typedef P2 Parameter2; typedef P3 Parameter3; virtual R operator()(Parameter1, Parameter2, Parameter3) = 0; }; // // \internal // template class FunctorImpl : public FunctorImplBase { public: typedef R ReturnValue; typedef P1 Parameter1; typedef P2 Parameter2; typedef P3 Parameter3; typedef P4 Parameter4; virtual R operator()(Parameter1, Parameter2, Parameter3, Parameter4) = 0; }; // // \internal // template class FunctorImpl : public FunctorImplBase { public: typedef R ReturnValue; typedef P1 Parameter1; typedef P2 Parameter2; typedef P3 Parameter3; typedef P4 Parameter4; typedef P5 Parameter5; virtual R operator()(Parameter1, Parameter2, Parameter3, Parameter4, Parameter5) = 0; }; // // \internal // template class FunctorHandler : public ParentFunctor::Impl { private: typedef typename ParentFunctor::Impl Base; Fun m_fun; virtual FunctorHandler* doClone() const { return new FunctorHandler(m_fun); } public: typedef typename Base::ReturnValue ReturnValue; typedef typename Base::Parameter1 Parameter1; typedef typename Base::Parameter2 Parameter2; typedef typename Base::Parameter3 Parameter3; typedef typename Base::Parameter4 Parameter4; typedef typename Base::Parameter5 Parameter5; FunctorHandler(const Fun& fun) : m_fun(fun) { } ReturnValue operator()() { return m_fun(); } ReturnValue operator()(Parameter1 p1) { return m_fun(p1); } ReturnValue operator()(Parameter1 p1, Parameter2 p2) { return m_fun(p1, p2); } ReturnValue operator()(Parameter1 p1, Parameter2 p2, Parameter3 p3) { return m_fun(p1, p2, p3); } ReturnValue operator()( Parameter1 p1, Parameter2 p2, Parameter3 p3, Parameter4 p4) { return m_fun(p1, p2, p3, p4); } ReturnValue operator()( Parameter1 p1, Parameter2 p2, Parameter3 p3, Parameter4 p4, Parameter5 p5) { return m_fun(p1, p2, p3, p4, p5); } }; // // \internal // template< class ParentFunctor, typename PointerToObject, typename PointerToMemFun> class FunctorMemFunHandler : public ParentFunctor::Impl { private: PointerToObject m_pobj; PointerToMemFun m_pmemf; typedef typename ParentFunctor::Impl Base; virtual FunctorMemFunHandler* doClone() const { return new FunctorMemFunHandler(m_pobj, m_pmemf); } public: typedef typename Base::ReturnValue ReturnValue; typedef typename Base::Parameter1 Parameter1; typedef typename Base::Parameter2 Parameter2; typedef typename Base::Parameter3 Parameter3; typedef typename Base::Parameter4 Parameter4; typedef typename Base::Parameter5 Parameter5; FunctorMemFunHandler(const PointerToObject& pobj, PointerToMemFun pmemf) : m_pobj(pobj), m_pmemf(pmemf) { } ReturnValue operator()() { return ((*m_pobj).*m_pmemf)(); } ReturnValue operator()(Parameter1 p1) { return ((*m_pobj).*m_pmemf)(p1); } ReturnValue operator()(Parameter1 p1, Parameter2 p2) { return ((*m_pobj).*m_pmemf)(p1, p2); } ReturnValue operator()(Parameter1 p1, Parameter2 p2, Parameter3 p3) { return ((*m_pobj).*m_pmemf)(p1, p2, p3); } ReturnValue operator()( Parameter1 p1, Parameter2 p2, Parameter3 p3, Parameter4 p4) { return ((*m_pobj).*m_pmemf)(p1, p2, p3, p4); } ReturnValue operator()( Parameter1 p1, Parameter2 p2, Parameter3 p3, Parameter4 p4, Parameter5 p5) { return ((*m_pobj).*m_pmemf)(p1, p2, p3, p4, p5); } }; /*! * A template class for generalizing the callable entity concept. * * You can test if the object can be invoked simply by issuing * if (FunctorObject) { ... } */ template class Functor { public: typedef FunctorImpl Impl; typedef typename Impl::Parameter1 Parameter1; typedef typename Impl::Parameter2 Parameter2; typedef typename Impl::Parameter3 Parameter3; typedef typename Impl::Parameter4 Parameter4; typedef typename Impl::Parameter5 Parameter5; typedef ReturnValue (*FunType)(); typedef ReturnValue (*FunType1)(typename Impl::Parameter1); typedef ReturnValue (*FunType2)( typename Impl::Parameter1, typename Impl::Parameter2); typedef ReturnValue (*FunType3)( typename Impl::Parameter1, typename Impl::Parameter2, typename Impl::Parameter3); typedef ReturnValue (*FunType4)( typename Impl::Parameter1, typename Impl::Parameter2, typename Impl::Parameter3, typename Impl::Parameter4); typedef ReturnValue (*FunType5)( typename Impl::Parameter1, typename Impl::Parameter2, typename Impl::Parameter3, typename Impl::Parameter4, typename Impl::Parameter5); private: Impl* m_impl; public: Functor() : m_impl(0) { } template Functor(const Fun& fun) : m_impl(new FunctorHandler(fun)) { } Functor(const FunType& fun) : m_impl(new FunctorHandler(fun)) { } Functor(const FunType1& fun) : m_impl(new FunctorHandler(fun)) { } Functor(const FunType2& fun) : m_impl(new FunctorHandler(fun)) { } Functor(const FunType3& fun) : m_impl(new FunctorHandler(fun)) { } Functor(const FunType4& fun) : m_impl(new FunctorHandler(fun)) { } Functor(const FunType5& fun) : m_impl(new FunctorHandler(fun)) { } template Functor(const PointerToObject& pobj, PointerToMemFun pmemfun) : m_impl(new FunctorMemFunHandler(pobj, pmemfun)) { } ~Functor() { delete m_impl; } Functor& operator=(const Functor& other) { Q_ASSERT(&other != this); Impl* newImpl = other.m_impl ? Impl::clone(other.m_impl) : 0; delete m_impl; m_impl = newImpl; return *this; } Functor(const Functor& other) : m_impl(0) { Q_ASSERT(&other != this); m_impl = other.m_impl ? Impl::clone(other.m_impl) : 0; } ReturnValue operator()() { Q_ASSERT(m_impl); return (*m_impl)(); } ReturnValue operator()(Parameter1 p1) { Q_ASSERT(m_impl); return (*m_impl)(p1); } ReturnValue operator()(Parameter1 p1, Parameter2 p2) { Q_ASSERT(m_impl); return (*m_impl)(p1, p2); } ReturnValue operator()(Parameter1 p1, Parameter2 p2, Parameter3 p3) { Q_ASSERT(m_impl); return (*m_impl)(p1, p2, p3); } ReturnValue operator()( Parameter1 p1, Parameter2 p2, Parameter3 p3, Parameter4 p4) { Q_ASSERT(m_impl); return (*m_impl)(p1, p2, p3, p4); } ReturnValue operator()( Parameter1 p1, Parameter2 p2, Parameter3 p3, Parameter4 p4, Parameter5 p5) { Q_ASSERT(m_impl); return (*m_impl)(p1, p2, p3, p4, p5); } bool operator!() const { return !m_impl; } private: // Helper for enabling 'if (sp)' struct Tester { Tester(int) {} void dummy() {} }; typedef void (Tester::*unspecified_boolean_type_)(); public: // enable 'if (sp)' operator unspecified_boolean_type_() const { return !m_impl ? 0 : &Tester::dummy; } }; } #endif /* HFUNCTOR_H_ */ herqq-1.0.0/hupnp/src/utils/hmisc_utils_p.h0000644000000000000000000000270711543637310017433 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HMISC_UTILS_P_H_ #define HMISC_UTILS_P_H_ #include "hglobal.h" class QHostAddress; // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // namespace Herqq { /* djb2 * * This algorithm was first reported by Dan Bernstein * many years ago in comp.lang.c */ unsigned long hash(const char* str, int n); QHostAddress findBindableHostAddress(); bool toBool(const QString&, bool* ok); } #endif /* HMISC_UTILS_P_H_ */ herqq-1.0.0/hupnp/src/utils/hthreadpool_p.h0000644000000000000000000000515011543637310017414 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HTHREADPOOL_P_H_ #define HTHREADPOOL_P_H_ // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "../general/hupnp_defs.h" #include #include #include #include #include #include namespace Herqq { namespace Upnp { class HThreadPool; // // // class HRunnable : public QRunnable, public QObject { H_DISABLE_COPY(HRunnable) friend class HThreadPool; public: enum Status { NotStarted, WaitingNewTask, RunningTask, Exiting }; private: Status m_status; QMutex m_statusMutex; QWaitCondition m_statusWait; HThreadPool* m_owner; bool m_doNotInform; public: HRunnable(); virtual ~HRunnable() = 0; void signalTaskComplete(); void signalExit(); Status wait(); bool setupNewTask(); }; // // // class HThreadPool : public QObject { Q_OBJECT H_DISABLE_COPY(HThreadPool) friend class HRunnable; private: QThreadPool* m_threadPool; QList m_runnables; QMutex m_runnablesMutex; void exiting(HRunnable*); public: HThreadPool(QObject* parent); virtual ~HThreadPool(); void start(HRunnable*); void shutdown(); inline void setMaxThreadCount(qint32 count) { m_threadPool->setMaxThreadCount(count); } inline int activeThreadCount() const { return m_threadPool->activeThreadCount(); } }; } } #endif /* HTHREADPOOL_P_H_ */ herqq-1.0.0/hupnp/src/utils/hthreadpool_p.cpp0000644000000000000000000000715611543637310017757 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hthreadpool_p.h" namespace Herqq { namespace Upnp { /******************************************************************************* * HRunnable ******************************************************************************/ HRunnable::HRunnable() : m_status(NotStarted), m_statusMutex(), m_statusWait(), m_owner(0), m_doNotInform(false) { } HRunnable::~HRunnable() { if (!m_doNotInform) { m_owner->exiting(this); } } void HRunnable::signalTaskComplete() { QMutexLocker locker(&m_statusMutex); Q_ASSERT(m_status == RunningTask); m_status = WaitingNewTask; m_statusWait.wakeOne(); } void HRunnable::signalExit() { QMutexLocker locker(&m_statusMutex); if (m_status == Exiting) { return; } m_status = Exiting; m_statusWait.wakeAll(); } HRunnable::Status HRunnable::wait() { QMutexLocker locker(&m_statusMutex); Q_ASSERT(m_status != NotStarted); for(;;) { if (m_status == Exiting || m_status == WaitingNewTask) { return m_status; } m_statusWait.wait(&m_statusMutex, 100); } return Exiting; } bool HRunnable::setupNewTask() { QMutexLocker locker(&m_statusMutex); if (m_status == Exiting) { return false; } m_status = RunningTask; return true; } /******************************************************************************* * HThreadPool ******************************************************************************/ HThreadPool::HThreadPool(QObject* parent) : QObject(parent), m_threadPool(new QThreadPool(this)) { } HThreadPool::~HThreadPool() { shutdown(); } void HThreadPool::exiting(HRunnable* runnable) { QMutexLocker locker(&m_runnablesMutex); QList::iterator it = m_runnables.begin(); for (; it != m_runnables.end(); ++it) { if (*it == runnable) { m_runnables.erase(it); return; } } } void HThreadPool::start(HRunnable* runnable) { Q_ASSERT(runnable); Q_ASSERT(runnable->m_status == HRunnable::NotStarted); Q_ASSERT(!runnable->m_owner); runnable->m_status = HRunnable::WaitingNewTask; runnable->m_owner = this; QMutexLocker locker(&m_runnablesMutex); m_runnables.append(runnable); locker.unlock(); m_threadPool->start(runnable); } void HThreadPool::shutdown() { QMutexLocker locker(&m_runnablesMutex); for (int i = 0; i < m_runnables.size(); ++i) { m_runnables.at(i)->m_doNotInform = true; m_runnables.at(i)->signalExit(); } m_runnables.clear(); locker.unlock(); m_threadPool->waitForDone(); } } } herqq-1.0.0/hupnp/src/utils/utils.pri0000644000000000000000000000043511543637310016270 0ustar rootrootHEADERS += \ $$SRC_LOC/hmisc_utils_p.h \ $$SRC_LOC/hfunctor.h \ $$SRC_LOC/hglobal.h \ $$SRC_LOC/hsysutils_p.h \ $$SRC_LOC/hthreadpool_p.h SOURCES += \ $$SRC_LOC/hmisc_utils_p.cpp \ $$SRC_LOC/hsysutils_p.cpp \ $$SRC_LOC/hthreadpool_p.cpp herqq-1.0.0/hupnp/src/utils/hmisc_utils_p.cpp0000644000000000000000000000476411543637310017773 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hmisc_utils_p.h" #include #include namespace Herqq { unsigned long hash(const char *str, int n) { int c; unsigned long hash_value = 5381; while (n--) { c = *str++; hash_value = ((hash_value << 5) + hash_value) + c; // hash_value*33 + c } return hash_value; } QHostAddress findBindableHostAddress() { QHostAddress address = QHostAddress::LocalHost; foreach (const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) { if (iface.flags() & QNetworkInterface::IsUp && !(iface.flags() & QNetworkInterface::IsLoopBack)) { QList entries = iface.addressEntries(); foreach(const QNetworkAddressEntry& entry, entries) { if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) { address = entry.ip(); goto end; } } } } end: return address; } bool toBool(const QString& arg, bool* ok) { bool retVal = false, match = true; if (arg == "1") { retVal = true; } else if (arg == "0") { retVal = false; } else if (arg.compare("true", Qt::CaseInsensitive) == 0) { retVal = true; } else if (arg.compare("false", Qt::CaseInsensitive) == 0) { retVal = false; } else if (arg.compare("yes", Qt::CaseInsensitive) == 0) { retVal = true; } else if (arg.compare("no", Qt::CaseInsensitive) == 0) { retVal = false; } else { match = false; } if (ok) { *ok = match; } return retVal; } } herqq-1.0.0/hupnp/src/utils/hsysutils_p.h0000644000000000000000000000271711543637310017160 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef SYSUTILS_H #define SYSUTILS_H // // !! Warning !! // // This file is not part of public API and it should // never be included in client code. The contents of this file may // change or the file may be removed without of notice. // #include "hglobal.h" #include namespace Herqq { // // // class HSysUtils : private QThread { H_DISABLE_COPY(HSysUtils) private: HSysUtils (); ~HSysUtils(); public: static void msleep(quint32 msecs); static void sleep(quint32 secs); static void usleep(quint32 usecs); }; } #endif // SYSUTILS_H herqq-1.0.0/hupnp/src/utils/hglobal.h0000644000000000000000000000721211543637310016175 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #ifndef HGLOBAL_H_ #define HGLOBAL_H_ #include #define H_DISABLE_ASSIGN(Class) \ Class& operator=(const Class& clazz); #define H_DISABLE_COPY(Class) \ Class(const Class& clazz); \ Class& operator=(const Class& clazz); #define H_FORCE_SINGLETON(Class) \ private: \ Class(const Class& clazz); \ Class& operator=(const Class& clazz); \ Class(); \ ~Class(); #define H_DECLARE_PRIVATE(Class) \ inline Class##Private* h_func() { return reinterpret_cast(h_ptr); } \ inline const Class##Private* h_func() const { return reinterpret_cast(h_ptr); } \ friend class Class##Private; #define H_DECLARE_PUBLIC(Class) \ inline Class* q_func() { return static_cast(q_ptr); } \ inline const Class* q_func() const { return static_cast(q_ptr); } \ friend class Class; #define H_DECLARE_PARENT(Class) \ inline Class* p_func() { return static_cast(p_ptr); } \ inline const Class* p_func() const { return static_cast(p_ptr); } #define H_D(Class) Class##Private * const h = h_func() #define H_Q(Class) Class * const q = q_func() #define H_P(Class) Class * const p = p_func() #define H_D_P(Class) Class * const p = h_func()->p_func() #ifdef H_BUILD_STATIC #define H_DECL_EXPORT #define H_DECL_IMPORT #endif #ifndef H_DECL_EXPORT # ifdef Q_OS_WIN # define H_DECL_EXPORT __declspec(dllexport) # elif defined(QT_VISIBILITY_AVAILABLE) # define H_DECL_EXPORT __attribute__((visibility("default"))) # endif # ifndef H_DECL_EXPORT # define H_DECL_EXPORT # endif #endif #ifndef H_DECL_IMPORT # if defined(Q_OS_WIN) # define H_DECL_IMPORT __declspec(dllimport) # else # define H_DECL_IMPORT # endif #endif #if defined(H_BUILD_UPNP_CORE_LIB) # define H_UPNP_CORE_EXPORT H_DECL_EXPORT #else # define H_UPNP_CORE_EXPORT H_DECL_IMPORT #endif #if defined(H_BUILD_UPNP_LIGHTING_LIB) # define H_UPNP_LIGHTING_EXPORT H_DECL_EXPORT #else # define H_UPNP_LIGHTING_EXPORT H_DECL_IMPORT #endif #if defined(H_BUILD_UPNP_AV_LIB) # define H_UPNP_AV_EXPORT H_DECL_EXPORT #else # define H_UPNP_AV_EXPORT H_DECL_IMPORT #endif // ********************** IMPORTANT ***************************** // the following asserts are never undefined by the Herqq libraries ==> // the purpose of them is just that; they are supposed to be always enabled, // unlike Q_ASSERT, which is a no-op in release builds #ifndef H_ASSERT #define H_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) #endif #ifndef H_ASSERT_X #define H_ASSERT_X(cond, where, what) ((!(cond)) ? qt_assert_x(where, what,__FILE__,__LINE__) : qt_noop()) #endif #define STR(X) #X #define STRX(X) STR(X) #ifndef H_FUN #define H_FUN __FUNCTION__ #endif #define H_AT __FILE__ ":" STRX(__LINE__) #endif /* HGLOBAL_H_ */ herqq-1.0.0/hupnp/src/utils/hsysutils_p.cpp0000644000000000000000000000227211543637310017507 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of Herqq UPnP (HUPnP) library. * * Herqq UPnP is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Herqq UPnP 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Herqq UPnP. If not, see . */ #include "hsysutils_p.h" namespace Herqq { HSysUtils::HSysUtils() { } HSysUtils::~HSysUtils() { } void HSysUtils::msleep(quint32 msecs) { QThread::msleep(msecs); } void HSysUtils::sleep(quint32 secs) { QThread::sleep(secs); } void HSysUtils::usleep(quint32 usecs) { QThread::usleep(usecs); } } herqq-1.0.0/hupnp/LICENSE_LGPLv3.txt0000644000000000000000000001721111543637310015377 0ustar rootroot GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. herqq-1.0.0/hupnp/Doxyfile0000644000000000000000000002264311543637310014200 0ustar rootroot# Doxyfile 1.5.9 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = Herqq PROJECT_NUMBER = OUTPUT_DIRECTORY = docs CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = NO REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = YES INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO QT_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO EXTENSION_MAPPING = BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = YES EXTRACT_ANON_NSPACES = NO HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES HIDE_FRIEND_COMPOUNDS = YES HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO HIDE_SCOPE_NAMES = YES SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = NO SORT_BRIEF_DOCS = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = NO SHOW_DIRECTORIES = NO SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = src INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.h *.cpp RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = */obj/* */bin/* */*test*/ */lib/* EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES HTML_DYNAMIC_SECTIONS = NO GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO CHM_INDEX_ENCODING = BINARY_TOC = NO TOC_EXPAND = NO GENERATE_QHP = NO QCH_FILE = QHP_NAMESPACE = QHP_VIRTUAL_FOLDER = doc QHP_CUST_FILTER_NAME = QHP_CUST_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS = QHG_LOCATION = DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NONE TREEVIEW_WIDTH = 250 FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES MSCGEN_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO DOT_FONTNAME = FreeSans DOT_FONTSIZE = 10 DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO herqq-1.0.0/hupnp/hupnp.pro0000644000000000000000000000023711543637310014341 0ustar rootrootTEMPLATE = subdirs CONFIG += ordered !CONFIG(DISABLE_QTSOAP) : SUBDIRS += lib/qtsoap-2.7-opensource/buildlib !CONFIG(DISABLE_CORE) : SUBDIRS += src.pro herqq-1.0.0/hupnp/include/0000755000000000000000000000000011543637460014114 5ustar rootrootherqq-1.0.0/hupnp/include/HUpnpCore/0000755000000000000000000000000011543637460015757 5ustar rootrootherqq-1.0.0/hupnp/include/HUpnpCore/HDevicesSetupData0000644000000000000000000000017711543637306021213 0ustar rootroot#ifndef H_DEVICESSETUPDATA_ #define H_DEVICESSETUPDATA_ #include "public/hdevices_setupdata.h" #endif // H_DEVICESSETUPDATA_ herqq-1.0.0/hupnp/include/HUpnpCore/HServerService0000644000000000000000000000016211543637306020577 0ustar rootroot#ifndef H_SERVER_SERVICE #define H_SERVER_SERVICE #include "public/hserverservice.h" #endif // H_SERVER_SERVICE herqq-1.0.0/hupnp/include/HUpnpCore/public/0000755000000000000000000000000011543637460017235 5ustar rootrootherqq-1.0.0/hupnp/include/HUpnpCore/public/hupnp_global.h0000644000000000000000000000006011543637306022053 0ustar rootroot#include "../../../src/general/hupnp_global.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hfunctor.h0000644000000000000000000000005211543637306021232 0ustar rootroot#include "../../../src/utils/hfunctor.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hactioninvoke_callback.h0000644000000000000000000000007611543637306024065 0ustar rootroot#include "../../../src/devicemodel/hactioninvoke_callback.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hasyncop.h0000644000000000000000000000006011543637306021225 0ustar rootroot#include "../../../src/devicemodel/hasyncop.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdevicemodel_creator.h0000644000000000000000000000010211543637306023545 0ustar rootroot#include "../../../src/devicemodel/server/hdevicemodelcreator.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hserviceinfo.h0000644000000000000000000000006411543637306022071 0ustar rootroot#include "../../../src/dataelements/hserviceinfo.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hclientdevice.h0000644000000000000000000000007411543637306022214 0ustar rootroot#include "../../../src/devicemodel/client/hclientdevice.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hserverstatevariable.h0000644000000000000000000000010311543637306023624 0ustar rootroot#include "../../../src/devicemodel/server/hserverstatevariable.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hservices_setupdata.h0000644000000000000000000000007311543637306023452 0ustar rootroot#include "../../../src/devicemodel/hservices_setupdata.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hupnp_defs.h0000644000000000000000000000005611543637306021541 0ustar rootroot#include "../../../src/general/hupnp_defs.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hactioninfo.h0000644000000000000000000000006411543637306021706 0ustar rootroot#include "../../../src/dataelements/hactioninfo.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hupnp_fwd.h0000644000000000000000000000005511543637306021377 0ustar rootroot#include "../../../src/general/hupnp_fwd.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hcontrolpoint.h0000644000000000000000000000010311543637306022301 0ustar rootroot#include "../../../src/devicehosting/controlpoint/hcontrolpoint.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hserviceid.h0000644000000000000000000000006311543637306021531 0ustar rootroot#include "../../../src/dataelements/hserviceid.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hclientactionop.h0000644000000000000000000000007611543637306022573 0ustar rootroot#include "../../../src/devicemodel/client/hclientactionop.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdevicehost.h0000644000000000000000000000010011543637306021701 0ustar rootroot#include "../../../src/devicehosting/devicehost/hdevicehost.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hclientstatevariable.h0000644000000000000000000000010311543637306023574 0ustar rootroot#include "../../../src/devicemodel/client/hclientstatevariable.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hupnpinfo.h0000644000000000000000000000005411543637306021412 0ustar rootroot#include "../../../src/general/hupnpinfo.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hstatevariable_event.h0000644000000000000000000000007411543637306023605 0ustar rootroot#include "../../../src/devicemodel/hstatevariable_event.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hserveraction.h0000644000000000000000000000007411543637306022262 0ustar rootroot#include "../../../src/devicemodel/server/hserveraction.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdiscoverytype.h0000644000000000000000000000006711543637306022471 0ustar rootroot#include "../../../src/dataelements/hdiscoverytype.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hserverservice.h0000644000000000000000000000007511543637306022446 0ustar rootroot#include "../../../src/devicemodel/server/hserverservice.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hcontrolpoint_configuration.h0000644000000000000000000000012211543637306025231 0ustar rootroot#include "../../../src/devicehosting/controlpoint/hcontrolpoint_configuration.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hexecargs.h0000644000000000000000000000006111543637306021353 0ustar rootroot#include "../../../src/devicemodel/hexecargs.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hclientaction.h0000644000000000000000000000007411543637306022232 0ustar rootroot#include "../../../src/devicemodel/client/hclientaction.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hclientservice.h0000644000000000000000000000007511543637306022416 0ustar rootroot#include "../../../src/devicemodel/client/hclientservice.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hstatevariables_setupdata.h0000644000000000000000000000010111543637306024630 0ustar rootroot#include "../../../src/devicemodel/hstatevariables_setupdata.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hstatevariableinfo.h0000644000000000000000000000007311543637306023257 0ustar rootroot#include "../../../src/dataelements/hstatevariableinfo.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hendpoint.h0000644000000000000000000000005411543637306021374 0ustar rootroot#include "../../../src/socket/hendpoint.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hactions_setupdata.h0000644000000000000000000000007211543637306023266 0ustar rootroot#include "../../../src/devicemodel/hactions_setupdata.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hactionarguments.h0000644000000000000000000000007011543637306022755 0ustar rootroot#include "../../../src/devicemodel/hactionarguments.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hproduct_tokens.h0000644000000000000000000000007011543637306022615 0ustar rootroot#include "../../../src/dataelements/hproduct_tokens.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdevicestatus.h0000644000000000000000000000006411543637306022260 0ustar rootroot#include "../../../src/devicemodel/hdevicestatus.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdiscovery_messages.h0000644000000000000000000000006411543637306023453 0ustar rootroot#include "../../../src/ssdp/hdiscovery_messages.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdevicehost_configuration.h0000644000000000000000000000011611543637306024637 0ustar rootroot#include "../../../src/devicehosting/devicehost/hdevicehost_configuration.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hssdp.h0000644000000000000000000000004511543637306020525 0ustar rootroot#include "../../../src/ssdp/hssdp.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hactioninvoke.h0000644000000000000000000000006511543637306022247 0ustar rootroot#include "../../../src/devicemodel/hactioninvoke.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hupnp_datatypes.h0000644000000000000000000000006311543637306022614 0ustar rootroot#include "../../../src/general/hupnp_datatypes.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hclonable.h0000644000000000000000000000005511543637306021334 0ustar rootroot#include "../../../src/general/hclonable.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdeviceinfo.h0000644000000000000000000000006311543637306021667 0ustar rootroot#include "../../../src/dataelements/hdeviceinfo.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hglobal.h0000644000000000000000000000005011543637306021010 0ustar rootroot#include "../../../src/utils/hglobal.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hresourcetype.h0000644000000000000000000000006611543637306022310 0ustar rootroot#include "../../../src/dataelements/hresourcetype.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdevices_setupdata.h0000644000000000000000000000007211543637306023250 0ustar rootroot#include "../../../src/devicemodel/hdevices_setupdata.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hudn.h0000644000000000000000000000005511543637306020343 0ustar rootroot#include "../../../src/dataelements/hudn.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hserverdevice.h0000644000000000000000000000007411543637306022244 0ustar rootroot#include "../../../src/devicemodel/server/hserverdevice.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hmulticast_socket.h0000644000000000000000000000006311543637306023131 0ustar rootroot#include "../../../src/socket/hmulticast_socket.h" herqq-1.0.0/hupnp/include/HUpnpCore/public/hdevicemodel_infoprovider.h0000644000000000000000000000010111543637306024613 0ustar rootroot#include "../../../src/devicemodel/hdevicemodel_infoprovider.h" herqq-1.0.0/hupnp/include/HUpnpCore/HStateVariableEvent0000644000000000000000000000021211543637306021534 0ustar rootroot#ifndef H_STATEVARIABLE_EVENT_ #define H_STATEVARIABLE_EVENT_ #include "public/hstatevariable_event.h" #endif // H_STATEVARIABLE_EVENT_ herqq-1.0.0/hupnp/include/HUpnpCore/HServicesSetupData0000644000000000000000000000020311543637306021402 0ustar rootroot#ifndef H_SERVICESETUPINFOS_ #define H_SERVICESETUPINFOS_ #include "public/hservices_setupdata.h" #endif // H_SERVICESETUPINFOS_ herqq-1.0.0/hupnp/include/HUpnpCore/HClientDevice0000644000000000000000000000015311543637306020346 0ustar rootroot#ifndef H_DEVICEPROXY_ #define H_DEVICEPROXY_ #include "public/hclientdevice.h" #endif // H_DEVICEPROXY_ herqq-1.0.0/hupnp/include/HUpnpCore/HServiceInfo0000644000000000000000000000015211543637306020223 0ustar rootroot#ifndef H_SERVICEINFO_ #define H_SERVICEINFO_ #include "public/hserviceinfo.h" #endif // H_SERVICEINFO_ herqq-1.0.0/hupnp/include/HUpnpCore/HActionArguments0000644000000000000000000000017211543637306021114 0ustar rootroot#ifndef H_ACTIONARGUMENTS_ #define H_ACTIONARGUMENTS_ #include "public/hactionarguments.h" #endif // H_ACTIONARGUMENTS_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceModelCreator0000644000000000000000000000021211543637306021504 0ustar rootroot#ifndef H_DEVICEMODEL_CREATOR_ #define H_DEVICEMODEL_CREATOR_ #include "public/hdevicemodel_creator.h" #endif // H_DEVICEMODEL_CREATOR_ herqq-1.0.0/hupnp/include/HUpnpCore/HFunctor0000644000000000000000000000013211543637306017425 0ustar rootroot#ifndef H_FUNCTOR_ #define H_FUNCTOR_ #include "public/hfunctor.h" #endif // H_FUNCTOR_ herqq-1.0.0/hupnp/include/HUpnpCore/HUpnpDataTypes0000644000000000000000000000016611543637306020555 0ustar rootroot#ifndef H_UPNP_DATATYPES_ #define H_UPNP_DATATYPES_ #include "public/hupnp_datatypes.h" #endif // H_UPNP_DATATYPES_ herqq-1.0.0/hupnp/include/HUpnpCore/HResourceAvailable0000644000000000000000000000020611543637306021377 0ustar rootroot#ifndef H_DISCOVERY_MESSAGES_ #define H_DISCOVERY_MESSAGES_ #include "public/hdiscovery_messages.h" #endif // H_DISCOVERY_MESSAGES_ herqq-1.0.0/hupnp/include/HUpnpCore/HActionSetup0000644000000000000000000000016011543637306020244 0ustar rootroot#ifndef H_ACTIONSETUP_ #define H_ACTIONSETUP_ #include "public/hactions_setupdata.h" #endif // H_ACTIONSETUP_ herqq-1.0.0/hupnp/include/HUpnpCore/HServiceSetup0000644000000000000000000000016411543637306020433 0ustar rootroot#ifndef H_SERVICESETUP_ #define H_SERVICESETUP_ #include "public/hservices_setupdata.h" #endif // H_SERVICESETUP_ herqq-1.0.0/hupnp/include/HUpnpCore/HEndpoint0000644000000000000000000000013611543637306017571 0ustar rootroot#ifndef H_ENDPOINT_ #define H_ENDPOINT_ #include "public/hendpoint.h" #endif // H_ENDPOINT_ herqq-1.0.0/hupnp/include/HUpnpCore/HActionInvokeCallback0000644000000000000000000000022211543637306022013 0ustar rootroot#ifndef H_ACTIONINVOKE_CALLBACK_ #define H_ACTIONINVOKE_CALLBACK_ #include "public/hactioninvoke_callback.h" #endif // H_ACTIONINVOKE_CALLBACK_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceHost0000644000000000000000000000014611543637306020047 0ustar rootroot#ifndef H_DEVICEHOST_ #define H_DEVICEHOST_ #include "public/hdevicehost.h" #endif // H_DEVICEHOST_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceSetup0000644000000000000000000000016011543637306020226 0ustar rootroot#ifndef H_DEVICESETUP_ #define H_DEVICESETUP_ #include "public/hdevices_setupdata.h" #endif // H_DEVICESETUP_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceHostRuntimeStatus0000644000000000000000000000022011543637306022610 0ustar rootroot#ifndef H_DEVICEHOST_RUNTIMESTATUS_ #define H_DEVICEHOST_RUNTIMESTATUS_ #include "public/hdevicehost.h" #endif // H_DEVICEHOST_RUNTIMESTATUS_ herqq-1.0.0/hupnp/include/HUpnpCore/HActionInvoke0000644000000000000000000000015611543637306020404 0ustar rootroot#ifndef H_ACTIONINVOKE_ #define H_ACTIONINVOKE_ #include "public/hactioninvoke.h" #endif // H_ACTIONINVOKE_ herqq-1.0.0/hupnp/include/HUpnpCore/HDiscoveryResponse0000644000000000000000000000020611543637306021475 0ustar rootroot#ifndef H_DISCOVERY_MESSAGES_ #define H_DISCOVERY_MESSAGES_ #include "public/hdiscovery_messages.h" #endif // H_DISCOVERY_MESSAGES_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceInfo0000644000000000000000000000014611543637306020025 0ustar rootroot#ifndef H_DEVICEINFO_ #define H_DEVICEINFO_ #include "public/hdeviceinfo.h" #endif // H_DEVICEINFO_ herqq-1.0.0/hupnp/include/HUpnpCore/HClientAction0000644000000000000000000000015611543637306020367 0ustar rootroot#ifndef H_CLIENTACTION_ #define H_CLIENTACTION_ #include "public/hclientaction.h" #endif // H_CLIENTACTION_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceConfiguration0000644000000000000000000000023611543637306021741 0ustar rootroot#ifndef H_DEVICEHOST_CONFIGURATION_ #define H_DEVICEHOST_CONFIGURATION_ #include "public/hdevicehost_configuration.h" #endif // H_DEVICEHOST_CONFIGURATION_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceStatus0000644000000000000000000000015611543637306020416 0ustar rootroot#ifndef H_DEVICESTATUS_ #define H_DEVICESTATUS_ #include "public/hdevicestatus.h" #endif // H_DEVICESTATUS_ herqq-1.0.0/hupnp/include/HUpnpCore/HActionsSetupData0000644000000000000000000000020211543637306021216 0ustar rootroot#ifndef H_ACTIONS_SETUPDATA_ #define H_ACTIONS_SETUPDATA_ #include "public/hactions_setupdata.h" #endif // H_ACTIONS_SETUPDATA_ herqq-1.0.0/hupnp/include/HUpnpCore/HStateVariablesSetupData0000644000000000000000000000023611543637306022536 0ustar rootroot#ifndef H_STATEVARIABLES_SETUPDATA_ #define H_STATEVARIABLES_SETUPDATA_ #include "public/hstatevariables_setupdata.h" #endif // H_STATEVARIABLES_SETUPDATA_ herqq-1.0.0/hupnp/include/HUpnpCore/HDiscoveryRequest0000644000000000000000000000020611543637306021327 0ustar rootroot#ifndef H_DISCOVERY_MESSAGES_ #define H_DISCOVERY_MESSAGES_ #include "public/hdiscovery_messages.h" #endif // H_DISCOVERY_MESSAGES_ herqq-1.0.0/hupnp/include/HUpnpCore/HResourceType0000644000000000000000000000016111543637306020440 0ustar rootroot#ifndef H_RESOURCE_TYPE_ #define H_RESOURCE_TYPE_ #include "public/hresourcetype.h" #endif // H_RESOURCE_TYPE_ herqq-1.0.0/hupnp/include/HUpnpCore/HDiscoveryType0000644000000000000000000000016211543637306020621 0ustar rootroot#ifndef H_DISCOVERYTYPE_ #define H_DISCOVERYTYPE_ #include "public/hdiscoverytype.h" #endif // H_DISCOVERYTYPE_ herqq-1.0.0/hupnp/include/HUpnpCore/HControlPointConfiguration0000644000000000000000000000024611543637306023175 0ustar rootroot#ifndef H_CONTROLPOINT_CONFIGURATION_ #define H_CONTROLPOINT_CONFIGURATION_ #include "public/hcontrolpoint_configuration.h" #endif // H_CONTROLPOINT_CONFIGURATION_ herqq-1.0.0/hupnp/include/HUpnpCore/HServerDevice0000644000000000000000000000015611543637306020401 0ustar rootroot#ifndef H_SERVERDEVICE_ #define H_SERVERDEVICE_ #include "public/hserverdevice.h" #endif // H_SERVERDEVICE_ herqq-1.0.0/hupnp/include/HUpnpCore/HResourceUpdate0000644000000000000000000000020611543637306020741 0ustar rootroot#ifndef H_DISCOVERY_MESSAGES_ #define H_DISCOVERY_MESSAGES_ #include "public/hdiscovery_messages.h" #endif // H_DISCOVERY_MESSAGES_ herqq-1.0.0/hupnp/include/HUpnpCore/HMulticastSocket0000644000000000000000000000017611543637306021133 0ustar rootroot#ifndef H_MULTICAST_SOCKET_ #define H_MULTICAST_SOCKET_ #include "public/hmulticast_socket.h" #endif // H_MULTICAST_SOCKET_ herqq-1.0.0/hupnp/include/HUpnpCore/HActionInfo0000644000000000000000000000014611543637306020043 0ustar rootroot#ifndef H_ACTIONINFO_ #define H_ACTIONINFO_ #include "public/hactioninfo.h" #endif // H_ACTIONINFO_ herqq-1.0.0/hupnp/include/HUpnpCore/HUpnpInfo0000644000000000000000000000013611543637306017547 0ustar rootroot#ifndef H_UPNPINFO_ #define H_UPNPINFO_ #include "public/hupnpinfo.h" #endif // H_UPNPINFO_ herqq-1.0.0/hupnp/include/HUpnpCore/HSsdp0000644000000000000000000000011611543637306016720 0ustar rootroot#ifndef H_SSDP_ #define H_SSDP_ #include "public/hssdp.h" #endif // H_SSDP_ herqq-1.0.0/hupnp/include/HUpnpCore/HClientActionOp0000644000000000000000000000017111543637306020663 0ustar rootroot#ifndef H_CLIENTACTION_OP_ #define H_CLIENTACTION_OP_ #include "public/hclientactionop.h" #endif // H_CLIENTACTION_OP_ herqq-1.0.0/hupnp/include/HUpnpCore/HProductToken0000644000000000000000000000016011543637306020427 0ustar rootroot#ifndef H_PRODUCTOKENS_ #define H_PRODUCTOKENS_ #include "public/hproduct_tokens.h" #endif // H_PRODUCTOKENS_ herqq-1.0.0/hupnp/include/HUpnpCore/HActionArgument0000644000000000000000000000017211543637306020731 0ustar rootroot#ifndef H_ACTIONARGUMENTS_ #define H_ACTIONARGUMENTS_ #include "public/hactionarguments.h" #endif // H_ACTIONARGUMENTS_ herqq-1.0.0/hupnp/include/HUpnpCore/HClientStateVariable0000644000000000000000000000021211543637306021671 0ustar rootroot#ifndef H_CLIENTSTATEVARIABLE_ #define H_CLIENTSTATEVARIABLE_ #include "public/hclientstatevariable.h" #endif // H_CLIENTSTATEVARIABLE_ herqq-1.0.0/hupnp/include/HUpnpCore/HServiceId0000644000000000000000000000014211543637306017663 0ustar rootroot#ifndef H_SERVICEID_ #define H_SERVICEID_ #include "public/hserviceid.h" #endif // H_SERVICEID_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceModelInfoProvider0000644000000000000000000000023611543637306022521 0ustar rootroot#ifndef H_DEVICEMODEL_INFOPROVIDER_ #define H_DEVICEMODEL_INFOPROVIDER_ #include "public/hdevicemodel_infoprovider.h" #endif // H_DEVICEMODEL_INFOPROVIDER_ herqq-1.0.0/hupnp/include/HUpnpCore/HAsyncOp0000644000000000000000000000013211543637306017361 0ustar rootroot#ifndef H_ASYNCOP_ #define H_ASYNCOP_ #include "public/hasyncop.h" #endif // H_ASYNCOP_ herqq-1.0.0/hupnp/include/HUpnpCore/HServerStateVariable0000644000000000000000000000021511543637306021724 0ustar rootroot#ifndef H_SERVER_STATEVARIABLE_ #define H_SERVER_STATEVARIABLE_ #include "public/hserverstatevariable.h" #endif // H_SERVER_STATEVARIABLE_ herqq-1.0.0/hupnp/include/HUpnpCore/HExecArgs0000644000000000000000000000013611543637306017512 0ustar rootroot#ifndef H_EXECARGS_ #define H_EXECARGS_ #include "public/hexecargs.h" #endif // H_EXECARGS_ herqq-1.0.0/hupnp/include/HUpnpCore/HResourceUnavailable0000644000000000000000000000020611543637306021742 0ustar rootroot#ifndef H_DISCOVERY_MESSAGES_ #define H_DISCOVERY_MESSAGES_ #include "public/hdiscovery_messages.h" #endif // H_DISCOVERY_MESSAGES_ herqq-1.0.0/hupnp/include/HUpnpCore/HClonable0000644000000000000000000000013611543637306017530 0ustar rootroot#ifndef H_CLONABLE_ #define H_CLONABLE_ #include "public/hclonable.h" #endif // H_CLONABLE_ herqq-1.0.0/hupnp/include/HUpnpCore/HControlPoint0000644000000000000000000000015611543637306020445 0ustar rootroot#ifndef H_CONTROLPOINT_ #define H_CONTROLPOINT_ #include "public/hcontrolpoint.h" #endif // H_CONTROLPOINT_ herqq-1.0.0/hupnp/include/HUpnpCore/HStateVariableInfo0000644000000000000000000000020211543637306021345 0ustar rootroot#ifndef H_STATEVARIABLEINFO_ #define H_STATEVARIABLEINFO_ #include "public/hstatevariableinfo.h" #endif // H_STATEVARIABLEINFO_ herqq-1.0.0/hupnp/include/HUpnpCore/HUdn0000644000000000000000000000011211543637306016531 0ustar rootroot#ifndef H_UDN_ #define H_UDN_ #include "public/hudn.h" #endif // H_UDN_ herqq-1.0.0/hupnp/include/HUpnpCore/HServerAction0000644000000000000000000000016111543637306020413 0ustar rootroot#ifndef H_SERVER_ACTION_ #define H_SERVER_ACTION_ #include "public/hserveraction.h" #endif // H_SERVER_ACTION_ herqq-1.0.0/hupnp/include/HUpnpCore/HDeviceHostConfiguration0000644000000000000000000000023611543637306022577 0ustar rootroot#ifndef H_DEVICEHOST_CONFIGURATION_ #define H_DEVICEHOST_CONFIGURATION_ #include "public/hdevicehost_configuration.h" #endif // H_DEVICEHOST_CONFIGURATION_ herqq-1.0.0/hupnp/include/HUpnpCore/HClientService0000644000000000000000000000015711543637306020553 0ustar rootroot#ifndef H_SERVICE_PROXY #define H_SERVICE_PROXY #include "public/hclientservice.h" #endif // H_SERVICE_PROXY herqq-1.0.0/hupnp/include/HUpnpCore/HUpnp0000644000000000000000000000015211543637306016731 0ustar rootroot#ifndef H_UPNP_GLOBAL_ #define H_UPNP_GLOBAL_ #include "public/hupnp_global.h" #endif // H_UPNP_GLOBAL_ herqq-1.0.0/hupnp/include/HUpnpCore/private/0000755000000000000000000000000011543637460017431 5ustar rootrootherqq-1.0.0/hupnp/include/HUpnpCore/private/hservice_p.h0000644000000000000000000000006211543637306021726 0ustar rootroot#include "../../../src/devicemodel/hservice_p.h" herqq-1.0.0/hupnp/include/HUpnpCore/private/hserverservice_p.h0000644000000000000000000000007611543637306023162 0ustar rootroot#include "../../../src/devicemodel/server/hserverservice_p.h" herqq-1.0.0/hupnp/include/HUpnpCore/private/hdevice_p.h0000644000000000000000000000006111543637306021524 0ustar rootroot#include "../../../src/devicemodel/hdevice_p.h" herqq-1.0.0/hupnp/include/HUpnpCore/private/hserverdevice_p.h0000644000000000000000000000007511543637306022760 0ustar rootroot#include "../../../src/devicemodel/server/hserverdevice_p.h" herqq-1.0.0/hupnp/include/HUpnpCore/HProductTokens0000644000000000000000000000016011543637306020612 0ustar rootroot#ifndef H_PRODUCTOKENS_ #define H_PRODUCTOKENS_ #include "public/hproduct_tokens.h" #endif // H_PRODUCTOKENS_ herqq-1.0.0/hupnp/LICENSE_GPLv3.txt0000644000000000000000000010362111543637310015264 0ustar rootrootGNU General Public License version 3 (GPLv3) GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. “This License” refers to version 3 of the GNU General Public License. “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. A “covered work” means either the unmodified Program or a work based on the Program. To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . herqq-1.0.0/hupnp/ChangeLog0000644000000000000000000004325411543637310014245 0ustar rootroot# HUPnP Changelog HUPnP 1.0.0 [Mar. 28, 2011] -------------------------------------------------------------------------------- - Added support for adding a new root device into HDeviceHost instance after the instance is initialized. - Fixed a possible crash bug in device host. - Fixed a possible crash bug relating to HControlPoint::quit(). - Fixed HDeviceHost::quit() to clear the state appropriately. - Reorganized parts of the project structure and restructured some of the project files. - Modified the build to check if the qmake's CONFIG variable contains USE_QT_INSTALL_LOC flag and if so, install HUPnP headers to QT_INSTALL_HEADERS and binaries to QT_INSTALL_LIBS. - Did some small improvements and modifications not worth mentioning individually. - Updated documentation. Special thanks to Maximilian Lang and Jaroslav Reznik for reporting their ideas and findings to me. Much appreciated. HUPnP 0.9.1 [Feb. 23, 2011] -------------------------------------------------------------------------------- - Modified the main project file to check if the qmake's CONFIG parameter contains: * DISABLE_QTSOAP, in which case qtsoap is not built, * DISABLE_CORE, in which case the hupnp core is not built or * DISABLE_TESTAPP, in which case the simple test app is not built. - Updated the copyright statements to include the year 2011. - Added macros detailing the API version and a function for querying the library version at runtime. - Removed an unimplemented member function declaration from HProductToken. - Added equality operators to HServiceSetup and HServicesSetupData classes. - Updated documentation. Special thanks to Nikhil Marathe and Jaroslav Reznik for reporting their ideas and findings to me. Much appreciated. HUPnP 0.9.0 [Feb. 1, 2011] -------------------------------------------------------------------------------- - Modified the client side action invocation and the signaling of action completion to use clearer and more extensible API. - Modified the HActionArgument class to use explicit sharing, which enabled the HActionArguments class to take in and return instances of HActionArgument, rather than pointers to them. - Added the possibility to replace the implementation of HServerService::createActionInvokes() with the use of Qt's Meta Object system. That is, HUPnP can now do the mapping of action names to HActionInvoke objects automatically, if the desired methods use the Q_INVOKABLE macro. See the documentation for more details. - Added convenience methods to HClientService and HServerService for retrieving the value of a state variable. HServerService also has a convenience method for setting the value of a state variable. - Fixed the HControlPoint to properly relay UPnP action error codes to the user. - Fixed the HDeviceHost to send proper error codes to control points when action invocation fails. - Fixed HControlPoint::quit() to properly clean its state as it was supposed to do. - Fixed a logic error in the handling of client side action invocations. - Removed a link-time dependency to QtGui library. The dependency to QtGui was in the QtSoap library that is currently included with HUPnP. - Modified error handling and reporting of the description document parser to be clearer and more thorough. - Modified the description document parser at client-side to ignore the error of missing the element. This was done to improve interoperability with other UPnP software. Special thanks to Nikhil Marathe and Yury G. Kudryashov for reporting their findings to me. Much appreciated. HUPnP 0.8.0 [Dec 19, 2010] -------------------------------------------------------------------------------- - Separated the client-side and server-side to use their own device model types. For example, there's now HClientDevice and HServerDevice in place of HDevice. - Fine tuned the device model types for their purposes more precisely. For instance, server-side action type does not have asynchronous invocation API and client-side action types does not have synchronous invocation API anymore. - Removed the possibility for the user to plug-in client-side device model classes. - Decoupled the "type creation" and "setup data" API away from the device model components to their own types (HDeviceModelCreator and HDeviceModelInfoProvider). - Modified the client-side action invocation semantics to send the "results" directly through the specified callback or the invokeComplete() signal. - Moved the UPnP action return codes directly to Herqq::Upnp namespace. - Modified the HControlPoint and HDeviceHost to run in a single thread only. - Removed exceptions from HUPnP altogether. - Removed the dependency to QtGui library by replacing the use of QImage with QByteArray. QImage was used to store icon data. - Replaced the internal use of QHttpHeader, QHttpRequestHeader and QHttpResponseHeader with similar custom classes. - Added convenience methods to HActionArguments for getting and setting a state variable value safely. - Fixed a few bugs in HTTP header parsing. - Fixed a few memory leaks. - Fixed several errors in the project files and added the possibility to define the install location of HUPnP. - Did various optimizations that improve speed and decrease the memory foot print. - Fixed a problem with QtCreator's "shadow build feature" that caused the launch of SimpleTestApp's HTestDevice to fail, as the required description documents could not be found. - Did internal refactoring in various places. - Did code cleansing and a number of general improvements not worth mentioning individually. - Updated documentation. Special thanks to Jukka Kinnunen and João Xavier for reporting their findings to me. Much appreciated. HUPnP 0.7.0 [Oct 6, 2010] -------------------------------------------------------------------------------- - Added classes for setting up each component of the device model. See the reference documentation about the device model creation for more details. - Modified the structure and contents of the "include" directory and added the possibility to "deploy" the built binaries and public headers to a folder for easier deployment (using "make install"). - Introduced "information" classes for each core component of the device model. These classes contain static information read from description documents. - Added the possibility to define whether HDeviceHost runs user code in a single or multiple threads. - Added support for HTTP authentication during client-side action invocation. - Added the possibility to execute action invocation in a "fire and forget" manner. - Improved the extensibility of HControlPoint's and HDeviceHost's configuration classes. - Modified the HActionArgument and HActionArguments to use value-semantics in full. - Modified the access modifiers of several methods in the components of the device model to improve extensibility. - Modified the HAction's generic error codes to use an enumeration rather than static member functions. - Unified some of the names of similar methods amongst device model components. - Removed the use of Qt's event dispatcher from HControlPoint and HDeviceHost. - Prefixed the include directives to Qt headers in public HUPnP header files to include the Qt module name. - Fixed a bug, which exposed a few private exception classes to public interface. HUPnP should not expose exceptions into the public interface anymore. - Fixed several bugs in event handling, action invocation and component initialization that could have caused dead-lock situations. - Fixed a possible crash bug in generation of a SOAP error message. - Fixed a bug in service description parse code in relation to allowed value ranges. - Fixed a possible crash bug in client-side action invocation. - Fixed a possible crash bug in the shutdown of a control point and device host. - Fixed a bug in generic HTTP messaging related to handling packets that lack the "content-length" header. - Modified build settings to enable the Qt Creator's "shadow build" feature. - Did internal refactoring in various places. - Many small optimizations, code cleansing and general improvements not worth mentioning individually. - Updated documentation. Special thanks to Nikhil Marathe , Sebastian Marek , Jukka Kinnunen and Paulo Romulo for testing and using the library and reporting their findings and ideas to me. Much appreciated. HUPnP 0.6.0 [June 25, 2010] -------------------------------------------------------------------------------- - License changed from GPLv3 to LGPLv3. - Significant modifications to the HUPnP device model. See the reference documentation for more information. - Added support for specifying the network interfaces to be used with the HUPnP hosting API. - Added support for a unicast device discovery into the HControlPoint. - Added various helper methods to some of the members of the device model and the hosting API. - Added support for retrieving runtime status information of a HDeviceHost. - Modified asynchronous action invocation to use a class named HAsyncOp to abstract the use of various input and output arguments controlling the execution and waiting of an asynchronous operation. - Modified the usage semantics and the interface of HSsdp. See the reference documentation for more information. - Modified the SSDP layer to send messages with the destination UDP port set to 0 to the port 1900. - Renamed several classes and enumerations to improve clarity. - Fixed a bug in HMulticastSocket relating to operations targeted at a multicast group using a specific network interface. - Fixed a bug in the initialization of HControlPoint. - Fixed a bug relating to client-side action invocation, which in certain error scenarios resulted in a null pointer dereference. - Did internal refactoring in various places. - Many small optimizations, code cleansing and general improvements not worth mentioning individually. - Updated documentation. Special thanks to Nikhil Marathe for testing and using the library and reporting his findings to me. Much appreciated. -------------------------------------------------------------------------------- HUPnP 0.5.0 [May 1, 2010] The changes done between 0.4 and 0.5 were significant and the list below is far from complete. For much more information of what has been you can check the version control history. - Major redesign of the hosting API. Both HControlPoint and HDeviceHost were changed notably in an attempt to add more power, configurability and extensibility to the classes. - HDeviceHost and HControlPoint no longer expose the device trees (HUPnP device model) using QSharedPointer. Raw pointers are used instead. - Modified the HControlPoint and HDeviceHost API regarding return values of various methods. Now methods signal failure with a boolean return value and the last error occurred can be checked with a separate call. - Modified the design of action arguments. Input and output arguments are no longer separated at type-level. - Did numerous modifications to improve interoperability with other UPnP software. Generally this meant lessening the strictness of HUPnP or making the level of strictness "configurable". - Did significant changes to the SSDP layer. Mainly the changes were about cleaning the API and making it more powerful. However, the implementation was improved as well. The changes include several bug fixes and improve interoperability with other UPnP software. - Event subscription at the control point now uses Qt event loop only (used threads before). This change is part of the plan of reducing worker thread usage to absolute minimum and attempting to utilize the Qt event loop as much as possible instead. - Added proper support for MX wait time during discovery. - Removed the 'T' postfix of certain type definitions, as it isn't part of the Qt's design conventions. Along with this change some type definitions were also renamed, such as HServicePtrList was changed to HServiceList and HDevicePtrList was changed to HDeviceList. - Renamed the toReadable() and toWritable() methods in HStateVariable to readable() and writable() to better convey the semantics that new unrelated types are not created. - Fixed several bugs relating to URL handling. - Fixed a possible null pointer dereference bug in HException. - Fixed a few bugs in creation of event subscription messages. - Fixed a few bugs in the HDeviceHost relating to UPnP event handling. - Fixed a crash bug in the simple test app. - Fixed a bug relating to multicast address check in HEndpoint. - Fixed a few bugs in general HTTP messaging / handling. - Various logging improvements. - Did internal refactoring in various places. - Removed insulation from several small classes that are unlikely to change. - Many small optimizations, code cleansing and general improvements not worth mentioning individually. - Updated documentation. Special thanks to Bart Cerneels , Thiago Macieira, James Wa , Nikhil Marathe , Jukka Kinnunen , Simon Zsolt and Pekka Turunen for testing and using the library or otherwise checking it out, and reporting their findings to me. Much appreciated. HUPnP 0.4.0 [Mar. 4, 2010] - Modified the design of state variables and their use. More specifically, the API is now clear that state variables can be changed directly only at server-side. - Added the possibility of locking a writable state variable for exclusive access at server-side. - Modified the design of action arguments. Input and output arguments are no longer separated at type-level. - Removed exception usage from HTTP messaging. This was mainly because of a MinGW bug (http://sourceforge.net/tracker/index.php?func=detail&aid=2837096&group_id=2435&atid=102435), which essentially causes multi-threaded exception usage be unsafe. Please note, HUPnP still uses exceptions elsewhere, which means that with MinGW 4.4.0 HUPnP is subject to crashes. The HUPnP HTTP messaging used exceptions to signal timeouts, peer disconnects and such, which made the bug all too easy to appear in case multiple threads were simultaneously running their own HUPnP HTTP messaging "engines". This is the case with the simple HUPnP test app, which enables the launch of a HDeviceHost and multiple HControlPoints within the same process using separate threads. - Modified the server-side action invocation mechanics when the invocations come over the network. - Modified the example application to use the state variable locker, which fixes a race condition. - Fixed a few errors in internal HTTP messaging code. These mainly affected action invocation and event notification. - Modified the internal asynch. HTTP handler code to support chunked encoding. - Removed insulation from a few small classes that are unlikely to change. - Some small optimizations here and there. - Updated documentation. - Many smaller improvements not worth mentioning individually. HUPnP 0.3.0 [Feb. 17, 2010] - Significant refactoring of the project, file and class structures. - Added a simple example application to be distributed along with HUPnP. The example demonstrates basic HUPnP usage. - Reduced thread usage by utilizing the Qt's eventloop more. - Removed exceptions from the public interface. This affected HDeviceInfo + several classes in the SSDP "module". - Removed the HCore and HUtils libraries and moved their code directly into the HUpnp library. - Modified the action invocation semantics. This changed the HAction interface as well. - Modified the HControlPoint interface. - Modified the initialization of HSsdp. This also meant a change to the interface. - Fixed several memory leaks and memory access errors. - Improved logging by feeding more information to the messages. - Updated documentation. - Many smaller improvements not worth mentioning individually. HUPnP 0.2.0 [Feb. 2, 2010] - Significant refactoring of the project, file and class structures. - Fixed several bugs relating to URL handling in HDeviceHost and HControlPoint. - Changed action invocation on the control point side to use persistent sockets. - Fixed a bug in HStateVariable, which caused "allowed value ranges" to be parsed improperly. - Fixed a bug in HDeviceHost, which caused the HDeviceHost to announce wrong cache-control max-age timeouts. - Fixed a bug in HDeviceHost, which in a certain scenario caused a failure in transmission of an event NOTIFY message. - Added support for enabling/disabling warning logs that relate to non-standard behaviour discovered in other UPnP software. - Updated documentation. - Several other improvements not worth mentioning individually. Special thanks goes to Jochen Becher for testing the library and reporting of his findings. Some of the above-mentioned bugs were discovered due to his efforts. In addition, he suggested the possibility of disabling warnings that relate to non-standard behaviour discovered in other UPnP software. Thank you! HUPnP 0.1.1 [Jan. 26, 2010] - Added support for chunked encoding. - Fixed several deficiences relating to action invocation error handling. - Fixed a bug in HControlPoint where the HTTP Host header field was not always sent in a GET request. * This was found by Jochen Becher . Thanks! - Fixed a bug in HDeviceHost, which forced description documents to reside in the current directory to be found. - Removed exception usage from "simple" classes in Ssdp module. - A few small improvements not worth mentioning individually. - Updated documentation. - Created this change log. herqq-1.0.0/hupnp/src.pro0000644000000000000000000000371511543637310014002 0ustar rootrootTEMPLATE = lib TARGET = HUpnp QT += network xml QT -= gui CONFIG += warn_on dll thread DEFINES += H_BUILD_UPNP_CORE_LIB VERSION = 1.0.0 exists(options.pri) { include(options.pri) } INCLUDEPATH += ./include/ CONFIG(DISABLE_QTSOAP) { INCLUDEPATH += $$[QT_INSTALL_HEADERS]/QtSoap } else { INCLUDEPATH += ./lib/qtsoap-2.7-opensource/src } LIBS += -L"./bin/" !CONFIG(DISABLE_QTSOAP): LIBS += -L"./lib/qtsoap-2.7-opensource/lib" debug:DEFINES += DEBUG win32 { debug { LIBS += -lQtSolutions_SOAP-2.7d } else { LIBS += -lQtSolutions_SOAP-2.7 } LIBS += -lws2_32 TARGET_EXT = .dll } else { LIBS += -lQtSolutions_SOAP-2.7 } OBJECTS_DIR = obj DESTDIR = ./bin MOC_DIR = obj SRC_LOC = ./src/utils include (./src/utils/utils.pri) SRC_LOC = ./src include (src/http/http.pri) include (src/ssdp/ssdp.pri) include (src/socket/socket.pri) include (src/general/general.pri) include (src/devicemodel/devicemodel.pri) include (src/dataelements/dataelements.pri) include (src/devicehosting/devicehosting.pri) !CONFIG(DISABLE_QTSOAP) { win32 { QMAKE_POST_LINK += copy lib\\qtsoap-2.7-opensource\\lib\\* bin /Y } else { QMAKE_POST_LINK += cp -fR ./lib/qtsoap-2.7-opensource/lib/* ./bin/ } } CONFIG(USE_QT_INSTALL_LOC) { INSTLOC_INC = $$[QT_INSTALL_HEADERS]/HUpnpCore INSTLOC_LIB = $$[QT_INSTALL_LIBS] } else { isEmpty(PREFIX) { PREFIX = ./deploy } INSTLOC_INC = $$PREFIX/include/HUpnpCore INSTLOC_LIB = $$PREFIX/lib } includes.files += ./include/HUpnpCore/H* includes.path = $$INSTLOC_INC public_headers.files = $$find(HEADERS, ^((?!_p).)*$)* public_headers.path = $$INSTLOC_INC/public private_headers.files = $$EXPORTED_PRIVATE_HEADERS private_headers.path = $$INSTLOC_INC/private target.path = $$INSTLOC_LIB INSTALLS += includes public_headers private_headers target herqq-1.0.0/hupnp/docs/0000755000000000000000000000000011543637604013421 5ustar rootrootherqq-1.0.0/hupnp/docs/html/0000755000000000000000000000000011543637604014365 5ustar rootrootherqq-1.0.0/hupnp/docs/html/functions_0x6c.html0000644000000000000000000001202511543637604020123 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- l -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_resource_update.html0000644000000000000000000005675211543637604025521 0ustar rootroot Herqq: HResourceUpdate Class Reference

HResourceUpdate Class Reference

Class representing the device update (ssdp:update) message. More...

#include <HResourceUpdate>

List of all members.

Public Member Functions

 HResourceUpdate ()
 HResourceUpdate (const QUrl &location, const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=-1, qint32 nextBootId=-1, qint32 searchPort=-1)
 ~HResourceUpdate ()
 HResourceUpdate (const HResourceUpdate &)
HResourceUpdateoperator= (const HResourceUpdate &)
bool isValid (HValidityCheckLevel level) const
QUrl location () const
const HDiscoveryTypeusn () const
qint32 bootId () const
qint32 configId () const
qint32 nextBootId () const
qint32 searchPort () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HResourceUpdate &, const HResourceUpdate &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HResourceUpdate &obj1, const HResourceUpdate &obj2)

Detailed Description

Class representing the device update (ssdp:update) message.

Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, or you receive instances of this class from the Herqq::Upnp::HSsdp.

Remarks:
the class provides an assignment operator, which is not thread-safe.
See also:
HSsdp

Constructor & Destructor Documentation

Constructs a new, empty instance.

The constructed object is not valid, i.e isValid() returns false.

See also:
isValid()
HResourceUpdate ( const QUrl &  location,
const HDiscoveryType usn,
qint32  bootId = -1,
qint32  configId = -1,
qint32  nextBootId = -1,
qint32  searchPort = -1 
)

Constructs a new instance using the specified parameters.

Parameters:
locationspecifies the URL to the UPnP description of the root device. If the location is invalid or empty the created object will be invalid.
usnspecifies the Unique Service Name. The created object is invalid if the provided USN is invalid.
bootIdspecifies the BOOTID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0.
configIdspecifies the CONFIGID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0
nextBootId
searchPortspecifies the SEARCHPORT.UPNP.ORG header value. Note that this is optional in UDA v1.1, whereas it is not specified at all in UDA v1.0. If specified, this is the port at which the device must listen for unicast M-SEARCH messages. Otherwise the port is by default 1900. This parameter is optional.
Remarks:
if searchPort is smaller than 49152 or larger than 65535 it is set to -1. This is specified in the UDA v1.1.

Destroys the instance.

HResourceUpdate ( const HResourceUpdate other)

Copy constructor.

Copies the contents of the other to this.


Member Function Documentation

HResourceUpdate & operator= ( const HResourceUpdate other)

Assigns the contents of the other to this.

Returns:
a reference to this object.
bool isValid ( HValidityCheckLevel  level) const

Indicates whether or not the object contains valid announcement information.

Parameters:
levelindicates whether the check should be strictly according to the UDA specification. If set to false some checks are omitted that are known to be poorly implemented in some UPnP software.
Returns:
true in case the objects contains valid announcement information in terms of the requested strictness.
QUrl location ( ) const

Returns the location of the announced device.

Returns:
The location of the announced device. This is the URL where the device description can be retrieved. The returned object will be empty if this object is invalid.
See also:
isValid()
const HDiscoveryType & usn ( ) const

Returns the Unique Service Name.

Returns:
The Unique Service Name.
qint32 bootId ( ) const

Returns the value of BOOTID.UPNP.ORG.

Returns:
The value of BOOTID.UPNP.ORG. If the value is not specified -1 is returned.
qint32 configId ( ) const

Returns the value of CONFIGID.UPNP.ORG.

Returns:
The value of CONFIGID.UPNP.ORG. If the value is not specified -1 is returned.
qint32 nextBootId ( ) const
Returns:
If the value is not specified -1 is returned.
qint32 searchPort ( ) const

Returns the value of SEARCHPORT.UPNP.ORG header field.

Returns:
The value of SEARCHPORT.UPNP.ORG header field. If the value is not specified -1 is returned.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HResourceUpdate ,
const HResourceUpdate  
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HResourceUpdate obj1,
const HResourceUpdate obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_upnp_data_types.html0000644000000000000000000020124311543637604025512 0ustar rootroot Herqq: HUpnpDataTypes Class Reference

HUpnpDataTypes Class Reference

An utility class for working with UPnP data types. More...

#include <HUpnpDataTypes>

List of all members.

Public Types

enum  DataType {
  Undefined = 0, ui1, ui2, ui4 ,
  i2, i4, integer, r4,
  r8, number, fixed_14_4, fp,
  character, string, date, dateTime,
  dateTimeTz, time, timeTz, boolean,
  bin_base64, bin_hex, uri, uuid
}
typedef quint8 ui1T
typedef quint16 ui2T
typedef quint32 ui4T
typedef qint8 i1T
typedef qint16 i2T
typedef qint32 i4T
typedef i4T integerT
typedef float r4T
typedef qreal r8T
typedef r8T numberT
typedef qreal fixed_14_4T
typedef float fpT
typedef char characterT
typedef QString stringT
typedef QDate dateT
typedef QDateTime dateTimeT
typedef QTime timeT
typedef QTime time_tzT
typedef bool booleanT
typedef QByteArray bin_base64T
typedef QByteArray bin_hexT
typedef QUrl uriT
typedef QUuid uuidT

Static Public Member Functions

static const QString & ui1_str ()
static const QString & ui2_str ()
static const QString & ui4_str ()
static const QString & i1_str ()
static const QString & i2_str ()
static const QString & i4_str ()
static const QString & integer_str ()
static const QString & r4_str ()
static const QString & r8_str ()
static const QString & number_str ()
static const QString & fixed_14_4_str ()
static const QString & fp_str ()
static const QString & character_str ()
static const QString & string_str ()
static const QString & date_str ()
static const QString & dateTime_str ()
static const QString & dateTimeTz_str ()
static const QString & time_str ()
static const QString & time_tz_str ()
static const QString & boolean_str ()
static const QString & bin_base64_str ()
static const QString & bin_hex_str ()
static const QString & uri_str ()
static const QString & uuid_str ()
static DataType dataType (const QString &dataTypeAsStr)
static bool isNumeric (DataType datatype)
static bool isInteger (DataType datatype)
static bool isRational (DataType arg)
static QString toString (DataType datatype)

Detailed Description

An utility class for working with UPnP data types.


Member Typedef Documentation

typedef quint8 ui1T

Type definition for a DataType::ui1.

typedef quint16 ui2T

Type definition for a DataType::ui2.

typedef quint32 ui4T

Type definition for a DataType::ui4.

typedef qint8 i1T

Type definition for a DataType::i1.

typedef qint16 i2T

Type definition for a DataType::i2.

typedef qint32 i4T

Type definition for a DataType::i4.

typedef i4T integerT

Type definition for a DataType::integer.

typedef float r4T

Type definition for a DataType::r4.

typedef qreal r8T

Type definition for a DataType::r8.

typedef r8T numberT

Type definition for a DataType::number.

typedef qreal fixed_14_4T

Type definition for a DataType::fixed_14_4.

typedef float fpT

Type definition for a DataType::fp.

typedef char characterT

Type definition for a DataType::char.

typedef QString stringT

Type definition for a DataType::string.

typedef QDate dateT

Type definition for a DataType::date.

typedef QDateTime dateTimeT

Type definition for a DataType::dateTime.

typedef QTime timeT

Type definition for a DataType::time.

typedef QTime time_tzT

Type definition for a DataType::timeTz.

typedef bool booleanT

Type definition for a DataType::boolean.

typedef QByteArray bin_base64T

Type definition for a DataType::bin_base64.

typedef QByteArray bin_hexT

Type definition for a DataType::bin_hex.

typedef QUrl uriT

Type definition for a DataType::uri.

typedef QUuid uuidT

Type definition for a DataType::uuid.


Member Enumeration Documentation

enum DataType

This enum type defines the UPnP data types set by the UPnP Device Architecture v1.1 specification.

Enumerator:
Undefined 

Undefined, illegal data type.

ui1 

Unsigned 1 Byte int.

Same format as int without leading sign.

ui2 

Unsigned 2 Byte int.

Same format as int without leading sign.

ui4 

Unsigned 4 Byte int.

Same format as int without leading sign.

1 Byte int. Same format as int.

i2 

2 Byte int.

Same format as int.

i4 

4 Byte int.

Same format as int. MUST be between -2147483648 and 2147483647.

integer 

Fixed point, integer number.

r4 

4 Byte float.

Same format as float. MUST be between 3.40282347E+38 to 1.17549435E-38.

r8 

8 Byte float.

Same format as float. MUST be between -1.79769313486232E308 and - 4.94065645841247E-324 for negative values, and between 4.94065645841247E-324 and 1.79769313486232E308 for positive values, i.e., IEEE 64-bit (8-Byte) double.

number 

Same as r8.

fixed_14_4 

Same as r8 but no more than 14 digits to the left of the decimal point and no more than 4 to the right.

fp 

Floating point number.

Mantissa (left of the decimal) and/or exponent MAY have a leading sign. Mantissa and/or exponent MAY have leading zeros, which SHOULD be ignored by the recipient. Decimal character in mantissa is a period, i.e., whole digits in mantissa separated from fractional digits by period ("."). Mantissa separated from exponent by "E".

character 

Unicode string.

One character long.

string 

Unicode string.

No limit on length.

date 

Date in a subset of ISO 8601 format without time data.

dateTime 

Date in ISO 8601 format with OPTIONAL time but no time zone.

dateTimeTz 

Date in ISO 8601 format with OPTIONAL time and OPTIONAL time zone.

time 

Time in a subset of ISO 8601 format with no date and no time zone.

timeTz 

Time in a subset of ISO 8601 format with OPTIONAL time zone but no date.

boolean 

"0" for false or "1" for true.

The values "true", "yes", "false", or "no" are deprecated and MUST NOT be sent but MUST be accepted when received. When received, the values "true" and "yes" MUST be interpreted as true and the values "false" and "no" MUST be interpreted as false.

bin_base64 

MIME-style Base64 encoded binary BLOB.

Takes 3 Bytes, splits them into 4 parts, and maps each 6 bit piece to an octet. (3 octets are encoded as 4.) No limit on size.

bin_hex 

Hexadecimal digits representing octets.

Treats each nibble as a hex digit and encodes as a separate Byte. (1 octet is encoded as 2.) No limit on size.

uri 

Universal Resource Identifier.

uuid 

Universally Unique ID.


Member Function Documentation

static const QString& ui1_str ( ) [inline, static]

The string identifier for an unsigned 1 byte int.

See also:
DataType::ui1
static const QString& ui2_str ( ) [inline, static]

The string identifier for an unsigned 2 byte int.

See also:
DataType::ui2
static const QString& ui4_str ( ) [inline, static]

The string identifier for an unsigned 4 byte int.

See also:
DataType::ui4
static const QString& i1_str ( ) [inline, static]

The string identifier for a 1 byte int.

See also:
DataType::i1
static const QString& i2_str ( ) [inline, static]

The string identifier for a 2 byte int.

See also:
DataType::i2
static const QString& i4_str ( ) [inline, static]

The string identifier for a 4 byte int.

See also:
DataType::i4
static const QString& integer_str ( ) [inline, static]

The string identifier for a fixed point, integer number.

See also:
DataType::integer
static const QString& r4_str ( ) [inline, static]

The string identifier for a 4 byte float.

See also:
DataType::r4
static const QString& r8_str ( ) [inline, static]

The string identifier for a 8 byte float.

See also:
DataType::r8
static const QString& number_str ( ) [inline, static]

The string identifier for a 8 byte float.

This is an alias for r8.

See also:
DataType::number
static const QString& fixed_14_4_str ( ) [inline, static]

The string identifier for a 8 byte float that has no more than 14 digits to the left of the decimal point and no more than 4 to the right.

See also:
DataType::fixed_14_4
static const QString& fp_str ( ) [inline, static]

The string identifier for a floating point number.

See also:
DataType::fp
static const QString& character_str ( ) [inline, static]

The string identifier for a unicode string that is one character long.

See also:
DataType::char
static const QString& string_str ( ) [inline, static]

The string identifier for a unicode string that has no limit on length.

See also:
DataType::string
static const QString& date_str ( ) [inline, static]

The string identifier for a date in a subset of ISO 8601 format without time data.

See also:
DataType::date
static const QString& dateTime_str ( ) [inline, static]

The string identifier for a date in ISO 8601 format with OPTIONAL time but no time zone.

See also:
DataType::dateTime
static const QString& dateTimeTz_str ( ) [inline, static]

The string identifier for a date in ISO 8601 format with OPTIONAL time and OPTIONAL time zone.

See also:
DataType::dateTimeTz
static const QString& time_str ( ) [inline, static]

The string identifier for a time in a subset of ISO 8601 format with no date and no time zone.

See also:
DataType::time
static const QString& time_tz_str ( ) [inline, static]

The string identifier for a time in a subset of ISO 8601 format with OPTIONAL time zone but no date.

See also:
DataType::timeTz
static const QString& boolean_str ( ) [inline, static]

The string identifier for a boolean.

See also:
DataType::boolean
static const QString& bin_base64_str ( ) [inline, static]

The string identifier for a MIME-style Base64 encoded binary BLOB.

See also:
DataType::bin_base64
static const QString& bin_hex_str ( ) [inline, static]

The string identifier for a hexadecimal digits representing octets.

See also:
DataType::bin_hex
static const QString& uri_str ( ) [inline, static]

The string identifier for a universal Resource Identifier.

See also:
DataType::uri
static const QString& uuid_str ( ) [inline, static]

The string identifier for a universally Unique ID.

See also:
DataType::uuid
HUpnpDataTypes::DataType dataType ( const QString &  dataTypeAsStr) [static]

Returns the UPnP data type enum value that matches the content of the specified string, if any.

Parameters:
dataTypeAsStrspecifies the "name" of the UPnP data type as string. For example, the string could contain "i4", which in the UDA v1.1 specification is defined as 4-byte signed integer.
Returns:
The UPnP data type enum value that matches the content of the specified string. If the specified string does not correspond to any UPnP data type, HUpnpDataTypes::Undefined is returned.
static bool isNumeric ( DataType  datatype) [inline, static]

Indicates whether or not the specified data type is numeric.

Parameters:
datatypespecifies the data type to be checked.
Return values:
trueif the specified data type is numeric.
falsein case the data type is not numeric or it is undefined.
static bool isInteger ( DataType  datatype) [inline, static]

Indicates whether or not the specified data type is an integer.

Parameters:
datatypespecifies the data type to be checked.
Return values:
trueif the specified data type is an integer.
falsein case the data type is not an integer or it is undefined.
static bool isRational ( DataType  arg) [inline, static]

Indicates whether or not the specified data type is a rational number.

Parameters:
argspecifies the data type to be checked.
Return values:
trueif the specified data type is a rational number.
falsein case the data type is not rational or it is undefined.
QString toString ( DataType  datatype) [static]

Returns the UDA defined string representation of the specified data type.

Parameters:
datatypespecifies the data type which string representation is requested.
Returns:
The UDA defined string representation of the specified data type.
herqq-1.0.0/hupnp/docs/html/functions_0x76.html0000644000000000000000000001526011543637604020053 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- v -

herqq-1.0.0/hupnp/docs/html/hupnpinfo_8h.html0000644000000000000000000001673411543637604017673 0ustar rootroot Herqq: src/general/hupnpinfo.h File Reference

src/general/hupnpinfo.h File Reference

This file contains information of the HUPnP core library. More...

#include <HUpnpCore/HUpnp>

Namespaces

namespace  Herqq
namespace  Herqq::Upnp

Defines

#define HUPNP_CORE_MAJOR_VERSION   1
#define HUPNP_CORE_MINOR_VERSION   0
#define HUPNP_CORE_PATCH_VERSION   0
#define HUPNP_CORE_VERSION   STRX(HUPNP_CORE_MAJOR_VERSION.HUPNP_CORE_MINOR_VERSION.HUPNP_CORE_PATCH_VERSION)

Functions

const char * hupnpCoreVersion ()

Detailed Description

This file contains information of the HUPnP core library.


Define Documentation

#define HUPNP_CORE_MAJOR_VERSION   1

This is the major version of the HUPnP Core library with which this header file was provided.

This value is useful for compile time checks.

See also:
Herqq::Upnp::hupnpCoreVersion()
#define HUPNP_CORE_MINOR_VERSION   0

This is the minor version of the HUPnP Core library with which this header file was provided.

This value is useful for compile time checks.

See also:
Herqq::Upnp::hupnpCoreVersion()
#define HUPNP_CORE_PATCH_VERSION   0

This is the patch version of the HUPnP Core library with which this header file was provided.

This value is useful for compile time checks.

See also:
Herqq::Upnp::hupnpCoreVersion()
#define HUPNP_CORE_VERSION   STRX(HUPNP_CORE_MAJOR_VERSION.HUPNP_CORE_MINOR_VERSION.HUPNP_CORE_PATCH_VERSION)

This is the version of the HUPnP Core library with which this header file was provided.

This value is useful for compile time checks.

See also:
Herqq::Upnp::hupnpCoreVersion()
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_model_creator.html0000644000000000000000000003101211543637604026444 0ustar rootroot Herqq: HDeviceModelCreator Class Reference

HDeviceModelCreator Class Reference

A protocol class for creating HServerDevice and HServerService instances. More...

#include <HDeviceModelCreator>

Inheritance diagram for HDeviceModelCreator:
HClonable

List of all members.

Public Member Functions

 HDeviceModelCreator ()
virtual ~HDeviceModelCreator ()
virtual HServerDevicecreateDevice (const HDeviceInfo &info) const
virtual HServerServicecreateService (const HServiceInfo &serviceInfo, const HDeviceInfo &parentDeviceInfo) const =0
virtual HDeviceModelCreatorclone () const

Detailed Description

A protocol class for creating HServerDevice and HServerService instances.

The primary purpose of this protocol class is to build instances of the HUPnP's Device Model at server-side. If you wish to host a device in an HDeviceHost you have to derive from this class and override its abstract methods.

See also:
Device Hosting, HServerDevice, HServerService

Constructor & Destructor Documentation

Creates a new instance.

~HDeviceModelCreator ( ) [virtual]

Destroys the instance.


Member Function Documentation

HServerDevice * createDevice ( const HDeviceInfo info) const [virtual]

Creates a device matching the provided device information.

Parameters:
infospecifies information of the device type the creator is asked to create.
Returns:
a heap allocated device matching the provided device information or null in case the creator does not recognize the specified device type.
Remarks:
The ownership of the created device is transferred to the caller.
virtual HServerService* createService ( const HServiceInfo serviceInfo,
const HDeviceInfo parentDeviceInfo 
) const [pure virtual]

Creates a service matching the provided service information.

Parameters:
serviceInfospecifies information of the service type the creator is asked to create.
parentDeviceInfospecifies information about the parent UPnP device that contains this service.
Returns:
a heap allocated service matching the provided service information or null in case the creator does not recognize the specified service type.
Remarks:
The ownership of the created service is transferred to the caller.
HDeviceModelCreator * clone ( ) const [virtual]

Returns a deep copy of the instance.

Returns:
a deep copy of the instance.
Remarks:
  • the ownership of the returned object is transferred to the caller.

Reimplemented from HClonable.

herqq-1.0.0/hupnp/docs/html/nav_h.png0000644000000000000000000000014111543637604016162 0ustar rootroot‰PNG  IHDR ,é@(IDATxíݱ 0 A½2°ÁU¶— !kÜJrª¯ƒžZýÿÆo‡üèIEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_resource_type-members.html0000644000000000000000000002740211543637604026636 0ustar rootroot Herqq: Member List

HResourceType Member List

This is the complete list of members for HResourceType, including all inherited members.
All enum valueHResourceType
compare(const HResourceType &other, VersionMatch versionMatch) const HResourceType
Domain enum valueHResourceType
EqualOrGreater enum valueHResourceType
Exact enum valueHResourceType
HResourceType()HResourceType
HResourceType(const QString &resourceTypeAsStr)HResourceType
Ignore enum valueHResourceType
Inclusive enum valueHResourceType
isDeviceType() const HResourceType [inline]
isServiceType() const HResourceType [inline]
isStandardType() const HResourceType [inline]
isValid() const HResourceType [inline]
None enum valueHResourceType
operator!=(const HResourceType &obj1, const HResourceType &obj2)HResourceType [related]
operator==(const HResourceType &, const HResourceType &)HResourceType [friend]
qHash(const HResourceType &key)HResourceType [related]
StandardDeviceType enum valueHResourceType
StandardServiceType enum valueHResourceType
Token enum nameHResourceType
toString(Tokens tokens=All) const HResourceType
type() const HResourceType [inline]
Type enum nameHResourceType
Type enum valueHResourceType
TypeSuffix enum valueHResourceType
Undefined enum valueHResourceType
UrnPrefix enum valueHResourceType
VendorSpecifiedDeviceType enum valueHResourceType
VendorSpecifiedServiceType enum valueHResourceType
version() const HResourceType
Version enum valueHResourceType
VersionMatch enum nameHResourceType
~HResourceType()HResourceType
herqq-1.0.0/hupnp/docs/html/functions_enum.html0000644000000000000000000001037311543637604020313 0ustar rootroot Herqq: Class Members - Enumerations
 
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_resource_update-members.html0000644000000000000000000001456211543637604027142 0ustar rootroot Herqq: Member List

HResourceUpdate Member List

This is the complete list of members for HResourceUpdate, including all inherited members.
bootId() const HResourceUpdate
configId() const HResourceUpdate
HResourceUpdate()HResourceUpdate
HResourceUpdate(const QUrl &location, const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=-1, qint32 nextBootId=-1, qint32 searchPort=-1)HResourceUpdate
HResourceUpdate(const HResourceUpdate &)HResourceUpdate
isValid(HValidityCheckLevel level) const HResourceUpdate
location() const HResourceUpdate
nextBootId() const HResourceUpdate
operator!=(const HResourceUpdate &obj1, const HResourceUpdate &obj2)HResourceUpdate [related]
operator=(const HResourceUpdate &)HResourceUpdate
operator==(const HResourceUpdate &, const HResourceUpdate &)HResourceUpdate [friend]
searchPort() const HResourceUpdate
usn() const HResourceUpdate
~HResourceUpdate()HResourceUpdate
herqq-1.0.0/hupnp/docs/html/nav_f.png0000644000000000000000000000023711543637604016166 0ustar rootroot‰PNG  IHDR8³»fIDATxíÝIB1 Q;uÛ¿@ÑÏh;áÚ ±aË !ŽÐ‹V½CÈíþ âŠÅÆ|c±˜¾™¶¶3èsÑFÐFP»S{PšSšsVãlN®F.F.“ã2’ˆüµ¤ï_U¿Œ¾˜Ïþ«‰ÈH Ým”°•IEND®B`‚herqq-1.0.0/hupnp/docs/html/functions_0x75.html0000644000000000000000000002265711543637604020062 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- u -

herqq-1.0.0/hupnp/docs/html/setting_up_the_devicemodel.html0000644000000000000000000012256311543637604022645 0ustar rootroot Herqq: Setting Up the Device Model

Setting Up the Device Model

Before We Start

Please note that in case you are writing client-side software you rarely need to worry about how the device model gets built. But if you are implementing a server-side UPnP device, this is something you should know. In addition, you should first skim through the Tutorial for Building a UPnP Device if you haven't already.

How HDeviceHost builds a device tree

When you initialize an Herqq::Upnp::HDeviceHost you have to provide it:

  • one or more device descriptions that represent the UPnP device(s) you want to host and
  • a device model creator that creates the C++ classes representing the UPnP devices and services defined in the description documents.

You can find more information about setting up the Herqq::Upnp::HDeviceHost in Device Hosting, but what is relevant here is that you provide two pieces of information that must match; the C++ classes created by the device model creator must reflect the description documents and vice versa.

During its initialization an HDeviceHost scans the provided description document(s) and whenever it encounters a definition of a UPnP device it invokes the device model creator you have provided to create an instance of HServerDevice matching the device definition in the description document. Similarly, whenever it encounters a UPnP service it invokes the device model creator to create an instance of HServerService.

When creating a device the HDeviceHost provides an HDeviceInfo object to the creator, which contains the information read from the description document. And again, when creating a service an HServiceInfo object is provided to the creator. Based on the information in the info objects the device model creator is expected to create an HServerDevice or HServerService instance if it can, or return null otherwise. If the device model creator returns null the HDeviceHost creates an instance of a default type used to represent the encountered UPnP device or service.

Consider an example of a simple device model creator,

 #include <HUpnpCore/HDeviceModelCreator>

 class MyCreator : public Herqq::Upnp::HDeviceModelCreator
 {

 private:

   // overridden from HDeviceModelCreator
   virtual MyCreator* newInstance() const
   {
       return new MyCreator();
   }

 public:

   // overridden from HDeviceModelCreator
   virtual MyHServerDevice* createDevice(const Herqq::Upnp::HDeviceInfo& info) const
   {
       if (info.deviceType().toString() == "urn:herqq-org:device:MyDevice:1")
       {
           return new MyHServerDevice();
       }

       return 0;
   }

   // overridden from HDeviceModelCreator
   virtual MyHServerService* createService(
       const Herqq::Upnp::HServiceInfo& serviceInfo,
       const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const
   {
       if (serviceInfo.serviceType().toString() == "urn:herqq-org:service:MyService:1")
       {
           return new HMyServerService();
       }

       // Note, parentDeviceInfo is not needed in this case, but there are
       // scenarios when it is mandatory to know information of the parent
       // device to create the correct HServerService type.

       return 0;
   }
 };
Note:
The HDeviceHost takes ownership of the returned objects. However, the HDeviceHost will not destroy any of them until it is being deleted.

Plugging in Custom Functionality

In the UPnP architecture the actions represent the functionality of a device. Actions are contained by services and services are contained by devices. Thus, custom functionality means custom actions, which are logically placed into custom services. Custom services, on the other hand, don't have to reside inside custom devices. This is because ultimately a device is only a container for services and that is certainly something the default device types used by HUPnP can handle.

So, to plug-in custom functionality you need a custom service type, which main purpose is to map callable entities to UPnP action names.

Note:
A callable entity is a C++ concept that is used to refer to anything that can be called with the operator(), such as a normal function, functor or a member function.

There are two ways to do the mapping. You can either override Herqq::Upnp::HServerService::createActionInvokes() in your custom HServerService type, or you can mark member functions of your custom HServerService as Q_INVOKABLE.

Consider an example of overriding the createActionInvokes(),

 Herqq::Upnp::HServerService::HActionInvokes MyConnectionManagerService::createActionInvokes()
 {
   Herqq::Upnp::HServerService::HActionInvokes retVal;

   retVal.insert("GetProtocolInfo",
       HActionInvoke(this, &MyConnectionManagerService::getProtocolInfo));

   retVal.insert("PrepareForConnection",
       HActionInvoke(this, &MyConnectionManagerService::prepareForConnection));

   retVal.insert("ConnectionComplete",
       HActionInvoke(this, &MyConnectionManagerService::connectionComplete));

   retVal.insert("GetCurrentConnectionIDs",
       HActionInvoke(this, &MyConnectionManagerService::getCurrentConnectionIDs));

   retVal.insert("GetCurrentConnectionInfo",
       HActionInvoke(this, &MyConnectionManagerService::getCurrentConnectionInfo));

   return retVal;
 }

The above code maps five member functions of the class MyConnectionManagerService to the five action names accordingly. Once the device tree is fully set up and the HServerDevice containing the MyConnectionManagerService is hosted by an HDeviceHost, action invocations are ultimately directed to these mapped member functions. In other words, in this case it is these member functions that have to do whatever it is that these actions are expected to do.

Note:
The callable entity concept detaches invocation logic from what is being invoked and enables these "entities" to be handled by value. It is a very powerful concept that allows you to map anything that can be called following a certain signature under the same interface and copy these entities around by-value.

To give you an idea of the versatility of an callable entity, you could do the above with normal functions too:

 namespace
 {
 int getProtocolInfo(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
 }

 int prepareForConnection(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
 }

 int connectionComplete(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
 }

 int getCurrentConnectionIDs(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
 }

 int getCurrentConnectionInfo(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
 }
 }

 Herqq::Upnp::HServerService::HActionInvokes MyConnectionManagerService::createActionInvokes()
 {
   Herqq::Upnp::HServerService::HActionInvokes retVal;

   retVal.insert("GetProtocolInfo", Herqq::Upnp::HActionInvoke(getProtocolInfo));
   retVal.insert("PrepareForConnection", Herqq::Upnp::HActionInvoke(prepareForConnection));
   retVal.insert("ConnectionComplete", Herqq::Upnp::HActionInvoke(connectionComplete));
   retVal.insert("GetCurrentConnectionIDs", Herqq::Upnp::HActionInvoke(getCurrentConnectionIDs));
   retVal.insert("GetCurrentConnectionInfo", Herqq::Upnp::HActionInvoke(getCurrentConnectionInfo));

   return retVal;
 }

And it doesn't stop there. You can use functors as well.

However, you can also let HUPnP to do the mapping and creation of the callable entities, but to do that you need to:

  • Make sure your custom HServerService type uses the Q_OBJECT macro.
  • Mark each member function to be used as an action implemention with Q_INVOKABLE macro.
  • Ensure that the member functions are named exactly as the corresponding actions are defined in the service description document.

Consider an example of using Q_INVOKABLE,

 class MyConnectionManagerService :
   public HServerService
 {
  Q_OBJECT

  public:

    MyConnectionManagerService();
    virtual ~MyConnectionManagerService();

    Q_INVOKABLE qint32 GetProtocolInfo(
        const HActionArguments& inArgs, HActionArguments* outArgs);

    Q_INVOKABLE qint32 PrepareForConnection(
        const HActionArguments& inArgs, HActionArguments* outArgs);

    Q_INVOKABLE qint32 ConnectionComplete(
        const HActionArguments& inArgs, HActionArguments* outArgs);

   Q_INVOKABLE qint32 GetCurrentConnectionIDs(
        const HActionArguments& inArgs, HActionArguments* outArgs);

   Q_INVOKABLE qint32 GetCurrentConnectionInfo(
        const HActionArguments& inArgs, HActionArguments* outArgs);
 };

Note, the method names are started with capital letters as are the corresponding actions defined in the ConnectionManager specification.

Once you have set up the action mappings, your custom HServerService is ready to be used. However, there is much more you can do with Herqq::Upnp::HDeviceModelInfoProvider::actionsSetupData() to ensure that the service description containing the action definitions is correct. Similarly, you can override Herqq::Upnp::HDeviceModelInfoProvider::stateVariablesSetupData() to provide additional information to HUPnP in order to make sure that the service description document is appropriately set up in terms of state variables as well. This may not be important to you if you are writing a "private" implementation of a service, but it could be very useful if you are writing a "public" library of UPnP devices and services that have to make sure they are appropriately used.

Note:
When implementing a custom HServerService class you have to define the implementations for the action definitions found in the corresponding service description document. You are not required to do anything else. However, you may provide additional information about the structure and details of a UPnP service via HDeviceModelInfoProvider::actionsSetupData() and HDeviceModelInfoProvider::stateVariablesSetupData(), but those are always optional.

Providing more information to the model setup process

There are a few ways to provide in-depth information of a UPnP device to ensure that a device model will get built as desired. All of the methods described here require HDeviceModelInfoProvider. First, you can override HDeviceModelInfoProvider::embedddedDevicesSetupData() and HDeviceModelInfoProvider::servicesSetupData() methods to specify what embedded devices and services has to be defined in the device description for an instance of the device type to function correctly. Second, you can provide detailed information of expected actions and their arguments when you override HDeviceModelInfoProvider::actionsSetupData(). Third, you can provide detailed information of expected state variables when you override HDeviceModelInfoProvider::stateVariablesSetupData().

Note:
All of these methods and techniques described here are optional.

The benefit of overriding these methods is that HUPnP can ensure that the provided description documents provide everything the respective C++ classes expect. The validation is done by HUPnP during the build of the device model and the build succeeds only if the provided description documents are appropriately defined. This way you never have to validate the device model yourself and you do not have to check everywhere if an embedded device, a service, a required action, an action argument or a state variable is provided. But if your device and service types are created for internal or otherwise controlled use only, implementing your own HDeviceModelInfoProvider may be unnecessary.

An example of servicesSetupData():

 Herqq::Upnp::HServicesSetupData MyDeviceModelInfoProvider::servicesSetupData(
     const Herqq::Upnp::HDeviceInfo& info)
 {
  Herqq::Upnp::HServicesSetupData retVal;

  QString type = info.deviceType().toString();
  if (type == "urn:schemas-upnp-org:device:DimmableLight:1")
  {
    retVal.insert(
       Herqq::Upnp::HServiceSetup(
           Herqq::Upnp::HServiceId("urn:schemas-upnp-org:serviceId:SwitchPower"),
           Herqq::Upnp::HResourceType("urn:schemas-upnp-org:service:SwitchPower:1")));

    retVal.insert(
       Herqq::Upnp::HServiceSetup(
           Herqq::Upnp::HServiceId("urn:schemas-upnp-org:serviceId:Dimming"),
           Herqq::Upnp::HResourceType("urn:schemas-upnp-org:service:Dimming:1")));
  }

   return retVal;
 }

The above definition instructs HUPnP to ensure that when the DimmableLight:1 device type is being initialized those two specified services are found in the device description document provided by the user. If either one of them is missing or contains invalid information, the device model build is aborted, the HDeviceHost::init() fails and HDeviceHost::error() returns HDeviceHost::InvalidDeviceDescriptionError. See the documentation of HServiceSetup for more information of what can be validated.

An example of embedddedDevicesSetupData():

 Herqq::Upnp::HDevicesSetupData MyDeviceModelInfoProvider::embedddedDevicesSetupData(
     const HDeviceInfo& info)
 {
  Herqq::Upnp::HDevicesSetupData retVal;

  QString type = info.deviceType().toString();
  if (type == "urn:custom-domain-org:device:MyDeviceType:1")
  {
    retVal.insert(
       Herqq::Upnp::HDeviceSetup(
           Herqq::Upnp::HResourceType("urn:my-domain-org:device:MyDevice_X:1")));

    retVal.insert(
       Herqq::Upnp::HDeviceSetup(
           Herqq::Upnp::HResourceType("urn:my-domain-org:device:MyDevice_Y:1")));
  }

   return retVal;
 }

The above definition instructs HUPnP to ensure that when the MyDeviceType:1 device type is being initialized those two specified embedded devices are found in the device description document provided by the user. If either one of them is missing or contains invalid information, the device model build is aborted, the HDeviceHost::init() fails and HDeviceHost::error() returns HDeviceHost::InvalidDeviceDescriptionError. See the documentation of HDeviceSetup for more information of what can be validated.

An example of stateVariablesSetupData():

 Herqq::Upnp::HStateVariablesSetupData MyDeviceModelInfoProvider::stateVariablesSetupData(
     const Herqq::Upnp::HServiceInfo& serviceInfo, const Herqq::Upnp::HDeviceInfo& parentDeviceInfo)
 {
  Herqq::Upnp::HStateVariablesSetupData retVal;

  if (info.serviceType().compare(
      HResourceType("urn:schemas-upnp-org:service:ConnectionManager:2"),
      HResourceType::Inclusive))
  {
    retVal.insert(HStateVariableInfo(
      "SourceProtocolInfo", HUpnpDataTypes::string));

    retVal.insert(HStateVariableInfo(
      "SinkProtocolInfo", HUpnpDataTypes::string));

    retVal.insert(HStateVariableInfo(
      "CurrentConnectionIDs", HUpnpDataTypes::string));

    retVal.insert(HStateVariableInfo(
      "A_ARG_TYPE_ConnectionStatus", HUpnpDataTypes::string));

    retVal.insert(HStateVariableInfo(
      "A_ARG_TYPE_ConnectionManager",HUpnpDataTypes::string));

    retVal.insert(HStateVariableInfo(
      "A_ARG_TYPE_ProtocolInfo", HUpnpDataTypes::string));

    retVal.insert(HStateVariableInfo(
      "A_ARG_TYPE_ConnectionID", HUpnpDataTypes::i4));

    retVal.insert(HStateVariableInfo(
      "A_ARG_TYPE_AVTransportID", HUpnpDataTypes::i4));

    retVal.insert(HStateVariableInfo(
      "A_ARG_TYPE_RcsID", HUpnpDataTypes::i4));
  }

   return retVal;
 }

The above definition instructs HUPnP to ensure that when the ConnectionManager:2 service type is being initialized all those specified state variables are found in the service description document provided by the user. If any one of them is missing or contains invalid information, the device model build is aborted, the HDeviceHost::init() fails and HDeviceHost::error() returns HDeviceHost::InvalidServiceDescriptionError. See the documentation of HStateVariableInfo for more information of what can be validated.

Finally, you can override HDeviceModelInfoProvider::actionsSetupData() to provide detailed information about the action and its expected arguments. See HActionSetup for more information of this.

Note:
It is planned that in the future this same information could be used to create instances of HUPnP's device model without description documents.
See also:
Device Hosting
herqq-1.0.0/hupnp/docs/html/classes.html0000644000000000000000000002675211543637604016724 0ustar rootroot Herqq: Class Index

Class Index

F | H
  F  
HClientDevice (Herqq::Upnp)   HDeviceModelCreator (Herqq::Upnp)   HProductToken (Herqq::Upnp)   HServiceId (Herqq::Upnp)   
Functor (Herqq)   HClientService (Herqq::Upnp)   HDeviceModelInfoProvider (Herqq::Upnp)   HProductTokens (Herqq::Upnp)   HServiceInfo (Herqq::Upnp)   
  H  
HClientStateVariable (Herqq::Upnp)   HDeviceSetup (Herqq::Upnp)   HResourceAvailable (Herqq::Upnp)   HServiceSetup (Herqq::Upnp)   
HActionArgument (Herqq::Upnp)   HClonable (Herqq::Upnp)   HDevicesSetupData (Herqq::Upnp)   HResourceType (Herqq::Upnp)   HServicesSetupData (Herqq::Upnp)   
HActionArguments (Herqq::Upnp)   HControlPoint (Herqq::Upnp)   HDiscoveryRequest (Herqq::Upnp)   HResourceUnavailable (Herqq::Upnp)   HSsdp (Herqq::Upnp)   
HActionInfo (Herqq::Upnp)   HControlPointConfiguration (Herqq::Upnp)   HDiscoveryResponse (Herqq::Upnp)   HResourceUpdate (Herqq::Upnp)   HStateVariableEvent (Herqq::Upnp)   
HActionSetup (Herqq::Upnp)   HDeviceConfiguration (Herqq::Upnp)   HDiscoveryType (Herqq::Upnp)   HServerAction (Herqq::Upnp)   HStateVariableInfo (Herqq::Upnp)   
HActionsSetupData (Herqq::Upnp)   HDeviceHost (Herqq::Upnp)   HEndpoint (Herqq::Upnp)   HServerDevice (Herqq::Upnp)   HStateVariablesSetupData (Herqq::Upnp)   
HAsyncOp (Herqq::Upnp)   HDeviceHostConfiguration (Herqq::Upnp)   HExecArgs (Herqq::Upnp)   HServerService (Herqq::Upnp)   HUdn (Herqq::Upnp)   
HClientAction (Herqq::Upnp)   HDeviceHostRuntimeStatus (Herqq::Upnp)   HMulticastSocket (Herqq::Upnp)   HServerStateVariable (Herqq::Upnp)   HUpnpDataTypes (Herqq::Upnp)   
HClientActionOp (Herqq::Upnp)   HDeviceInfo (Herqq::Upnp)   
F | H
herqq-1.0.0/hupnp/docs/html/builddevice_tutorial.html0000644000000000000000000010504411543637604021461 0ustar rootroot Herqq: Tutorial for Building a UPnP Device

Tutorial for Building a UPnP Device

Setting up the device and service descriptions

Generally, building a UPnP device with HUPnP involves two main steps in your part. First, you have to define a UPnP device description document following the specifications set by the UPnP forum. Depending of your UPnP Device Description document, you may need to define one or more UPnP service description documents as well. Second, you may have to implement a class for your device and most often one or more classes for each service your device contains.

For example, if you want to implement a standard UPnP device named BinaryLight:1, your device description could look something like this:

 <?xml version="1.0"?>
 <root xmlns="urn:schemas-upnp-org:device-1-0">
     <specVersion>
         <major>1</major>
         <minor>0</minor>
     </specVersion>
     <device>
         <deviceType>urn:schemas-upnp-org:device:BinaryLight:1</deviceType>
         <friendlyName>UPnP Binary Light</friendlyName>
         <manufacturer>MyCompany</manufacturer>
         <manufacturerURL>www.mywebsite.org</manufacturerURL>
         <modelDescription>New brilliant BinaryLight</modelDescription>
         <modelName>SuperWhiteLight 4000</modelName>
         <modelNumber>1</modelNumber>
         <UDN>uuid:138d3934-4202-45d7-bf35-8b50b0208139</UDN>
         <serviceList>
             <service>
                 <serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
                 <serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>
                 <SCPDURL>switchpower_scpd.xml</SCPDURL>
                 <controlURL>/control</controlURL>
                 <eventSubURL>/eventing</eventSubURL>
             </service>
         </serviceList>
     </device>
 </root>

Note that the above is the standard device template for UPnP BinaryLight:1 filled with imaginary information.

Since the BinaryLight:1 defines a service, SwitchPower:1, you have to provide a service description document that could look like this:

 <?xml version="1.0"?>
 <scpd xmlns="urn:schemas-upnp-org:service-1-0">
     <specVersion>
         <major>1</major>
         <minor>0</minor>
     </specVersion>
     <actionList>
         <action>
             <name>SetTarget</name>
             <argumentList>
                 <argument>
                     <name>newTargetValue</name>
                     <relatedStateVariable>Target</relatedStateVariable>
                     <direction>in</direction>
                 </argument>
             </argumentList>
          </action>
          <action>
              <name>GetTarget</name>
              <argumentList>
                  <argument>
                      <name>RetTargetValue</name>
                      <relatedStateVariable>Target</relatedStateVariable>
                      <direction>out</direction>
                  </argument>
              </argumentList>
          </action>
          <action>
              <name>GetStatus</name>
              <argumentList>
                  <argument>
                      <name>ResultStatus</name>
                      <relatedStateVariable>Status</relatedStateVariable>
                      <direction>out</direction>
                  </argument>
              </argumentList>
          </action>
      </actionList>
      <serviceStateTable>
          <stateVariable sendEvents="no">
              <name>Target</name>
              <dataType>boolean</dataType>
              <defaultValue>0</defaultValue>
          </stateVariable>
          <stateVariable sendEvents="yes">
              <name>Status</name>
              <dataType>boolean</dataType>
              <defaultValue>0</defaultValue>
          </stateVariable>
      </serviceStateTable>
 </scpd>

The above description is the standard service description for the SwitchPower:1 without any vendor specific declarations. For more information about description documents, see the UDA specification, sections 2.3 and 2.5.

Creating the necessary HUPnP classes

HUPnP doesn't require any classes to be created in order to "host" a UPnP device (make it visible for UPnP control points), but in order to plug in custom functionality you often have to accompany the device and service descriptions with corresponding classes.

In our example we have to derive a class we have to derive a class from Herqq::Upnp::HServerService for the SwitchPower:1 service description and we can derive a class from Herqq::Upnp::HServerDevice for the BinaryLight:1 device description. Note the last point, we do not have to create a class for the BinaryLight:1, but we can. Furthermore, if your service has no actions you do not need to create your own HServerService type either.

Note:
Omitting the creation of custom HServerDevice classes is common if there is no need to define a type that orchestrates the use, initialization and control of the contained services. Furthermore, such a type can specify information about the embedded devices and services that have to be present for the type to be initialized properly. And of course, it can offer features that are not present in the default HServerDevice class.

To create a custom Herqq::Upnp::HServerDevice you only need to derive from it. There are no abstract member functions to override, but there are a few virtual member functions that could be very useful to override in case you are writing a type for other people to use. For more information of this, see Device Model.

To create a concrete class from Herqq::Upnp::HServerService that exposes custom actions you can either:

  • Override Herqq::Upnp::HServerService::createActionInvokes(), which purpose is to create callable entities that will be called when the corresponding UPnP actions are invoked.
  • Define Q_INVOKABLE methods in your custom type derived from HServerService using the same method names as the action definitions in the service description document.

The first option is much more flexible, as you have full control over what HUPnP should call when a particular action is invoked. In addition, callable entities aren't tied to member functions. The second option may be more convenient, as you don't have to implement HServerService::createActionInvokes() and create the callable entities by yourself. Whichever option you choose, every action implementation has to have a signature of action(const HActionArguments&, HActionArguments*) and int as a return type.

Note:
  • The UPnP actions of a particular UPnP service are defined in the service's description file and your service implementation has to implement all of them.
  • The callable entities are used internally by HUPnP. HUPnP does not otherwise expose them directly in the public API for action invocation.

To continue with the example we will create two classes, one for the BinaryLight:1 and one for the SwitchPowerService:1. Note, the class for the BinaryLight:1 is not required, but it is done here for demonstration purposes. Also note that for this example the class declarations are put into the same header file, although in real code you might want to separate them.

mybinarylight.h

 #include <HUpnpCore/HServerDevice>
 #include <HUpnpCore/HServerService>

 class MyBinaryLightDevice :
    public Herqq::Upnp::HServerDevice
 {

 public:

    MyBinaryLightDevice();
    virtual ~MyBinaryLightDevice();
 };

 class MySwitchPowerService :
    public Herqq::Upnp::HServerService
 {
 protected:

     virtual HActionInvokes createActionInvokes();

 public:

     MySwitchPowerService();
     virtual ~MySwitchPowerService();
 };

In turn, the implementation could look something like this:

mybinarylight.cpp

 #include "mybinarylight.h"

 using namespace Herqq::Upnp;

 MyBinaryLightDevice::MyBinaryLightDevice()
 {
 }

 MyBinaryLightDevice::~MyBinaryLightDevice()
 {
 }

 MySwitchPowerService::MySwitchPowerService()
 {
 }

 MySwitchPowerService::~MySwitchPowerService()
 {
 }

 HServerServer::HActionInvokes MySwitchPowerService::createActionInvokes()
 {
     HActionInvokes retVal;
     return retVal;
 }

Those who know UPnP and paid close attention to the above example might have noticed that something was off. Where are the actions?

According to the UPnP Device Architecture (UDA), a service may have zero or more actions. If a service has no actions, you don't have to create a custom HServerService derivative in the first place, but even if you do, similar class declaration and definition as shown above are enough.

However, the standard BinaryLight:1 device type specifies the SwitchPower:1 service type that has three actions defined (look back in the service description document). Namely these are SetTarget, GetTarget and GetStatus. To make the example complete the MySwitchPowerService class requires some additional work. Note that next example shows only one way of making the service complete. There are a few other ways, which will be discussed later in depth.

The complete declaration for MySwitchPowerService:

mybinarylight.h

 #include <HUpnpCore/HServerService>

 class MySwitchPowerService :
    public Herqq::Upnp::HServerService
 {
 protected:

     virtual HActionInvokes createActionInvokes();

 public:

     MySwitchPowerService();
     virtual ~MySwitchPowerService();

     qint32 setTarget(
         const Herqq::Upnp::HActionArguments& inArgs,
         Herqq::Upnp::HActionArguments* outArgs);

     qint32 getTarget(
         const Herqq::Upnp::HActionArguments& inArgs,
         Herqq::Upnp::HActionArguments* outArgs);

     qint32 getStatus(
         const Herqq::Upnp::HActionArguments& inArgs,
         Herqq::Upnp::HActionArguments* outArgs);
 };

The complete definition for MySwitchPowerService:

mybinarylight.cpp

 #include "mybinarylight.h"

 #include <HUpnpCore/HServerAction>
 #include <HUpnpCore/HActionArguments>
 #include <HUpnpCore/HServerStateVariable>

 MySwitchPowerService::MySwitchPowerService()
 {
 }

 MySwitchPowerService::~MySwitchPowerService()
 {
 }

 HServerService::HActionInvokes MySwitchPowerService::createActionInvokes()
 {
     Herqq::Upnp::HServerService::HActionInvokes retVal;

     retVal.insert(
         "SetTarget",
         Herqq::Upnp::HActionInvoke(this, &MySwitchPowerService::setTarget));

     // The above lines map the MySwitchPowerService::setTarget() method to
     // the action that has the name SetTarget. In essence, this mapping instructs
     // HUPnP to call this method when the SetTarget action is invoked.
     // However, note that HActionInvoke accepts any "callable entity",
     // such as a normal function or a functor. Furthermore, if you use a
     // method the method does not have to be public.

     retVal.insert(
         "GetTarget",
         Herqq::Upnp::HActionInvoke(this, &MySwitchPowerService::getTarget));

     retVal.insert(
         "GetStatus",
         Herqq::Upnp::HActionInvoke(this, &MySwitchPowerService::getStatus));

     return retVal;
 }

 qint32 MySwitchPowerService::setTarget(
     const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
     Herqq::Upnp::HActionArgument newTargetValueArg = inArgs.get("newTargetValue");
     if (!newTargetValueArg.isValid())
     {
         // If MySwitchPowerService class is not made for direct public use
         // this check is redundant, since in that case this method is called only by
         // HUPnP and HUPnP always ensures that the action arguments defined in the
         // service description are present when an action is invoked.

         return Herqq::Upnp::UpnpInvalidArgs;
     }

     bool newTargetValue = newTargetValueArg.value().toBool();
     stateVariables().value("Target")->setValue(newTargetValue);

     // The above line modifies the state variable "Target", which reflects the
     // "target state" of a light device, i.e. if a user wants to turn off a light, the
     // "target state" is the light turned off whether the light can be turned
     // off or not.

     //
     // Do here whatever that is required to turn on / off the light
     // (set it to the target state)
     //

     //
     // If it succeeded, we should modify the Status state variable to reflect
     // the new state of the light.
     //

     stateVariables().value("Status")->setValue(newTargetValue);

     return Herqq::Upnp::UpnpSuccess;
 }

 qint32 MySwitchPowerService::getTarget(
     const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
     if (!outArgs)
     {
         // See the comments in MySwitchPowerService::setTarget why this
         // check is here. Basically, this check is redundant if this method
         // is called only by HUPnP, as HUPnP ensures proper arguments
         // are always provided when an action is invoked.

         return Herqq::Upnp::UpnpInvalidArgs;
     }

     bool b = stateVariables().value("Target")->value().toBool();
     outArgs->setValue("RetTargetValue", b);

     return Herqq::Upnp::UpnpSuccess;
 }

 qint32 MySwitchPowerService::getStatus(
     const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs)
 {
     if (!outArgs)
     {
         // See the comments in MySwitchPowerService::getTarget();
         return UpnpInvalidArgs;
     }

     bool b = stateVariables().value("Status")->value().toBool();
     outArgs->setValue("ResultStatus", b);

     return Herqq::Upnp::UpnpSuccess;
 }

The above example overrode the HServerService::createActionInvokes() and did the action name - callable entity mapping. However, if you'd rather have HUPnP do that automatically, you can mark your action implementations as Q_INVOKABLE as follows:

mybinarylight.h

 #include <HUpnpCore/HServerService>

 class MySwitchPowerService :
    public Herqq::Upnp::HServerService
 {
 Q_OBJECT

 public:

     MySwitchPowerService();
     virtual ~MySwitchPowerService();

     Q_INVOKABLE qint32 SetTarget(
         const Herqq::Upnp::HActionArguments& inArgs,
         Herqq::Upnp::HActionArguments* outArgs);

     Q_INVOKABLE qint32 GetTarget(
         const Herqq::Upnp::HActionArguments& inArgs,
         Herqq::Upnp::HActionArguments* outArgs);

     Q_INVOKABLE qint32 GetStatus(
         const Herqq::Upnp::HActionArguments& inArgs,
         Herqq::Upnp::HActionArguments* outArgs);
 };

Apart from changing the method names to start with capital letters, the method definitions stay otherwise the same.

Note:
Using Q_INVOKABLE methods as action implementations you have to ensure that the names of the member functions correspond exactly to the action names defined in the service description document.

Some closing notes

First of all, you may want to skim the discussion in Device Model and Device Hosting to fully understand the comments in the example above. Especially the section Setting Up the Device Model is useful if you want to learn the details of building a custom UPnP device using HUPnP. That being said, perhaps the most important issues of building a custom UPnP device using HUPnP can be summarized to:

  • Every device description has to have a corresponding Herqq::Upnp::HServerDevice and every service description has to have a corresponding Herqq::Upnp::HServerService. However, you don't have to create a custom HServerDevice, in which case HUPnP will create and use a default HServerDevice type. In addition, if a service has no actions you don't have to create a custom HServerService. On the other hand, most commonly a service has one or more actions, so this is something you'll be doing often.
  • You can create more advanced HServerDevice and HServerService classes perhaps to build a higher level public API or just to provide yourself a nicer interface for doing something. This was the case with MySwitchPowerService class, which extended the HServerService interface by providing the possibility of invoking the actions of the service through the setTarget(), getTarget() and getStatus() methods.
  • HUPnP allows direct (in-process) access to the hosted HServerDevice and HServerService classes, which means you can interact with your classes while they are being hosted and possibly used from external processes. Custom HServerDevice and HServerService interfaces may be beneficial in such a case.
  • The type behind an Herqq::Upnp::HActionInvoke can hold any callable entity, such as a pointer to a normal function, functor or a pointer to a member function.
  • A public callable entity should always strictly verify the input and respond to illegal input accordingly. A "private" callable entity that is called only by HUPnP can rest assured that HUPnP never passes a null input argument or an argument that has an incorrect name or data type.
  • Before implementing your own device and service types directly from HServerDevice and HServerService, you should check if HUPnP provides more refined classes to suit your requirements. For instance, HUPnP provides a base class Herqq::Upnp::Lighting::HAbstractSwitchPower for simplifying the implementation and use of SwitchPower:1.

In any case, the above example demonstrates a fully standard-compliant implementation of BinaryLight:1. The next step is to publish your HServerDevice in the network for UPnP control points to discover. You can find the instructions for that in HDeviceHost and Device Hosting.

herqq-1.0.0/hupnp/docs/html/tab_a.png0000644000000000000000000000021411543637604016136 0ustar rootroot‰PNG  IHDR$ÇÇ[SIDATxí» €@wçÉ¡œˆ˜*æ‚M˜ØIïÎF†ýL :®‡±nÌëN™ ¶±Á’„ØN&â¼_ ɭɾ}Õ¶8~î¾îOwv-ÿêA4Y)Ñ}IEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_resource_available-members.html0000644000000000000000000001555211543637604027600 0ustar rootroot Herqq: Member List

HResourceAvailable Member List

This is the complete list of members for HResourceAvailable, including all inherited members.
bootId() const HResourceAvailable
cacheControlMaxAge() const HResourceAvailable
configId() const HResourceAvailable
HResourceAvailable()HResourceAvailable
HResourceAvailable(qint32 cacheControlMaxAge, const QUrl &location, const HProductTokens &serverTokens, const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=-1, qint32 searchPort=-1)HResourceAvailable
HResourceAvailable(const HResourceAvailable &)HResourceAvailable
isValid(HValidityCheckLevel level) const HResourceAvailable
location() const HResourceAvailable
operator!=(const HResourceAvailable &obj1, const HResourceAvailable &obj2)HResourceAvailable [related]
operator=(const HResourceAvailable &)HResourceAvailable
operator==(const HResourceAvailable &, const HResourceAvailable &)HResourceAvailable [friend]
searchPort() const HResourceAvailable
serverTokens() const HResourceAvailable
usn() const HResourceAvailable
~HResourceAvailable()HResourceAvailable
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_configuration.png0000644000000000000000000000072511543637604026323 0ustar rootroot‰PNG  IHDR‰P˦PLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2dIDATxíÁŽÄ †ÅI|ÿGÞ*P±®™:ËN~µ"èWzM¯(’^9†€$Ï’<‰ˆºff9]~„iôˆÃ“s¦L-X2“åOÔ‰_‡ÙݾAÂⓘ;å!’»˜ÈeX’šÛ'†¤}³v|„ÓyâöõVgt¼vÐíA,I¢HzBÊ#»|I)QP”% j$  H@€$  Hþ E‘DAâ l‘ð@µ– Herqq: HResourceAvailable Class Reference

HResourceAvailable Class Reference

This is a class that represents the resource available (ssdp:alive) message. More...

#include <HResourceAvailable>

List of all members.

Public Member Functions

 HResourceAvailable ()
 HResourceAvailable (qint32 cacheControlMaxAge, const QUrl &location, const HProductTokens &serverTokens, const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=-1, qint32 searchPort=-1)
 ~HResourceAvailable ()
 HResourceAvailable (const HResourceAvailable &)
HResourceAvailableoperator= (const HResourceAvailable &)
bool isValid (HValidityCheckLevel level) const
const HProductTokensserverTokens () const
QUrl location () const
const HDiscoveryTypeusn () const
qint32 cacheControlMaxAge () const
qint32 bootId () const
qint32 configId () const
qint32 searchPort () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HResourceAvailable &, const HResourceAvailable &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HResourceAvailable &obj1, const HResourceAvailable &obj2)

Detailed Description

This is a class that represents the resource available (ssdp:alive) message.

According to the UDA, When a device is added to the network, it MUST multicast discovery messages to advertise its root device, any embedded devices, and any services. In HUPnP this class represents such an advertisement.

Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, or you receive instances of this class from the Herqq::Upnp::HSsdp.

Remarks:
the class provides an assignment operator, which is not thread-safe.
See also:
HSsdp

Constructor & Destructor Documentation

Constructs a new, empty instance.

The constructed object is not valid, i.e isValid() returns false.

See also:
isValid()
HResourceAvailable ( qint32  cacheControlMaxAge,
const QUrl &  location,
const HProductTokens serverTokens,
const HDiscoveryType usn,
qint32  bootId = -1,
qint32  configId = -1,
qint32  searchPort = -1 
)

Constructs a new instance using the specified parameters.

Parameters:
cacheControlMaxAgespecifies the number of seconds the advertisement is valid.
locationspecifies the URL to the UPnP description of the root device. If the location is invalid or empty the created object will be invalid.
serverTokensspecifies information about the host, the UPnP version used and of the product. Note that if this parameter specifies UPnP version 1.1 or later, bootId and configId have to be properly defined. Otherwise the created object will be invalid.
Note:
Although server tokens are mandatory according to the UDA, this is not enforced by this class for interoperability reasons.
Parameters:
usnspecifies the Unique Service Name. The created object is valid only if the provided USN is valid.
bootIdspecifies the BOOTID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0. Because of this the class requires a valid value (>= 0) only in case the serverTokens identify UPnP v1.1 or later.
configIdspecifies the CONFIGID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0. Because of this the class requires a valid value (>= 0) only in case the serverTokens identify UPnP v1.1 or later.
searchPortspecifies the SEARCHPORT.UPNP.ORG header value. Note that this is optional in UDA v1.1, whereas it is not specified at all in UDA v1.0. If specified, this is the port at which the device must listen for unicast M-SEARCH messages. Otherwise the port is by default 1900. This parameter is optional.
Remarks:
  • if cacheControlMaxAge is smaller than 5 it it set to 5, or if it is larger than 60 * 60 * 24 (a day in seconds) it is set to a day measured in seconds.
  • if searchPort is smaller than 49152 or larger than 65535 it is set to -1. The range is specified in UDA v1.1.
See also:
isValid()

Destroys the instance.

Copy constructor.

Copies the contents of the other object instance to this.


Member Function Documentation

HResourceAvailable & operator= ( const HResourceAvailable other)

Assigns the contents of the other object instance to this.

Remarks:
This is not thread-safe.
bool isValid ( HValidityCheckLevel  level) const

Indicates whether or not the object contains valid announcement information.

Parameters:
levelindicates whether the check should be strictly according to the UDA specification. If set to false some checks are omitted that are known to be poorly implemented in some UPnP software.
Returns:
true in case the objects contains valid announcement information in terms of the requested strictness.
const HProductTokens & serverTokens ( ) const

Returns the server tokens.

Returns:
The server tokens. The returned object is invalid if this object is invalid.
See also:
isValid()
QUrl location ( ) const

Returns the location of the announced device.

Returns:
The location of the announced device. This is the URL where the device description can be retrieved. The returned object is empty if this object is invalid.
See also:
isValid()
const HDiscoveryType & usn ( ) const

Returns the Unique Service Name.

The Unique Service Name identifies a unique device or service instance.

Returns:
The Unique Service Name. The returned object is invalid if this object is invalid.
See also:
isValid()
qint32 cacheControlMaxAge ( ) const

Returns the number of seconds the advertisement is valid.

Returns:
The number of seconds the advertisement is valid. If the object is valid the return value is never smaller than 5.
qint32 bootId ( ) const

Returns the value of BOOTID.UPNP.ORG.

Returns:
The value of BOOTID.UPNP.ORG. If the value is not specified -1 is returned.
qint32 configId ( ) const

Returns the value of CONFIGID.UPNP.ORG.

Returns:
The value of CONFIGID.UPNP.ORG. If the value is not specified -1 is returned.
qint32 searchPort ( ) const

Returns the value of SEARCHPORT.UPNP.ORG header field.

Returns:
The value of SEARCHPORT.UPNP.ORG header field. If the value is not specified -1 is returned.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HResourceAvailable ,
const HResourceAvailable  
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HResourceAvailable obj1,
const HResourceAvailable obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_async_op.png0000644000000000000000000000066211543637604023750 0ustar rootroot‰PNG  IHDRjPÆnPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2AIDATxíí²„ †e›ñþ/ùü@ù0McŒ™:0S«Hï#„íßn– 9Y >€B·¼_ëÌ¢VP ™—¸m(€â”g “)ÂoC)ôŒQ<[G•®qJ\1(+Š…ë+¯`æFTÛŠøÄ³(jP¤Ž%Ø’Ué-–¥äseéÀÉ2,ÞG]ÇïDM? ñeÔM”›Ùv˜½Já‰ÊÙå‡ÊÙåˆúh*P T ¨@êý¨ÃbÙòP:~N¨¢€ï8F§0%\§0Ò˜ ×¨kr©F×( (ãš"€×ã­ «@Ž%T-¥šÉk¦…6D©.ô8L?°”o€+zªÒ/KG«gBÉìi(Ô Œ;°û®F犫…oYì Wtjn>dâl*þDþÊÍþ+&”‚ŽWIEND®B`‚herqq-1.0.0/hupnp/docs/html/closed.png0000644000000000000000000000017611543637604016350 0ustar rootroot‰PNG  IHDR à‘EIDATxíÝA @! PŠ­iš/`Є.È?,!ƒu zlÞ–Jh1ߘ+výRLé§x@‘Ù (*79HÑ þl)¡ó²‰IEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_setup.html0000644000000000000000000007107711543637604025022 0ustar rootroot Herqq: HActionSetup Class Reference

HActionSetup Class Reference

This class is used to specify information that can be used to setup an HServerAction or validate a UPnP action. More...

#include <HActionSetup>

List of all members.

Public Member Functions

 HActionSetup ()
 HActionSetup (const QString &name, HInclusionRequirement incReq=InclusionMandatory)
 HActionSetup (const QString &name, int version, HInclusionRequirement incReq=InclusionMandatory)
 HActionSetup (const HActionSetup &)
HActionSetupoperator= (const HActionSetup &)
 ~HActionSetup ()
const HActionArgumentsinputArguments () const
const HActionArgumentsoutputArguments () const
HInclusionRequirement inclusionRequirement () const
bool isValid () const
QString name () const
int version () const
void setInputArguments (const HActionArguments &args)
void setOutputArguments (const HActionArguments &args)
bool setName (const QString &name, QString *err=0)
void setInclusionRequirement (HInclusionRequirement arg)
void setVersion (int version)

Detailed Description

This class is used to specify information that can be used to setup an HServerAction or validate a UPnP action.

See also:
HActionsSetupData, HClientAction, HServerAction
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new, invalid instance.

See also:
isValid()
HActionSetup ( const QString &  name,
HInclusionRequirement  incReq = InclusionMandatory 
) [explicit]

Creates a new instance.

Parameters:
namespecifies the name of the action. If the name value contains special characters other than hyphens or dots the instance will be invalid and name() will be empty.
incReqspecifies the inclusion requirement of the action.
See also:
isValid()
Remarks:
the version() is set to 1.
HActionSetup ( const QString &  name,
int  version,
HInclusionRequirement  incReq = InclusionMandatory 
)

Creates a new instance.

Parameters:
namespecifies the name of the action. If the name value contains special characters other than hyphens or dots the instance will be invalid and name() will be empty.
versionspecifies the UPnP service version in which the action was first specified.
incReqspecifies the inclusion requirement of the action.
See also:
isValid()
HActionSetup ( const HActionSetup other)

Copy constructor.

Creates a copy of other.

Destroys the instance.


Member Function Documentation

HActionSetup & operator= ( const HActionSetup other)

Assignment operator.

Copies the contents of other to this.

const HActionArguments & inputArguments ( ) const

Returns the setup information of the action's input arguments.

Returns:
The setup information of the action's input arguments.
See also:
setInputArguments()
const HActionArguments & outputArguments ( ) const

Returns the setup information of the action's output arguments.

Returns:
The setup information of the action's output arguments.
See also:
setOutputArguments()
HInclusionRequirement inclusionRequirement ( ) const

Returns the inclusion requirement of the action.

Returns:
The inclusion requirement of the action.
See also:
setInclusionRequirement()
bool isValid ( ) const

Indicates if the object is valid.

Returns:
true in case the object is valid, that is, the name(), version() and the inclusionRequirement() are properly defined.
QString name ( ) const

Returns the name of the action.

Returns:
The name of the action.
See also:
setName()
int version ( ) const

Returns the UPnP service version in which the action was first specified.

Returns:
The UPnP service version in which the action was first specified.
See also:
setVersion()
void setInputArguments ( const HActionArguments args)

Specifies the action's input arguments.

Parameters:
argsspecifies the setup information for the action's input arguments.
See also:
inputArguments()
void setOutputArguments ( const HActionArguments args)

Specifies the action's output arguments.

Parameters:
argsspecifies the setup information for the action's output arguments.
See also:
outputArguments()
bool setName ( const QString &  name,
QString *  err = 0 
)

Sets the name of the action.

Parameters:
namespecifies the name of the action.
erris a pointer to a QString that contains an error description in case the name could not be set. This is an optional parameter.
Returns:
true in case the specified name was successfully set.
See also:
name()
void setInclusionRequirement ( HInclusionRequirement  arg)

Sets the inclusion requirement of the action.

Parameters:
argspecifies the inclusion requirement of the action.
See also:
inclusionRequirement()
void setVersion ( int  version)

Specifies the UPnP service version in which the action was first specified.

Parameters:
versionspecifies the UPnP service version in which the action was first specified.
See also:
version()
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_discovery_type-members.html0000644000000000000000000002521611543637604027017 0ustar rootroot Herqq: Member List

HDiscoveryType Member List

This is the complete list of members for HDiscoveryType, including all inherited members.
All enum valueHDiscoveryType
createDiscoveryTypeForAllResources()HDiscoveryType [static]
createDiscoveryTypeForRootDevices()HDiscoveryType [static]
DeviceType enum valueHDiscoveryType
HDiscoveryType()HDiscoveryType
HDiscoveryType(const HUdn &udn, bool isRootDevice=false, HValidityCheckLevel checkLevel=StrictChecks)HDiscoveryType [explicit]
HDiscoveryType(const HResourceType &resourceType)HDiscoveryType [explicit]
HDiscoveryType(const HUdn &udn, const HResourceType &resourceType, HValidityCheckLevel checkLevel=StrictChecks)HDiscoveryType
HDiscoveryType(const QString &resource, HValidityCheckLevel checkLevel=StrictChecks)HDiscoveryType [explicit]
HDiscoveryType(const HDiscoveryType &)HDiscoveryType
operator!=(const HDiscoveryType &obj1, const HDiscoveryType &obj2)HDiscoveryType [related]
operator=(const HDiscoveryType &)HDiscoveryType
operator==(const HDiscoveryType &, const HDiscoveryType &)HDiscoveryType [friend]
resourceType() const HDiscoveryType
RootDevices enum valueHDiscoveryType
ServiceType enum valueHDiscoveryType
setResourceType(const HResourceType &resourceType)HDiscoveryType
setUdn(const HUdn &udn, HValidityCheckLevel checkLevel=StrictChecks)HDiscoveryType
SpecificDevice enum valueHDiscoveryType
SpecificDeviceWithType enum valueHDiscoveryType
SpecificRootDevice enum valueHDiscoveryType
SpecificServiceWithType enum valueHDiscoveryType
toString() const HDiscoveryType
Type enum nameHDiscoveryType
type() const HDiscoveryType
udn() const HDiscoveryType
Undefined enum valueHDiscoveryType
~HDiscoveryType()HDiscoveryType
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_service.html0000644000000000000000000005344311543637604025320 0ustar rootroot Herqq: HClientService Class Reference

A client-side class that represents a server-side UPnP service. More...

#include <HClientService>

Inherited by HDefaultClientService.

List of all members.

Public Slots

void notifyListeners ()

Signals

void stateChanged (const Herqq::Upnp::HClientService *source)

Public Member Functions

virtual ~HClientService ()=0
HClientDeviceparentDevice () const
const HServiceInfoinfo () const
QString description () const
const HClientActionsactions () const
const HClientStateVariablesstateVariables () const
bool isEvented () const
QVariant value (const QString &stateVarName, bool *ok=0) const

Protected Member Functions

 HClientService (const HServiceInfo &info, HClientDevice *parentDevice)

Detailed Description

A client-side class that represents a server-side UPnP service.

HClientService is a core component of the HUPnP's client-side Device Model and it models a UPnP service. The UPnP Device Architecture specifies a UPnP service as "Logical functional unit. Smallest units of control. Exposes actions and models the state of a physical device with state variables". In other words, a UPnP service is the entry point for accessing certain type of functionality and state of the containing device.

Using the class

You can retrieve the containing device, the parent device, using parentDevice(). You can retrieve all the actions the service contains by calling actions(), Similarly, you can retrieve all the state variables of the service by calling stateVariables().

The class exposes all the details in the device description concerning a service through info(). From the returned HServiceInfo object you can retrieve the serviceId and serviceType along with various URLs found in the device description, such as the:

  • scpdUrl, which returns the URL for fetching the service description,
  • controlUrl, which returns the URL to be used in action invocation and
  • eventSubUrl, which returns the URL used in event (un)subscriptions.

However, the above URLs usually provide informational value only, since HUPnP provides a simpler interface for everything those URLs expose:

  • You can retrieve the service description of a service using description().
  • Action invocation is abstracted into the HClientAction class.
  • You can receive all the event notifications from a UPnP service by connecting to the stateChanged() signal. You do not need to worry about UPnP eventing at all, since HUPnP handles that for you.
See also:
Device Model
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HClientService ( const HServiceInfo info,
HClientDevice parentDevice 
) [protected]

Creates a new instance.

Parameters:
infospecifies information of the service.
parentDevicespecifies the device instance that contains this service.

Default constructor for derived classes.

~HClientService ( ) [pure virtual]

Destroys the instance.


Member Function Documentation

HClientDevice * parentDevice ( ) const

Returns the parent HClientDevice that contains this service instance.

Returns:
The parent HClientDevice that contains this service instance.
const HServiceInfo & info ( ) const

Returns information about the service.

Returns:
information about the service. This information is usually read from a device description document.
QString description ( ) const

Returns the full service description.

Returns:
The full service description.
const HClientActions & actions ( ) const

Returns the actions the service supports.

Returns:
The actions the service supports.
Remarks:
The ownership of the returned objects is not transferred. Do not delete the returned objects.
const HClientStateVariables & stateVariables ( ) const

Returns the state variables of the service.

Returns:
The state variables of the service.
Remarks:
The ownership of the returned objects is not transferred. Do not delete the returned objects.
bool isEvented ( ) const

Indicates whether or not the service contains state variables that are evented.

Returns:
true in case the service contains one or more state variables that are evented.
Remarks:
In case the service is not evented, the stateChanged() signal will never be emitted and the notifyListeners() method does nothing.
QVariant value ( const QString &  stateVarName,
bool *  ok = 0 
) const

Returns the value of the specified state variable, if such exists.

This is a convenience method for retrieving a state variable by name and getting its value.

Parameters:
stateVarNamespecifies the name of the state variable.
okspecifies a pointer to a bool, which will contain true if the specified state variable was found and its value was returned. This is optional.
Returns:
The value of the specified state variable, if such exists. If this service does not contain the specified state variable, an invalid QVariant is returned.
Remarks:
The value of the state variable may be represented by an invalid QVariant. Because of this, if you want to be sure that the specified state variable was found and its value was returned, you should use the ok parameter.
void notifyListeners ( ) [slot]

Explicitly forces stateChanged() event to be emitted if the service is evented.

Otherwise this method does nothing.

void stateChanged ( const Herqq::Upnp::HClientService source) [signal]

This signal is emitted when the state of one or more state variables has changed.

Parameters:
sourcespecifies the source of the event.
Remarks:
This signal has thread affinity to the thread where the object resides. Do not connect to this signal from other threads.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_state_variable-members.html0000644000000000000000000001115211543637604030264 0ustar rootroot Herqq: Member List

HClientStateVariable Member List

This is the complete list of members for HClientStateVariable, including all inherited members.
HClientStateVariable(const HStateVariableInfo &info, HClientService *parent)HClientStateVariable [protected]
info() const HClientStateVariable
parentService() const HClientStateVariable
setValue(const QVariant &newValue)HClientStateVariable [protected]
value() const HClientStateVariable
valueChanged(const Herqq::Upnp::HClientStateVariable *source, const Herqq::Upnp::HStateVariableEvent &event)HClientStateVariable [signal]
~HClientStateVariable()=0HClientStateVariable [pure virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_exec_args.html0000644000000000000000000003415711543637604024263 0ustar rootroot Herqq: HExecArgs Class Reference

This class is used to specify information used to control the execution of an asynchronous operation and the notification of its completion. More...

#include <HExecArgs>

List of all members.

Public Types

enum  ExecType { Normal, FireAndForget }

Public Member Functions

 HExecArgs (ExecType type=Normal)
 ~HExecArgs ()
ExecType execType () const
void setExecType (ExecType type)

Friends

H_UPNP_CORE_EXPORT bool operator== (const HExecArgs &, const HExecArgs &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HExecArgs &obj1, const HExecArgs &obj2)

Detailed Description

This class is used to specify information used to control the execution of an asynchronous operation and the notification of its completion.

Remarks:
This class is thread-safe.

Member Enumeration Documentation

enum ExecType

This enumeration specifies how the asynchronous operation should be run.

Enumerator:
Normal 

This value indicates that the operation should be run normally and its completion or failure should be signaled normally.

FireAndForget 

This value indicates that the operation should be dispatched to be run, but its completion or failure isn't signaled.

This value is useful in situations where the result of the operation isn't interesting.


Constructor & Destructor Documentation

HExecArgs ( ExecType  type = Normal) [explicit]

Creates a new instance.

Parameters:
type
~HExecArgs ( )

Destroys the instance.


Member Function Documentation

ExecType execType ( ) const [inline]

Indicates how the operation should be run and its completion or failure be signaled.

Returns:
a value indicating how the operation should be run and its completion or failure be signaled.
See also:
setExecType()
void setExecType ( ExecType  type) [inline]

Sets the value indicating how the operation should be run and its completion or failure be signaled.

Parameters:
typespecifies the value indicating how the operation should be run and its completion or failure be signaled.
See also:
execType()

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HExecArgs ,
const HExecArgs  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
bool operator!= ( const HExecArgs obj1,
const HExecArgs obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_endpoint.html0000644000000000000000000005144611543637604024143 0ustar rootroot Herqq: HEndpoint Class Reference

HEndpoint Class Reference

Class that represents a network endpoint, which is a combination of a host address and a port number. More...

#include <HEndpoint>

List of all members.

Public Member Functions

 HEndpoint ()
 HEndpoint (const QHostAddress &hostAddress)
 HEndpoint (const QHostAddress &hostAddress, quint16 portNumber)
 HEndpoint (const QUrl &url)
 HEndpoint (const QString &arg)
 ~HEndpoint ()
bool isNull () const
QHostAddress hostAddress () const
quint16 portNumber () const
bool isMulticast () const
QString toString () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HEndpoint &, const HEndpoint &)
H_UPNP_CORE_EXPORT quint32 qHash (const HEndpoint &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HEndpoint &obj1, const HEndpoint &obj2)

Detailed Description

Class that represents a network endpoint, which is a combination of a host address and a port number.

Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HEndpoint ( )

Creates a new instance with host address set to QHostAddress::Null and port set to "0".

See also:
isNull()
HEndpoint ( const QHostAddress &  hostAddress)

Creates a new instance with the specified host address and port set to zero.

Parameters:
hostAddressspecifies the host address.
See also:
isNull()
HEndpoint ( const QHostAddress &  hostAddress,
quint16  portNumber 
)

Creates a new instance with the specified host address and port.

Parameters:
hostAddressspecifies the host address. If the host address is null the port number is set to zero.
portNumberspecifies the port number.
See also:
isNull()
HEndpoint ( const QUrl &  url)

Creates a new instance from the specified url.

Parameters:
urlspecifies the url from which the endpoint and port information is extracted (if present). If the URL does not contain a valid host information the port number is set to zero.
See also:
isNull()
HEndpoint ( const QString &  arg)

Creates a new instance from the specified string.

following format "hostAddress:portNumber", where [:portNumber] is optional.

Parameters:
argspecifies the string following format "hostAddress:portNumber", where [:portNumber] is optional. If the hostAddress is QHostAddress::Null the port number is set to zero.
See also:
isNull()
~HEndpoint ( )

Destroys the instance.


Member Function Documentation

bool isNull ( ) const [inline]

Indicates whether or not the end point is properly defined.

Returns:
true in case the end point is not defined.
QHostAddress hostAddress ( ) const [inline]

Returns the host address of the endpoint.

Returns:
The host address of the endpoint.
quint16 portNumber ( ) const [inline]

Returns the port number of the endpoint.

Returns:
The port number of the endpoint.
bool isMulticast ( ) const

Indicates whether or not the end point refers to a multicast address.

Returns:
true in case the end point refers to a multicast address.
QString toString ( ) const

Returns a string representation of the endpoint.

Returns:
The address and port number together separated by a ":". E.g "192.168.0.1:80". If the instance is null, i.e. isNull() returns true then an empty string is returned.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HEndpoint ,
const HEndpoint  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
H_UPNP_CORE_EXPORT quint32 qHash ( const HEndpoint ) [friend]

Returns a value that can be used as a unique key in a hash-map identifying the object.

Parameters:
keyspecifies the object from which the hash value is created.
Returns:
a value that can be used as a unique key in a hash-map identifying the object.
bool operator!= ( const HEndpoint obj1,
const HEndpoint obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_exec_args-members.html0000644000000000000000000001146411543637604025707 0ustar rootroot Herqq: Member List

HExecArgs Member List

This is the complete list of members for HExecArgs, including all inherited members.
ExecType enum nameHExecArgs
execType() const HExecArgs [inline]
FireAndForget enum valueHExecArgs
HExecArgs(ExecType type=Normal)HExecArgs [explicit]
Normal enum valueHExecArgs
operator!=(const HExecArgs &obj1, const HExecArgs &obj2)HExecArgs [related]
operator==(const HExecArgs &, const HExecArgs &)HExecArgs [friend]
setExecType(ExecType type)HExecArgs [inline]
~HExecArgs()HExecArgs
herqq-1.0.0/hupnp/docs/html/functions_0x65.html0000644000000000000000000001536211543637604020054 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- e -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_devices_setup_data.html0000644000000000000000000003457711543637604026164 0ustar rootroot Herqq: HDevicesSetupData Class Reference

HDevicesSetupData Class Reference

This class is used to specify information that can be used to validate UPnP devices. More...

#include <HDevicesSetupData>

List of all members.

Public Member Functions

 HDevicesSetupData ()
 ~HDevicesSetupData ()
bool contains (const HResourceType &deviceType) const
QSet< HResourceTypedeviceTypes () const
HDeviceSetup get (const HResourceType &type) const
bool isEmpty () const
int size () const
bool insert (const HDeviceSetup &newItem)
bool remove (const HResourceType &type)

Detailed Description

This class is used to specify information that can be used to validate UPnP devices.

Remarks:
This class is not thread-safe.
See also:
HDeviceSetup

Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isEmpty()

Destroys the instance.


Member Function Documentation

bool contains ( const HResourceType deviceType) const

Indicates if the instance contains an item with the specified device type.

Parameters:
deviceTypespecifies the device type of the searched item.
Returns:
true when the instance contains an item with the specified device type.
See also:
get()
QSet< HResourceType > deviceTypes ( ) const

Returns the device types of the contained items.

Returns:
The device types of the contained items.
HDeviceSetup get ( const HResourceType type) const

Retrieves an item.

Parameters:
typespecifies the device type of the item.
Returns:
The item with the specified device type. The returned item is invalid in case no item with the specified device type was found.
See also:
contains()
bool isEmpty ( ) const

Indicates if the object is empty.

Returns:
true in case the instance has no items.
int size ( ) const

Returns the number of contained items.

Returns:
The number of contained items.
bool insert ( const HDeviceSetup newItem)

Inserts a new item.

Parameters:
newItemspecifies the item to be added.
Returns:
true in case the item was added. The newItem will not be added if the instance already contains an item that has the same HDeviceSetup::deviceType() as the newItem or the newItem is invalid.
bool remove ( const HResourceType type)

Removes an existing item.

Parameters:
typespecifies the device type of the item to be removed.
Returns:
true in case the item was found and removed.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_configuration.html0000644000000000000000000005274411543637604026513 0ustar rootroot Herqq: HDeviceConfiguration Class Reference

HDeviceConfiguration Class Reference

This is a class for specifying a configuration to an HServerDevice that is to be created and hosted by an HDeviceHost. More...

#include <HDeviceConfiguration>

Inheritance diagram for HDeviceConfiguration:
HClonable

List of all members.

Public Member Functions

 HDeviceConfiguration ()
virtual ~HDeviceConfiguration ()
virtual HDeviceConfigurationclone () const
void setPathToDeviceDescription (const QString &pathToDeviceDescription)
QString pathToDeviceDescription () const
void setCacheControlMaxAge (qint32 maxAge=1800)
qint32 cacheControlMaxAge () const
bool isValid () const

Protected Member Functions

virtual void doClone (HClonable *target) const
virtual HDeviceConfigurationnewInstance () const

Detailed Description

This is a class for specifying a configuration to an HServerDevice that is to be created and hosted by an HDeviceHost.

A valid device configuration contains at least a path to a device description file. See setPathToDeviceDescription().

The other options available in this class affect the runtime behavior of a HDeviceHost in regard to the HServerDevice instance that is created based on the pathToDeviceDescription().

See also:
HDeviceHostConfiguration, HDeviceHost, HDeviceHost::init(), HServerDevice

Constructor & Destructor Documentation

Default constructor.

Creates a new, empty instance.

~HDeviceConfiguration ( ) [virtual]

Destroys the instance.


Member Function Documentation

virtual void doClone ( HClonable target) const [protected, virtual]

Clones the contents of this to the target object.

Every derived class that introduces member variables that should be copied as part of a cloning operation should override this method. The implementation should be something along these lines:

 void MyClonable::doClone(HClonable* target) const
 {
    MyClonable* myClonable = dynamic_cast<MyClonable*>(target);
    if (!myClonable)
    {
        return;
    }

    BaseClassOfMyClonable::doClone(target);

    // copy the variables introduced in *this* MyClonable
    // instance to "myClonable".
 }
Parameters:
targetspecifies the target object to which the contents of this instance are cloned.

Reimplemented from HClonable.

virtual HDeviceConfiguration* newInstance ( ) const [protected, virtual]

Creates a new instance.

This method is used as part of object cloning. Because of that, it is important that every concrete (non-abstract) descendant class overrides this method regardless of the type location in the inheritance tree:

 MyClonable* MyClonable::newInstance() const
 {
     return new MyClonable();
 }
Remarks:
  • the object has to be heap-allocated and
  • the ownership of the object is passed to the caller.

Implements HClonable.

virtual HDeviceConfiguration* clone ( ) const [virtual]

Returns a deep copy of the instance.

Returns:
a deep copy of the instance.
Remarks:
  • the ownership of the returned object is transferred to the caller.

Reimplemented from HClonable.

void setPathToDeviceDescription ( const QString &  pathToDeviceDescription)

Sets the path to the UPnP device description.

Parameters:
pathToDeviceDescriptionspecifies the path to the UPnP device description.
Remarks:
The provided path or the device description document is not validated in anyway. The device description validation occurs during the initialization of the HDeviceHost.
QString pathToDeviceDescription ( ) const

Returns the path to the device description.

Returns:
The path to the device description.
void setCacheControlMaxAge ( qint32  maxAge = 1800)

Sets the maximum age of presence announcements and discovery responses in seconds.

Parameters:
maxAgespecifies the maximum age of presence announcements and discovery messages. If a value smaller than 5 is specified, the max age is set to 5. If positive value larger than a day is specified, the max age is set to a day (60*60*24). The default is 1800 seconds, which equals to 30 minutes.
Attention:
the UDA instructs this value to be at least 30 minutes.
qint32 cacheControlMaxAge ( ) const

Returns the maximum age of presence announcements and discovery responses in seconds.

If the cache control max age has not been explicitly set, the return value is 1800.

Returns:
The maximum age of presence announcements and discovery responses in seconds.
bool isValid ( ) const

Indicates whether or not the object contains the necessary details for hosting an HServerDevice class in a HDeviceHost.

Return values:
truein case the object contains the necessary details for hosting an HServerDevice class in a HDeviceHost.
falseotherwise. In this case, the initialization of HDeviceHost cannot succeed. Make sure you have set the pathToDeviceDescription().
See also:
pathToDeviceDescription()
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_ssdp-members.html0000644000000000000000000003056411543637604024722 0ustar rootroot Herqq: Member List

HSsdp Member List

This is the complete list of members for HSsdp, including all inherited members.
All enum valueHSsdp
AllowedMessage enum nameHSsdp
announcePresence(const HResourceAvailable &msg, qint32 count=1)HSsdp
announcePresence(const HResourceUnavailable &msg, qint32 count=1)HSsdp
announceUpdate(const HResourceUpdate &msg, qint32 count=1)HSsdp
DeviceAvailable enum valueHSsdp
DeviceUnavailable enum valueHSsdp
DeviceUpdate enum valueHSsdp
deviceUpdateReceived(const Herqq::Upnp::HResourceUpdate &msg, const Herqq::Upnp::HEndpoint &source)HSsdp [signal]
DiscoveryRequest enum valueHSsdp
DiscoveryRequestMethod enum nameHSsdp
discoveryRequestReceived(const Herqq::Upnp::HDiscoveryRequest &msg, const Herqq::Upnp::HEndpoint &source, Herqq::Upnp::HSsdp::DiscoveryRequestMethod requestType)HSsdp [signal]
DiscoveryResponse enum valueHSsdp
discoveryResponseReceived(const Herqq::Upnp::HDiscoveryResponse &msg, const Herqq::Upnp::HEndpoint &source)HSsdp [signal]
filter() const HSsdp
HSsdp(QObject *parent=0)HSsdp
incomingDeviceAvailableAnnouncement(const HResourceAvailable &msg, const HEndpoint &source)HSsdp [protected, virtual]
incomingDeviceUnavailableAnnouncement(const HResourceUnavailable &msg, const HEndpoint &source)HSsdp [protected, virtual]
incomingDeviceUpdateAnnouncement(const HResourceUpdate &msg, const HEndpoint &source)HSsdp [protected, virtual]
incomingDiscoveryRequest(const HDiscoveryRequest &msg, const HEndpoint &source, DiscoveryRequestMethod requestType)HSsdp [protected, virtual]
incomingDiscoveryResponse(const HDiscoveryResponse &msg, const HEndpoint &source)HSsdp [protected, virtual]
init()HSsdp
init(const QHostAddress &unicastAddress)HSsdp
isInitialized() const HSsdp
MulticastDiscovery enum valueHSsdp
None enum valueHSsdp
resourceAvailableReceived(const Herqq::Upnp::HResourceAvailable &msg, const Herqq::Upnp::HEndpoint &source)HSsdp [signal]
resourceUnavailableReceived(const Herqq::Upnp::HResourceUnavailable &msg, const Herqq::Upnp::HEndpoint &source)HSsdp [signal]
sendDiscoveryRequest(const HDiscoveryRequest &msg, qint32 count=1)HSsdp
sendDiscoveryRequest(const HDiscoveryRequest &msg, const HEndpoint &destination, qint32 count=1)HSsdp
sendDiscoveryResponse(const HDiscoveryResponse &msg, const HEndpoint &destination, qint32 count=1)HSsdp
setFilter(AllowedMessages allowedMessages)HSsdp
UnicastDiscovery enum valueHSsdp
unicastEndpoint() const HSsdp
~HSsdp()HSsdp [virtual]
herqq-1.0.0/hupnp/docs/html/functions_func_0x69.html0000644000000000000000000003636611543637604021102 0ustar rootroot Herqq: Class Members - Functions
 

- i -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_control_point_configuration.html0000644000000000000000000007054511543637604030144 0ustar rootroot Herqq: HControlPointConfiguration Class Reference

HControlPointConfiguration Class Reference

Class for specifying initialization information to HControlPoint instances. More...

#include <HControlPointConfiguration>

Inheritance diagram for HControlPointConfiguration:
HClonable

List of all members.

Public Member Functions

 HControlPointConfiguration ()
virtual ~HControlPointConfiguration ()
virtual
HControlPointConfiguration
clone () const
bool subscribeToEvents () const
qint32 desiredSubscriptionTimeout () const
bool autoDiscovery () const
QList< QHostAddress > networkAddressesToUse () const
void setSubscribeToEvents (bool subscribeAutomatically)
void setDesiredSubscriptionTimeout (qint32 timeout)
void setAutoDiscovery (bool arg)
bool setNetworkAddressesToUse (const QList< QHostAddress > &addresses)

Protected Member Functions

virtual void doClone (HClonable *target) const
virtual
HControlPointConfiguration
newInstance () const

Detailed Description

Class for specifying initialization information to HControlPoint instances.

This class is used to pass initialization information for HControlPoint instances. The use of this is optional and an HControlPoint instance is perfectly functional with the default configuration.

However, you can configure an HControlPoint in following ways:

See also:
HControlPoint
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new instance.

Creates a new instance with default values.

Destroys the instance.


Member Function Documentation

void doClone ( HClonable target) const [protected, virtual]

Clones the contents of this to the target object.

Every derived class that introduces member variables that should be copied as part of a cloning operation should override this method. The implementation should be something along these lines:

 void MyClonable::doClone(HClonable* target) const
 {
    MyClonable* myClonable = dynamic_cast<MyClonable*>(target);
    if (!myClonable)
    {
        return;
    }

    BaseClassOfMyClonable::doClone(target);

    // copy the variables introduced in *this* MyClonable
    // instance to "myClonable".
 }
Parameters:
targetspecifies the target object to which the contents of this instance are cloned.

Reimplemented from HClonable.

HControlPointConfiguration * newInstance ( ) const [protected, virtual]

Creates a new instance.

This method is used as part of object cloning. Because of that, it is important that every concrete (non-abstract) descendant class overrides this method regardless of the type location in the inheritance tree:

 MyClonable* MyClonable::newInstance() const
 {
     return new MyClonable();
 }
Remarks:
  • the object has to be heap-allocated and
  • the ownership of the object is passed to the caller.

Implements HClonable.

HControlPointConfiguration * clone ( ) const [virtual]

Returns a deep copy of the instance.

Returns:
a deep copy of the instance.
Remarks:
  • the ownership of the returned object is transferred to the caller.

Reimplemented from HClonable.

bool subscribeToEvents ( ) const

Indicates whether to automatically subscribe to all events on all services of a device when a new device is added into the control of an HControlPoint.

Returns:
true in case the HControlPoint instance should subscribe to all events of all services of a newly added device.
See also:
setSubscribeToEvents()
qint32 desiredSubscriptionTimeout ( ) const

Returns the subscription timeout a control point requests when it subscribes to an evented service.

The default value is 30 minutes.

Returns:
The subscription timeout in seconds a control point requests when it subscribes to an evented service.
See also:
setDesiredSubscriptionTimeout()
bool autoDiscovery ( ) const

Indicates whether the control point should perform discovery upon initialization.

Returns:
true in case the the control point should perform discovery upon initialization. This is the default value.
Remarks:
if the discovery is not performed the control point will be unaware of UPnP devices that are already active in the network until they re-advertise themselves.
See also:
setAutoDiscovery()
QList< QHostAddress > networkAddressesToUse ( ) const

Returns the network addresses a control point should use in its operations.

Returns:
The network addresses a control point should use in its operations.
See also:
setNetworkAddressesToUse()
void setSubscribeToEvents ( bool  subscribeAutomatically)

Defines whether a control point should automatically subscribe to all events on all services of a device when a new device is added into the control of an HControlPoint.

Parameters:
subscribeAutomaticallywhen true an HControlPoint instance should by default subscribe to all events of all services of a newly added device.
See also:
subscribeToEvents()
void setDesiredSubscriptionTimeout ( qint32  timeout)

Sets the subscription timeout a control point requests when it subscribes to an evented service.

Values less than or equal to zero are rejected and instead the default value is used. The default value is 30 minutes.

Parameters:
timeoutspecifies the requested timeout in seconds.
See also:
desiredSubscriptionTimeout()
void setAutoDiscovery ( bool  arg)

Defines whether the control point should perform discovery upon initialization.

Parameters:
argwhen true an HControlPoint instance will perform discovery when it is initialized. This is the default.
Remarks:
if the discovery is not performed the control point will be unaware of UPnP devices that are already active in the network until they re-advertise themselves.
See also:
autoDiscovery()
bool setNetworkAddressesToUse ( const QList< QHostAddress > &  addresses)

Defines the network addresses the control point should use in its operations.

Parameters:
addressesspecifies the network addresses the control point should use in its operations.
Returns:
true in case the provided addresses are valid and can be used.
See also:
networkAddressesToUse()
herqq-1.0.0/hupnp/docs/html/functions_0x7e.html0000644000000000000000000002576011543637604020140 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- ~ -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_argument-members.html0000644000000000000000000001615111543637604027124 0ustar rootroot Herqq: Member List

HActionArgument Member List

This is the complete list of members for HActionArgument, including all inherited members.
dataType() const HActionArgument
detach()HActionArgument
HActionArgument()HActionArgument
HActionArgument(const QString &name, const HStateVariableInfo &stateVariableInfo, QString *err=0)HActionArgument
HActionArgument(const HActionArgument &)HActionArgument
isValid() const HActionArgument
isValidValue(const QVariant &value)HActionArgument
name() const HActionArgument
operator!() const HActionArgument
operator!=(const HActionArgument &, const HActionArgument &)HActionArgument [related]
operator=(const HActionArgument &)HActionArgument
operator==(const HActionArgument &, const HActionArgument &)HActionArgument [friend]
relatedStateVariable() const HActionArgument
setValue(const QVariant &value)HActionArgument
toString() const HActionArgument
value() const HActionArgument
~HActionArgument()HActionArgument
herqq-1.0.0/hupnp/docs/html/functions_0x74.html0000644000000000000000000001665711543637604020064 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- t -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_info-members.html0000644000000000000000000001512311543637604026233 0ustar rootroot Herqq: Member List

HActionInfo Member List

This is the complete list of members for HActionInfo, including all inherited members.
HActionInfo()HActionInfo
HActionInfo(const QString &name, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)HActionInfo
HActionInfo(const QString &name, const HActionArguments &inputArguments, const HActionArguments &outputArguments, bool hasRetVal, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)HActionInfo
HActionInfo(const HActionInfo &other)HActionInfo
inclusionRequirement() const HActionInfo
inputArguments() const HActionInfo
isValid() const HActionInfo
name() const HActionInfo
operator!=(const HActionInfo &obj1, const HActionInfo &obj2)HActionInfo [related]
operator=(const HActionInfo &other)HActionInfo
operator==(const HActionInfo &, const HActionInfo &)HActionInfo [friend]
outputArguments() const HActionInfo
qHash(const HActionInfo &key)HActionInfo [related]
returnArgumentName() const HActionInfo
~HActionInfo()HActionInfo
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_host.html0000644000000000000000000014450011543637604024611 0ustar rootroot Herqq: HDeviceHost Class Reference

This is a class for creating and hosting HServerDevice instances on the network. More...

#include <HDeviceHost>

List of all members.

Public Types

enum  DeviceHostError {
  UndefinedError = -1, NoError = 0, AlreadyInitializedError = 1, InvalidConfigurationError = 2,
  InvalidDeviceDescriptionError = 3, InvalidServiceDescriptionError = 4, CommunicationsError = 5, NotStarted = 6,
  ResourceConflict = 7
}

Public Slots

void quit ()

Public Member Functions

 HDeviceHost (QObject *parent=0)
virtual ~HDeviceHost ()
HServerDevicedevice (const HUdn &udn, TargetDeviceType target=RootDevices) const
HServerDevices rootDevices () const
bool init (const HDeviceHostConfiguration &configuration)
DeviceHostError error () const
QString errorDescription () const
bool isStarted () const
bool add (const HDeviceConfiguration &configuration)

Protected Member Functions

const HDeviceHostConfigurationconfiguration () const
const HDeviceHostRuntimeStatusruntimeStatus () const
void setError (DeviceHostError error, const QString &errorDescr)

Private Member Functions

virtual bool doInit ()
virtual void doQuit ()
virtual bool acceptSubscription (HServerService *targetService, const HEndpoint &source, bool isNew)

Detailed Description

This is a class for creating and hosting HServerDevice instances on the network.

As the name implies, this is the class in the HUPnP library used to expose UPnP devices to UPnP control points. The class hosts instances of HServerDevice, which means that the class takes care of all of the UPnP mechanics detaching the HServerDevice from it. This separation leaves the HServerDevice to model the UPnP device structure and to focus on the functionality of the specific device type. This is what the HUPnP Device Model is all about.

Hosting a device is simple, assuming you have the necessary device and service descriptions ready and the HUPnP device and service classes implemented. Basically, you only need to:

  • instantiate an HDeviceConfiguration for each UPnP device type to be hosted and pass them to the HDeviceHost inside a HDeviceHostConfiguration instance
  • instantiate and initialize an HDeviceHost
  • make sure a Qt event loop is present in the thread in which the HDeviceHost is run.

As an example, consider the following:

 // myclass.h

 #include "my_hdevice.h" // your code containing the type MyHDevice

 #include <HUpnpCore/HDeviceHost>
 #include <HUpnpCore/HDeviceModelCreator>

 #include <QtCore/QObject>

 class MyClass :
     public QObject
 {
 Q_OBJECT

 private:
     Herqq::Upnp::HDeviceHost* m_deviceHost;

 public:
     MyClass(QObject* parent = 0);
 };

 class MyCreator : public Herqq::Upnp::HDeviceModelCreator
 {

 private:

   // overridden from HDeviceModelCreator
   virtual MyCreator* newInstance() const;

 public:

   // overridden from HDeviceModelCreator
   virtual MyHServerDevice* createDevice(
       const Herqq::Upnp::HDeviceInfo& info) const;

   // overridden from HDeviceModelCreator
   virtual MyHServerService* createService(
       const Herqq::Upnp::HServiceInfo& serviceInfo,
       const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const;
 };

 // myclass.cpp

 MyCreator* MyCreator::newInstance() const
 {
     return new MyCreator();
 }

 MyHServerDevice* MyCreator::createDevice(const Herqq::Upnp::HDeviceInfo& info) const
 {
     if (info.deviceType().toString() == "urn:herqq-org:device:MyDevice:1")
     {
         return new MyHServerDevice();
     }

     return 0;
 }

 MyHServerService* MyCreator::createService(
     const Herqq::Upnp::HServiceInfo& serviceInfo,
     const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const
 {
     if (serviceInfo.serviceType().toString() == "urn:herqq-org:service:MyService:1")
     {
         return new HMyServerService();
     }

     // Note, parentDeviceInfo is not needed in this case, but there are
     // scenarios when it is mandatory to know information of the parent
     // device to create the correct HServerService type.

     return 0;
 }

 MyClass::MyClass(QObject* parent) :
     QObject(parent),
         m_deviceHost(new Herqq::Upnp::HDeviceHost(this))
 {
     Herqq::Upnp::HDeviceHostConfiguration hostConf;
     hostConf.setDeviceModelCreator(MyCreator());

     Herqq::Upnp::HDeviceConfiguration deviceConf;
     deviceConf.setPathToDeviceDescription("my_hdevice_devicedescription.xml");

     hostConf.add(deviceConf);

     if (!m_deviceHost->init(hostConf))
     {
         // The initialization failed, perhaps you should do something?
         // for starters, you can call error() to check the error type and
         // errorDescription() for a human-readable description of
         // the error that occurred.
         return;
     }

     // The host is running and your device should now be accessible to
     // UPnP Control points until the host is destroyed (assuming the current
     // thread has an event loop).
 }

There are a few noteworthy issues in the example above.

  1. The device host will fail to initialize if your HDeviceHostConfiguration instance is invalid; for instance, the device model creator is not specified or any of the paths to your UPnP device or service description documents are invalid. The point is, you should always check the return value.
  2. Your HServerDevice is accessible only as long as your HDeviceHost is alive. When the device host is destroyed every UPnP device it hosted are destroyed as well.
  3. HDeviceHost requires an event loop to function.
  4. The example above uses an HDeviceHost instance to host a single UPnP root device, but the same host could be used to host multiple UPnP root devices. Certainly you can create multiple HDeviceHost instances that each host a single root HServerDevice within a thread, even sharing an event loop. However, using a single HDeviceHost for multiple root HServerDevice instances reduces resource usage in various ways and makes all the configured UPnP root devices accessible to you from the same HDeviceHost instance.
Remarks:
  • HDeviceHost has thread affinity, which mandates that the HDeviceHost and any object managed by it must be destroyed in the thread in which the HDeviceHost at the time lives. You can use QObject::moveToThread() on the HDeviceHost, which causes the device host and every object managed by it to be moved to the chosen thread. However, you cannot move individual objects managed by HDeviceHost.
  • HDeviceHost is the owner of the instances of HServerDevice it manages. It manages the memory of every object it has created. In other words, a device host never transfers the ownership of the HServerDevice objects it manages; HDeviceHost always destroys every HServerDevice it manages when it is being destroyed.
See also:
Device Hosting, HServerDevice, HDeviceHostConfiguration, HDeviceConfiguration

Member Enumeration Documentation

Specifies return values that some of the methods of the class may return.

Enumerator:
UndefinedError 

Return value signifying general failure.

This return code is used when an operation could not be successfully completed, but the exact cause for the error could not be determined.

NoError 

No error has occurred.

AlreadyInitializedError 

Return value signifying that the device host is already successfully initialized.

InvalidConfigurationError 

Return value signifying that the provided host configuration was incorrect.

InvalidDeviceDescriptionError 

Return value signifying that a provided device description document was invalid.

InvalidServiceDescriptionError 

Return value signifying that a provided service description document was invalid.

CommunicationsError 

Return value used to indicate one or more more problems in communications layer.

For instance, perhaps the HTTP server or could the SSDP listener could not be initialized.

NotStarted 

Return value used to indicate that the device host instance is not property initiated.

ResourceConflict 

Return value used to indicate that operation failed due to a resource conflict.

For instance, trying to add more than one device with a same UDN will fail because of this.


Constructor & Destructor Documentation

HDeviceHost ( QObject *  parent = 0) [explicit]

Creates a new instance.

Parameters:
parentspecifies the parent QObject.
~HDeviceHost ( ) [virtual]

Destroys the instance.

Destroys the device host and every hosted device.


Member Function Documentation

bool doInit ( ) [private, virtual]

Performs the initialization of a derived class.

The HDeviceHost uses two-phase initialization in which the user first constructs an instance and then calls init() in order to ready the object for use. This method is called by the HDeviceHost during its private initialization after all the private data structures are constructed, but before any network operations are performed. At this point no HTTP or SSDP requests are served.

You can override this method to perform any further initialization of a derived class.

Returns:
true if and only if the initialization succeeded. If false is returned the initialization of the device host is aborted. In addition, it is advised that you call setError() before returning.
Remarks:
the default implementation does nothing.
See also:
init()
void doQuit ( ) [private, virtual]

Performs the de-initialization of a derived class.

Since it is possible to shutdown a device host without actually destroying the instance by calling quit(), derived classes have the possibility to run their own shutdown procedure by overriding this method. This method is called before the HDeviceHost cleans its private data structures but after it has stopped listening requests from the network.

Remarks:
the default implementation does nothing.
See also:
quit()
bool acceptSubscription ( HServerService targetService,
const HEndpoint source,
bool  isNew 
) [private, virtual]

Checks if a (re-)subscription should be accepted.

Derived classes can opt to override this method to decide what event subscriptions are accepted and what are not.

Parameters:
targetServicespecifies the target of the subscription.
sourcespecifies the location where the subscription came.
isNewindicates the type of the subscription. The value is true in case the subscription is new and false in case the subscription is a renewal to an existing subscription.
Returns:
true in case the subscription should be accepted.
Remarks:
by default all subscriptions are accepted.
const HDeviceHostConfiguration * configuration ( ) const [protected]

Returns the configuration used to initialize the device host.

Returns:
The configuration used to initialize the device host or null in case the device host is not initialized.
Remarks:
the returned object is not a copy and the ownership of the object is not transferred. Do not delete it.
const HDeviceHostRuntimeStatus * runtimeStatus ( ) const [protected]

Returns the object that details information of the status of a device host.

Returns:
The object that details information of the status of a device host.
Remarks:
  • A device host creates a single HDeviceHostRuntimeStatus object during its construction and deletes it when the device host is being deleted.
  • The returned object is always owned by the device host.
void setError ( DeviceHostError  error,
const QString &  errorDescr 
) [protected]

Sets the type and description of the last error occurred.

Parameters:
errorspecifies the error type.
errorDescrspecifies a human readable description of the error.
See also:
error(), errorDescription()
HServerDevice * device ( const HUdn udn,
TargetDeviceType  target = RootDevices 
) const

Returns a root device with the specified Unique Device Name.

Parameters:
udnspecifies the Unique Device Name of the desired root device.
targetspecifies the type of devices that are included in the search.
Returns:
The root device with the specified Unique Device Name, or a null pointer in case no currently managed root device has the specified UDN.
Warning:
the returned device will be deleted when the device host is being destroyed. However, do not delete the device object directly. The ownership of an HServerDevice is never transferred.
HServerDevices rootDevices ( ) const

Returns a list of UPnP root devices the host is currently managing.

The returned list contains pointers to root HServerDevice objects that are currently hosted by this instance.

Returns:
a list of pointers to root HServerDevice objects that are currently managed by the device host.
Warning:
the returned HServerDevice instances will be deleted when the device host is being destroyed. However, do not delete the device objects directly. The ownership of an HServerDevice is never transferred.
bool init ( const HDeviceHostConfiguration configuration)

Initializes the device host and the devices it is supposed to host.

Parameters:
configurationspecifies the configuration for the instance. The object has to contain at least one device configuration.
Returns:
true if the initialization of the device host succeeded. If false is returned you can call error() to get the type of the error, and you can call errorDescription() to get a human-readable description of the error.
See also:
quit()
DeviceHostError error ( ) const

Returns the type of the last error occurred.

Returns:
The type of the last error occurred.
QString errorDescription ( ) const

Returns a human readable description of the last error occurred.

Returns:
a human readable description of the last error occurred.
bool isStarted ( ) const

Indicates whether or not the host is successfully started.

Returns:
true in case the host is successfully started.
bool add ( const HDeviceConfiguration configuration)

Adds a new root device configuration to the device host.

If the provided configuration is valid, the device host creates a new device model instance, announces the new resource(s) to the network and adds the device model available into the control of this instance.

Parameters:
configurationspecifies the new root device to add.
Returns:
true if a device model corresponding to the specified configuration was created and added to the device host. If the method returns false, you can call error() and errorDescription() to get more information of the error that occurred.
Remarks:
The specified device configuration has to be compatible with the specified HDeviceHostConfiguration specified in init().
See also:
error(), errorDescription()
void quit ( ) [slot]

Quits the device host and destroys the UPnP devices it is hosting.

Note that this is automatically called when the device host is destroyed.

Attention:
Every pointer to object retrieved from this instance will be deleted. Be sure not to use any such pointer after calling this method.
See also:
init()
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_setup.html0000644000000000000000000005417711543637604025006 0ustar rootroot Herqq: HDeviceSetup Class Reference

HDeviceSetup Class Reference

This class is used to specify information that can be used to validate a UPnP device. More...

#include <HDeviceSetup>

List of all members.

Public Member Functions

 HDeviceSetup ()
 HDeviceSetup (const HResourceType &type, HInclusionRequirement incReq=InclusionMandatory)
 HDeviceSetup (const HResourceType &type, int version, HInclusionRequirement incReq=InclusionMandatory)
 ~HDeviceSetup ()
HDeviceSetupoperator= (const HDeviceSetup &)
 HDeviceSetup (const HDeviceSetup &)
const HResourceTypedeviceType () const
HInclusionRequirement inclusionRequirement () const
bool isValid () const
int version () const
void setInclusionRequirement (HInclusionRequirement arg)
void setDeviceType (const HResourceType &arg)
void setVersion (int version)

Detailed Description

This class is used to specify information that can be used to validate a UPnP device.

See also:
HDevicesSetupData, HClientDevice, HServerDevice
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new, invalid instance.

See also:
isValid()
HDeviceSetup ( const HResourceType type,
HInclusionRequirement  incReq = InclusionMandatory 
)

Creates a new instance.

Parameters:
typespecifies the device type.
incReqspecifies inclusion requirement of the device.
See also:
isValid()
Remarks:
the version() is set to 1.
HDeviceSetup ( const HResourceType type,
int  version,
HInclusionRequirement  incReq = InclusionMandatory 
)

Creates a new instance.

Parameters:
typespecifies the device type.
versionspecifies the version of the UPnP device, which first specified the embedded device.
incReqspecifies inclusion requirement of the device.
See also:
isValid()

Destroys the instance.

HDeviceSetup ( const HDeviceSetup other)

Assignment operator.

Copies the contents of other to this.


Member Function Documentation

HDeviceSetup & operator= ( const HDeviceSetup other)

Copy constructor.

Creates a copy of other.

const HResourceType & deviceType ( ) const

Returns the device type.

Returns:
The device type.
See also:
setDeviceType()
HInclusionRequirement inclusionRequirement ( ) const

Returns the inclusion requirement.

Returns:
The inclusion requirement.
See also:
setInclusionRequirement()
bool isValid ( ) const

Indicates if the object is valid.

Returns:
true in case the object is valid, that is, the device type, version and inclusion requirement are properly defined.
See also:
version(), deviceType(), inclusionRequirement()
int version ( ) const

Returns the version of the UPnP device, which first specified the embedded device.

Returns:
The version of the UPnP device, which first specified the embedded device.
See also:
setVersion()
void setInclusionRequirement ( HInclusionRequirement  arg)

Sets the the inclusion requirement.

Parameters:
argspecifies the inclusion requirement.
See also:
inclusionRequirement()
void setDeviceType ( const HResourceType arg)

Sets the device type.

Parameters:
argspecifies the device type.
See also:
deviceType()
void setVersion ( int  version)

Specifies the version of the UPnP device, which first specified the embedded device.

Parameters:
versionspecifies the version of the UPnP device, which first specified the embedded device.
See also:
version()
herqq-1.0.0/hupnp/docs/html/functions_func.html0000644000000000000000000001433611543637604020305 0ustar rootroot Herqq: Class Members - Functions
 

- a -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_info.html0000644000000000000000000014446211543637604024576 0ustar rootroot Herqq: HDeviceInfo Class Reference

HDeviceInfo Class Reference

This class is used to contain information of a UPnP device found in a UPnP device description document. More...

#include <HDeviceInfo>

List of all members.

Public Member Functions

 HDeviceInfo ()
 HDeviceInfo (const HResourceType &deviceType, const QString &friendlyName, const QString &manufacturer, const QString &modelName, const HUdn &udn, HValidityCheckLevel checkLevel=StrictChecks, QString *err=0)
 HDeviceInfo (const HResourceType &deviceType, const QString &friendlyName, const QString &manufacturer, const QUrl &manufacturerUrl, const QString &modelDescription, const QString &modelName, const QString &modelNumber, const QUrl &modelUrl, const QString &serialNumber, const HUdn &udn, const QString &upc, const QList< QUrl > &icons, const QUrl &presentationUrl, HValidityCheckLevel checkLevel=StrictChecks, QString *err=0)
 ~HDeviceInfo ()
 HDeviceInfo (const HDeviceInfo &other)
HDeviceInfooperator= (const HDeviceInfo &other)
bool isValid (HValidityCheckLevel level) const
void setManufacturerUrl (const QUrl &arg)
void setModelDescription (const QString &arg)
void setModelNumber (const QString &arg)
void setModelUrl (const QUrl &arg)
void setSerialNumber (const QString &arg)
void setUpc (const QString &arg)
void setIcons (const QList< QUrl > &arg)
void setPresentationUrl (const QUrl &arg)
const HResourceTypedeviceType () const
QString friendlyName () const
QString manufacturer () const
QUrl manufacturerUrl () const
QString modelDescription () const
QString modelName () const
QString modelNumber () const
QUrl modelUrl () const
QString serialNumber () const
const HUdnudn () const
QString upc () const
QList< QUrl > icons () const
QUrl presentationUrl () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HDeviceInfo &obj1, const HDeviceInfo &obj2)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HDeviceInfo &obj1, const HDeviceInfo &obj2)

Detailed Description

This class is used to contain information of a UPnP device found in a UPnP device description document.

A device description specifies a UPnP device. A device description specifies the services of a device, the embedded devices of a device and other information, such as the manufacturer, model name, serial number and the Unique Device Name that uniquely identifies a device. Instances of this class contain the previously mentioned "other" information found in device description documents.

Remarks:
This class is not thread-safe.
See also:
HServiceInfo, HActionInfo and HStateVariableInfo.

Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isValid()
HDeviceInfo ( const HResourceType deviceType,
const QString &  friendlyName,
const QString &  manufacturer,
const QString &  modelName,
const HUdn udn,
HValidityCheckLevel  checkLevel = StrictChecks,
QString *  err = 0 
)

Constructs a new instance from the specified parameters that the UDA specification mandates for a UPnP device.

The parameters the constructor expects are arguments defined in the device description file and they are all mandatory for a valid UPnP device.

Parameters:
deviceTypespecifies the device type.
friendlyNamespecifies a short description for the end-user. This cannot be empty and should be less than 64 characters.
manufacturerspecifies the name of the manufacturer. This cannot be empty and should be less than 64 characters.
modelNamespecifies the model name. This cannot be empty and should be less than 32 characters.
udnspecifies the unique device name. This is a universally unique identifier for the device, regardless if the device is root or embedded. The specified UDN has to be valid.
checkLevelspecifies the level of strictness used in validating the specified arguments. This parameter is optional.
errspecifies a pointer to a QString that contains an error description in case the construction failed. This parameter is optional.
Remarks:
in case any of the provided arguments does not meet the specified requirements, the created object is invalid.
See also:
isValid()
HDeviceInfo ( const HResourceType deviceType,
const QString &  friendlyName,
const QString &  manufacturer,
const QUrl &  manufacturerUrl,
const QString &  modelDescription,
const QString &  modelName,
const QString &  modelNumber,
const QUrl &  modelUrl,
const QString &  serialNumber,
const HUdn udn,
const QString &  upc,
const QList< QUrl > &  icons,
const QUrl &  presentationUrl,
HValidityCheckLevel  checkLevel = StrictChecks,
QString *  err = 0 
)

Constructs a new instance from the specified parameters.

These are all the arguments found in the device description file.

Parameters:
deviceTypespecifies the device type.
friendlyNamespecifies a short description for the end-user. This cannot be empty and should be less than 64 characters.
manufacturerspecifies the name of the manufacturer. This cannot be empty and should be less than 64 characters.
manufacturerUrlspecifies the web site for the manufacturer.
modelDescriptionspecifies the long description for the end user. This can be empty and should be less than 128 characters.
modelNamespecifies the model name. This cannot be empty and should be less than 32 characters.
modelNumberspecifies the model number of the device. There is no format specified. This should be less than 32 characters.
modelUrlspecifies the web site for the device model.
serialNumberspecifies the serial number of the device. No format specified. This should be less than 64 characters.
udnspecifies the unique device name. This is a universally unique identifier for the device, regardless if the device is root or embedded. The specified UDN has to be valid.
upcspecifies the Universal Product Code, which is 12-digit, all-numeric code that identifies the consumer package. Managed by the Uniform Code Council.
iconsspecifies the icons of the device, if any.
presentationUrlspecifies the URL for HTML-based user interface for controlling and/or viewing device status.
checkLevelspecifies the level of strictness used in validating the specified arguments. This parameter is optional.
errspecifies a pointer to a QString that contains an error description in case the construction failed. This is optional.
Remarks:
in case any of the provided arguments does not meet the specified requirements, the created object is invalid.
See also:
isValid()

Destroys the instance.

HDeviceInfo ( const HDeviceInfo other)

Copies the contents of the other to this.

Parameters:
otherspecifies the object to be copied.

Member Function Documentation

HDeviceInfo& operator= ( const HDeviceInfo other)

Assigns the contents of the other to this.

Parameters:
otherspecifies the object to be copied.
bool isValid ( HValidityCheckLevel  level) const

Indicates if the object is valid.

A valid object contains the mandatory data of a device description.

Parameters:
levelspecifies the level of strictness used in validating the object. This parameter is optional and the default level is strict.
Returns:
true in case the object is valid.
void setManufacturerUrl ( const QUrl &  arg)

Sets the URL for the web site of the manufacturer.

Parameters:
argspecifies the URL for the web site of the manufacturer.
See also:
manufacturerUrl()
void setModelDescription ( const QString &  arg)

Sets the model description.

A model description is used to display a long description for end user. Should be < 128 characters.

Parameters:
argspecifies the model description.
See also:
modelDescription()
void setModelNumber ( const QString &  arg)

Sets the model number.

There is no format specified for the model number, other than it should be < 32 characters.

Parameters:
argspecifies the model number.
See also:
modelNumber()
void setModelUrl ( const QUrl &  arg)

Sets the URL for the web site of the model.

Parameters:
argspecifies the model URL.
See also:
modelUrl()
void setSerialNumber ( const QString &  arg)

Sets the serial number of the device.

There is no format specified for the serial number, other than it should be < 64 characters.

Parameters:
argspecifies the serial number.
See also:
serialNumber()
void setUpc ( const QString &  arg)

Sets the Universal Product Code.

UPC is a 12-digit, all-numeric code that identifies the consumer package. Managed by the Uniform Code Council.

Parameters:
argspecifies the UPC.
See also:
upc()
void setIcons ( const QList< QUrl > &  arg)

Sets the icons of the device.

Parameters:
argspecifies the icons of the device.
See also:
icons()
void setPresentationUrl ( const QUrl &  arg)

Sets the presentation URL.

Presentation URL specifies the URL for HTML-based user interface for controlling and/or viewing device status.

Parameters:
argspecifies the presentation URL.
See also:
presentationUrl()
const HResourceType& deviceType ( ) const

Returns the type of the device found in the device description file.

Returns:
The type of the device found in the device description file.
QString friendlyName ( ) const

Returns short description for end user.

Returns:
short description for end user.
QString manufacturer ( ) const

Returns manufacturer's name.

Returns:
manufacturer's name.
QUrl manufacturerUrl ( ) const

Returns the manufacturer's web site.

Returns:
The manufacturer's web site.
See also:
setManufacturerUrl()
QString modelDescription ( ) const

Returns long description for end user.

Returns:
long description for end user.
See also:
setModelDescription()
QString modelName ( ) const

Returns the model name.

Returns:
The model name.
QString modelNumber ( ) const

Returns the model number.

Returns:
The model number.
See also:
setModelNumber()
QUrl modelUrl ( ) const

Returns the web site for the device model.

Returns:
The web site for the device model.
See also:
setModelUrl()
QString serialNumber ( ) const

Returns the serial number.

Returns:
The serial number.
See also:
setSerialNumber()
const HUdn& udn ( ) const

Returns the Unique Device Name.

Returns:
Universally-unique identifier for the device, whether root or embedded.
Remarks:
the UDN is same over time for a specific device instance.
QString upc ( ) const

Returns the Universal Product Code.

Returns:
The Universal Product Code.
See also:
setUpc()
QList< QUrl > icons ( ) const

Returns the icons of the device, if any.

Returns:
The icons of the device.
See also:
setIcons()
QUrl presentationUrl ( ) const

Returns the location of the device's presentation page.

Returns:
The location of the device's presentation page.
See also:
setPresentationUrl()

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HDeviceInfo obj1,
const HDeviceInfo obj2 
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HDeviceInfo obj1,
const HDeviceInfo obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_host_configuration.png0000644000000000000000000000076611543637604027365 0ustar rootroot‰PNG  IHDR¢P­v^;PLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2…IDATxíß’… ÆÃ3ãû?ò^‚Š:5mqv?.²åôöø„—ã“‚ øÝˆ¤O"¢ª™YN§Ÿ@,˜‘«k*M)Q" ¯~éô«ˆŒBåuøZ•Ão ñ›ôªòiÄU5¯-"7VÄa¸Ü17v´ÏöZ-ºç¢yã/z¯£qˆ@üÓˆáå¸]òý[þ?ÄœÃ3ÆGÌ9<ã ¢£D ˆ@"D ˆ@âF(¼=+@b8Ä2w¸gè*z5É!áëpãd‚è͘=D‡í–3ƒ bqEâÕÕwêòª®ÄPfغn'þË/µ‹vˆ–ÍW86[2ѯ®°ò_ÝÖ¦Aä“|ƒh=›ýºÆp1TãQçVQäªçøëÿWJf.!Ö O#6µÐF±_`?N#º‰Þ"¶?9˼_‹ û¦m3žD¬§Z‡Öv´ Herqq: Namespace Members
Here is a list of all documented namespace members with links to the namespaces they belong to:

- a -

- b -

- c -

- d -

- e -

- f -

- h -

- i -

- l -

- n -

- r -

- s -

- t -

- u -

- v -

- w -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_host_configuration.html0000644000000000000000000013052111543637604027536 0ustar rootroot Herqq: HDeviceHostConfiguration Class Reference

HDeviceHostConfiguration Class Reference

This class is used to specify one or more device configurations to an HDeviceHost instance and to configure the functionality of the HDeviceHost that affect every hosted HServerDevice. More...

#include <HDeviceHostConfiguration>

Inheritance diagram for HDeviceHostConfiguration:
HClonable

List of all members.

Public Member Functions

 HDeviceHostConfiguration ()
 HDeviceHostConfiguration (const HDeviceConfiguration &)
virtual ~HDeviceHostConfiguration ()
virtual HDeviceHostConfigurationclone () const
bool add (const HDeviceConfiguration &deviceConfiguration)
void clear ()
QList< const
HDeviceConfiguration * > 
deviceConfigurations () const
qint32 individualAdvertisementCount () const
QList< QHostAddress > networkAddressesToUse () const
qint32 subscriptionExpirationTimeout () const
HDeviceModelCreatordeviceModelCreator () const
HDeviceModelInfoProviderdeviceModelInfoProvider () const
void setDeviceModelCreator (const HDeviceModelCreator &creator)
void setDeviceModelInfoProvider (const HDeviceModelInfoProvider &infoProvider)
void setIndividualAdvertisementCount (qint32 count)
void setSubscriptionExpirationTimeout (qint32 timeout)
bool setNetworkAddressesToUse (const QList< QHostAddress > &addresses)
bool isEmpty () const
bool isValid () const

Protected Member Functions

virtual void doClone (HClonable *target) const
virtual HDeviceHostConfigurationnewInstance () const

Detailed Description

This class is used to specify one or more device configurations to an HDeviceHost instance and to configure the functionality of the HDeviceHost that affect every hosted HServerDevice.

The initialization of an HDeviceHost requires a valid host configuration. A valid host configuration contains at least one device configuration and a device model creator, as otherwise the host would have nothing to do and no means to create UPnP device and service objects.

The initialization of an HDeviceHost follows roughly these steps:

Besides specifying the device configurations, you can configure an HDeviceHost in following ways:

  • Specify how many times each resource advertisement is sent with setIndividualAdvertisementCount(). The default is 2.
  • Specify the timeout for event subscriptions with setSubscriptionExpirationTimeout(). The default is 0, which means that an HDeviceHost respects the subscription timeouts requested by control points as long as the requested values are less than a day.
  • Specify the network addresses an HDeviceHost should use in its operations with setNetworkAddressesToUse(). The default is the first found interface that is up. Non-loopback interfaces have preference, but if none are found the loopback is used. However, in this case UDP multicast is not available.
See also:
HDeviceConfiguration, HDeviceHost

Constructor & Destructor Documentation

Default constructor.

Creates a new, empty instance.

See also:
isEmpty(), isValid()

Creates a new instance.

Creates an instance with a single device configuration. This is a convenience method.

See also:
isEmpty(), isValid()
~HDeviceHostConfiguration ( ) [virtual]

Destroys the instance.


Member Function Documentation

virtual void doClone ( HClonable target) const [protected, virtual]

Clones the contents of this to the target object.

Every derived class that introduces member variables that should be copied as part of a cloning operation should override this method. The implementation should be something along these lines:

 void MyClonable::doClone(HClonable* target) const
 {
    MyClonable* myClonable = dynamic_cast<MyClonable*>(target);
    if (!myClonable)
    {
        return;
    }

    BaseClassOfMyClonable::doClone(target);

    // copy the variables introduced in *this* MyClonable
    // instance to "myClonable".
 }
Parameters:
targetspecifies the target object to which the contents of this instance are cloned.

Reimplemented from HClonable.

virtual HDeviceHostConfiguration* newInstance ( ) const [protected, virtual]

Creates a new instance.

This method is used as part of object cloning. Because of that, it is important that every concrete (non-abstract) descendant class overrides this method regardless of the type location in the inheritance tree:

 MyClonable* MyClonable::newInstance() const
 {
     return new MyClonable();
 }
Remarks:
  • the object has to be heap-allocated and
  • the ownership of the object is passed to the caller.

Implements HClonable.

virtual HDeviceHostConfiguration* clone ( ) const [virtual]

Returns a deep copy of the instance.

Returns:
a deep copy of the instance.
Remarks:
  • the ownership of the returned object is transferred to the caller.

Reimplemented from HClonable.

bool add ( const HDeviceConfiguration deviceConfiguration)

Adds a device configuration.

Parameters:
deviceConfigurationspecifies the device configuration to be added. The configuration is added only if it is valid, see HDeviceConfiguration::isValid().
Returns:
true in case the configuration was added. Only valid HDeviceConfiguration instances are added, see HDeviceConfiguration::isValid().
void clear ( )

Removes device configurations.

Remarks:
This method removes the device configurations, but it does not reset other set attributes to their default values.
QList< const HDeviceConfiguration * > deviceConfigurations ( ) const

Returns the currently stored device configurations.

Returns:
The currently stored device configurations. The returned list contains pointers to const device configuration objects this instance owns. The ownership of the objects is not transferred.
qint32 individualAdvertisementCount ( ) const

Indicates how many times the device host sends each individual advertisement / announcement.

The default value is 2.

Returns:
how many times the device host sends each individual advertisement / announcement.
See also:
setIndividualAdvertisementCount()
QList< QHostAddress > networkAddressesToUse ( ) const

Returns the network addresses a device host should use in its operations.

Returns:
The network addresses a device host should use in its operations.
See also:
setNetworkAddressesToUse()
qint32 subscriptionExpirationTimeout ( ) const

Returns the timeout the device host uses for subscriptions.

The default value is zero, which means that the device host honors the timeouts requested by control points up to a day. Larger values are set to a day.

Returns:
The timeout in seconds the device host uses for subscriptions.
See also:
setSubscriptionExpirationTimeout()
HDeviceModelCreator * deviceModelCreator ( ) const

Returns the device model creator the HDeviceHost should use to create HServerDevice instances.

Returns:
The device model creator the HDeviceHost should use to create HServerDevice instances.
See also:
setDeviceModelCreator()
HDeviceModelInfoProvider * deviceModelInfoProvider ( ) const

Returns the device model info provider the HDeviceHost should use to validate device model components.

Returns:
The device model info provider the HDeviceHost should use to validate device model components.
void setDeviceModelCreator ( const HDeviceModelCreator creator)

Sets the device model creator the HDeviceHost should use to create HServerDevice instances.

Parameters:
creatorspecifies the device model creator the HDeviceHost should use to create HServerDevice instances.
See also:
deviceModelCreator()
void setDeviceModelInfoProvider ( const HDeviceModelInfoProvider infoProvider)

Sets the device model info provider the HDeviceHost should use to validate device model components.

Parameters:
infoProviderspecifies the device model info provider the HDeviceHost should use to validate device model components.
void setIndividualAdvertisementCount ( qint32  count)

Specifies how many times the device host sends each individual advertisement / announcement.

By default, each advertisement is sent twice.

Parameters:
countspecifies how many times the device host sends each individual advertisement / announcement. If the provided value is smaller than 1 the advertisement count is set to 1.
See also:
individualAdvertisementCount()
void setSubscriptionExpirationTimeout ( qint32  timeout)

Specifies the timeout the device host uses for subscriptions.

The default value is zero, which means that the device host honors the timeouts requested by control points.

Parameters:
timeoutspecifies the desired timeout in seconds.

  • If timeout is greater than zero the device host will use the timeout as such for subscriptions.
  • If timeout is zero the device host will honor the timeout requested by control points.
  • If timeout is negative the subscription timeout is set to a day.
Note:
the maximum expiration timeout value is a day. Larger values are set to a day. This applies to the timeout requests made by control points as well.
See also:
subscriptionExpirationTimeout()
bool setNetworkAddressesToUse ( const QList< QHostAddress > &  addresses)

Defines the network addresses the device host should use in its operations.

Parameters:
addressesspecifies the network addresses the device host should use in its operations.
See also:
networkAddressesToUse()
bool isEmpty ( ) const

Indicates if the instance contains any device configurations.

Returns:
true in case the instance contains no device configurations. In this case the object cannot be used to initialize an HDeviceHost.
See also:
isValid()
bool isValid ( ) const

Indicates if the object is valid, i.e it can be used to initialize an HDeviceHost instance.

Returns:
true if the object is valid. A valid object is not empty and its deviceModelCreator() is set.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_action-members.html0000644000000000000000000001077011543637604026561 0ustar rootroot Herqq: Member List

HClientAction Member List

This is the complete list of members for HClientAction, including all inherited members.
beginInvoke(const HActionArguments &inArgs, HExecArgs *execArgs=0)HClientAction
beginInvoke(const HActionArguments &inArgs, const HActionInvokeCallback &completionCallback, HExecArgs *execArgs=0)HClientAction
HClientAction(const HActionInfo &info, HClientService *parent)HClientAction [protected]
info() const HClientAction
invokeComplete(Herqq::Upnp::HClientAction *source, const Herqq::Upnp::HClientActionOp &operation)HClientAction [signal]
parentService() const HClientAction
~HClientAction()=0HClientAction [pure virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_device.html0000644000000000000000000007537411543637604025156 0ustar rootroot Herqq: HServerDevice Class Reference

This is an abstract base class for server-side UPnP devices hosted by HDeviceHost. More...

#include <HServerDevice>

Inherited by HDefaultServerDevice.

List of all members.

Public Member Functions

virtual ~HServerDevice ()=0
HServerDeviceparentDevice () const
HServerDevicerootDevice () const
HServerServiceserviceById (const HServiceId &serviceId) const
const HServerServicesservices () const
HServerServices servicesByType (const HResourceType &serviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const
const HServerDevicesembeddedDevices () const
HServerDevices embeddedDevicesByType (const HResourceType &deviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const
const HDeviceInfoinfo () const
QString description () const
QList< QUrl > locations (LocationUrlType urlType=AbsoluteUrl) const
const HDeviceStatus & deviceStatus () const

Protected Member Functions

virtual bool finalizeInit (QString *errDescription)
 HServerDevice ()
bool init (const HDeviceInfo &info, HServerDevice *parentDevice=0)

Detailed Description

This is an abstract base class for server-side UPnP devices hosted by HDeviceHost.

HServerDevice is a core component of the HUPnP's server-side Device Model and it models a UPnP device, both root and embedded.

Note:
As detailed in the UPnP Device Architecture specification, a UPnP device is essentially a container for services and possibly for other (embedded) UPnP devices.

Using the class

The most common uses of HServerDevice involve reading the various device information elements originally set in the device description file and enumerating the exposed services. By calling info() you get an HDeviceInfo object from which you can read all the informational elements found in the device description. Calling services() gives you a list of HServerService instances the device exposes. Note that it is the services that contain the functionality and runtime status of the device.

Some devices also contain embedded devices, which you can get by calling embeddedDevices().

You can retrieve the device's description file by calling description() or you can manually read it from any of the locations returned by locations(). If the device is an embedded device, it always has a parent device, which you can get by calling parentDevice().

Sub-classing

First of all, if you want to implement a custom UPnP device using HUPnP, note that you do not have to subclass HServerDevice. But you can and there are valid reasons to do so.

Subclassing HServerDevice is extremely simple, as you are not required to override anything. However, if you choose to subclass HServerDevice, it is most likely because:

  • you want HUPnP to run strict validation routines on the description documents provided by users,
  • you want a custom HServerDevice type to do some additional initialization routines,
  • you want to extend the HServerDevice API in some way or
  • you want to create a custom type for design purposes.

See Setting Up the Device Model for more information of this topic.

Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HServerDevice ( ) [protected]

Creates a new instance.

~HServerDevice ( ) [pure virtual]

Destroys the instance.


Member Function Documentation

bool finalizeInit ( QString *  errDescription) [protected, virtual]

Provides the opportunity to do post-construction initialization routines in derived classes.

As HServerDevice is part of the HUPnP's server-side Device Model, its initialization process is usually driven by HUPnP. If this is the case, at the time of instantiation of a descendant HServerDevice the base HServerDevice sub-object is not yet fully set up. In other words, at that time it is not guaranteed that every private or protected member of a HServerDevice are set to their "final" values that are used once the object is fully initialized and ready to be used.

Because of the above, descendants of HServerDevice should not reference or rely on values of HServerDevice at the time of construction. If the initialization of a HServerDevice descendant needs to do things that rely on HServerDevice being fully set up, you can override this method. This method is called once right after the base HServerDevice is fully initialized.

Parameters:
errDescription
Returns:
true in case the initialization succeeded.
Note:
It is advisable to keep the constructors of the descendants of HServerDevice small and fast, and do more involved initialization routines here.
bool init ( const HDeviceInfo info,
HServerDevice parentDevice = 0 
) [protected]

Initializes the instance.

This method will succeed only once after construction. Subsequent calls will do nothing.

Parameters:
infospecifies information of the device. This is usually read from a device description document.
parentDevicespecifies parent UPnP device, if any.
HServerDevice * parentDevice ( ) const

Returns the parent device of this device, if any.

Returns:
The parent device of this device, if any, or a null pointer in case the device is a root device.
Remarks:
The pointer is guaranteed to be valid throughout the lifetime of this object.
HServerDevice * rootDevice ( ) const

Returns the root device of the device tree to which this device belongs.

Returns:
The root device of the device tree to which this device belongs.
Remarks:
This device could be the root device of the device tree in question, in which case a pointer to this instance is returned.
HServerService * serviceById ( const HServiceId serviceId) const

Returns the service that has the specified service ID.

Parameters:
serviceIdspecifies the service to be returned.
Returns:
The service that has the specified service ID or a null pointer in case there is no service with the specified ID.
Remarks:
The pointer is guaranteed to be valid throughout the lifetime of this object.
const HServerServices & services ( ) const

Returns the services this device exports.

Returns:
The services this device exports. The collection is empty if the device has no services.
Remarks:
the pointers are guaranteed to be valid throughout the lifetime of this object.
HServerServices servicesByType ( const HResourceType serviceType,
HResourceType::VersionMatch  versionMatch = HResourceType::Inclusive 
) const

Returns the services of a specific UPnP service type.

Parameters:
serviceTypespecifies the UPnP service type of interest. Only services matching the type are returned.
versionMatchspecifies how the version information in argument serviceType should be used. The default is inclusive match, which essentially means that any service with a service type version that is less than or equal to the version specified in argument serviceType is successfully matched.
Returns:
The services of the specified type.
Remarks:
the pointers are guaranteed to be valid throughout the lifetime of this object.
const HServerDevices & embeddedDevices ( ) const

Returns the embedded devices of this device.

Returns:
The embedded devices of this device. The collection is empty if the device has no embedded devices.
Remarks:
the pointers are guaranteed to be valid throughout the lifetime of this object.
HServerDevices embeddedDevicesByType ( const HResourceType deviceType,
HResourceType::VersionMatch  versionMatch = HResourceType::Inclusive 
) const

Returns the embedded devices of a specific UPnP device type.

Parameters:
deviceTypespecifies the UPnP device type of interest. Only devices matching the type are returned.
versionMatchspecifies how the version information in argument deviceType should be used. The default is inclusive match, which essentially means that any device with a device type version that is less than or equal to the version specified in argument deviceType is successfully matched.
Returns:
The embedded devices of the specified type.
Remarks:
the pointers are guaranteed to be valid throughout the lifetime of this object.
const HDeviceInfo & info ( ) const

Returns information about the device.

Returns:
information about the device. This is often read from the device description.
QString description ( ) const

Returns the UPnP device description of this device.

Returns:
The UPnP device description that is associated to this device.
Remarks:
an embedded device returns the same device description as its root device.
QList< QUrl > locations ( LocationUrlType  urlType = AbsoluteUrl) const

Returns a list of locations where the device is currently available.

Parameters:
urlTypespecifies whether the returned location URLs are absolute URLs for retrieving the device description. By default absolute URLs are returned and from these URLs the device description should be retrievable.
Returns:
a list of locations where the device is currently available.
const HDeviceStatus & deviceStatus ( ) const
Returns:
herqq-1.0.0/hupnp/docs/html/namespace_herqq_1_1_upnp.html0000644000000000000000000015124311543637604022117 0ustar rootroot Herqq: Herqq::Upnp Namespace Reference

Herqq::Upnp Namespace Reference

The namespace that contains all of the Herqq UPnP core functionality. More...

Classes

class  HActionInfo
 This class is used to contain information of a UPnP action found in a UPnP service description document. More...
class  HDeviceInfo
 This class is used to contain information of a UPnP device found in a UPnP device description document. More...
class  HDiscoveryType
 This is a class that depicts the different discovery types used in UPnP networking. More...
class  HProductToken
 This class represents a product token as defined in the RFC 2616, section 3.8. More...
class  HProductTokens
 This class is used to parse the product tokens defined by HTTP/1.1. More...
class  HResourceType
 This is a class used to depict a UPnP resource, which is either a UPnP device or a UPnP service. More...
class  HServiceId
 Class that represents the service identifier of a UPnP service. More...
class  HServiceInfo
 This class is used to contain information of a UPnP service found in a UPnP device description document. More...
class  HStateVariableInfo
 This class is used to contain information of a UPnP state variable found in a UPnP service description document. More...
class  HUdn
 This is a class used to depict a Unique Device Name (UDN), which is a unique device identifier that has to remain the same over time for a specific device instance. More...
class  HControlPoint
 This is a class for discovering and interacting with UPnP devices in the network. More...
class  HControlPointConfiguration
 Class for specifying initialization information to HControlPoint instances. More...
class  HDeviceHost
 This is a class for creating and hosting HServerDevice instances on the network. More...
class  HDeviceHostRuntimeStatus
 This is a class for detailing information of the runtime status of an HDeviceHost instance. More...
class  HDeviceConfiguration
 This is a class for specifying a configuration to an HServerDevice that is to be created and hosted by an HDeviceHost. More...
class  HDeviceHostConfiguration
 This class is used to specify one or more device configurations to an HDeviceHost instance and to configure the functionality of the HDeviceHost that affect every hosted HServerDevice. More...
class  HClientAction
 A client-side class that represents a server-side UPnP action. More...
class  HClientActionOp
 This class is used to identify a client-side action invocation and detail information of it. More...
class  HClientDevice
 This is a client-side class that represents a server-side UPnP device. More...
class  HClientService
 A client-side class that represents a server-side UPnP service. More...
class  HClientStateVariable
 A client-side class that represents a server-side UPnP state variable. More...
class  HActionArgument
 This is a class that represents an argument used in a UPnP action invocation. More...
class  HActionArguments
 A storage class for HActionArgument instances. More...
class  HActionSetup
 This class is used to specify information that can be used to setup an HServerAction or validate a UPnP action. More...
class  HActionsSetupData
 This class is used to specify information that can be used to setup HServerAction instances or generally validate the actions of a UPnP service. More...
class  HAsyncOp
 This abstract class is used as a base for identifying an asynchronous operation and detail information of it. More...
class  HDeviceModelInfoProvider
 A protocol class for providing information that is used to validate components of UPnP's device architecture and to setup components of HUPnP's device model. More...
class  HDeviceSetup
 This class is used to specify information that can be used to validate a UPnP device. More...
class  HDevicesSetupData
 This class is used to specify information that can be used to validate UPnP devices. More...
class  HExecArgs
 This class is used to specify information used to control the execution of an asynchronous operation and the notification of its completion. More...
class  HServiceSetup
 This class is used to specify information that can be used to validate a UPnP service. More...
class  HServicesSetupData
 This class is used to specify information that can be used to validate UPnP services. More...
class  HStateVariableEvent
 This is a class used to transfer state variable event information. More...
class  HStateVariablesSetupData
 This class is used to specify information that can be used to validate UPnP state variables. More...
class  HDeviceModelCreator
 A protocol class for creating HServerDevice and HServerService instances. More...
class  HServerAction
 A class that represents a server-side UPnP action. More...
class  HServerDevice
 This is an abstract base class for server-side UPnP devices hosted by HDeviceHost. More...
class  HServerService
 This is an abstract base class for server-side UPnP services. More...
class  HServerStateVariable
 This is a class that represents a server-side UPnP state variable. More...
class  HClonable
 This class defines an interface for cloning instances of polymorphic classes. More...
class  HUpnpDataTypes
 An utility class for working with UPnP data types. More...
class  HEndpoint
 Class that represents a network endpoint, which is a combination of a host address and a port number. More...
class  HMulticastSocket
 This is a class for multicast communication. More...
class  HResourceAvailable
 This is a class that represents the resource available (ssdp:alive) message. More...
class  HResourceUnavailable
 Class that represents the device unavailable (ssdp:byebye) message. More...
class  HResourceUpdate
 Class representing the device update (ssdp:update) message. More...
class  HDiscoveryRequest
 Class representing an M-SEARCH (ssdp:discover) message. More...
class  HDiscoveryResponse
 This is a class that represents a response to a HDiscoveryRequest. More...
class  HSsdp
 This class is used for sending and receiving SSDP messages defined by the UPnP Device Architecture specification. More...

Typedefs

typedef Functor< int,
H_TYPELIST_2(const
Herqq::Upnp::HActionArguments
&, Herqq::Upnp::HActionArguments *) 
HActionInvoke )
typedef Functor< bool,
H_TYPELIST_2(HClientAction
*, const HClientActionOp &) 
HActionInvokeCallback )
typedef QList< HEndpointHEndpoints
typedef QList< HClientService * > HClientServices
typedef QList< HServerService * > HServerServices
typedef QList< HClientDevice * > HClientDevices
typedef QList< HServerDevice * > HServerDevices
typedef QHash< QString, const
HClientStateVariable * > 
HClientStateVariables
typedef QHash< QString,
HServerStateVariable * > 
HServerStateVariables
typedef QHash< QString,
HStateVariableInfo
HStateVariableInfos
typedef QHash< QString,
HClientAction * > 
HClientActions
typedef QHash< QString,
HServerAction * > 
HServerActions

Enumerations

enum  UpnpErrorCode {
  UpnpSuccess = 200, UpnpInvalidAction = 401, UpnpInvalidArgs = 402, UpnpActionFailed = 501,
  UpnpArgumentValueInvalid = 600, UpnpArgumentValueOutOfRange = 601, UpnpOptionalActionNotImplemented = 602, UpnpOutOfMemory = 603,
  UpnpHumanInterventionRequired = 604, UpnpStringArgumentTooLong = 605, UpnpInvocationInProgress = 0x00f00000, UpnpUndefinedFailure = 0x0ff00000
}
enum  DeviceVisitType { VisitThisOnly = 0, VisitThisAndDirectChildren, VisitThisRecursively }
enum  TargetDeviceType { AllDevices, EmbeddedDevices, RootDevices }
enum  LocationUrlType { AbsoluteUrl, BaseUrl }
enum  HValidityCheckLevel { StrictChecks, LooseChecks }
enum  HInclusionRequirement { InclusionRequirementUnknown = 0, InclusionMandatory, InclusionOptional }
enum  HLogLevel {
  None = 0, Fatal = 1, Critical = 2, Warning = 3,
  Information = 4, Debug = 5, All = 6
}

Functions

QString upnpErrorCodeToString (qint32 errCode)
void SetLoggingLevel (HLogLevel level)
void EnableNonStdBehaviourWarnings (bool arg)
const char * hupnpCoreVersion ()

Detailed Description

The namespace that contains all of the Herqq UPnP core functionality.


Enumeration Type Documentation

This enumeration specifies the generic error codes that UPnP action invocation may return.

These values correspond to the values defined in the UDA, excluding NotImplemented and UndefinedFailure, which are defined for the purposes of HUPnP.

Note:
These are only the generic error codes. Many UPnP devices define and use domain specific error codes that cannot be specified here.
Enumerator:
UpnpSuccess 

Action invocation succeeded.

UpnpInvalidAction 

Invalid action.

The specified action was not found.

UpnpInvalidArgs 

Action invocation failed due to:

  • not enough arguments,
  • arguments in wrong order,
  • one or more arguments have wrong data type
UpnpActionFailed 

The current state of the service prevents the action invocation.

UpnpArgumentValueInvalid 

Action invocation failed due to an invalid argument value.

UpnpArgumentValueOutOfRange 

Action invocation failed due to:

  • an argument value is less than the minimum of the allowed value range,
  • an argument value is more than the maximum of the allowed value range,
  • an argument value is not in the allowed value list
UpnpOptionalActionNotImplemented 

Action invocation failed due to the requested action being optional and not implemented by the device.

UpnpOutOfMemory 

Action invocation failed due to insufficient memory.

The device does not have sufficient memory available to complete the action. This MAY be a temporary condition; the control point MAY choose to retry the unmodified request again later and it MAY succeed if memory is available.

UpnpHumanInterventionRequired 

The device has encountered an error condition which it cannot resolve itself and required human intervention such as a reset or power cycle.

See the device display or documentation for further guidance.

UpnpStringArgumentTooLong 

Action invocation failed due to a string argument being too long for the device to handle properly.

UpnpInvocationInProgress 

The action invocation is in progress.

Remarks:
This value is defined and used by HUPnP in-process only.
UpnpUndefinedFailure 

Action invocation failed, but the exact cause could not be determined.

Action invocation failed, but the exact cause could not be determined.

Remarks:
This value is defined and used by HUPnP in-process only.

This enumeration specifies how a device tree should be traversed given a starting node.

HUPnP Device Model is organized into a tree that has a root device, which may contain embedded devices as its children and they may contain embedded devices as their children recursively.

This enumeration is used to specify how a device and its children are traversed.

Enumerator:
VisitThisOnly 

This value is used to indicate that only the device in question is visited.

VisitThisAndDirectChildren 

This value is used to indicate that this device and its embedded devices are visited.

VisitThisRecursively 

This value is used to indicate that this device and all of its child devices are visited recursively.

This enumeration specifies the device types that are considered as targets of an operation.

Enumerator:
AllDevices 

This value is used to indicate that all devices, both root and embedded are the targets of an operation.

EmbeddedDevices 

This value is used to indicate that only embedded devices are the targets of an operation.

RootDevices 

This value is used to indicate that only root devices are the targets of an operation.

This enumeration specifies the type of a device location URL.

Enumerator:
AbsoluteUrl 

The absolute URL for the device description.

BaseUrl 

The base URL of the device.

This is the URL with which the various other URLs found in a device description are resolved.


Function Documentation

QString H_UPNP_CORE_EXPORT upnpErrorCodeToString ( qint32  errCode)

Returns a string representation of the specified error code.

Parameters:
errCodespecififes the error code.
Returns:
a string representation of the specified error code.
H_UPNP_CORE_EXPORT const char * hupnpCoreVersion ( )

Returns the runtime version of the HUPnP Core library as a string.

You can use this function to query the version of the HUPnP core library at runtime.

For compile time checks you may use the macros:

  • HUPNP_CORE_MAJOR_VERSION,
  • HUPNP_CORE_MINOR_VERSION,
  • HUPNP_CORE_PATCH_VERSION and
  • HUPNP_CORE_VERSION.
Returns:
The runtime version of the HUPnP Core library as a string. The format is major.minor.patch.
Remarks:
The returned string is statically allocated. You should never delete or free it manually.
herqq-1.0.0/hupnp/docs/html/group__hupnp__devicemodel.html0000644000000000000000000012656511543637604022476 0ustar rootroot Herqq: Device Model

Device Model

This page explains the concept of HUPnP Device Model, which is the logical object hierarchy of HUPnP representing the UPnP Device Architecture. More...

Classes

class  HClientAction
 A client-side class that represents a server-side UPnP action. More...
class  HClientActionOp
 This class is used to identify a client-side action invocation and detail information of it. More...
class  HClientDevice
 This is a client-side class that represents a server-side UPnP device. More...
class  HClientService
 A client-side class that represents a server-side UPnP service. More...
class  HClientStateVariable
 A client-side class that represents a server-side UPnP state variable. More...
class  HActionArgument
 This is a class that represents an argument used in a UPnP action invocation. More...
class  HActionArguments
 A storage class for HActionArgument instances. More...
class  HActionSetup
 This class is used to specify information that can be used to setup an HServerAction or validate a UPnP action. More...
class  HActionsSetupData
 This class is used to specify information that can be used to setup HServerAction instances or generally validate the actions of a UPnP service. More...
class  HAsyncOp
 This abstract class is used as a base for identifying an asynchronous operation and detail information of it. More...
class  HDeviceModelInfoProvider
 A protocol class for providing information that is used to validate components of UPnP's device architecture and to setup components of HUPnP's device model. More...
class  HDeviceSetup
 This class is used to specify information that can be used to validate a UPnP device. More...
class  HDevicesSetupData
 This class is used to specify information that can be used to validate UPnP devices. More...
class  HExecArgs
 This class is used to specify information used to control the execution of an asynchronous operation and the notification of its completion. More...
class  HServiceSetup
 This class is used to specify information that can be used to validate a UPnP service. More...
class  HServicesSetupData
 This class is used to specify information that can be used to validate UPnP services. More...
class  HStateVariableEvent
 This is a class used to transfer state variable event information. More...
class  HStateVariablesSetupData
 This class is used to specify information that can be used to validate UPnP state variables. More...
class  HDeviceModelCreator
 A protocol class for creating HServerDevice and HServerService instances. More...
class  HServerAction
 A class that represents a server-side UPnP action. More...
class  HServerDevice
 This is an abstract base class for server-side UPnP devices hosted by HDeviceHost. More...
class  HServerService
 This is an abstract base class for server-side UPnP services. More...
class  HServerStateVariable
 This is a class that represents a server-side UPnP state variable. More...

Typedefs

typedef Functor< int,
H_TYPELIST_2(const
Herqq::Upnp::HActionArguments
&, Herqq::Upnp::HActionArguments *) 
HActionInvoke )
typedef Functor< bool,
H_TYPELIST_2(HClientAction
*, const HClientActionOp &) 
HActionInvokeCallback )
typedef QHash< QString,
HActionInvoke > 
HActionInvokes
typedef QList< HClientService * > HClientServices
typedef QList< HServerService * > HServerServices
typedef QList< HClientDevice * > HClientDevices
typedef QList< HServerDevice * > HServerDevices
typedef QHash< QString, const
HClientStateVariable * > 
HClientStateVariables
typedef QHash< QString,
HServerStateVariable * > 
HServerStateVariables
typedef QHash< QString,
HStateVariableInfo > 
HStateVariableInfos
typedef QHash< QString,
HClientAction * > 
HClientActions
typedef QHash< QString,
HServerAction * > 
HServerActions

Detailed Description

This page explains the concept of HUPnP Device Model, which is the logical object hierarchy of HUPnP representing the UPnP Device Architecture.

A few notes about the design

The main four components of the UPnP device model are a device, a service, a state variable and an action. These four components form a type of a tree in which devices and services are contained by devices, and state variables and actions are contained by services. This is called the device tree. A device tree has a root device, which is a UPnP device that has no parent, but may contain other UPnP devices. These contained devices are called embedded devices.

HUPnP's device model mimicts this design closely. At server-side the main four components are HServerDevice, HServerService, HServerStateVariable and HServerAction. At client-side the main four components are HClientDevice, HClientService, HClientStateVariable and HClientAction.

The purpose of the other classes part of the HUPnP's device model is to support the initialization and use of the four core components both at the server and client-side.

API differences between client and server sides

The HUPnP device model is largely the same at the server and client sides. That is, whether you are writing a custom UPnP device or trying to interact with a UPnP device found in the network, you will be interacting with the HUPnP device model in a similar manner. Regardless of that, there are some important differences, which is why the server and client-side define and use different types that do not share ancestors provided by HUPnP.

First and most importantly, server side contains the "businness" logic of a UPnP device and clients only invoke or use it. This logic should not be duplicated to the client-side, as it serves no purpose there. Having a design that explicitly states this separation of concerns at type level should certainly help in making the purpose of each type clear.

Second, UPnP clients are unable to modify server-side state variables directly and in a uniform manner. This is because UPnP Device Architecture does not specify a mechanism for changing the value of a state variable from client-side. Certainly the value of a state variable may be changeable, but that and the way it is done depends of the service type in which the state variable is defined. On the other hand, server-side has to have direct read-write access to the state variables. This type of difference should be explicit in the design.

Third, client-side action invocation should naturally be asynchronous to the user, as the call most often involves network access. On the server-side the action invocations are direct method calls and as such the burden of running them "asynchronously" with the help of worker threads should reside at the user code.

The lifetime and ownership of objects

Every device (HClientDevice and HServerDevice) has the ownership of all of its embedded devices, services, actions and state variables and the ownership is never released. This means that every device always manages the memory used by the objects it owns. Hence, the owner of a root device ultimately has the ownership of an entire device tree.

This is a very important point to remember: the lifetime of every object contained by the root device depends of the lifetime of the root device.

In other words, when a root device is deleted, every embedded device, service, state variable and action underneath it are deleted as well. Furthermore, every root device is always owned by HUPnP and the ownership is never released. Because of this you must never call delete to any of the components of the device model that is setup by HUPnP. Failing to follow this rule will result in undefined behavior.

Note:
There are situations where you may want to instruct HUPnP to delete a device. For instance, when a UPnP device is removed from the network you may want your HControlPoint instance to remove the device that is no longer available. This can be done through the HControlPoint interface. But note, HUPnP never deletes a device object without an explicit request from a user.

Usage

Basic use is about interacting with already created objects that comprise the device model. To get started you need to initialize either a device host or a control point and retrieve a device or a list of devices from it. See Device Hosting for more information about device hosts and control points. Once you have access to a device you can interact with any of its embedded devices, services, state variables and actions until:

  • you explicitly request the root device of the device tree to be deleted,
  • delete the owner of a device tree, such as HControlPoint or HDeviceHost.

See the corresponding classes for more information concerning their use.

Note:
By default, HControlPoint keeps the state of the state variables up-to-date. That is, using default configuration an HControlPoint automatically subscribes to events the UPnP services expose. In such a case the state of a device tree the control point maintains reflects the state of the corresponding device tree at server-side as accurately as the server keeps sending events.

If you wish to implement and host your own UPnP device things get more involved. See Tutorial for Building a UPnP Device to get started on building your own UPnP devices using HUPnP.


Typedef Documentation

typedef Functor<int, H_TYPELIST_2( const Herqq::Upnp::HActionArguments&, Herqq::Upnp::HActionArguments*) HActionInvoke)

This is a type definition for a callable entity that is used for HServerAction invocation.

You can create HActionInvoke objects using normal functions, functors and member functions that follow the signature of

qint32 function(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs = 0);

The following example demonstrates how you can instantiate the HActionInvoke for a normal function, functor and a member function.

 #include <HActionInvoke>
 #include <HUpnpCore/HActionArguments>

 #include "myclass.h" // your code that contains declaration for MyClass

 namespace
 {
 qint32 freefun(
      const Herqq::Upnp::HActionArguments& inArgs,
      Herqq::Upnp::HActionArguments* outArgs)
 {
     return 0;
 }

 class MyFunctor
 {
 public:
     qint32 operator()(
         const Herqq::Upnp::HActionArguments& inArgs,
         Herqq::Upnp::HActionArguments* outArgs)
     {
         return 0;
     }
 };
 }

 qint32 MyClass::memfun(
      const Herqq::Upnp::HActionArguments& inArgs,
      Herqq::Upnp::HActionArguments* outArgs = 0)
 {
 }

 void MyClass::example()
 {
     Herqq::Upnp::HActionInvoke usingFreeFunction(freefun);

     MyFunctor myfunc;
     Herqq::Upnp::HActionInvoke usingFunctor(myfunc);

     Herqq::Upnp::HActionInvoke usingMemberFunction(this, &MyClass::memfun);
 }

You can test if the object can be invoked simply by issuing if (actionInvokeObject) { ... }

typedef Functor<bool, H_TYPELIST_2( HClientAction*, const HClientActionOp&) HActionInvokeCallback)

This is a type definition for a callable entity that is used as a callback for signaling the completion of an HClientAction invocation.

You can create HActionInvokeCallback objects using normal functions, functors and member functions that follow the signature of

bool function(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&);

Parameters

  • The first parameter is a type of an "ID" of the asynchronous action invocation.
  • The second parameter specifies the output arguments of the action invocation, which may be empty.

Return value

The return value indicates if the invoked HClientAction should emit an HClientAction::invokeComplete() after the callback has returned.

  • true indicates that the HClientAction should sent the corresponding event.

The following example demonstrates how you can instantiate the HActionInvokeCallback for a normal function, functor and a member function.

 #include <HUpnpCore/HClientAction>

 #include "myclass.h" // your code that contains declaration for MyClass

 namespace
 {
 bool freefun(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&)
 {
     return true;
 }

 class MyFunctor
 {
 public:
     bool operator()(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&)
     {
         return true;
     }
 };
 }

 bool MyClass::memfun(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&)
 {
     return true;
 }

 void MyClass::example()
 {
     Herqq::Upnp::HActionInvokeCallback usingFreeFunction(freefun);

     MyFunctor myfunc;
     Herqq::Upnp::HActionInvokeCallback usingFunctor(myfunc);

     Herqq::Upnp::HActionInvokeCallback usingMemberFunction(this, &MyClass::memfun);
 }

You can test if the object can be invoked simply by issuing if (actionInvokeCallbackObject) { ... }

typedef QHash<QString, HActionInvoke> HActionInvokes [protected, inherited]

This is a type definition for a hash table containing HActionInvoke objects keyed with strings representing the names of the actions.

See also:
HActionInvoke
typedef QList<HClientService*> HClientServices

This is a type definition to a list of pointers to Herqq::Upnp::HClientService instances.

See also:
HClientService
typedef QList<HServerService*> HServerServices

This is a type definition to a list of pointers to Herqq::Upnp::HServerService instances.

See also:
HServerService
typedef QList<HClientDevice*> HClientDevices

This is a type definition to a list of pointers to Herqq::Upnp::HClientDevice instances.

See also:
HClientDevice
typedef QList<HServerDevice*> HServerDevices

This is a type definition to a list of pointers to Herqq::Upnp::HServerDevice instances.

See also:
HServerDevice
typedef QHash<QString, const HClientStateVariable*> HClientStateVariables

This is a type definition to a hash table of pointers to const Herqq::Upnp::HServerStateVariable instances keyed with the state variable names.

See also:
HClientStateVariable
typedef QHash<QString, HServerStateVariable*> HServerStateVariables

This is a type definition to a hash table of pointers to Herqq::Upnp::HServerStateVariable instances keyed with the state variable names.

See also:
HServerStateVariable
typedef QHash<QString, HStateVariableInfo> HStateVariableInfos

This is a type definition to a hash table of Herqq::Upnp::HStateVariableInfo instances keyed with the state variable names.

See also:
HStateVariableInfo
typedef QHash<QString, HClientAction*> HClientActions

This is a type definition to a hash table of pointers to Herqq::Upnp::HClientAction instances keyed with the action names.

See also:
HClientAction
typedef QHash<QString, HServerAction*> HServerActions

This is a type definition to a hash table of pointers to Herqq::Upnp::HServerAction instances keyed with the action names.

See also:
HServerAction
herqq-1.0.0/hupnp/docs/html/modules.html0000644000000000000000000000365711543637604016736 0ustar rootroot Herqq: Modules

Modules

Here is a list of all modules:
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_model_creator-members.html0000644000000000000000000001204011543637604030074 0ustar rootroot Herqq: Member List

HDeviceModelCreator Member List

This is the complete list of members for HDeviceModelCreator, including all inherited members.
clone() const HDeviceModelCreator [virtual]
createDevice(const HDeviceInfo &info) const HDeviceModelCreator [virtual]
createService(const HServiceInfo &serviceInfo, const HDeviceInfo &parentDeviceInfo) const =0HDeviceModelCreator [pure virtual]
doClone(HClonable *target) const HClonable [protected, virtual]
HClonable()HClonable
HDeviceModelCreator()HDeviceModelCreator
newInstance() const =0HClonable [protected, pure virtual]
~HClonable()HClonable [virtual]
~HDeviceModelCreator()HDeviceModelCreator [virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_control_point_configuration.png0000644000000000000000000000074511543637604027757 0ustar rootroot‰PNG  IHDR¦P¤þAPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2tIDATxíA’Ä EÅ®òþGž Ñ$Ý“Q¦?‹á!nÃË…„Wt ÀæÃ$}‰fd9\þ+LFÝSÂ'6ÆH‘Jšu¦ËË13ñk7›•ÆS˜,6fsÔª\9˦žq‹™›m/Ìnø ‹~µÓm¾¥µiþ7«·<£µŽË˜Àæcºð€¤'œ~+fJ.8}`¦ä‚Ó &:˜À&0 L`˜À&0 L`nI.$‡ó&0·ÇäJï†Ç)w a0vÎZ–º@CLŽrÓ´»ãÄÞz ³Ê q@âÔeã¢U’JSL§NJRËç¨Û²µÞt†Yb³.{­bVY˜9©¶ÛvS‹™ÿö}„fh"IîÏœ.õ“ûõkÙbvvŸ`J޶Æ4}†iÔÜ}̹“ªXßÇ”_^[zÒ4M§w‰m:Ѧ©‡bGºp¨Ûe·Ð½°K0ëöÞùN7/Òý0ßÈ?0¹-¦ ù¹Ä$ aëÂIEND®B`‚herqq-1.0.0/hupnp/docs/html/tabs.css0000644000000000000000000000210711543637604016030 0ustar rootroot.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } herqq-1.0.0/hupnp/docs/html/functions_func_0x74.html0000644000000000000000000001431511543637604021064 0ustar rootroot Herqq: Class Members - Functions herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_discovery_response.html0000644000000000000000000007153611543637604026252 0ustar rootroot Herqq: HDiscoveryResponse Class Reference

HDiscoveryResponse Class Reference

This is a class that represents a response to a HDiscoveryRequest. More...

#include <HDiscoveryResponse>

List of all members.

Public Member Functions

 HDiscoveryResponse ()
 HDiscoveryResponse (qint32 cacheControlMaxAge, const QDateTime &date, const QUrl &location, const HProductTokens &serverTokens, const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=0, qint32 searchPort=-1)
 HDiscoveryResponse (const HDiscoveryResponse &)
HDiscoveryResponseoperator= (const HDiscoveryResponse &)
 ~HDiscoveryResponse ()
bool isValid (HValidityCheckLevel level) const
const HProductTokensserverTokens () const
QDateTime date () const
const HDiscoveryTypeusn () const
QUrl location () const
qint32 cacheControlMaxAge () const
qint32 bootId () const
qint32 configId () const
qint32 searchPort () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HDiscoveryResponse &, const HDiscoveryResponse &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HDiscoveryResponse &obj1, const HDiscoveryResponse &obj2)

Detailed Description

This is a class that represents a response to a HDiscoveryRequest.

Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, or you receive instances of this class from the Herqq::Upnp::HSsdp.

Remarks:
the class provides an assignment operator, which is not thread-safe.
See also:
HSsdp

Constructor & Destructor Documentation

Constructs a new, empty instance.

The constructed object is not valid, i.e isValid() returns false.

See also:
isValid()
HDiscoveryResponse ( qint32  cacheControlMaxAge,
const QDateTime &  date,
const QUrl &  location,
const HProductTokens serverTokens,
const HDiscoveryType usn,
qint32  bootId = -1,
qint32  configId = 0,
qint32  searchPort = -1 
)

Constructs a new instance using the specified parameters.

The constructed object will be invalid, i.e. isValid() returns false in case the provided information is invalid.

Parameters:
cacheControlMaxAgespecifies the number of seconds the advertisement is valid.
date
locationspecifies the URL to the UPnP description of the root device. If the location is invalid or empty the created object will be invalid.
serverTokensspecifies information about the host, the UPnP version used and of the product. Note that if this parameter specifies UPnP version 1.1 or later, bootId and configId have to be properly defined. Otherwise the created object will be invalid.
Note:
Although server tokens are mandatory according to the UDA, this is not enforced by this class for interoperability reasons.
Parameters:
usnspecifies the Unique Service Name. The created object is valid only if the provided USN is valid.
bootIdspecifies the BOOTID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0. Because of this the class requires a valid value (>= 0) only in case the serverTokens identify UPnP v1.1 or later.
configIdspecifies the CONFIGID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0. Because of this, the class requires a valid value (>= 0) only in case the serverTokens identify UPnP v1.1 or later.
searchPortspecifies the SEARCHPORT.UPNP.ORG header value. Note that this is optional in UDA v1.1, whereas it is not specified at all in UDA v1.0. If specified, this is the port at which the device must listen for unicast M-SEARCH messages. Otherwise the port is the default 1900. This parameter is optional.
Remarks:
  • if cacheControlMaxAge is smaller than 5, it it set to 5 or if it is larger than 60 * 60 * 24 (a day in seconds), it is set to a day measured in seconds.
  • if searchPort is smaller than 49152 or larger than 65535 it is set to -1. The range is specified in UDA v1.1.
See also:
isValid()

Copy constructor.

Copies the contents of other to this.

Destroys the instance.


Member Function Documentation

HDiscoveryResponse & operator= ( const HDiscoveryResponse other)

Assigns the contents of the other to this.

Makes a deep copy.

Returns:
reference to this object.
bool isValid ( HValidityCheckLevel  level) const

Indicates whether or not the object contains valid announcement information.

Parameters:
levelindicates whether the check should be strictly according to the UDA specification. If set to false some checks are omitted that are known to be poorly implemented in some UPnP software.
Returns:
true in case the objects contains valid announcement information in terms of the requested strictness.
const HProductTokens & serverTokens ( ) const

Returns the server tokens.

Returns:
The server tokens.
QDateTime date ( ) const

Returns the date when the response was generated.

Returns:
The date when the response was generated.
const HDiscoveryType & usn ( ) const

Returns the Unique Service Name.

The Unique Service Name identifies a unique device or service instance.

Returns:
The Unique Service Name. The returned object is invalid if this object is invalid.
See also:
isValid()
QUrl location ( ) const

Returns the location of the announced device.

Returns:
The location of the announced device. This is the URL where the device description can be retrieved. The returned object will be empty if this object is invalid.
See also:
isValid()
qint32 cacheControlMaxAge ( ) const

Returns the number of seconds the advertisement is valid.

Returns:
The number of seconds the advertisement is valid.
qint32 bootId ( ) const

Returns the value of BOOTID.UPNP.ORG.

Returns:
The value of BOOTID.UPNP.ORG. If the value is not specified -1 is returned.
qint32 configId ( ) const

Returns the value of CONFIGID.UPNP.ORG.

Returns:
The value of CONFIGID.UPNP.ORG. If the value is not specified -1 is returned.
qint32 searchPort ( ) const

Returns the value of SEARCHPORT.UPNP.ORG header field.

Returns:
The value of SEARCHPORT.UPNP.ORG header field. If the value is not specified -1 is returned.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HDiscoveryResponse ,
const HDiscoveryResponse  
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically the equivalent.
bool operator!= ( const HDiscoveryResponse obj1,
const HDiscoveryResponse obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically the equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_discovery_response-members.html0000644000000000000000000001622411543637604027673 0ustar rootroot Herqq: Member List

HDiscoveryResponse Member List

This is the complete list of members for HDiscoveryResponse, including all inherited members.
bootId() const HDiscoveryResponse
cacheControlMaxAge() const HDiscoveryResponse
configId() const HDiscoveryResponse
date() const HDiscoveryResponse
HDiscoveryResponse()HDiscoveryResponse
HDiscoveryResponse(qint32 cacheControlMaxAge, const QDateTime &date, const QUrl &location, const HProductTokens &serverTokens, const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=0, qint32 searchPort=-1)HDiscoveryResponse
HDiscoveryResponse(const HDiscoveryResponse &)HDiscoveryResponse
isValid(HValidityCheckLevel level) const HDiscoveryResponse
location() const HDiscoveryResponse
operator!=(const HDiscoveryResponse &obj1, const HDiscoveryResponse &obj2)HDiscoveryResponse [related]
operator=(const HDiscoveryResponse &)HDiscoveryResponse
operator==(const HDiscoveryResponse &, const HDiscoveryResponse &)HDiscoveryResponse [friend]
searchPort() const HDiscoveryResponse
serverTokens() const HDiscoveryResponse
usn() const HDiscoveryResponse
~HDiscoveryResponse()HDiscoveryResponse
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_model_info_provider.html0000644000000000000000000004207211543637604027662 0ustar rootroot Herqq: HDeviceModelInfoProvider Class Reference

HDeviceModelInfoProvider Class Reference

A protocol class for providing information that is used to validate components of UPnP's device architecture and to setup components of HUPnP's device model. More...

#include <HDeviceModelInfoProvider>

Inheritance diagram for HDeviceModelInfoProvider:
HClonable

List of all members.

Public Member Functions

 HDeviceModelInfoProvider ()
virtual ~HDeviceModelInfoProvider ()=0
virtual HServicesSetupData servicesSetupData (const HDeviceInfo &info) const
virtual HDevicesSetupData embedddedDevicesSetupData (const HDeviceInfo &info) const
virtual HActionsSetupData actionsSetupData (const HServiceInfo &serviceInfo, const HDeviceInfo &parentDeviceInfo) const
virtual HStateVariablesSetupData stateVariablesSetupData (const HServiceInfo &serviceInfo, const HDeviceInfo &parentDeviceInfo) const
virtual HDeviceModelInfoProviderclone () const

Detailed Description

A protocol class for providing information that is used to validate components of UPnP's device architecture and to setup components of HUPnP's device model.

The main purpose of this class is to define an interface that enables the users to provide information that HUPnP can use for verification and validation purposes. Although optional, this information can be especially useful when provided to HDeviceHost via HDeviceHostConfiguration. This enables HUPnP to use the information to verify that device and service descriptions are setup according to the specified information.

The benefit of this is that your custom device model components can rest assured that all the required state variables, actions, services and embedded devices are properly defined and initialized before the instantiation of the HUPnP's device model (device tree) is published for control points to use.

The benefits of this may be somewhat difficult to realize at first, since most of the time it is you, the user, who provides the implementation and the description documents. Apart from inadvertent mistakes, you usually get those right. However, when someone else provides the implementation of the HUPnP's device model or the description documents, mismatches can easily occur and this is where the benefits of this additional information are truly useful. Remember, in UPnP architecture the description documents are used to marshal device model information from servers to clients. If the description documents do not accurately reflect the server-side implementation, the client-side may not be able to correctly invoke the server-side.

See also:
Device Hosting, HDeviceHostConfiguration

Constructor & Destructor Documentation

Creates a new instance.

~HDeviceModelInfoProvider ( ) [pure virtual]

Destroys the instance.


Member Function Documentation

HServicesSetupData servicesSetupData ( const HDeviceInfo info) const [virtual]

Returns information of the services the specified device type may contain.

Parameters:
infospecifies the device type.
Returns:
information of the services the specified device type may contain.
HDevicesSetupData embedddedDevicesSetupData ( const HDeviceInfo info) const [virtual]

Returns information of the embedded devices the specified device type may contain.

Parameters:
infospecifies the device type.
Returns:
information of the embedded devices the specified device type may contain.
HActionsSetupData actionsSetupData ( const HServiceInfo serviceInfo,
const HDeviceInfo parentDeviceInfo 
) const [virtual]

Returns information of the actions the specified service type may contain.

Parameters:
serviceInfospecifies the service type.
parentDeviceInfospecifies information about the parent UPnP device that contains this service.
Returns:
information of the actions the specified service type may contain.
HStateVariablesSetupData stateVariablesSetupData ( const HServiceInfo serviceInfo,
const HDeviceInfo parentDeviceInfo 
) const [virtual]

Returns information of the state variables the specified service type may contain.

Parameters:
serviceInfospecifies the service type.
parentDeviceInfospecifies information about the parent UPnP device that contains this service.
Returns:
information of the state variables the specified service type may contain.
HDeviceModelInfoProvider * clone ( ) const [virtual]

Returns a deep copy of the instance.

Returns:
a deep copy of the instance.
Remarks:
  • the ownership of the returned object is transferred to the caller.

Reimplemented from HClonable.

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_device-members.html0000644000000000000000000001347511543637604026550 0ustar rootroot Herqq: Member List

HClientDevice Member List

This is the complete list of members for HClientDevice, including all inherited members.
description() const HClientDevice
embeddedDevices() const HClientDevice
embeddedDevicesByType(const HResourceType &deviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const HClientDevice
HClientDevice(const HDeviceInfo &info, HClientDevice *parentDev=0)HClientDevice [protected]
info() const HClientDevice
locations(LocationUrlType urlType=AbsoluteUrl) const HClientDevice
parentDevice() const HClientDevice
rootDevice() const HClientDevice
serviceById(const HServiceId &serviceId) const HClientDevice
services() const HClientDevice
servicesByType(const HResourceType &serviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const HClientDevice
~HClientDevice()=0HClientDevice [pure virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_ssdp.html0000644000000000000000000016661111543637604023275 0ustar rootroot Herqq: HSsdp Class Reference

This class is used for sending and receiving SSDP messages defined by the UPnP Device Architecture specification. More...

#include <HSsdp>

Inherited by HControlPointSsdpHandler, and HDeviceHostSsdpHandler.

List of all members.

Public Types

enum  DiscoveryRequestMethod { MulticastDiscovery, UnicastDiscovery }
enum  AllowedMessage {
  None = 0x00, DeviceAvailable = 0x01, DeviceUpdate = 0x02, DeviceUnavailable = 0x04,
  DiscoveryRequest = 0x08, DiscoveryResponse = 0x10, All = 0x1f
}

Signals

void discoveryRequestReceived (const Herqq::Upnp::HDiscoveryRequest &msg, const Herqq::Upnp::HEndpoint &source, Herqq::Upnp::HSsdp::DiscoveryRequestMethod requestType)
void discoveryResponseReceived (const Herqq::Upnp::HDiscoveryResponse &msg, const Herqq::Upnp::HEndpoint &source)
void resourceAvailableReceived (const Herqq::Upnp::HResourceAvailable &msg, const Herqq::Upnp::HEndpoint &source)
void deviceUpdateReceived (const Herqq::Upnp::HResourceUpdate &msg, const Herqq::Upnp::HEndpoint &source)
void resourceUnavailableReceived (const Herqq::Upnp::HResourceUnavailable &msg, const Herqq::Upnp::HEndpoint &source)

Public Member Functions

 HSsdp (QObject *parent=0)
virtual ~HSsdp ()
void setFilter (AllowedMessages allowedMessages)
AllowedMessages filter () const
bool init ()
bool init (const QHostAddress &unicastAddress)
bool isInitialized () const
HEndpoint unicastEndpoint () const
qint32 announcePresence (const HResourceAvailable &msg, qint32 count=1)
qint32 announcePresence (const HResourceUnavailable &msg, qint32 count=1)
qint32 announceUpdate (const HResourceUpdate &msg, qint32 count=1)
qint32 sendDiscoveryRequest (const HDiscoveryRequest &msg, qint32 count=1)
qint32 sendDiscoveryRequest (const HDiscoveryRequest &msg, const HEndpoint &destination, qint32 count=1)
qint32 sendDiscoveryResponse (const HDiscoveryResponse &msg, const HEndpoint &destination, qint32 count=1)

Protected Member Functions

virtual bool incomingDiscoveryRequest (const HDiscoveryRequest &msg, const HEndpoint &source, DiscoveryRequestMethod requestType)
virtual bool incomingDiscoveryResponse (const HDiscoveryResponse &msg, const HEndpoint &source)
virtual bool incomingDeviceAvailableAnnouncement (const HResourceAvailable &msg, const HEndpoint &source)
virtual bool incomingDeviceUnavailableAnnouncement (const HResourceUnavailable &msg, const HEndpoint &source)
virtual bool incomingDeviceUpdateAnnouncement (const HResourceUpdate &msg, const HEndpoint &source)

Detailed Description

This class is used for sending and receiving SSDP messages defined by the UPnP Device Architecture specification.

Simple Service Discovery Protocol (SSDP) is an expired IETF Internet draft on which the UPnP discovery mechanism is built. This class implements only the SSDP functionality mandated by the UPnP Device Architecture specification. This class does not implement the SSDP draft in full.

To use this class, you only need to instantiate it and connect to the exposed signals to receive events when SSDP messages are received. You can also derive a sub-class and override the various virtual member functions to handle the received messages.

Remarks:
  • this class requires an event loop for listening incoming messages
  • this class has thread-affinity, which mandates that the instances of this class has to be used in the thread in which they are located at the time.

Member Enumeration Documentation

This enumeration specifies the different discovery methods the HSsdp class can run.

Enumerator:
MulticastDiscovery 

This is the default multicast discovery supported both UDA v1.0 and UDA v1.1.

UnicastDiscovery 

The unicast discovery specified in UDA v1.1.

This enum is used to define a "filter", which specifies which message types are to be processed when encountered.

See also:
filter(), setFilter()
Enumerator:
None 

No messages are processed.

DeviceAvailable 

Device available messages are processed.

DeviceUpdate 

Device update messages are processed.

DeviceUnavailable 

Device unavailable messages are processed.

DiscoveryRequest 

Discovery request messages are processed.

DiscoveryResponse 

Discovery response messages are processed.

All 

Discovery response messages are processed.


Constructor & Destructor Documentation

HSsdp ( QObject *  parent = 0)

Creates a new instance.

Parameters:
parentspecifies the parent QObject.
~HSsdp ( ) [virtual]

Destroys the instance.


Member Function Documentation

bool incomingDiscoveryRequest ( const HDiscoveryRequest msg,
const HEndpoint source,
DiscoveryRequestMethod  requestType 
) [protected, virtual]

This method is called immediately after receiving a discovery request.

Override this method if you want to handle the message. You can also connect to the discoveryRequestReceived() signal.

Parameters:
msgspecifies the incoming message.
sourcespecifies the source TCP/IP endpoint that sent the message.
requestTypespecifies the type of the incoming discovery request.
Return values:
truein case the message was handled successfully and the discoveryRequestReceived() signal should not be sent.
falsein case the message was not handled and the discoveryRequestReceived() signal should be sent.
See also:
discoveryRequestReceived()
bool incomingDiscoveryResponse ( const HDiscoveryResponse msg,
const HEndpoint source 
) [protected, virtual]

This method is called immediately after receiving a discovery response.

Override this method if you want to handle message. You can also connect to the discoveryResponseReceived() signal.

Parameters:
msgspecifies the incoming message.
sourcespecifies the source TCP/IP endpoint that sent the message.
Return values:
truein case the message was handled successfully and the discoveryResponseReceived() signal should not be sent.
falsein case the message was not handled and the discoveryResponseReceived() signal should be sent.
See also:
discoveryResponseReceived()
bool incomingDeviceAvailableAnnouncement ( const HResourceAvailable msg,
const HEndpoint source 
) [protected, virtual]

This method is called immediately after receiving a device available announcement.

Override this method if you want to handle message. You can also connect to the discoveryRequestReceived() signal.

Parameters:
msgspecifies the incoming message.
sourcespecifies the source TCP/IP endpoint that sent the message.
Return values:
truein case the message was handled successfully and the resourceAvailableReceived() signal should not be sent.
falsein case the message was not handled and the resourceAvailableReceived() signal should be sent.
See also:
resourceAvailableReceived()
bool incomingDeviceUnavailableAnnouncement ( const HResourceUnavailable msg,
const HEndpoint source 
) [protected, virtual]

This method is called immediately after receiving a device unavailable announcement.

Override this method if you want to handle message. You can also connect to the resourceUnavailableReceived() signal.

Parameters:
msgspecifies the incoming message.
sourcespecifies the source TCP/IP endpoint that sent the message.
Return values:
truein case the message was handled successfully and the resourceUnavailableReceived() signal should not be sent.
falsein case the message was not handled and the resourceUnavailableReceived() signal should be sent.
See also:
resourceUnavailableReceived()
bool incomingDeviceUpdateAnnouncement ( const HResourceUpdate msg,
const HEndpoint source 
) [protected, virtual]

This method is called immediately after receiving a device update announcement.

Override this method if you want to handle message. You can also connect to the deviceUpdateRecieved() signal.

Parameters:
msgspecifies the incoming message.
sourcespecifies the source TCP/IP endpoint that sent the message.
Return values:
truein case the message was handled successfully and the deviceUpdateRecieved() signal should not be sent.
falsein case the message was not handled and the deviceUpdateRecieved() signal should be sent.
See also:
deviceUpdateRecieved()
void setFilter ( AllowedMessages  allowedMessages)

Sets the filter of what message types are accepted for processing.

The default is HSsdp::All.

Parameters:
allowedMessagesdefines the message types the instance should accept for further processing. Other message types will be silently ignored.
See also:
filter()
HSsdp::AllowedMessages filter ( ) const

Returns the message types that are currently accepted for processing.

Default is HSsdp::All.

Returns:
The message types that are currently accepted for processing.
See also:
setFilter()
bool init ( )

Sets the instance to listen the network for SSDP messages and and attempts to init the unicast socket of the instance to the address of the first found network address that is up and that is not loopback.

If no such interface is found the loopback address is used.

Return values:
truein case the instances was successfully bound to some address.
falsein case the instance could not be bound or the instance was already bound.
Remarks:
HSsdp has to be bound to receive messages of any type.
bool init ( const QHostAddress &  unicastAddress)

Sets the instance to listen the network for SSDP messages and attempts to init a unicast socket of the instance to the specified address.

Parameters:
unicastAddressspecifies the address that should be used for unicast messaging.
Return values:
truein case the instance was successfully bound to the specified address.
falsein case the instance could not be bound or the instance was already bound to the specified address.
Remarks:
HSsdp has to be bound to receive messages of any type.
bool isInitialized ( ) const

Indicates if the instance is bound to listen for messages using one or more network interfaces.

Returns:
true in case the instance is bound to listen for messages using one or more network interfaces.
HEndpoint unicastEndpoint ( ) const

Returns the UDP endpoint that is used for unicast communication.

Returns:
The UDP endpoint that is used for unicast communication.
qint32 announcePresence ( const HResourceAvailable msg,
qint32  count = 1 
)

Sends the specified device availability announcement.

Parameters:
msgspecifies the announcement to send.
countspecifies how many times the announcement is send. The default is 1.
Returns:
The number of messages sent, 0 in case no messages was sent or -1 in case the provided message is not valid.
qint32 announcePresence ( const HResourceUnavailable msg,
qint32  count = 1 
)

Sends the specified device availability announcement.

Parameters:
msgspecifies the announcement to send.
countspecifies how many times the announcement is send. The default is 1.
Returns:
The number of messages sent, 0 in case no messages was sent or -1 in case the provided message is not valid.
qint32 announceUpdate ( const HResourceUpdate msg,
qint32  count = 1 
)

Sends the specified device update announcement.

Parameters:
msgspecifies the message to send.
countspecifies how many times the announcement is send. The default is 1.
Returns:
The number of messages sent, 0 in case no messages was sent or -1 in case the provided message is not valid.
qint32 sendDiscoveryRequest ( const HDiscoveryRequest msg,
qint32  count = 1 
)

Sends the specified discovery request.

Sends the specified discovery request to a multicast address 239.255.255.250.

Parameters:
msgspecifies the announcement to send.
countspecifies how many times the announcement is send. The default is 1.
Returns:
The number of messages sent, 0 in case no messages was sent or -1 in case the provided message is not valid.
qint32 sendDiscoveryRequest ( const HDiscoveryRequest msg,
const HEndpoint destination,
qint32  count = 1 
)

Sends the specified discovery request.

Sends the specified discovery request to a specified address. The address can be an unicast address or a multicast address.

Parameters:
msgspecifies the announcement to send.
destinationspecifies the target UDP endpoint of the message. If the port of the specified endpoint is set to zero the message is sent to the specified host address using the default port 1900.
countspecifies how many times the announcement is send. The default is 1.
Returns:
The number of messages sent, 0 in case no messages was sent or -1 in case the provided message or the destination is not valid.
qint32 sendDiscoveryResponse ( const HDiscoveryResponse msg,
const HEndpoint destination,
qint32  count = 1 
)

Sends the specified discovery response.

Parameters:
msgspecifies the announcement to send.
destinationspecifies the target of the response. If the port of the specified endpoint is set to zero the message is sent to the specified host address using the default port 1900.
countspecifies how many times the announcement is send. The default is 1.
Returns:
The number of messages sent, 0 in case no messages was sent or -1 in case the provided message is not valid.
void discoveryRequestReceived ( const Herqq::Upnp::HDiscoveryRequest msg,
const Herqq::Upnp::HEndpoint source,
Herqq::Upnp::HSsdp::DiscoveryRequestMethod  requestType 
) [signal]

This signal is emitted when a discovery request is received.

Parameters:
msgspecifies the received discovery request message.
sourcespecifies the location where the message came.
requestTypespecifies the type of the incoming discovery request.
void discoveryResponseReceived ( const Herqq::Upnp::HDiscoveryResponse msg,
const Herqq::Upnp::HEndpoint source 
) [signal]

This signal is emitted when a discovery response is received.

Parameters:
msgspecifies the received discovery response message.
sourcespecifies the location where the message came.
void resourceAvailableReceived ( const Herqq::Upnp::HResourceAvailable msg,
const Herqq::Upnp::HEndpoint source 
) [signal]

This signal is emitted when a device announcement is received.

Parameters:
msgspecifies the device announcement message.
sourcespecifies the location where the message came.
void deviceUpdateReceived ( const Herqq::Upnp::HResourceUpdate msg,
const Herqq::Upnp::HEndpoint source 
) [signal]

This signal is emitted when a device update is received.

Parameters:
msgspecifies the device update message.
sourcespecifies the location where the message came.
void resourceUnavailableReceived ( const Herqq::Upnp::HResourceUnavailable msg,
const Herqq::Upnp::HEndpoint source 
) [signal]

This signal is emitted when a device announcement is received.

Parameters:
msgspecifies the device announcement message.
sourcespecifies the location where the message came.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_services_setup_data.html0000644000000000000000000004522611543637604026356 0ustar rootroot Herqq: HServicesSetupData Class Reference

HServicesSetupData Class Reference

This class is used to specify information that can be used to validate UPnP services. More...

#include <HServicesSetupData>

List of all members.

Public Member Functions

 HServicesSetupData ()
 ~HServicesSetupData ()
HServiceSetup get (const HServiceId &id) const
bool contains (const HServiceId &id) const
bool isEmpty () const
int size () const
QSet< HServiceIdserviceIds () const
bool insert (const HServiceSetup &newItem, bool overWrite=false)
bool remove (const HServiceId &id)

Friends

H_UPNP_CORE_EXPORT bool operator== (const HServicesSetupData &, const HServicesSetupData &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HServicesSetupData &obj1, const HServicesSetupData &obj2)

Detailed Description

This class is used to specify information that can be used to validate UPnP services.

Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isEmpty()

Destroys the instance.


Member Function Documentation

HServiceSetup get ( const HServiceId id) const

Retrieves a service setup object.

Parameters:
idspecifies the service ID of the item.
Returns:
The item with the specified service ID. Note that the returned item is invalid, i.e. HServiceSetup::isValid() returns false in case no item with the specified service ID was found.
See also:
contains()
bool contains ( const HServiceId id) const

Indicates if the instance contains a service setup item that has the specified service ID.

Parameters:
idspecifies the service ID of the item.
Returns:
true if the instance contains an item with the specified service ID.
See also:
get()
bool isEmpty ( ) const

Indicates if the object is empty.

Returns:
true in case the instance has no items.
int size ( ) const

Returns the number of contained items.

Returns:
The number of contained items.
QSet< HServiceId > serviceIds ( ) const

Returns the service IDs of the contained items.

Returns:
The service IDs of the contained items.
bool insert ( const HServiceSetup newItem,
bool  overWrite = false 
)

Inserts a new item.

Parameters:
newItemspecifies the item to be added.
overWritespecifies whether to replace an already existing item with the same service ID. The default is false.
Returns:
true in case the item was added. The newItem will not be added if the instance already contains an item that has the same HServiceSetup::serviceId() as the newItem and the overWrite is false, or the newItem is invalid.
bool remove ( const HServiceId id)

Removes an existing item.

Parameters:
idspecifies the service ID of the item to be removed.
Returns:
true in case the item was found and removed.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HServicesSetupData ,
const HServicesSetupData  
) [friend]

Compares the two objects for equality.

Returns:
true in case the provided objects are equal, false otherwise.
bool operator!= ( const HServicesSetupData obj1,
const HServicesSetupData obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the provided objects are not equal, false otherwise.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_service-members.html0000644000000000000000000001266111543637604026745 0ustar rootroot Herqq: Member List

HClientService Member List

This is the complete list of members for HClientService, including all inherited members.
actions() const HClientService
description() const HClientService
HClientService(const HServiceInfo &info, HClientDevice *parentDevice)HClientService [protected]
info() const HClientService
isEvented() const HClientService
notifyListeners()HClientService [slot]
parentDevice() const HClientService
stateChanged(const Herqq::Upnp::HClientService *source)HClientService [signal]
stateVariables() const HClientService
value(const QString &stateVarName, bool *ok=0) const HClientService
~HClientService()=0HClientService [pure virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_services_setup_data-members.html0000644000000000000000000001320311543637604027774 0ustar rootroot Herqq: Member List

HServicesSetupData Member List

This is the complete list of members for HServicesSetupData, including all inherited members.
contains(const HServiceId &id) const HServicesSetupData
get(const HServiceId &id) const HServicesSetupData
HServicesSetupData()HServicesSetupData
insert(const HServiceSetup &newItem, bool overWrite=false)HServicesSetupData
isEmpty() const HServicesSetupData
operator!=(const HServicesSetupData &obj1, const HServicesSetupData &obj2)HServicesSetupData [related]
operator==(const HServicesSetupData &, const HServicesSetupData &)HServicesSetupData [friend]
remove(const HServiceId &id)HServicesSetupData
serviceIds() const HServicesSetupData
size() const HServicesSetupData
~HServicesSetupData()HServicesSetupData
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_action-members.html0000644000000000000000000000744211543637604026613 0ustar rootroot Herqq: Member List

HServerAction Member List

This is the complete list of members for HServerAction, including all inherited members.
HServerAction(const HActionInfo &info, HServerService *parentService)HServerAction [protected]
info() const HServerAction
invoke(const HActionArguments &inArgs, HActionArguments *outArgs=0)HServerAction
parentService() const HServerAction
~HServerAction()=0HServerAction [pure virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_configuration-members.html0000644000000000000000000001356711543637604030143 0ustar rootroot Herqq: Member List

HDeviceConfiguration Member List

This is the complete list of members for HDeviceConfiguration, including all inherited members.
cacheControlMaxAge() const HDeviceConfiguration
clone() const HDeviceConfiguration [virtual]
doClone(HClonable *target) const HDeviceConfiguration [protected, virtual]
HClonable()HClonable
HDeviceConfiguration()HDeviceConfiguration
isValid() const HDeviceConfiguration
newInstance() const HDeviceConfiguration [protected, virtual]
pathToDeviceDescription() const HDeviceConfiguration
setCacheControlMaxAge(qint32 maxAge=1800)HDeviceConfiguration
setPathToDeviceDescription(const QString &pathToDeviceDescription)HDeviceConfiguration
~HClonable()HClonable [virtual]
~HDeviceConfiguration()HDeviceConfiguration [virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_actions_setup_data.html0000644000000000000000000004054611543637604026173 0ustar rootroot Herqq: HActionsSetupData Class Reference

HActionsSetupData Class Reference

This class is used to specify information that can be used to setup HServerAction instances or generally validate the actions of a UPnP service. More...

#include <HActionsSetupData>

List of all members.

Public Member Functions

 HActionsSetupData ()
bool insert (const HActionSetup &newItem)
bool remove (const QString &name)
HActionSetup get (const QString &name) const
bool setInclusionRequirement (const QString &name, HInclusionRequirement incReq)
bool contains (const QString &name) const
QSet< QString > names () const
qint32 size () const
bool isEmpty () const
void clear ()

Detailed Description

This class is used to specify information that can be used to setup HServerAction instances or generally validate the actions of a UPnP service.

Remarks:
This class is not thread-safe.
See also:
HActionSetup

Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isEmpty()

Member Function Documentation

bool insert ( const HActionSetup newItem)

Inserts a new item.

Parameters:
newItemspecifies the item to be added.
Returns:
true in case the item was added. The item will not be added if the instance already contains an item with the same name as newItem or the newItem is invalid.
See also:
remove()
bool remove ( const QString &  name)

Removes an existing item.

Parameters:
namespecifies the name of the item to be removed.
Returns:
true in case the item was found and removed.
See also:
insert()
HActionSetup get ( const QString &  name) const

Retrieves an action setup object.

Parameters:
namespecifies the name of the item to be retrieved.
Returns:
The item with the specified name. Note that the returned item is invalid, i.e. HActionSetup::isValid() returns false in case no item with the specified name was found.
See also:
contains()
bool setInclusionRequirement ( const QString &  name,
HInclusionRequirement  incReq 
)

This is a convenience method for setting the inclusion requirement element of an item.

Parameters:
namespecifies the name of the item.
incReqspecifies the inclusion requirement value.
Returns:
true when the item was found and the inclusion requirement element was set.
bool contains ( const QString &  name) const [inline]

Indicates if the instance contains an item with the specified name.

Parameters:
namespecifies the name of the item.
Returns:
true when the instance contains an item with the specified name.
See also:
get()
QSet< QString > names ( ) const

Returns the names of the contained items.

Returns:
The names of the contained items.
qint32 size ( ) const [inline]

Returns the number of contained items.

Returns:
The number of contained items.
bool isEmpty ( ) const [inline]

Indicates if the object is empty.

Returns:
true in case the instance has no items.
void clear ( ) [inline]

Removes every contained object.

herqq-1.0.0/hupnp/docs/html/functions_func_0x64.html0000644000000000000000000002216211543637604021062 0ustar rootroot Herqq: Class Members - Functions
 

- d -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_devices_setup_data-members.html0000644000000000000000000001161511543637604027600 0ustar rootroot Herqq: Member List

HDevicesSetupData Member List

This is the complete list of members for HDevicesSetupData, including all inherited members.
contains(const HResourceType &deviceType) const HDevicesSetupData
deviceTypes() const HDevicesSetupData
get(const HResourceType &type) const HDevicesSetupData
HDevicesSetupData()HDevicesSetupData
insert(const HDeviceSetup &newItem)HDevicesSetupData
isEmpty() const HDevicesSetupData
remove(const HResourceType &type)HDevicesSetupData
size() const HDevicesSetupData
~HDevicesSetupData()HDevicesSetupData
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_action.html0000644000000000000000000005233311543637604025132 0ustar rootroot Herqq: HClientAction Class Reference

A client-side class that represents a server-side UPnP action. More...

#include <HClientAction>

Inherited by HDefaultClientAction.

List of all members.

Signals

void invokeComplete (Herqq::Upnp::HClientAction *source, const Herqq::Upnp::HClientActionOp &operation)

Public Member Functions

virtual ~HClientAction ()=0
HClientServiceparentService () const
const HActionInfoinfo () const
HClientActionOp beginInvoke (const HActionArguments &inArgs, HExecArgs *execArgs=0)
HClientActionOp beginInvoke (const HActionArguments &inArgs, const HActionInvokeCallback &completionCallback, HExecArgs *execArgs=0)

Protected Member Functions

 HClientAction (const HActionInfo &info, HClientService *parent)

Detailed Description

A client-side class that represents a server-side UPnP action.

HClientAction is a core component of the HUPnP's client-side Device Model and it models a UPnP action. The UPnP Device Architecture specifies a UPnP action as a command, which takes one or more input and output arguments and that may have a return value.

This class is used to invoke the server-side UPnP actions from the client-side. You can get information of the action using info(), which includes the action's input and output arguments. You can dispatch an asynchronous action invocation to the server-side using beginInvoke(). Once the server responds, invokeComplete() signal is sent.

See also:
HActionInfo, HClientService
Remarks:
  • This class has thread-affinity.

Constructor & Destructor Documentation

HClientAction ( const HActionInfo info,
HClientService parent 
) [protected]

Creates a new instance.

Parameters:
infospecifies information of the action.
parentspecifies the UPnP service that contains this action.
~HClientAction ( ) [pure virtual]

Destroys the instance.

An HClientAction is always destroyed by the HClientAction that contains it when it is being deleted. Further, unless you hold the ownership of the HClientAction instance, you should never destroy it.


Member Function Documentation

HClientService* parentService ( ) const

Returns the parent service of the action.

Returns:
The parent service of the action.
Warning:
the pointer is guaranteed to point to a valid object as long as the HClientAction exists, which ultimately is as long as the containing root device exists.
See also:
HClientDevice
const HActionInfo& info ( ) const

Returns information about the action that is read from the service description.

Returns:
information about the action that is read from the service description.
HClientActionOp beginInvoke ( const HActionArguments inArgs,
HExecArgs execArgs = 0 
)

Schedules the action to be invoked.

The method performs an asynchronous action invocation. The invocation is placed in a queue and it will be run once it's at the head of the queue.

Unless you specified the action to be executed as fire and forget, the signal invokeComplete() is emitted once the invocation is complete.

Parameters:
inArgsspecifies the input arguments for the action invocation.
execArgsspecifies information used to control the execution of the action invocation procedure. This is optional.
Returns:
an object that identifies the asynchronous operation. This object will be sent through the invokeComplete() signal once the invocation is done.
See also:
invokeComplete()
HClientActionOp beginInvoke ( const HActionArguments inArgs,
const HActionInvokeCallback completionCallback,
HExecArgs execArgs = 0 
)

Schedules the action to be invoked.

The method performs an asynchronous action invocation. The invocation is placed in a queue and it will be run once it's at the head of the queue.

Unless you specified the action to be executed as fire and forget, the specified callback is called when the invocation is complete. No events are sent unless that is explicitly requested by returning true from the callback function.

The different semantics compared to the other beginInvoke() method are important to notice:

  • If a completion callback is valid, no event is sent unless the invoker explicitly requests that.
  • The callback is always invoked immediately after the invocation has succeeded or failed. If the callback returns true, the invokeComplete() signal will be emitted immediately after.
Parameters:
inArgsspecifies the input arguments for the action invocation
completionCallbackspecifies the callable entity that is called once the action invocation is completed or failed. If the specified callable entity is not valid and it cannot be called, the callable entity is ignored and the invokeComplete() signal is sent sent instead.
execArgsspecifies information used to control the execution of the action invocation procedure. This is optional.
Returns:
an object that identifies the asynchronous operation. This object will be sent through the callback and the invokeComplete() once the invocation is done.
See also:
invokeComplete()
void invokeComplete ( Herqq::Upnp::HClientAction source,
const Herqq::Upnp::HClientActionOp operation 
) [signal]

This signal is emitted when an invocation has been successfully completed or the invocation failed, unless the invocation was started as fire and forget.

Parameters:
sourceidentifies the HClientAction that ran the operation.
operationspecifies information of the operation that completed.
See also:
beginInvoke()
Remarks:
This signal has thread affinity to the thread where the object resides. Do not connect to this signal from other threads.
herqq-1.0.0/hupnp/docs/html/functions_0x69.html0000644000000000000000000004304211543637604020054 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- i -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_product_tokens-members.html0000644000000000000000000001534311543637604027012 0ustar rootroot Herqq: Member List

HProductTokens Member List

This is the complete list of members for HProductTokens, including all inherited members.
extraTokens() const HProductTokens
hasExtraTokens() const HProductTokens
HProductTokens()HProductTokens
HProductTokens(const QString &arg)HProductTokens [explicit]
HProductTokens(const HProductTokens &)HProductTokens
isEmpty() const HProductTokens
isValid() const HProductTokens
operator!=(const HProductTokens &obj1, const HProductTokens &obj2)HProductTokens [related]
operator=(const HProductTokens &)HProductTokens
operator==(const HProductTokens &, const HProductTokens &)HProductTokens [related]
osToken() const HProductTokens
productToken() const HProductTokens
tokens() const HProductTokens
toString() const HProductTokens
upnpToken() const HProductTokens
~HProductTokens()HProductTokens
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_multicast_socket.html0000644000000000000000000003464611543637604025703 0ustar rootroot Herqq: HMulticastSocket Class Reference

HMulticastSocket Class Reference

This is a class for multicast communication. More...

#include <HMulticastSocket>

List of all members.

Public Member Functions

 HMulticastSocket (QObject *parent=0)
virtual ~HMulticastSocket ()
bool joinMulticastGroup (const QHostAddress &groupAddress)
bool joinMulticastGroup (const QHostAddress &groupAddress, const QHostAddress &localAddress)
bool leaveMulticastGroup (const QHostAddress &groupAddress)
bool leaveMulticastGroup (const QHostAddress &groupAddress, const QHostAddress &localAddress)
bool setMulticastTtl (quint8 arg)
bool bind (quint16 port=0)

Detailed Description

This is a class for multicast communication.

Remarks:
this class has thread-affinity, which mandates that the instances of this class has to be used in the thread in which they are located at the time.

Constructor & Destructor Documentation

HMulticastSocket ( QObject *  parent = 0) [explicit]

Constructs a new instance.

Parameters:
parentspecifies the parent QObject.
~HMulticastSocket ( ) [virtual]

Destroys the instance.


Member Function Documentation

bool joinMulticastGroup ( const QHostAddress &  groupAddress)

Attempts to joins into the specified multicast group address.

Parameters:
groupAddressspecifies the multicast group address.
Return values:
truein case the operation succeeded.
falsein case the operation failed. For instance, this happens when the socket is not bound to a port.
bool joinMulticastGroup ( const QHostAddress &  groupAddress,
const QHostAddress &  localAddress 
)

Attempts to joins into the specified multicast group address using the specified local address.

Parameters:
groupAddressspecifies the multicast group address.
localAddressspecifies the local addresses from which the join message is sent.
Return values:
truein case the operation succeeded.
falsein case the operation failed. For instance, this happens when the socket is not bound to a port.
bool leaveMulticastGroup ( const QHostAddress &  groupAddress)

Attempts to leave from the specified multicast group address.

Parameters:
groupAddressspecifies the multicast group address.
Return values:
truein case the operation succeeded.
falsein case the operation failed. For example, this happens when the socket has not joined to the specified multicast address.
bool leaveMulticastGroup ( const QHostAddress &  groupAddress,
const QHostAddress &  localAddress 
)

Attempts to leave from the specified multicast group address using the specified local address.

Parameters:
groupAddressspecifies the multicast group address.
localAddressspecifies the local addresses from which the leave message is sent.
Return values:
truein case the operation succeeded.
falsein case the operation failed. For example, this happens when the socket has not joined to the specified multicast address.
bool setMulticastTtl ( quint8  arg)

Attempts to set the Time To Live attribute for each message.

Parameters:
argspecifies the value for Time To Live.
Returns:
true in case the operation succeeded.
bool bind ( quint16  port = 0)

Attempts to bind the socket into the specified port using BindMode flags and a QHostAddress value that are suitable for a multicast socket.

Parameters:
portspecifies the port to which to bind.
Returns:
true in case the operation succeeded.
herqq-1.0.0/hupnp/docs/html/functions_func_0x67.html0000644000000000000000000001156411543637604021071 0ustar rootroot Herqq: Class Members - Functions herqq-1.0.0/hupnp/docs/html/functions_0x6a.html0000644000000000000000000001035511543637604020125 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- j -

herqq-1.0.0/hupnp/docs/html/globals.html0000644000000000000000000000473511543637604016707 0ustar rootroot Herqq: File Members
Here is a list of all documented file members with links to the documentation:
herqq-1.0.0/hupnp/docs/html/functions_func_0x6f.html0000644000000000000000000002435411543637604021151 0ustar rootroot Herqq: Class Members - Functions herqq-1.0.0/hupnp/docs/html/functions_0x64.html0000644000000000000000000002774211543637604020060 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- d -

herqq-1.0.0/hupnp/docs/html/namespacemembers_func.html0000644000000000000000000000530211543637604021575 0ustar rootroot Herqq: Namespace Members
 
herqq-1.0.0/hupnp/docs/html/functions_0x68.html0000644000000000000000000002754311543637604020063 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- h -

herqq-1.0.0/hupnp/docs/html/group__hupnp__ssdp.html0000644000000000000000000002532511543637604021157 0ustar rootroot Herqq: Ssdp

This page provides information about the HUPnP's classes that provide the SSDP functionality required for the discovery phase of the UPnP Device Architecture. More...

Classes

class  HResourceAvailable
 This is a class that represents the resource available (ssdp:alive) message. More...
class  HResourceUnavailable
 Class that represents the device unavailable (ssdp:byebye) message. More...
class  HResourceUpdate
 Class representing the device update (ssdp:update) message. More...
class  HDiscoveryRequest
 Class representing an M-SEARCH (ssdp:discover) message. More...
class  HDiscoveryResponse
 This is a class that represents a response to a HDiscoveryRequest. More...
class  HSsdp
 This class is used for sending and receiving SSDP messages defined by the UPnP Device Architecture specification. More...

Detailed Description

This page provides information about the HUPnP's classes that provide the SSDP functionality required for the discovery phase of the UPnP Device Architecture.

According to the UPnP Device Architecture specification version 1.1, When a device is added to the network, the UPnP discovery protocol allows that device to advertise its services to control points on the network. Similarly, when a control point is added to the network, the UPnP discovery protocol allows that control point to search for devices of interest on the network (p. 19).

The mentioned discovery protocol is SSDP and it is about exchanging HTTP messages over UDP.

Note:
As mentioned in the Herqq::Upnp::HSsdp, these classes implement the SSDP as it is required by the UDA specification. The IETF SSDP draft is not implemented in full.

To send or receive SSDP messages, you need to use Herqq::Upnp::HSsdp class. You can either derive from it or use it directly. In either case, sending messages is straightforward:

 Herqq::Upnp::HSsdp ssdp;

 Herqq::Upnp::HResourceAvailable deviceAvailable(
       1800, // how long the advertisement is valid in seconds
       QUrl("127.0.0.1:1900/mydevice"), // where the device description can be downloaded
       Herqq::Upnp::HProductTokens("unix/5.1 UPnP/1.1 MyProduct/1.0"), // some information about the host and product
       Herqq::Upnp::HDiscoveryType("uuid:5d724fc2-5c5e-4760-a123-f04a9136b300::upnp:rootdevice")); // universally unique identifier

 ssdp.announcePresence(deviceAvailable);

The above example sends a single ssdp:alive message indicating that a UPnP root device is now available.

Note:
All SSDP classes validate the provided information during object construction. For instance, if the argument to the Herqq::Upnp::HDiscoveryType is invalid, the constructed object will be invalid as well, e.g Herqq::Upnp::HDiscoveryType::isValid() returns false. In such a case, the creation of Herqq::Upnp::HResourceAvailable will fail and consequenlty, the HSsdp will not send anything.

Receiving messages is almost as simple. You can use the class directly in which case you have to connect to the exposed signals. For instance, to receive signals when resource available messages are received, you should do:

 MyClass::MyClass(QObject* parent) :
     QObject(parent), m_ssdp(new Herqq::Upnp::HSsdp())
 {
     connect(
         m_ssdp, SIGNAL(resourceAvailableReceived(Herqq::Upnp::HResourceAvailable)),
         this  , SLOT  (resourceAvailableReceived(Herqq::Upnp::HResourceAvailable)));
 }

 MyClass::resourceAvailableReceived(const Herqq::Upnp::HResourceAvailable&)
 {
     // do something
 }

Note the used signature with the SIGNAL and SLOT macros. You can also derive from HSsdp in which case you can override the various protected virtual methods that will be called upon message reception.

Attention:
Usually you have no need to use the classes in this module directly. These classes may be useful in case you are writing your own device host or control point. Otherwise, the Herqq::Upnp::HControlPoint and Herqq::Upnp::HDeviceHost classes may suit your needs better.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_host_configuration-members.html0000644000000000000000000002275611543637604031200 0ustar rootroot Herqq: Member List

HDeviceHostConfiguration Member List

herqq-1.0.0/hupnp/docs/html/functions_func_0x6e.html0000644000000000000000000001507411543637604021147 0ustar rootroot Herqq: Class Members - Functions herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_device.html0000644000000000000000000006114611543637604025116 0ustar rootroot Herqq: HClientDevice Class Reference

This is a client-side class that represents a server-side UPnP device. More...

#include <HClientDevice>

Inherited by HDefaultClientDevice.

List of all members.

Public Member Functions

virtual ~HClientDevice ()=0
HClientDeviceparentDevice () const
HClientDevicerootDevice () const
HClientServiceserviceById (const HServiceId &serviceId) const
HClientServices services () const
HClientServices servicesByType (const HResourceType &serviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const
HClientDevices embeddedDevices () const
HClientDevices embeddedDevicesByType (const HResourceType &deviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const
const HDeviceInfoinfo () const
QString description () const
QList< QUrl > locations (LocationUrlType urlType=AbsoluteUrl) const

Protected Member Functions

 HClientDevice (const HDeviceInfo &info, HClientDevice *parentDev=0)

Detailed Description

This is a client-side class that represents a server-side UPnP device.

HClientDevice is a core component of the HUPnP's client-side Device Model and it models a UPnP device, both root and embedded. As detailed in the UPnP Device Architecture specification, a UPnP device is essentially a container for services and possibly for other (embedded) UPnP devices.

Using the class

The most common uses of HClientDevice involve reading the various device information elements originally set in the device description file and enumerating the exposed services. By calling info() you get an HDeviceInfo object from which you can read all the informational elements found in the device description. Calling services() gives you a list of HClientService instances the device exposes. Note that it is the services that contain the functionality and runtime status of the device.

Some devices also contain embedded devices, which you can get by calling embeddedDevices().

You can retrieve the device's description file by calling description() or you can manually read it from any of the locations returned by locations(). If the device is an embedded device, it always has a parent device, which you can get by calling parentDevice().

Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HClientDevice ( const HDeviceInfo info,
HClientDevice parentDev = 0 
) [protected]

Creates a new instance.

Parameters:
infospecifies information of the device. This is often read from a device description document.
parentDevspecifies the parent device of this device, if any.
~HClientDevice ( ) [pure virtual]

Destroys the instance.


Member Function Documentation

HClientDevice * parentDevice ( ) const

Returns the parent device of this device, if any.

Returns:
The parent device of this device, if any, or a null pointer in case the device is a root device.
Remarks:
The pointer is guaranteed to be valid throughout the lifetime of this object.
HClientDevice * rootDevice ( ) const

Returns the root device of the device tree to which this device belongs.

Returns:
The root device of the device tree to which this device belongs.
Remarks:
This device could be the root device of the device tree in question, in which case a pointer to this instance is returned.
HClientService * serviceById ( const HServiceId serviceId) const

Returns the service that has the specified service ID.

Parameters:
serviceIdspecifies the service to be returned.
Returns:
The service that has the specified service ID or a null pointer in case there is no service with the specified ID.
Remarks:
The pointer is guaranteed to be valid throughout the lifetime of this object.
HClientServices services ( ) const

Returns the services this device exports.

Returns:
The services this device exports. The collection is empty if the device has no services.
Remarks:
The pointers are guaranteed to be valid throughout the lifetime of this object.
HClientServices servicesByType ( const HResourceType serviceType,
HResourceType::VersionMatch  versionMatch = HResourceType::Inclusive 
) const

Returns the services of a specific UPnP service type.

Parameters:
serviceTypespecifies the UPnP service type of interest. Only services matching the type are returned.
versionMatchspecifies how the version information in argument serviceType should be used. The default is inclusive match, which essentially means that any service with a service type version that is less than or equal to the version specified in argument serviceType is successfully matched.
Returns:
The services of the specified type.
Remarks:
the pointers are guaranteed to be valid throughout the lifetime of this object.
HClientDevices embeddedDevices ( ) const

Returns the embedded devices of this device.

Returns:
The embedded devices of this device. The collection is empty if the device has no embedded devices.
Remarks:
the pointers are guaranteed to be valid throughout the lifetime of this object.
HClientDevices embeddedDevicesByType ( const HResourceType deviceType,
HResourceType::VersionMatch  versionMatch = HResourceType::Inclusive 
) const

Returns the embedded devices of a specific UPnP device type.

Parameters:
deviceTypespecifies the UPnP device type of interest. Only devices matching the type are returned.
versionMatchspecifies how the version information in argument deviceType should be used. The default is inclusive match, which essentially means that any device with a device type version that is less than or equal to the version specified in argument deviceType is successfully matched.
Returns:
The embedded devices of the specified type.
Remarks:
the pointers are guaranteed to be valid throughout the lifetime of this object.
const HDeviceInfo & info ( ) const

Returns information about the device.

Returns:
information about the device. This is often read from the device description.
QString description ( ) const

Returns the UPnP device description of this device.

Returns:
The UPnP device description that is associated to this device.
Remarks:
an embedded device returns the same device description as its root device.
QList< QUrl > locations ( LocationUrlType  urlType = AbsoluteUrl) const

Returns a list of locations where the device is currently available.

Parameters:
urlTypespecifies whether the returned location URLs are absolute URLs for retrieving the device description. By default absolute URLs are returned and from these URLs the device description should be retrievable.
Returns:
a list of locations where the device is currently available.
herqq-1.0.0/hupnp/docs/html/functions_0x72.html0000644000000000000000000002034111543637604020043 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- r -

herqq-1.0.0/hupnp/docs/html/functions_0x71.html0000644000000000000000000001203111543637604020037 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- q -

herqq-1.0.0/hupnp/docs/html/functions_func_0x68.html0000644000000000000000000002733411543637604021074 0ustar rootroot Herqq: Class Members - Functions
 

- h -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_control_point.html0000644000000000000000000032416511543637604025215 0ustar rootroot Herqq: HControlPoint Class Reference

This is a class for discovering and interacting with UPnP devices in the network. More...

#include <HControlPoint>

List of all members.

Public Types

enum  ControlPointError {
  UndefinedError, NotInitializedError, AlreadyInitializedError, CommunicationsError,
  InvalidArgumentError
}
enum  SubscriptionStatus { Unsubscribed, Subscribing, Subscribed }

Public Slots

void quit ()

Signals

void authenticationRequired (QNetworkReply *reply, QAuthenticator *authenticator)
void subscriptionSucceeded (Herqq::Upnp::HClientService *service)
void subscriptionFailed (Herqq::Upnp::HClientService *service)
void subscriptionCanceled (Herqq::Upnp::HClientService *service)
void rootDeviceOnline (Herqq::Upnp::HClientDevice *device)
void rootDeviceOffline (Herqq::Upnp::HClientDevice *device)
void rootDeviceInvalidated (Herqq::Upnp::HClientDevice *device)
void rootDeviceRemoved (const Herqq::Upnp::HDeviceInfo &deviceInfo)

Public Member Functions

 HControlPoint (QObject *parent=0)
 HControlPoint (const HControlPointConfiguration &configuration, QObject *parent=0)
virtual ~HControlPoint ()
bool init ()
ControlPointError error () const
QString errorDescription () const
bool isStarted () const
HClientDevicedevice (const HUdn &udn, TargetDeviceType deviceType=RootDevices) const
HClientDevices rootDevices () const
HClientDevices devices (const HResourceType &deviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive, TargetDeviceType deviceTypes=RootDevices)
bool removeRootDevice (HClientDevice *rootDevice)
bool subscribeEvents (HClientDevice *device, DeviceVisitType visitType)
bool subscribeEvents (HClientService *service)
SubscriptionStatus subscriptionStatus (const HClientService *service) const
bool cancelEvents (HClientDevice *device, DeviceVisitType visitType)
bool cancelEvents (HClientService *service)
bool scan (const HDiscoveryType &discoveryType, qint32 count=1)
bool scan (const HDiscoveryType &discoveryType, const HEndpoint &destination, qint32 count=1)

Protected Types

enum  DeviceDiscoveryAction { IgnoreDevice, AddDevice, AddDevice_SubscribeEventsIfConfigured, AddDevice_SubscribeAllEvents }

Protected Member Functions

const HControlPointConfigurationconfiguration () const
void setError (ControlPointError error, const QString &errorDescr)

Private Member Functions

virtual bool doInit ()
virtual void doQuit ()
virtual DeviceDiscoveryAction acceptRootDevice (HClientDevice *device)
virtual bool acceptResource (const HDiscoveryType &usn, const HEndpoint &source)

Detailed Description

This is a class for discovering and interacting with UPnP devices in the network.

According to the UPnP Device Architecture specification, a control point is an entity, which "retrieves device and service descriptions, sends actions to services, polls for service state variables, and receives events from services" . In other words, a UPnP control point discovers UPnP devices, queries their state, listens their asynchronous events and invokes them to perform actions. A control point is the client in the UPnP architecture, whereas a UPnP device is the server.

HControlPoint does all of the above, but mostly hiding it from the user if the user wishes so. To discover UPnP devices all you need to do is create an instance of HControlPoint, initialize it by calling init() and check if devices are already found by calling rootDevices(), devices() or device(). You can also listen for a number of events, such as:

Consider an example:

 // myclass.h

 #include <HUpnpCore/HControlPoint>

 class MyClass :
     public QObject
 {
 Q_OBJECT

 private:

     Herqq::Upnp::HControlPoint* m_controlPoint;

 private slots:

     void rootDeviceOnline(Herqq::Upnp::HClientDevice*);
     void rootDeviceOffline(Herqq::Upnp::HClientDevice*);

 public:

     MyClass(QObject* parent = 0);
 };

 // myclass.cpp

 #include "myclass.h"
 #include <HUpnpCore/HClientDevice>

 MyClass::MyClass(QObject* parent) :
     QObject(parent), m_controlPoint(new Herqq::Upnp::HControlPoint(this))
 {
     connect(
         m_controlPoint,
         SIGNAL(rootDeviceOnline(Herqq::Upnp::HClientDevice*)),
         this,
         SLOT(rootDeviceOnline(Herqq::Upnp::HClientDevice*)));

     connect(
         m_controlPoint,
         SIGNAL(rootDeviceOffline(Herqq::Upnp::HClientDevice*)),
         this,
         SLOT(rootDeviceOffline(Herqq::Upnp::HClientDevice*)));

     if (!m_controlPoint->init())
     {
         // the initialization failed, perhaps you should do something?
         // for starters, you can call error() to check the error type and
         // errorDescription() for a human-readable description of
         // the error that occurred.
         return;
     }

     // the control point is running and any standard-compliant UPnP device
     // on the same network should now be discoverable.

     // remember also that the current thread has to have an event loop
 }

 void MyClass::rootDeviceOnline(Herqq::Upnp::HClientDevice* newDevice)
 {
     // device discovered, should something be done with it? Perhaps we want
     // to learn something from it:
     Herqq::Upnp::HDeviceInfo info = newDevice->info();
     // do something with the info object
 }

 void MyClass::rootDeviceOffline(Herqq::Upnp::HClientDevice* rootDevice)
 {
     // device announced that it is going away and the control point sends
     // a notification of this. However, the device isn't removed from the
     // control point until explicitly requested:

     m_controlPoint->removeRootDevice(rootDevice);
 }

Once you have obtained a pointer to a HClientDevice you can enumerate its services, invoke its actions, listen for events of changed state and so on. Basically, a root HClientDevice object at the control point side is an entry point to a very accurate object model depicting the real root UPnP device that has been discovered. For more information about the HClientDevice and the object model, see the page detailing the HUPnP Device Model.

You can call quit() to stop an initialized control point instance from listening the network and to clear its state.

Remarks:
  • This class has thread affinity. You have to use it and destroy it in the thread in which it is located.
  • You can use QObject::moveToThread() on the HControlPoint, which causes the control point and every object managed by it to be moved to the chosen thread. However, you cannot move individual objects managed by HControlPoint.
  • a control point never transfers the ownership of the HClientDevice objects it manages.
  • HControlPoint always destroys every HClientDevice it manages when it is being destroyed.
Warning:
See notes about object deletion in ~HControlPoint().
See also:
HClientDevice, HClientDevices, Device Model

Member Enumeration Documentation

enum DeviceDiscoveryAction [protected]

This enumeration specifies the actions to take when a device has been discovered.

See also:
acceptRootDevice()
Enumerator:
IgnoreDevice 

Ignores the device.

In case the discovered device is a new device this value instructs the control point to ignore and delete it.

In case the discovered device is already in the control of the control point this value instructs the control point to ignore it. However, the device is not removed from the control point. To do that you have to call removeRootDevice().

AddDevice 

Adds a new device into the control point and retains an existing device in the control point.

In case the discovered device is a new device the new device is added into the HControlPoint. Otherwise the device is already in the control point and nothing is done.

The control point will not subscribe to events.

AddDevice_SubscribeEventsIfConfigured 

Adds the device into the control point and subscribes to evented services according to the configuration of the control point.

In case the discovered device is a new device the new device is added into the HControlPoint. Otherwise the device is already in the control point and nothing is done in this regard.

The control point determines whether to subscribe to events based on its configuration. Default configuration instructs the control point to subscribe to all events. The same is done if no configuration was provided.

AddDevice_SubscribeAllEvents 

Adds the device into the control point and subscribes to all evented services.

In case the discovered device is a new device the new device is added into the HControlPoint. Otherwise the device is already in the control point and nothing is done in this regard.

The control points subscribes to all evented services contained by the device and its embedded devices.

This enumeration specifies error types some of the methods of HControlPoint may return.

Enumerator:
UndefinedError 

General failure or no error.

This error code is used to indicate that either:

  • the exact cause for an error could not be determined or
  • no error has occurred.
NotInitializedError 

Control point is not initialized.

This error code is used to indicate that the control point has not been initialized.

AlreadyInitializedError 

Control point is already initialized.

This error code is used to indicate that the control point is already initialized.

CommunicationsError 

Networking error.

This error code is used to indicate that an error occurred in some networking component, such as in HTTP server or in SSDP module.

InvalidArgumentError 

Argument error.

This error code is used to indicate that a member function was called with an invalid argument and the call was aborted.

This enumeration is used to describe the status of an event subscription.

See also:
subscriptionStatus()
Enumerator:
Unsubscribed 

No subscription exists for the specified service.

This value is used when there is no subscription or subscription attempt being made to a specified service.

Subscribing 

A subscription attempt is in progress.

This value is used when a subscription attempt to the events of the specified service is in progress.

See also:
subscriptionSucceeded(), subscriptionFailed()
Subscribed 

A subscription is active.

This value is used when the control point has successfully subscribed to the events of the specified service.


Constructor & Destructor Documentation

HControlPoint ( QObject *  parent = 0)

Creates a new instance.

Parameters:
parentspecifies the parent QObject, if any.
See also:
HControlPointConfiguration
Remarks:
the created control point creates and uses a default configuration.
HControlPoint ( const HControlPointConfiguration configuration,
QObject *  parent = 0 
)

Creates a new instance.

Parameters:
configurationspecifies information that can be used to modify the default behavior of the control point instance. If you want to use the default configuration, you should use the default constructor.
parentspecifies the parent QObject, if any.
See also:
HControlPointConfiguration
~HControlPoint ( ) [virtual]

Destroys the control point and every hosted device.

Warning:
When a control point is being destroyed the control point destroys all of its child objects. You should discard any pointers retrieved from the control point to prevent accidental dereference.
Remarks:
An HControlPoint instance has to be destroyed in the thread in which it is located.

Member Function Documentation

bool doInit ( ) [private, virtual]

Performs the initialization of a derived class.

The HControlPoint uses two-phase initialization in which the user first constructs an instance and then calls init() in order to ready the object for use. This method is called by the HControlPoint during its private initialization after all the private data structures are constructed but before any network activity. At this point, no HTTP or SSDP requests are served.

You can override this method to perform any further initialization of a derived class.

Returns:
true if and only if the initialization succeeded. If false is returned the initialization of the control point is aborted. In addition, it is advised that you call setError() before returning.
Remarks:
the default implementation does nothing.
See also:
init()
void doQuit ( ) [private, virtual]

Performs the de-initialization of a derived class.

Since it is possible to shutdown a control point without actually destroying the instance by calling quit(), derived classes have the possibility to run their own shutdown procedure by overriding this method. This method is called before the HControlPoint cleans its private data structures but after it has stopped listening requests from the network.

Remarks:
the default implementation does nothing.
See also:
quit()
HControlPoint::DeviceDiscoveryAction acceptRootDevice ( HClientDevice device) [private, virtual]

This method specifies the actions to take when a device has been discovered.

A discovered device may be a new device to the control point or a device that is already in the control point. The latter scenario is true when a device goes offline, is not removed from the control point and later comes back online with the same UPnP configuration (see UDA for more information about a UPnP device configuration).

If you have derived a class from HControlPoint you have the option of choosing whether a discovered device should be managed by the control point, and whether the control point should subscribe to the events published by the services of the device. To do this you have to override this method.

Note:
  • This method takes precedence over any configuration options provided to the control point at the time of its construction
  • This method is called when:
    • a new root HClientDevice has been built and
    • a previously known device comes back online with the same UPnP device configuration value it had before it went offline.
Parameters:
devicespecifies the discovered device.
Returns:
value indicating what should be done with the specified device.

By default every successfully built device will be added to the control point and its events are subscribed according to the control point configuration.

See also:
DeviceDiscoveryAction()
bool acceptResource ( const HDiscoveryType usn,
const HEndpoint source 
) [private, virtual]

This method is called whenever a new a device has been detected on the network.

Override this method in case you want to control which devices get built.

Every UPnP resource belongs to a UPnP device tree, and every advertisement and notification of a resource contains all the information needed to build a full model of the device tree. An advertisement is sent by a UPnP device to advertise itself, its embedded devices or any of the services contained within the device tree. A notification is the response from a UPnP device to a discovery sent by a control point.

If an advertisement or a notification is received that identifies a resource belonging to a device that is currently not in the control of this control point, this method is called. If you accept the specified resource the control point will retrieve all the information from the target UPnP device to build a device model of the device tree the UPnP device represents.

Note:
once you have accepted a resource from a particular UPnP device, this method will not be called again for other resource advertisements or notifications from the UPnP device. On the other hand, if you do not accept a resource and the same UPnP device sends another notification or advertisement, this method will be called again.
Parameters:
usncontains information about the resource.
sourcespecifies the source of the advertisement.
Returns:
true when the resource is accepted and a device model should be built for the UPnP device that sent the notification / advertisement. If the device is built successfully the acceptRootDevice() will be called. By default every new device is accepted, built and added into an HControlPoint.
const HControlPointConfiguration * configuration ( ) const [protected]

Returns the configuration used to initialize the control point.

Returns:
The configuration used to initialize the control point.
Note:
If no configuration was provided at the time of object construction the control point creates a default configuration and uses that. This method always returns a pointer to a valid object, even if the control point is not initialized.
Remarks:
the returned object is not a copy and the ownership of the object is not transferred. Do not delete the object.
void setError ( ControlPointError  error,
const QString &  errorDescr 
) [protected]

Sets the type and description of the last occurred error.

Parameters:
errorspecifies the error type.
errorDescrspecifies a human readable description of the error.
See also:
error(), errorDescription()
bool init ( )

Initializes the control point.

This has to be called for the control point to start monitoring the network for UPnP devices. To stop an initialized control point instance from listening network events you can call quit() or delete the object.

Note:
By default an HControlPoint instance performs a device discovery upon initialization. However, you can override this in the configuration.
Returns:
true if the initialization of the control point succeeded. If false is returned you can call error() to get the type of the error, and you can call errorDescription() to get a human-readable description of the error.
See also:
quit(), error(), errorDescription()

Returns the type of the last error occurred.

Returns:
The type of the last error occurred.
QString errorDescription ( ) const

Returns a human readable description of the last error occurred.

Returns:
a human readable description of the last error occurred.
bool isStarted ( ) const

Indicates whether or not the host is successfully started.

Returns:
true in case the host is successfully started.
HClientDevice * device ( const HUdn udn,
TargetDeviceType  deviceType = RootDevices 
) const

Returns a device with the specified Unique Device Name that the control point is currently managing.

Parameters:
udnspecifies the Unique Device Name of the desired device.
deviceTypespecifies whether the search should consider root devices only. The default is to search root devices only.
Returns:
The device with the specified Unique Device Name, or a null pointer in case no currently managed device has the specified UDN.
Warning:
the returned device will be deleted at the latest when the control point is being destroyed. In addition, you can call removeRootDevice() to remove and delete a root device. However, the call will fail if you pass it an embedded device. Moreover, do not delete a device object directly. The ownership of an HClientDevice is never transferred.
Remarks:
This method does not perform a network scan. The search is run against the devices that are already in the control of the control point. You can call scan() to perform an explicit network scan.
HClientDevices rootDevices ( ) const

Returns a list of UPnP root devices the control point is currently managing.

The returned list contains pointers to root HClientDevice objects that are currently managed by this instance.

Returns:
a list of pointers to root HClientDevice objects the control point is currently managing.
Warning:
the returned devices will be deleted at the latest when the control point is being destroyed. In addition, you can call removeRootDevice() to remove and delete a root device. However, do not delete the device objects directly. The ownership of an HClientDevice is never transferred.
Remarks:
This method does not perform a network scan.
HClientDevices devices ( const HResourceType deviceType,
HResourceType::VersionMatch  versionMatch = HResourceType::Inclusive,
TargetDeviceType  deviceTypes = RootDevices 
)

Returns a list of UPnP devices the control point is currently managing and that match the provided search criteria.

The returned list contains pointers to HClientDevice objects that are currently managed by this instance. It is important to note that unlike the method rootDevices() this method may return pointers to both root and embedded devices.

Parameters:
deviceTypespecifies the UPnP device type to be searched.
versionMatchspecifies how the version information in argument deviceType should be used. The default is inclusive match, which essentially means that any device with a device type version that is less than or equal to the version specified in argument deviceType is successfully matched.
deviceTypesspecifies whether the search should consider root devices only. The default is to search root devices only.
Returns:
a list of pointers to HClientDevice objects the control point is currently managing.
Warning:
the returned devices will be deleted at the latest when the control point is being destroyed. In addition, you can call removeRootDevice() to remove and delete a root device. However, the call will fail if you pass it an embedded device. Moreover, do not delete the device objects directly. The ownership of an HClientDevice is never transferred.
Remarks:
This method does not perform a network scan. The search is run against the devices that are already in the control of the control point. You can call scan() to perform an explicit network scan.
bool removeRootDevice ( HClientDevice rootDevice)

Removes the root device from the control point and deletes it.

Parameters:
rootDevicespecifies the root device to be removed. Nothing is done if the device is not in the control of this control point or the device is not a root device.
Return values:
truein case the device was successfully removed and deleted.
falsein case:

  • the specified argument was null,
  • the specified device is not managed by this control point or
  • the specified device is not a root device.
Remarks:
the specified object is deleted if and only if the method returns true.
See also:
error(), errorDescription()
bool subscribeEvents ( HClientDevice device,
DeviceVisitType  visitType 
)

Subscribes to events of the specified services contained by the specified device.

You can use this method to subscribe to events of multiple evented services contained by the specified device at once.

Parameters:
devicespecifies the device that contains the services, which events are subscribed.
visitTypespecifies how the device tree is traversed. A subscription is sent to every service of every visited device.
Return values:
truein case the subscriptions were successfully dispatched. Note, any subscription may still fail. You can connect to subscriptionSucceeded() and subscriptionFailed() signals to be notified upon subscription success and failure.
falsein case the specified argument is null or it does not belong to a device held by the control point.
Remarks:
  • services which events are already subscribed to are skipped.
  • the method returns immediately. Every successful subscription results in subscriptionSucceeded() signal sent. Every failed subscription results in subscriptionFailed() signal sent.
  • every subscription is maintained until:
    • an error occurs
    • it is explicitly canceled

Thus, a subscription is automatically renewed before expiration until an error occurs or it is canceled.

See also:
error(), errorDescription()
bool subscribeEvents ( HClientService service)

Subscribes to the events of the service.

Parameters:
servicespecifies the service
Return values:
truein case the subscription request was successfully dispatched. Note, the subscription may still fail. You can connect to subscriptionSucceeded() and subscriptionFailed() signals to be notified upon subscription success and failure.
falsein case the specified argument:

  • is null,
  • it does not belong to a device held by the control point,
  • is not evented or
  • there already exists a subscription for the specified service.
Remarks:
  • the method returns immediately. A successful subscription results in subscriptionSucceeded() signal sent. A failed subscription results in subscriptionFailed() signal sent.
  • a subscription is maintained by the control point until:
    • an error occurs
    • it is explicitly canceled

Thus, a subscription is automatically renewed before expiration until an error occurs or it is canceled.

See also:
error(), errorDescription()
HControlPoint::SubscriptionStatus subscriptionStatus ( const HClientService service) const

Checks if there exists a subscription to the events of the specified service.

Parameters:
servicespecifies the service to be checked.
Return values:
HControlPoint::Unsubscribedwhen the service is not evented or there is no active susbcription or subscription attempt going on to the specified service.
HControlPoint::Subscribingwhen the service is evented and an subscription attempt is being made to the specified service.
HControlPoint::Subscribedwhen there exists an active subscription to the specified service.
bool cancelEvents ( HClientDevice device,
DeviceVisitType  visitType 
)

Cancels the event subscriptions of every service contained by the device.

Any services which events are not subscribed are skipped.

Parameters:
devicespecifies the device that contains the services, which subscriptions are canceled.
visitTypespecifies how the device tree is traversed. A subscription cancellation request is sent to every service of every visited device.
Return values:
truein case the cancellation request of a subscription was successfully dispatched. Note, this does not mean that the cancellation was successfully received and handled by the UPnP device in question. Upon success the state of the control point instance is modified appropriately, but it is never guaranteed that the target UPnP device receives or processes the cancellation request.
falsein case

  • the specified argument is null,
  • the device is not managed by this control point or
  • there were no active subscriptions matching the search criteria to cancel.
Remarks:
This method returns immediately.
See also:
error(), errorDescription()
bool cancelEvents ( HClientService service)

Cancels the event subscription of the service.

Parameters:
servicespecifies the service, which event subscription is to be canceled.
Return values:
truein case the cancellation request of a subscription was successfully dispatched. Note, this does not mean that the cancellation was successfully received and handled by the UPnP device in question. Upon success the state of the control point instance is modified appropriately, but it is never guaranteed that the target UPnP device receives or processes the cancellation request.
falsein case

  • the specified argument is null,
  • the service does not belong to a device held by the control point or
  • there is no active subscription to the specified service.
Remarks:
This method returns immediately.
See also:
error(), errorDescription()
bool scan ( const HDiscoveryType discoveryType,
qint32  count = 1 
)

Scans the network for resources of interest.

Using the default configuration HControlPoint automatically searches and adds every device it finds. In that case the device list returned by rootDevices() usually reflects the UPnP device status of the network. However, there are situations where you may want to explicitly ask the HControlPoint to update its status and you can call this method to do that.

Parameters:
discoveryTypespecifies the type of the discovery to perform.
countspecifies how many times the discovery should be performed. The number translates directly to the number of SSDP messages send. The default is 1.
Remarks:
  • This method returns immediately.
  • As a result of this call there may be any number of rootDeviceOnline() signals emitted as a consequence of newly found devices.
  • The call will not affect the expiration of existing devices. More specifically, any device that does not respond to the scan will not be considered as expired and no rootDeviceOffline() signals will be sent consequently.
bool scan ( const HDiscoveryType discoveryType,
const HEndpoint destination,
qint32  count = 1 
)

Scans the network for resources of interest.

Using the default configuration HControlPoint automatically searches and adds every device it finds. In that case the device list returned by rootDevices() usually reflects the UPnP device status of the network. However, there are situations where you may want to explicitly ask the HControlPoint to perform a discovery on a specific TCP/IP endpoint. In other words, you can perform a unicast device discovery using this method.

Parameters:
discoveryTypespecifies the type of the discovery to perform.
destinationspecifies the location where the discovery is sent. If the port of the specified endpoint is set to zero the message is sent to the specified host address using the default port 1900.
countspecifies how many times the discovery should be performed. The number translates directly to the number of SSDP messages send. The default is 1.
Remarks:
  • This method returns immediately.
  • As a result of this call there may be any number of rootDeviceOnline() signals emitted as a consequence of newly found devices.
  • The call will not affect the expiration of existing devices. More specifically, any device that does not respond to the scan will not be considered as expired and no rootDeviceOffline() signals will be sent consequently.
void quit ( ) [slot]

Shuts down the control point.

The control point stops listening for network events, deletes all the devices it is hosting and cancels all event subscriptions. In essence, the control point purges it state. You can re-initialize the control point by calling init() again.

Attention:
Every pointer to object retrieved from this instance will be deleted. Be sure not to use any such pointer after calling this method.
See also:
init()
void authenticationRequired ( QNetworkReply *  reply,
QAuthenticator *  authenticator 
) [signal]

This signal is emitted whenever a final server requests authentication before it delivers the requested contents.

This signal is relayed from the underlying QNetworkAccessManager, which is used by the HControlPoint to run HTTP messaging. As specified in the reference documentation of QNetworkAccessManager, the slot connected to this signal should fill the credentials for the contents (which can be determined by inspecting the reply object) in the authenticator object. QNetworkAccessManager will cache the credentials internally and will send the same values if the server requires authentication again, without emitting the authenticationRequired() signal. If it rejects the credentials, this signal will be emitted again.

Parameters:
replyspecifies the requested contents.
authenticatorspecifies the authenticator object to which the user should fill in the credentials.
void subscriptionSucceeded ( Herqq::Upnp::HClientService service) [signal]

This signal is emitted when the initial subscription to the specified service succeeded.

Parameters:
servicespecifies the target service of the event subscription.
See also:
subscriptionFailed()
void subscriptionFailed ( Herqq::Upnp::HClientService service) [signal]

This signal is emitted when an event subscription to the specified service failed.

Note:
this signal may be emitted in three different scenarios:
  • the initial subscription failed
  • an automatic subscription renewal failed
  • a re-subscription failed If you want to try to re-subscribe to the service you can call subscribe() again.
Parameters:
servicespecifies the service, which event subscription failed.
See also:
subscriptionSucceeded()
void subscriptionCanceled ( Herqq::Upnp::HClientService service) [signal]

This signal is emitted when an event subscription to the specified service has been canceled.

Parameters:
servicespecifies the service, which subscription was canceled.
void rootDeviceOnline ( Herqq::Upnp::HClientDevice device) [signal]

This signal is emitted when a device has been discovered.

Parameters:
deviceis the discovered device.
Remarks:
the discovered device may already be managed by this instance. This is the case when a device goes offline and comes back online before it is removed from the control point.
See also:
rootDeviceOffline(), removeRootDevice()
void rootDeviceOffline ( Herqq::Upnp::HClientDevice device) [signal]

This signal is sent when a root device has announced that it is going offline or the expiration timeout associated with the device tree has elapsed.

After a device has gone offline you may want to remove the device from the control point using removeRootDevice(). Alternatively, if you do not remove the device and the device comes back online later:

  • a rootDeviceOnline() signal is emitted in case the device uses the same configuration as it did before going offline or
  • a rootDeviceInvalidated() signal is emitted in case the device uses a different configuration as it did before going offline. If this is the case you should remove the device as it no longer reflects the real device accurately.
Parameters:
deviceis the device that went offline and is not reachable at the moment.
See also:
rootDeviceOnline(), rootDeviceInvalidated(), removeRootDevice()
void rootDeviceInvalidated ( Herqq::Upnp::HClientDevice device) [signal]

This signal is emitted when a previously discovered device has changed its configuration and must be discarded.

The UDA v1.1 specifies the configuration of a root device to consist of the device description documents of all the devices in the device tree and all the service description documents of the services in the device tree. If the configuration changes the old device tree has to be discarded in place of the new one.

After this signal is emitted the specified HClientDevice object has become invalid and should be discarded and removed immediately. In addition, rootDeviceOnline() signal may be emitted shortly after this signal, but only when the new configuration of the device is accepted by this instance.

Parameters:
deviceis the device that has been invalidated.
void rootDeviceRemoved ( const Herqq::Upnp::HDeviceInfo deviceInfo) [signal]

This signal is emitted when a root device has been removed from the control of this control point and deleted.

Parameters:
deviceInfospecifies information about the device that was removed and deleted.
See also:
rootDeviceOffline()
herqq-1.0.0/hupnp/docs/html/functions_0x6d.html0000644000000000000000000001372311543637604020132 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- m -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_udn.html0000644000000000000000000004622311543637604023106 0ustar rootroot Herqq: HUdn Class Reference

This is a class used to depict a Unique Device Name (UDN), which is a unique device identifier that has to remain the same over time for a specific device instance. More...

#include <HUdn>

List of all members.

Public Member Functions

 HUdn ()
 HUdn (const QUuid &value)
 HUdn (const QString &value)
 ~HUdn ()
bool isValid (HValidityCheckLevel checkLevel) const
QUuid value () const
QString toString () const
QString toSimpleUuid () const

Static Public Member Functions

static HUdn createUdn ()

Friends

H_UPNP_CORE_EXPORT quint32 qHash (const HUdn &)
H_UPNP_CORE_EXPORT bool operator== (const HUdn &, const HUdn &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HUdn &obj1, const HUdn &obj2)

Detailed Description

This is a class used to depict a Unique Device Name (UDN), which is a unique device identifier that has to remain the same over time for a specific device instance.

A valid UDN follows the format "uuid:"+"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", where the five hex fields form up a valid UUID.

Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HUdn ( )

Constructs a new, empty instance.

Instance created by this constructor is not valid, i.e. isValid() will return false.

See also:
isValid
HUdn ( const QUuid &  value)

Constructs a new instance based on the provided value.

Parameters:
valuespecifies the UUID of the UDN. If the provided UUID is invalid, the created HUdn is invalid as well.
See also:
isValid
HUdn ( const QString &  value)

Constructs a new instance based on the provided value.

Parameters:
valuespecifies the string from which the object is constructed. The argument has to contain a valid UUID and it can be prefixed with "uuid:". The UUID part in turn must be formatted along the requirements of QUuid: the string "must be formatted as five hex fields separated by '-', e.g., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where 'x' is a hex digit. The curly braces shown here are optional, but it is normal to include them. If the argument does not form a proper UUID, the created UDN is invalid.
See also:
isValid
~HUdn ( )

Destroys the instance.


Member Function Documentation

bool isValid ( HValidityCheckLevel  checkLevel) const [inline]

Indicates if the UDN is defined or not.

Parameters:
checkLevelspecifies whether the check should be done strictly according to the UDA specifications (1.0 & 1.1). That is, the UDN has to contain a proper UUID. If checkLevel is false the UDN is considered valid if it is not empty.
Returns:
true in case the UDN is valid considering the checkLevel argument.
QUuid value ( ) const

Returns the UUID component of the UDN.

Returns:
The UUID component of the UDN.
Remarks:
if the UDN is not strictly valid, i.e. isValid(true) returns false, this method will return a null QUuid.
QString toString ( ) const

Returns the complete UDN value.

Returns:
the complete UDN value when the UDN is valid. For instance, "uuid:5d794fc2-5c5e-4460-a023-f04a51363300" is a valid UDN. Otherwise an empty string is returned.
QString toSimpleUuid ( ) const

Returns the UUID component of the UDN as string.

Returns:
the UUID component of the UDN as string when the UDN is valid. For instance, if the complete UDN is "uuid:5d794fc2-5c5e-4460-a023-f04a51363300", this method will return "5d794fc2-5c5e-4460-a023-f04a51363300". Otherwise an empty string is returned.
HUdn createUdn ( ) [static]

Creates a new strictly valid UDN.

Returns:
a new strictly valid UDN.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT quint32 qHash ( const HUdn ) [friend]

Returns a value that can be used as a unique key in a hash-map identifying the UDN object.

Parameters:
keyspecifies the UDN from which the hash value is created.
Returns:
a value that can be used as a unique key in a hash-map identifying the UDN object.
H_UPNP_CORE_EXPORT bool operator== ( const HUdn ,
const HUdn  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
bool operator!= ( const HUdn obj1,
const HUdn obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/tab_b.png0000644000000000000000000000026211543637604016142 0ustar rootroot‰PNG  IHDR$ÇÇ[yIDATxíÝÛ Â €Ñ?|SVÓˆ´bB#P®½8³‰O¾:É™D>ßm{SûIí'¹äz(!•TBÞ‰y#¤WìJDp¾ã|Ã…†ó »ìR˜]áá æ™Ð6q·‰›]ç•qŠŒÓÊÕD.&0èÀ =ƒJD”ˆü=@*é*ç×IEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_clonable-members.html0000644000000000000000000000723711543637604025531 0ustar rootroot Herqq: Member List

HClonable Member List

This is the complete list of members for HClonable, including all inherited members.
clone() const HClonable [virtual]
doClone(HClonable *target) const HClonable [protected, virtual]
HClonable()HClonable
newInstance() const =0HClonable [protected, pure virtual]
~HClonable()HClonable [virtual]
herqq-1.0.0/hupnp/docs/html/hactioninvoke__callback_8h.html0000644000000000000000000000604511543637604022473 0ustar rootroot Herqq: src/devicemodel/hactioninvoke_callback.h File Reference

src/devicemodel/hactioninvoke_callback.h File Reference

#include <HUpnpCore/HUpnp>
#include <HUpnpCore/HFunctor>

Namespaces

namespace  Herqq
namespace  Herqq::Upnp

Typedefs

typedef Functor< bool,
H_TYPELIST_2(HClientAction
*, const HClientActionOp &) 
HActionInvokeCallback )

Detailed Description

herqq-1.0.0/hupnp/docs/html/hierarchy.html0000644000000000000000000001541511543637604017237 0ustar rootroot Herqq: Class Hierarchy

Class Hierarchy

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_resource_type.html0000644000000000000000000011535711543637604025215 0ustar rootroot Herqq: HResourceType Class Reference

This is a class used to depict a UPnP resource, which is either a UPnP device or a UPnP service. More...

#include <HResourceType>

List of all members.

Public Types

enum  Type {
  Undefined = 0, StandardDeviceType, StandardServiceType, VendorSpecifiedDeviceType,
  VendorSpecifiedServiceType
}
enum  VersionMatch { Ignore, Exact, Inclusive, EqualOrGreater }
enum  Token {
  None = 0x00, UrnPrefix = 0x01, Domain = 0x02, Type = 0x04,
  TypeSuffix = 0x08, Version = 0x10, All = 0x1f
}

Public Member Functions

 HResourceType ()
 HResourceType (const QString &resourceTypeAsStr)
 ~HResourceType ()
Type type () const
bool isValid () const
bool isDeviceType () const
bool isServiceType () const
bool isStandardType () const
qint32 version () const
QString toString (Tokens tokens=All) const
bool compare (const HResourceType &other, VersionMatch versionMatch) const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HResourceType &, const HResourceType &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HResourceType &obj1, const HResourceType &obj2)
H_UPNP_CORE_EXPORT quint32 qHash (const HResourceType &key)

Detailed Description

This is a class used to depict a UPnP resource, which is either a UPnP device or a UPnP service.

Both UPnP device and service descriptions use the type concept to a give the corresponding device or service context that can be used in identification. In device descriptions the device type is specified following the format

urn:schemas-upnp-org:device:deviceType:ver 

or

urn:domain-name:device:deviceType:ver 

in case of a vendor defined type.

In service descriptions the service type is specified as

urn:schemas-upnp-org:service:serviceType:ver 

or

urn:domain-name:service:serviceType:ver 

in case of a vendor defined type.

For more information, see the device type and service type definitions in UDA v1.1 at pages 44 and 46, respectively.

This class abstracts the above service and device type concepts to a resource and helps in handling the various elements of a resource type.

Remarks:
This class is not thread-safe.

Member Enumeration Documentation

enum Type

Specifies the type of the resource.

See UPnP v1.1 Device Architecture specification for more information.

Enumerator:
Undefined 

No resource defined.

This is used when the object is constructed using the default constructor.

StandardDeviceType 

The resource is urn:schemas-upnp-org:device:deviceType:ver.

StandardServiceType 

The resource is urn:schemas-upnp-org:service:serviceType:ver.

VendorSpecifiedDeviceType 

The resource is urn:domain-name:device:deviceType:ver.

VendorSpecifiedServiceType 

The resource is urn:domain-name:service:serviceType:ver.

This enumeration specifies how the version part of a HResourceType is matched against a target value.

Enumerator:
Ignore 

The version part of HResoureType objects is ignored.

Exact 

The version part of HResourceType object has to be identical to the specified value.

Inclusive 

The version part of HResourceType object has to be less than or equal to the specified value.

EqualOrGreater 

The version part of HResourceType object has to be greater than or equal to the specified value.

enum Token

Enumeration that specifies the tokens or parts of a resource type.

For instance, if the resource type is defined as urn:schemas-upnp-org:device:deviceType:ver then the tokens are the parts separated by colons.

Enumerator:
None 

This is a special value used to denote "no tokens".

UrnPrefix 

The "urn:" token.

Domain 

The domain token, e.g.

"schemas-upnp-org".

Type 

The type of the resource, e.g.

"device" or "service".

TypeSuffix 

The type suffix of the resource, e.g.

"deviceType" or "serviceType".

Version 

The version of the resource type.

Most commonly this is an integer.

All 

This is a special value used to denote "all tokens".


Constructor & Destructor Documentation

Constructs a new, empty instance.

Instance created by this constructor is not valid, i.e. isValid() will return false.

See also:
isValid()
HResourceType ( const QString &  resourceTypeAsStr)

Constructs a new, empty instance from the specified parameter.

Parameters:
resourceTypeAsStrspecifies the resource type following the one of the following formats:
  • urn:schemas-upnp-org:device:deviceType:ver for standard device type
  • urn:domain-name:device:deviceType:ver for vendor defined device type
  • urn:schemas-upnp-org:service:serviceType:ver for standard service type
  • urn:domain-name:service:serviceType:ver for vendor defined service type
See also:
isValid()

Destroys the instance.


Member Function Documentation

Type type ( ) const [inline]

Returns the type of the resource.

Returns:
The type of the resource.
bool isValid ( ) const [inline]

Indicates if the object is valid.

This method is provided for convenience. It simply checks if the type() is HResourceType::Undefined.

Returns:
true in case the object represents a valid resource type.
bool isDeviceType ( ) const [inline]

Indicates whether or not the resource type is a device type.

This method is provided for convenience. It checks if the type is either HResourceType::StandardDeviceType or HResourceType::VendorSpecifiedDeviceType.

Returns:
true in case the resource type is a device type.
bool isServiceType ( ) const [inline]

Indicates whether or not the resource type is a service type.

This method is provided for convenience. It checks if the type is either HResourceType::StandardServiceType or HResourceType::VendorSpecifiedServiceType.

Returns:
true in case the resource type is a service type.
bool isStandardType ( ) const [inline]

Indicates whether or not the resource type is a standard type defined by the UPnP forum.

This method is provided for convenience. It checks if the type is either HResourceType::StandardDeviceType or HResourceType::StandardServiceType.

Return values:
truein case the resource type is defined by the UPnP forum.
falsein case the resource type is vendor defined.
qint32 version ( ) const

Returns the version of the resource type.

Returns:
the version of the resource type if the object is valid. In case the object is invalid -1 is returned.
See also:
isValid()
QString toString ( Tokens  tokens = All) const

Returns a string representation of the object.

A resource type can be broken into 5 tokens, which are depicted in the Token enum. This function is used to retrieve an arbitrary combination of these tokens as a string. For instance, if you would like to retrieve the resource type, resource type suffix and the version as a string you would issue:

Parameters:
tokensspecifies what components of the objects are included in the returned string. The default is to return everything.
Returns:
a string representation of the object as defined by the provided tokens if the object is valid. Otherwise an empty string is returned.
Remarks:
By default the contents of the object are returned in full.
bool compare ( const HResourceType other,
VersionMatch  versionMatch 
) const

Compares this object to the provided object according to the specified HResourceType::VersionMatch argument.

Parameters:
otherspecifies the other HResourceType object.
versionMatchspecifies how the version information in the objects are compared against one another. The target of the comparison is always this object. Therefore if the versionMatch is set to HResourceType::Inclusive, the specified other object defines the upper bound for the comparison.
Returns:
true in case the two objects are considered a match taking into account the specified HResourceType::VersionMatch argument.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HResourceType ,
const HResourceType  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
bool operator!= ( const HResourceType obj1,
const HResourceType obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
H_UPNP_CORE_EXPORT quint32 qHash ( const HResourceType key) [related]

Returns a value that can be used as a unique key in a hash-map identifying the resource type object.

Parameters:
keyspecifies the resource type from which the hash value is created.
Returns:
a value that can be used as a unique key in a hash-map identifying the resource type object.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_service-members.html0000644000000000000000000001560511543637604026776 0ustar rootroot Herqq: Member List

HServerService Member List

This is the complete list of members for HServerService, including all inherited members.
actions() const HServerService
createActionInvokes()HServerService [protected, virtual]
description() const HServerService
finalizeInit(QString *errDescription)HServerService [protected, virtual]
HActionInvokes typedefHServerService [protected]
HServerService()HServerService [protected]
info() const HServerService
init(const HServiceInfo &info, HServerDevice *parentDevice)HServerService [protected]
isEvented() const HServerService
notifyListeners()HServerService [slot]
parentDevice() const HServerService
setValue(const QString &stateVarName, const QVariant &value)HServerService
stateChanged(const Herqq::Upnp::HServerService *source)HServerService [signal]
stateVariables() const HServerService
value(const QString &stateVarName, bool *ok=0) const HServerService
~HServerService()=0HServerService [pure virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_service_setup.html0000644000000000000000000007241111543637604025176 0ustar rootroot Herqq: HServiceSetup Class Reference

HServiceSetup Class Reference

This class is used to specify information that can be used to validate a UPnP service. More...

#include <HServiceSetup>

List of all members.

Public Member Functions

 HServiceSetup ()
 HServiceSetup (const HServiceId &id, const HResourceType &serviceType, HInclusionRequirement incReq=InclusionMandatory)
 HServiceSetup (const HServiceId &id, const HResourceType &serviceType, int version, HInclusionRequirement incReq=InclusionMandatory)
HServiceSetupoperator= (const HServiceSetup &)
 HServiceSetup (const HServiceSetup &)
 ~HServiceSetup ()
HInclusionRequirement inclusionRequirement () const
bool isValid (HValidityCheckLevel checkLevel) const
const HServiceIdserviceId () const
const HResourceTypeserviceType () const
int version () const
void setInclusionRequirement (HInclusionRequirement arg)
void setServiceId (const HServiceId &arg)
void setServiceType (const HResourceType &arg)
void setVersion (int version)

Related Functions

(Note that these are not member functions.)
H_UPNP_CORE_EXPORT bool operator== (const HServiceSetup &, const HServiceSetup &)
bool operator!= (const HServiceSetup &obj1, const HServiceSetup &obj2)

Detailed Description

This class is used to specify information that can be used to validate a UPnP service.

See also:
HServicesSetupData, HClientService, HServerService
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new, invalid instance.

See also:
isValid()
HServiceSetup ( const HServiceId id,
const HResourceType serviceType,
HInclusionRequirement  incReq = InclusionMandatory 
)

Creates a new instance.

Parameters:
idspecifies the service ID.
serviceTypespecifies the service type.
incReqspecifies the inclusion requirement of the service.
See also:
isValid()
Remarks:
the version() is set to 1.
HServiceSetup ( const HServiceId id,
const HResourceType serviceType,
int  version,
HInclusionRequirement  incReq = InclusionMandatory 
)

Creates a new instance.

Parameters:
idspecifies the service ID.
serviceTypespecifies the service type.
versionspecifies the version of the UPnP device, which first specified the service.
incReqspecifies the inclusion requirement of the service.
See also:
isValid()
HServiceSetup ( const HServiceSetup other)

Copy constructor.

Creates a copy of other.

Destroys the instance.


Member Function Documentation

HServiceSetup & operator= ( const HServiceSetup other)

Assignment operator.

Copies the contents of other to this.

HInclusionRequirement inclusionRequirement ( ) const

Returns the inclusion requirement.

Returns:
The inclusion requirement.
See also:
setInclusionRequirement()
bool isValid ( HValidityCheckLevel  checkLevel) const

Indicates if the object is valid.

Parameters:
checkLevelspecifies whether the validity of the object should be checked strictly according to the UDA specification.
Returns:
true in case the object is valid, that is, the service ID, service type, version and inclusion requirement are all properly defined in respect to the specified checkLevel.
const HServiceId & serviceId ( ) const

Returns the service ID.

Returns:
The service ID.
See also:
setServiceId()
const HResourceType & serviceType ( ) const

Returns the service type.

Returns:
The service type.
See also:
setServiceType()
int version ( ) const

Returns the version of the UPnP device, which first specified the service.

Returns:
The version of the UPnP device, which first specified the service.
See also:
setVersion()
void setInclusionRequirement ( HInclusionRequirement  arg)

Sets the the inclusion requirement.

Parameters:
argspecifies the inclusion requirement.
See also:
inclusionRequirement()
void setServiceId ( const HServiceId arg)

Sets the service ID.

Parameters:
argspecifies the service ID.
See also:
serviceId()
void setServiceType ( const HResourceType arg)

Sets the service type.

Parameters:
argspecifies the service type.
See also:
serviceType()
void setVersion ( int  version)

Sets the version of the UPnP device, which first specified the service.

Parameters:
versiondefines the version of the UPnP device, which first specifies the service.
See also:
version()

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HServiceSetup ,
const HServiceSetup  
) [related]

Compares the two objects for equality.

Returns:
true in case the provided objects are equal, false otherwise.
bool operator!= ( const HServiceSetup obj1,
const HServiceSetup obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the provided objects are not equal, false otherwise.
herqq-1.0.0/hupnp/docs/html/functions_0x62.html0000644000000000000000000001463511543637604020053 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- b -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_endpoint-members.html0000644000000000000000000001403411543637604025563 0ustar rootroot Herqq: Member List

HEndpoint Member List

This is the complete list of members for HEndpoint, including all inherited members.
HEndpoint()HEndpoint
HEndpoint(const QHostAddress &hostAddress)HEndpoint
HEndpoint(const QHostAddress &hostAddress, quint16 portNumber)HEndpoint
HEndpoint(const QUrl &url)HEndpoint
HEndpoint(const QString &arg)HEndpoint
hostAddress() const HEndpoint [inline]
isMulticast() const HEndpoint
isNull() const HEndpoint [inline]
operator!=(const HEndpoint &obj1, const HEndpoint &obj2)HEndpoint [related]
operator==(const HEndpoint &, const HEndpoint &)HEndpoint [friend]
portNumber() const HEndpoint [inline]
qHash(const HEndpoint &)HEndpoint [friend]
toString() const HEndpoint
~HEndpoint()HEndpoint
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_setup-members.html0000644000000000000000000001361311543637604026424 0ustar rootroot Herqq: Member List

HDeviceSetup Member List

This is the complete list of members for HDeviceSetup, including all inherited members.
deviceType() const HDeviceSetup
HDeviceSetup()HDeviceSetup
HDeviceSetup(const HResourceType &type, HInclusionRequirement incReq=InclusionMandatory)HDeviceSetup
HDeviceSetup(const HResourceType &type, int version, HInclusionRequirement incReq=InclusionMandatory)HDeviceSetup
HDeviceSetup(const HDeviceSetup &)HDeviceSetup
inclusionRequirement() const HDeviceSetup
isValid() const HDeviceSetup
operator=(const HDeviceSetup &)HDeviceSetup
setDeviceType(const HResourceType &arg)HDeviceSetup
setInclusionRequirement(HInclusionRequirement arg)HDeviceSetup
setVersion(int version)HDeviceSetup
version() const HDeviceSetup
~HDeviceSetup()HDeviceSetup
herqq-1.0.0/hupnp/docs/html/namespaces.html0000644000000000000000000000463111543637604017376 0ustar rootroot Herqq: Namespace List

Namespace List

Here is a list of all documented namespaces with brief descriptions:
HerqqThe main namespace of Herqq libraries
Herqq::UpnpThe namespace that contains all of the Herqq UPnP core functionality
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_model_creator.png0000644000000000000000000000072111543637604026267 0ustar rootroot‰PNG  IHDR‹P>v!PLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2`IDATxíÝK’!`1UÞÿȳ@4fÒ¡R¿‹~øê/(f[yJyÔ,Xn²\‰ˆfͪç²ùR {RXæ7ˆCTk¥J#`ò&ÍŸ±ôo?º·ÝJ¾eá[ÌÊHåm–]\dI¬¥ïò°¸ÛKÛ÷Ý<Š÷ï—ð|QOý>Gø€X^µä)å’Ò®™æÛ,­åÁ$²´–“É‚<‚X`X`X`ùb å)…ÒXþdáõ¼Š:.*lƒ¼ÑHÒÕ‡O,‹žþ,зز™ëÜÂ3ј¯W÷Ùë•e6ØqÆŸÃå"†E# ~°]Ü âj¾Z±ô£ï‰E*°„Ô‚ÉÚò|Æ&5jáx„j7–1Ÿn>µ˜.6.*4a\ü~ña=µ˜nã.Ån¿ø¹âýrp¾Ì»M,›_¶áWþÍóE+ü‡lòÿ°ÀËí–<åÄAcü–IEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_state_variable_info-members.html0000644000000000000000000003416011543637604027745 0ustar rootroot Herqq: Member List

HStateVariableInfo Member List

This is the complete list of members for HStateVariableInfo, including all inherited members.
allowedValueList() const HStateVariableInfo
dataType() const HStateVariableInfo
defaultValue() const HStateVariableInfo
eventingType() const HStateVariableInfo
EventingType enum nameHStateVariableInfo
HStateVariableInfo()HStateVariableInfo
HStateVariableInfo(const QString &name, HUpnpDataTypes::DataType dataType, HInclusionRequirement incReq, QString *err=0)HStateVariableInfo
HStateVariableInfo(const QString &name, HUpnpDataTypes::DataType dataType, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)HStateVariableInfo
HStateVariableInfo(const QString &name, HUpnpDataTypes::DataType dataType, const QVariant &defaultValue, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)HStateVariableInfo
HStateVariableInfo(const QString &name, const QVariant &defaultValue, const QStringList &allowedValueList, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)HStateVariableInfo
HStateVariableInfo(const QString &name, HUpnpDataTypes::DataType dataType, const QVariant &defaultValue, const QVariant &minimumValue, const QVariant &maximumValue, const QVariant &stepValue, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)HStateVariableInfo
HStateVariableInfo(const HStateVariableInfo &)HStateVariableInfo
inclusionRequirement() const HStateVariableInfo
isConstrained() const HStateVariableInfo
isValid() const HStateVariableInfo
isValidValue(const QVariant &value, QVariant *convertedValue=0, QString *err=0) const HStateVariableInfo
maxEventRate() const HStateVariableInfo
maximumValue() const HStateVariableInfo
minimumValue() const HStateVariableInfo
name() const HStateVariableInfo
NoEvents enum valueHStateVariableInfo
operator!=(const HStateVariableInfo &obj1, const HStateVariableInfo &obj2)HStateVariableInfo [related]
operator=(const HStateVariableInfo &)HStateVariableInfo
operator==(const HStateVariableInfo &, const HStateVariableInfo &)HStateVariableInfo [friend]
qHash(const HStateVariableInfo &key)HStateVariableInfo [related]
setAllowedValueList(const QStringList &arg)HStateVariableInfo
setAllowedValueRange(const QVariant &minimumValue, const QVariant &maximumValue, const QVariant &stepValue, QString *err=0)HStateVariableInfo
setDefaultValue(const QVariant &arg, QString *err=0)HStateVariableInfo
setEventingType(EventingType arg)HStateVariableInfo
setInclusionRequirement(HInclusionRequirement arg)HStateVariableInfo
setMaxEventRate(qint32 arg)HStateVariableInfo
setVersion(qint32 version)HStateVariableInfo
stepValue() const HStateVariableInfo
UnicastAndMulticast enum valueHStateVariableInfo
UnicastOnly enum valueHStateVariableInfo
version() const HStateVariableInfo
~HStateVariableInfo()HStateVariableInfo
herqq-1.0.0/hupnp/docs/html/doxygen.css0000644000000000000000000002735511543637604016570 0ustar rootroot/* The standard CSS for doxygen */ body, table, div, p, dl { font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; font-size: 12px; } /* @group Heading Levels */ h1 { font-size: 150%; } h2 { font-size: 120%; } h3 { font-size: 100%; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd, p.starttd { margin-top: 2px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } p.endtd { margin-bottom: 2px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } h3.version { font-size: 90%; text-align: center; } div.qindex, div.navtab{ background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; padding: 2px; } div.qindex, div.navpath { width: 100%; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #3D578C; font-weight: normal; text-decoration: none; } .contents a:visited { color: #4665A2; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #9CAFD4; color: #ffffff; border: 1px double #869DCA; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code { color: #4665A2; } a.codeRef { color: #4665A2; } /* @end */ dl.el { margin-left: -1cm; } .fragment { font-family: monospace, fixed; font-size: 105%; } pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; } div.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; border: solid thin #333; border-radius: 0.5em; -webkit-border-radius: .5em; -moz-border-radius: .5em; box-shadow: 2px 2px 3px #999; -webkit-box-shadow: 2px 2px 3px #999; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); } div.groupHeader { margin-left: 16px; margin-top: 12px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background: white; color: black; margin: 0; } div.contents { margin-top: 10px; margin-left: 10px; margin-right: 10px; } td.indexkey { background-color: #EBEFF6; font-weight: bold; border: 1px solid #C4CFE5; margin: 2px 0px 2px 0; padding: 2px 10px; } td.indexvalue { background-color: #EBEFF6; border: 1px solid #C4CFE5; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #EEF1F7; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } address.footer { text-align: right; padding-right: 12px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } /* @end */ /* .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } */ td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #A3B4D7; } th.dirtab { background: #EBEFF6; font-weight: bold; } hr { height: 0px; border: none; border-top: 1px solid #4A6AAA; } hr.footer { height: 1px; } /* @group Member Descriptions */ table.memberdecls { border-spacing: 0px; padding: 0px; } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #F9FAFC; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memItemLeft, .memItemRight, .memTemplParams { border-top: 1px solid #C4CFE5; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memTemplParams { color: #4665A2; white-space: nowrap; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtemplate { font-size: 80%; color: #4665A2; font-weight: normal; margin-left: 9px; } .memnav { background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 0; margin-bottom: 10px; } .memname { white-space: nowrap; font-weight: bold; margin-left: 6px; } .memproto { border-top: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 0px 6px 0px; color: #253555; font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 8px; border-top-left-radius: 8px; /* firefox specific markup */ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; -moz-border-radius-topright: 8px; -moz-border-radius-topleft: 8px; /* webkit specific markup */ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 8px; -webkit-border-top-left-radius: 8px; background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; } .memdoc { border-bottom: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 2px 5px; background-color: #FBFCFD; border-top-width: 0; /* opera specific markup */ border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); /* firefox specific markup */ -moz-border-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); /* webkit specific markup */ -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } .params, .retval, .exception, .tparams { border-spacing: 6px 2px; } .params .paramname, .retval .paramname { font-weight: bold; vertical-align: top; } .params .paramtype { font-style: italic; vertical-align: top; } .params .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } /* @end */ /* @group Directory (tree) */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin: 0px; } /* these are for tree view when used as main index */ .directory { font-size: 9pt; font-weight: bold; margin: 5px; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } /* The following two styles can be used to replace the root node title with an image of your choice. Simply uncomment the next two styles, specify the name of your image and be sure to set 'height' to the proper pixel height of your image. */ /* .directory h3.swap { height: 61px; background-repeat: no-repeat; background-image: url("yourimage.gif"); } .directory h3.swap span { display: none; } */ .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } /* these are for tree view when not used as main index */ .directory-alt { font-size: 100%; font-weight: bold; } .directory-alt h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory-alt > h3 { margin-top: 0; } .directory-alt p { margin: 0px; white-space: nowrap; } .directory-alt div { display: none; margin: 0px; } .directory-alt img { vertical-align: -30%; } /* @end */ div.dynheader { margin-top: 8px; } address { font-style: normal; color: #2A3D61; } table.doxtable { border-collapse:collapse; } table.doxtable td, table.doxtable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.doxtable th { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; text-align:left; } .tabsearch { top: 0px; left: 10px; height: 36px; background-image: url('tab_b.png'); z-index: 101; overflow: hidden; font-size: 13px; } .navpath ul { font-size: 11px; background-image:url('tab_b.png'); background-repeat:repeat-x; height:30px; line-height:30px; color:#8AA0CC; border:solid 1px #C2CDE4; overflow:hidden; margin:0px; padding:0px; } .navpath li { list-style-type:none; float:left; padding-left:10px; padding-right:15px; background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; color:#364D7C; } .navpath li.navelem a { height:32px; display:block; text-decoration: none; outline: none; } .navpath li.navelem a:hover { color:#6884BD; } .navpath li.footer { list-style-type:none; float:right; padding-left:10px; padding-right:15px; background-image:none; background-repeat:no-repeat; background-position:right; color:#364D7C; font-size: 8pt; } div.summary { float: right; font-size: 8pt; padding-right: 5px; width: 50%; text-align: right; } div.summary a { white-space: nowrap; } div.ingroups { font-size: 8pt; padding-left: 5px; width: 50%; text-align: left; } div.ingroups a { white-space: nowrap; } div.header { background-image:url('nav_h.png'); background-repeat:repeat-x; background-color: #F9FAFC; margin: 0px; border-bottom: 1px solid #C4CFE5; } div.headertitle { padding: 5px 5px 5px 10px; } dl { padding: 0 0 0 10px; } dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug { border-left:4px solid; padding: 0 0 0 6px; } dl.note { border-color: #D0D000; } dl.warning, dl.attention { border-color: #FF0000; } dl.pre, dl.post, dl.invariant { border-color: #00D000; } dl.deprecated { border-color: #505050; } dl.todo { border-color: #00C0E0; } dl.test { border-color: #3030E0; } dl.bug { border-color: #C08050; } #projectlogo { text-align: center; vertical-align: bottom; border-collapse: separate; } #projectlogo img { border: 0px none; } #projectname { font: 300% arial,sans-serif; margin: 0px; padding: 0px; } #projectbrief { font: 120% arial,sans-serif; margin: 0px; padding: 0px; } #projectnumber { font: 50% arial,sans-serif; margin: 0px; padding: 0px; } #titlearea { padding: 0px; margin: 0px; width: 100%; border-bottom: 1px solid #5373B4; } herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_control_point-members.html0000644000000000000000000004125111543637604026635 0ustar rootroot Herqq: Member List

HControlPoint Member List

This is the complete list of members for HControlPoint, including all inherited members.
acceptResource(const HDiscoveryType &usn, const HEndpoint &source)HControlPoint [private, virtual]
acceptRootDevice(HClientDevice *device)HControlPoint [private, virtual]
AddDevice enum valueHControlPoint [protected]
AddDevice_SubscribeAllEvents enum valueHControlPoint [protected]
AddDevice_SubscribeEventsIfConfigured enum valueHControlPoint [protected]
AlreadyInitializedError enum valueHControlPoint
authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)HControlPoint [signal]
cancelEvents(HClientDevice *device, DeviceVisitType visitType)HControlPoint
cancelEvents(HClientService *service)HControlPoint
CommunicationsError enum valueHControlPoint
configuration() const HControlPoint [protected]
ControlPointError enum nameHControlPoint
device(const HUdn &udn, TargetDeviceType deviceType=RootDevices) const HControlPoint
DeviceDiscoveryAction enum nameHControlPoint [protected]
devices(const HResourceType &deviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive, TargetDeviceType deviceTypes=RootDevices)HControlPoint
doInit()HControlPoint [private, virtual]
doQuit()HControlPoint [private, virtual]
error() const HControlPoint
errorDescription() const HControlPoint
HControlPoint(QObject *parent=0)HControlPoint
HControlPoint(const HControlPointConfiguration &configuration, QObject *parent=0)HControlPoint
IgnoreDevice enum valueHControlPoint [protected]
init()HControlPoint
InvalidArgumentError enum valueHControlPoint
isStarted() const HControlPoint
NotInitializedError enum valueHControlPoint
quit()HControlPoint [slot]
removeRootDevice(HClientDevice *rootDevice)HControlPoint
rootDeviceInvalidated(Herqq::Upnp::HClientDevice *device)HControlPoint [signal]
rootDeviceOffline(Herqq::Upnp::HClientDevice *device)HControlPoint [signal]
rootDeviceOnline(Herqq::Upnp::HClientDevice *device)HControlPoint [signal]
rootDeviceRemoved(const Herqq::Upnp::HDeviceInfo &deviceInfo)HControlPoint [signal]
rootDevices() const HControlPoint
scan(const HDiscoveryType &discoveryType, qint32 count=1)HControlPoint
scan(const HDiscoveryType &discoveryType, const HEndpoint &destination, qint32 count=1)HControlPoint
setError(ControlPointError error, const QString &errorDescr)HControlPoint [protected]
Subscribed enum valueHControlPoint
subscribeEvents(HClientDevice *device, DeviceVisitType visitType)HControlPoint
subscribeEvents(HClientService *service)HControlPoint
Subscribing enum valueHControlPoint
subscriptionCanceled(Herqq::Upnp::HClientService *service)HControlPoint [signal]
subscriptionFailed(Herqq::Upnp::HClientService *service)HControlPoint [signal]
subscriptionStatus(const HClientService *service) const HControlPoint
SubscriptionStatus enum nameHControlPoint
subscriptionSucceeded(Herqq::Upnp::HClientService *service)HControlPoint [signal]
UndefinedError enum valueHControlPoint
Unsubscribed enum valueHControlPoint
~HControlPoint()HControlPoint [virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_action_op-members.html0000644000000000000000000002003011543637604027245 0ustar rootroot Herqq: Member List

HClientActionOp Member List

This is the complete list of members for HClientActionOp, including all inherited members.
abort()HAsyncOp [virtual]
errorDescription() const HAsyncOp
HAsyncOp()HAsyncOp [protected]
HAsyncOp(qint32 returnCode, const QString &errorDescription)HAsyncOp [protected]
HAsyncOp(const HAsyncOp &)HAsyncOp [protected]
HClientActionOp()HClientActionOp
HClientActionOp(const HActionArguments &inArgs)HClientActionOp
HClientActionOp(const HClientActionOp &)HClientActionOp
id() const HAsyncOp
inputArguments() const HClientActionOp
isNull() const HAsyncOp
operator!() const HAsyncOp [inline]
operator=(const HClientActionOp &)HClientActionOp
Herqq::Upnp::HAsyncOp::operator=(const HAsyncOp &)HAsyncOp [protected]
outputArguments() const HClientActionOp
returnValue() const HAsyncOp
setErrorDescription(const QString &arg)HAsyncOp
setOutputArguments(const HActionArguments &outArgs)HClientActionOp
setReturnValue(int returnValue)HAsyncOp
~HAsyncOp()=0HAsyncOp [pure virtual]
~HClientActionOp()HClientActionOp [virtual]
herqq-1.0.0/hupnp/docs/html/functions_func_0x63.html0000644000000000000000000002171211543637604021061 0ustar rootroot Herqq: Class Members - Functions
 

- c -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_service_info-members.html0000644000000000000000000001455411543637604026425 0ustar rootroot Herqq: Member List

HServiceInfo Member List

This is the complete list of members for HServiceInfo, including all inherited members.
controlUrl() const HServiceInfo
eventSubUrl() const HServiceInfo
HServiceInfo()HServiceInfo
HServiceInfo(const HServiceId &serviceId, const HResourceType &serviceType, const QUrl &controlUrl, const QUrl &eventSubUrl, const QUrl &scpdUrl, HInclusionRequirement incReq=InclusionMandatory, HValidityCheckLevel checkLevel=StrictChecks, QString *err=0)HServiceInfo
HServiceInfo(const HServiceInfo &other)HServiceInfo
inclusionRequirement() const HServiceInfo
isValid(HValidityCheckLevel level) const HServiceInfo
operator!=(const HServiceInfo &obj1, const HServiceInfo &obj2)HServiceInfo [related]
operator=(const HServiceInfo &other)HServiceInfo
operator==(const HServiceInfo &obj1, const HServiceInfo &obj2)HServiceInfo [friend]
scpdUrl() const HServiceInfo
serviceId() const HServiceInfo
serviceType() const HServiceInfo
~HServiceInfo()HServiceInfo
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_state_variables_setup_data.html0000644000000000000000000005025311543637604027677 0ustar rootroot Herqq: HStateVariablesSetupData Class Reference

HStateVariablesSetupData Class Reference

This class is used to specify information that can be used to validate UPnP state variables. More...

#include <HStateVariablesSetupData>

List of all members.

Public Types

enum  DefaultInclusionPolicy { Accept, Deny }

Public Member Functions

 HStateVariablesSetupData (DefaultInclusionPolicy defIncPol=Accept)
DefaultInclusionPolicy defaultInclusionPolicy () const
bool contains (const QString &name) const
HStateVariableInfo get (const QString &name) const
bool isEmpty () const
QSet< QString > names () const
qint32 size () const
bool insert (const HStateVariableInfo &newItem)
bool remove (const QString &name)
bool setInclusionRequirement (const QString &name, HInclusionRequirement incReq)

Detailed Description

This class is used to specify information that can be used to validate UPnP state variables.

Remarks:
This class is not thread-safe.

Member Enumeration Documentation

This enumeration specifies the actions the HUPnP device model builder should take when it encounters an unknown state variable definition in a service description file.

Enumerator:
Accept 

The unknown state variable should be accepted.

Deny 

The unknown state variable should be rejected.

In this case the build of a device tree is aborted.


Constructor & Destructor Documentation

Creates a new, empty instance.

Parameters:
defIncPolspecifies the default inclusion policy for state variables that are not contained in this instance.
See also:
isEmpty(), defaultInclusionPolicy()

Member Function Documentation

HStateVariablesSetupData::DefaultInclusionPolicy defaultInclusionPolicy ( ) const

Returns the default inclusion policy.

The default inclusion policy specifies the action to take when a state variable definition in a service description file does not map to any HStateVariableInfo object contained within this instance.

Returns:
The default inclusion policy.
bool contains ( const QString &  name) const

Indicates if the instance contains an item that has the specified name.

Parameters:
namespecifies the name of the item.
Returns:
true when the instance contains an item that has the specified name.
See also:
get(), isEmpty()
HStateVariableInfo get ( const QString &  name) const

Retrieves an item.

Parameters:
namespecifies the name of the item to be retrieved.
Returns:
The item with the specified name. Note that the returned item is invalid, i.e. HStateVariableInfo::isValid() returns false in case no item with the specified name was found.
See also:
contains(), isEmpty()
bool isEmpty ( ) const

Indicates if the object is empty.

Returns:
true in case the instance has no items.
QSet< QString > names ( ) const

Returns the names of the contained items.

Returns:
The names of the contained items.
qint32 size ( ) const

Returns the number of contained items.

Returns:
The number of contained items.
bool insert ( const HStateVariableInfo newItem)

Inserts a new item.

Parameters:
newItemspecifies the item to be added.
Returns:
true in case the item was added. The item will not be added if the instance already contains an item that has the same name as the newItem.
See also:
remove()
bool remove ( const QString &  name)

Removes an existing item.

Parameters:
namespecifies the name of the item to be removed.
Returns:
true in case the item was found and removed.
See also:
insert()
bool setInclusionRequirement ( const QString &  name,
HInclusionRequirement  incReq 
)

Sets the inclusion requirement element of an item.

Parameters:
namespecifies the name of the item.
incReqspecifies the inclusion requirement value.
Returns:
true when the item was found and the inclusion requirement element was set.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_state_variable_event.html0000644000000000000000000003123111543637604026477 0ustar rootroot Herqq: HStateVariableEvent Class Reference

HStateVariableEvent Class Reference

This is a class used to transfer state variable event information. More...

#include <HStateVariableEvent>

List of all members.

Public Member Functions

 HStateVariableEvent ()
 HStateVariableEvent (const QVariant &previousValue, const QVariant &newValue)
 HStateVariableEvent (const HStateVariableEvent &)
 ~HStateVariableEvent ()
HStateVariableEventoperator= (const HStateVariableEvent &)
bool isEmpty () const
QVariant previousValue () const
QVariant newValue () const

Detailed Description

This is a class used to transfer state variable event information.

See also:
HClientStateVariable, HServerStateVariable
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isEmpty()
HStateVariableEvent ( const QVariant &  previousValue,
const QVariant &  newValue 
)

Creates a new instance based on the provided values.

Parameters:
previousValuespecifies the value before the change.
newValuespecifies the value of the state variable at the time the event was generated.
See also:
isEmpty()

Copy constructor.

Copies the contents of the other to this.

Destroys the instance.


Member Function Documentation

HStateVariableEvent & operator= ( const HStateVariableEvent other)

Assigns the contents of the other object to this.

Returns:
reference to this object.
bool isEmpty ( ) const

Indicates if the instance is empty.

Returns:
true if the instance is empty, which means that none of its attributes contain a valid non-empty value.
QVariant previousValue ( ) const

Returns the previous value of the state variable.

Returns:
The previous value of the state variable.
QVariant newValue ( ) const

Returns the new, changed value of the state variable.

Returns:
The new, changed value of the state variable.
herqq-1.0.0/hupnp/docs/html/functions_func_0x62.html0000644000000000000000000001273311543637604021063 0ustar rootroot Herqq: Class Members - Functions
 

- b -

herqq-1.0.0/hupnp/docs/html/functions_rela.html0000644000000000000000000001207211543637604020270 0ustar rootroot Herqq: Class Members - Related Functions herqq-1.0.0/hupnp/docs/html/functions_func_0x76.html0000644000000000000000000001374111543637604021070 0ustar rootroot Herqq: Class Members - Functions herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_host_runtime_status-members.html0000644000000000000000000000722411543637604031410 0ustar rootroot Herqq: Member List

HDeviceHostRuntimeStatus Member List

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_resource_unavailable-members.html0000644000000000000000000001402111543637604030131 0ustar rootroot Herqq: Member List

HResourceUnavailable Member List

This is the complete list of members for HResourceUnavailable, including all inherited members.
bootId() const HResourceUnavailable
configId() const HResourceUnavailable
HResourceUnavailable()HResourceUnavailable
HResourceUnavailable(const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=-1)HResourceUnavailable
HResourceUnavailable(const HResourceUnavailable &)HResourceUnavailable
isValid(HValidityCheckLevel level) const HResourceUnavailable
location() const HResourceUnavailable
operator!=(const HResourceUnavailable &obj1, const HResourceUnavailable &obj2)HResourceUnavailable [related]
operator=(const HResourceUnavailable &)HResourceUnavailable
operator==(const HResourceUnavailable &, const HResourceUnavailable &)HResourceUnavailable [friend]
usn() const HResourceUnavailable
~HResourceUnavailable()HResourceUnavailable
herqq-1.0.0/hupnp/docs/html/functions_0x73.html0000644000000000000000000005066311543637604020056 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- s -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_resource_unavailable.html0000644000000000000000000005242711543637604026515 0ustar rootroot Herqq: HResourceUnavailable Class Reference

HResourceUnavailable Class Reference

Class that represents the device unavailable (ssdp:byebye) message. More...

#include <HResourceUnavailable>

List of all members.

Public Member Functions

 HResourceUnavailable ()
 HResourceUnavailable (const HDiscoveryType &usn, qint32 bootId=-1, qint32 configId=-1)
 ~HResourceUnavailable ()
 HResourceUnavailable (const HResourceUnavailable &)
HResourceUnavailableoperator= (const HResourceUnavailable &)
bool isValid (HValidityCheckLevel level) const
const HDiscoveryTypeusn () const
qint32 bootId () const
qint32 configId () const
HEndpoint location () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HResourceUnavailable &, const HResourceUnavailable &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HResourceUnavailable &obj1, const HResourceUnavailable &obj2)

Detailed Description

Class that represents the device unavailable (ssdp:byebye) message.

According to the UDA, When a device and its services are going to be removed from the network, the device SHOULD multicast an ssdp:byebye message corresponding to each of the ssdp:alive messages it multicasted that have not already expired. In HUPnP this class represents such a message.

Usually you create instances of this class to be sent by the Herqq::Upnp::HSsdp, or you receive instances of this class from the Herqq::Upnp::HSsdp.

Remarks:
the class provides an assignment operator, which is not thread-safe.
See also:
HSsdp

Constructor & Destructor Documentation

Constructs a new, empty instance.

The constructed object is not valid, i.e isValid() returns false.

See also:
isValid()
HResourceUnavailable ( const HDiscoveryType usn,
qint32  bootId = -1,
qint32  configId = -1 
)

Creates a new instance.

Parameters:
usnspecifies the Unique Service Name. The created object is invalid if the provided USN is invalid.
bootIdspecifies the BOOTID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0.
configIdspecifies the CONFIGID.UPNP.ORG header value. Note that this is mandatory in UDA v1.1, whereas it is not specified at all in UDA v1.0.
See also:
isValid()

Destroys the instance.

Copy constructor.

Copies the contents of the other to this object.


Member Function Documentation

HResourceUnavailable & operator= ( const HResourceUnavailable other)

Assigns the contents of the other to this.

Returns:
a reference to this object.
bool isValid ( HValidityCheckLevel  level) const

Indicates whether or not the object contains valid announcement information.

Parameters:
levelindicates whether the check should be strictly according to the UDA specification. If set to false some checks are omitted that are known to be poorly implemented in some UPnP software.
Returns:
true in case the objects contains valid announcement information in terms of the requested strictness.
const HDiscoveryType & usn ( ) const

Returns the Unique Service Name.

The Unique Service Name identifies a unique device or service instance.

Returns:
The Unique Service Name. The returned object is invalid if this object is invalid.
See also:
isValid()
qint32 bootId ( ) const

Returns the value of BOOTID.UPNP.ORG.

Returns:
The value of BOOTID.UPNP.ORG. If the value is not specified -1 is returned.
qint32 configId ( ) const

Returns the value of CONFIGID.UPNP.ORG.

Returns:
The value of CONFIGID.UPNP.ORG. If the value is not specified -1 is returned.
HEndpoint location ( ) const

Returns the IP endpoint of the device that went offline.

Returns:
The IP endpoint of the device that went offline.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HResourceUnavailable ,
const HResourceUnavailable  
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HResourceUnavailable obj1,
const HResourceUnavailable obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/group__hupnp__common.html0000644000000000000000000005522111543637604021474 0ustar rootroot Herqq: Common

Classes

class  HActionInfo
 This class is used to contain information of a UPnP action found in a UPnP service description document. More...
class  HDeviceInfo
 This class is used to contain information of a UPnP device found in a UPnP device description document. More...
class  HDiscoveryType
 This is a class that depicts the different discovery types used in UPnP networking. More...
class  HProductToken
 This class represents a product token as defined in the RFC 2616, section 3.8. More...
class  HProductTokens
 This class is used to parse the product tokens defined by HTTP/1.1. More...
class  HResourceType
 This is a class used to depict a UPnP resource, which is either a UPnP device or a UPnP service. More...
class  HServiceId
 Class that represents the service identifier of a UPnP service. More...
class  HServiceInfo
 This class is used to contain information of a UPnP service found in a UPnP device description document. More...
class  HStateVariableInfo
 This class is used to contain information of a UPnP state variable found in a UPnP service description document. More...
class  HUdn
 This is a class used to depict a Unique Device Name (UDN), which is a unique device identifier that has to remain the same over time for a specific device instance. More...
class  HClonable
 This class defines an interface for cloning instances of polymorphic classes. More...

Typedefs

typedef QList< HEndpoint > HEndpoints

Enumerations

enum  HValidityCheckLevel { StrictChecks, LooseChecks }
enum  HInclusionRequirement { InclusionRequirementUnknown = 0, InclusionMandatory, InclusionOptional }
enum  HLogLevel {
  None = 0, Fatal = 1, Critical = 2, Warning = 3,
  Information = 4, Debug = 5, All = 6
}

Functions

void SetLoggingLevel (HLogLevel level)
void EnableNonStdBehaviourWarnings (bool arg)

Typedef Documentation

typedef QList<HEndpoint> HEndpoints

This is a type definition to a list of Herqq::Upnp::HEndpoint instances.

See also:
HEndpoint

Enumeration Type Documentation

enum HValidityCheckLevel

This enumeration is used to specify the strictness of argument validation.

Enumerator:
StrictChecks 

The arguments are validated strictly according to the UDA v1.0 and v1.1 specifications.

LooseChecks 

The validation allows slight deviations from the UDA specifications in an attempt to improve interoperability.

The accepted exceptions have been encountered in other UPnP software that are popular enough to warrant the exceptional behavior.

enum HInclusionRequirement

This enumeration specifies whether a component of the Device Model is mandatory within a specific UPnP device.

In more detail, any component of the device model (a device, a service, a state variable or an action) may be specified as a mandatory or an optional part of a UPnP device; for example, a UPnP device may have two mandatory embedded devices and one optional embedded device. The same applies to the other components as well.

When HUPnP builds an object model of a UPnP device, this information can be used in validating a description document, or verifying that the provided device tree accurately depicts a description document.

For instance, if the author of a subclass of a HServerService has specified that a particular action is mandatory, the user of the class, who is the one that provides the description document, has to make sure that the description document also contains the definition of the action.

These types of mappings are optional, but they are highly useful in case the component is to be used as a public part of a library. They help to ensure that the implementation back-end reflects the used description documents appropriately. This is important, as it is the description documents that are transferred from servers to clients and it is these documents that advertise what a particular UPnP device supports and is capable of doing.

From the client's perspective they are also useful in defining requirements for device and service types. For instance, if you have a component that expects a discovered UPnP device to contain certain services, state variables and actions, HUPnP can use these requirements to filter devices that are suitable in terms of advertised capabilities.

Enumerator:
InclusionRequirementUnknown 

This value indicates that the inclusion requirement for the component is not specified.

This value is used only in error situations.

InclusionMandatory 

This value indicates that the component has to be appropriately specified.

It is a critical error if the component is missing.

InclusionOptional 

This value indicates that the component is optional and may or may not be specified.

enum HLogLevel

This enumeration specifies the logging levels that can be used with the device host.

Enumerator:
None 

No logs are generated.

Remarks:
by default, HUPnP uses this logging level.
Fatal 

Only fatal messages are logged.

Most often a fatal message is followed by termination of the application.

Critical 

Only critical and fatal messages are logged.

Most often a critical message signals a severe runtime error.

Warning 

Messages with level set to warning, critical and fatal are logged.

A warning message usually signifies an error or exceptional situation that should be noted. Most often the system stability is not at stake when warning messages appear, but they may still indicate that some component, internal or external, is not functioning correctly. Usually the source of warnings should be investigated.

Information 

All but debug level messages are logged.

An informational message is used to log status information of control flow. A good example of an informational message is when a sizable component logs the start of an initialization procedure.

Debug 

All up to the debug messages are output.

This excludes only the function enter and exit messages.

Remarks:
Enabling this level of logging has notable effect on performance. This generally should be used only for debugging purposes.
All 

Every log message is output.

This includes even the function enters and exits.

Remarks:
Enabling this level of logging has severe effect on performance. This is very rarely needed and usually the debug level is far more helpful.

Function Documentation

void H_UPNP_CORE_EXPORT SetLoggingLevel ( HLogLevel  level)

Sets the logging level the HUPnP should use.

Parameters:
levelspecifies the desired logging level.
Remarks:
  • The new logging level will take effect immediately.
  • The function is thread-safe.
void H_UPNP_CORE_EXPORT EnableNonStdBehaviourWarnings ( bool  arg)

Enables / disables warnings that relate to non-standard behavior discovered in other UPnP software.

Most often if non-standard behavior in other UPnP software is discovered, it isn't fatal or critical and it may be possible to inter-operate with the software. However, deviations from the specifications and standards are unfortunate and such errors should be fixed.

Regardless, you may not want to be notified about these warnings in which case you can specifically disable all the warnings that relate to non-standard behavior.

Parameters:
argspecifies whether to output warnings that are about non-standard behavior in other UPnP software.
Remarks:
by default, the non standard behavior warnings are on.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_product_tokens.html0000644000000000000000000010065111543637604025357 0ustar rootroot Herqq: HProductTokens Class Reference

HProductTokens Class Reference

This class is used to parse the product tokens defined by HTTP/1.1. More...

#include <HProductTokens>

List of all members.

Public Member Functions

 HProductTokens ()
 HProductTokens (const QString &arg)
 HProductTokens (const HProductTokens &)
 ~HProductTokens ()
HProductTokensoperator= (const HProductTokens &)
bool isValid () const
bool isEmpty () const
HProductToken osToken () const
HProductToken upnpToken () const
HProductToken productToken () const
QVector< HProductTokenextraTokens () const
bool hasExtraTokens () const
QVector< HProductTokentokens () const
QString toString () const

Related Functions

(Note that these are not member functions.)
H_UPNP_CORE_EXPORT bool operator== (const HProductTokens &, const HProductTokens &)
bool operator!= (const HProductTokens &obj1, const HProductTokens &obj2)

Detailed Description

This class is used to parse the product tokens defined by HTTP/1.1.

According to the HTTP/1.1, Product tokens are used to allow communicating applications to identify themselves by software name and version. In UDA, the product tokens consist of three tokens, in which The first product token identifes the operating system in the form OS name/OS version, the second token represents the UPnP version and MUST be UPnP/1.1, and the third token identifes the product using the form product name/product version. For example, "SERVER: unix/5.1 UPnP/1.1 MyProduct/1.0".

Unfortunately, product tokens found in UPnP products are rarely conforming to the HTTP/1.1 and UDA specifications. Many products handle "product tokens" as a string that contains "key/value" pairs laid out and delimited arbitrarily. Because of this, HProductTokens has to accept input that is not strictly standard-conformant. However, at absolute minimum UPnP devices have to provide the UPnP version token. Because of that, HProductTokens instance is considered valid if the instance contains a valid UPnP version token. All other tokens are considered optional and they may not be present in a valid instance. In practice this means that if isValid() returns true the instance contains a valid UPnP version token, which can be retrieved using upnpToken(). In that case the tokens() returns a list at least of size one. In addition, the instance may contain other data that could not be parsed following the HTTP/1.1 and UDA specifications. This data cannot be retrieved using any of the functions that return HProductToken instances, but you can retrieve the full unparsed product tokens string using toString().

Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Constructs a new invalid and empty instance.

See also:
isValid(), isEmpty()
HProductTokens ( const QString &  arg) [explicit]

Creates a new instance based on the provided argument.

Parameters:
argspecifies the product tokens. In case the specified argument does not contain a valid UPnP version token the created object will be invalid. However, the object will not be empty and the provided string is returned when toString() is called.
See also:
isValid(), isEmpty(), toString(), upnpToken()

Copy constructor.

Creates a copy of the other object.

Destroys the instance.


Member Function Documentation

HProductTokens& operator= ( const HProductTokens )

Assigns the contents of the other to this.

Returns:
a reference to this object.
bool isValid ( ) const

Indicates whether the object contains at least the UPnP version token defined in the UDA.

Returns:
true in case the object contains at least the UPnP version token defined in the UDA.
Remarks:
an invalid object is not necessarily empty; an object may contain data that could not be parsed into HProductToken objects. In this case you can call toString() to retrieve the full product tokens string.
See also:
isEmpty()
bool isEmpty ( ) const

Indicates whether the object contains any information at all.

Returns:
true in case the object does not contain any information.
Remarks:
an empty object is also invalid.
See also:
isValid()
HProductToken osToken ( ) const

Returns the product token that defines information of an operating system.

Returns:
The product token that defines information of an operating system.
Remarks:
This is not necessarily defined in a non-empty object.
See also:
isValid()
HProductToken upnpToken ( ) const

Returns the product token that defines UPnP version.

Returns:
The product token that defines UPnP version. This token always follows the format "UPnP"/majorVersion.minorVersion, where majorVersion and minorVersion are positive integers. Furthermore, currently the majorVersion is always 1 and the minorVersion is either 0 or 1.
Remarks:
This is always defined in a valid object.
See also:
isValid()
HProductToken productToken ( ) const

Returns the product token that defines the actual product in the form product name/product version.

Returns:
The product token that defines the actual product in the form product name/product version.
Remarks:
This is not necessarily defined in a non-empty object.
See also:
isValid()
QVector< HProductToken > extraTokens ( ) const

Returns the extra tokens.

A valid HProductTokens object contains at least the upnpToken(). A strictly valid HProductTokens object contains at least the osToken(), upnpToken() and producToken(). However, a HProductTokens instance may contain more than these three tokens, which are called extra tokens in this context.

Returns:
The extra tokens, if such are defined and the object is valid.
See also:
hasExtraTokens(), isValid(), tokens()
bool hasExtraTokens ( ) const

Indicates if the object contains extra tokens in addition to osToken(), upnpToken() and producToken().

Returns:
true in case the object contains extra tokens in addition to osToken(), upnpToken() and producToken().
QVector< HProductToken > tokens ( ) const

Returns all product tokens the instance contains.

A valid HProductTokens object will return a vector that contains at least one entry, the upnpToken(). A strictly valid HProductTokens object will return a vector that contains at least three entries, the osToken(), upnpToken() and producToken(). If the object contains extra tokens the extra tokens are appended to the returned vector.

Returns:
all product tokens in a vector. An invalid object returns a vector with no elements. However, even in this case the object may not be empty.
See also:
isValid(), isEmpty(), extraTokens(), toString()
QString toString ( ) const

Returns a string representation of the object.

Returns:
a string representation of the object.
Remarks:
This method may return a non-empty string even in case isValid() returns false. In this case the instance was created with a string that could not be tokenized according to the UDA and HTTP 1.1 specifications.
See also:
isEmpty(), isValid()

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HProductTokens ,
const HProductTokens  
) [related]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HProductTokens obj1,
const HProductTokens obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_async_op.html0000644000000000000000000005256411543637604024140 0ustar rootroot Herqq: HAsyncOp Class Reference

This abstract class is used as a base for identifying an asynchronous operation and detail information of it. More...

#include <HAsyncOp>

Inheritance diagram for HAsyncOp:
HClientActionOp

List of all members.

Public Member Functions

virtual ~HAsyncOp ()=0
QString errorDescription () const
void setErrorDescription (const QString &arg)
int returnValue () const
void setReturnValue (int returnValue)
unsigned int id () const
bool isNull () const
bool operator! () const
virtual void abort ()

Protected Member Functions

 HAsyncOp ()
 HAsyncOp (qint32 returnCode, const QString &errorDescription)
 HAsyncOp (const HAsyncOp &)
HAsyncOpoperator= (const HAsyncOp &)

Detailed Description

This abstract class is used as a base for identifying an asynchronous operation and detail information of it.

Some HUPnP components provide an asynchronous interface for running possible long-standing operations. A most notable example of this is the client-side action invocation initiated with HClientAction::beginInvoke(). In cases like this, the class running the operation returns a derivative of this class, which is used to identify and describe the running operation.

Usage

The component that runs an asynchronous operation provides an instance derived from this class when the operation is started. A copy of that instance is provided also when the component signals the operation is complete. The provided instance uniquely identifies the operation, carries information whether the operation eventually succeeded or not and it may contain an error description in case of an error.

For example:

 HClientActionOp op = someActionObject->beginInvoke();

 //
 // The operation completes, after which you can:
 //

 int retVal = op.returnValue();
 // retrieve a return value indicating whether the operation succeeded.

 QString errDescr = op.errorDescription();
 // retrieve an error description if the operation failed.
Note:
HAsyncOp and any derivative class provided by HUPnP use explicit sharing, which basically means that every copy of an instance references the same underlying data and any change to that data is visible to all of the copies.
Remarks:
This class is not thread-safe.
See also:
HClientActionOp

Constructor & Destructor Documentation

HAsyncOp ( ) [protected]

Creates a new valid instance.

Creates a new valid instance, i.e isNull() always returns false.

See also:
isNull()
HAsyncOp ( qint32  returnCode,
const QString &  errorDescription 
) [protected]

Creates a new instance, invalid instance.

Parameters:
returnCodespecifies the return code.
errorDescriptionspecifies a human-readable description of the error that occurred.
HAsyncOp ( const HAsyncOp op) [protected]

Copy constructor.

Creates a shallow copy of other increasing the reference count of other.

~HAsyncOp ( ) [pure virtual]

Destroys the instance.

Decreases the reference count or destroys the instance once the reference count drops to zero.


Member Function Documentation

HAsyncOp & operator= ( const HAsyncOp op) [protected]

Assignment operator.

Switches this instance to refer to the contents of other increasing the reference count of other.

QString errorDescription ( ) const

Returns a human readable error description.

Returns:
a human readable error description, if any.
See also:
setErrorDescription()
void setErrorDescription ( const QString &  arg)

Sets a human readable error description.

Parameters:
argspecifies the human readable error description.
See also:
errorDescription()
int returnValue ( ) const

Returns the return value of the asynchronous operation.

See also:
setReturnValue()
void setReturnValue ( int  returnValue)

Sets the return value of the asynchronous operation.

Parameters:
returnValuespecifies the return value of the asynchronous operation.
See also:
returnValue()
unsigned int id ( ) const

Returns an identifier of the asynchronous operation.

Returns:
an identifier of the asynchronous operation. The identifier is "unique" within the process where the library is loaded. More specifically, the ID is monotonically incremented and it is allowed to overflow.
bool isNull ( ) const

Indicates whether the object identifies an asynchronous operation.

Return values:
truein case the object does not identify an asynchronous operation. This is usually the case when an operation was not successfully started.
falsein case the object identifies an asynchronous operation.
bool operator! ( ) const [inline]

Indicates whether the object identifies an asynchronous operation.

This is a convenience method and it is semantically equivalent with isNull().

Return values:
truein case the object does not identify an asynchronous operation. This is usually the case when an operation was not successfully started.
falsein case the object identifies an asynchronous operation.
void abort ( ) [virtual]

Aborts the execution of the operation.

Aborts the execution of the operation.

Remarks:
It is up to the implementation to decide whether to implement this. The default implementation does nothing.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_multicast_socket-members.html0000644000000000000000000001143511543637604027322 0ustar rootroot Herqq: Member List

HMulticastSocket Member List

This is the complete list of members for HMulticastSocket, including all inherited members.
bind(quint16 port=0)HMulticastSocket
HMulticastSocket(QObject *parent=0)HMulticastSocket [explicit]
joinMulticastGroup(const QHostAddress &groupAddress)HMulticastSocket
joinMulticastGroup(const QHostAddress &groupAddress, const QHostAddress &localAddress)HMulticastSocket
leaveMulticastGroup(const QHostAddress &groupAddress)HMulticastSocket
leaveMulticastGroup(const QHostAddress &groupAddress, const QHostAddress &localAddress)HMulticastSocket
setMulticastTtl(quint8 arg)HMulticastSocket
~HMulticastSocket()HMulticastSocket [virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_state_variable_info.html0000644000000000000000000021436611543637604026325 0ustar rootroot Herqq: HStateVariableInfo Class Reference

HStateVariableInfo Class Reference

This class is used to contain information of a UPnP state variable found in a UPnP service description document. More...

#include <HStateVariableInfo>

List of all members.

Public Types

enum  EventingType { NoEvents = 0, UnicastOnly = 1, UnicastAndMulticast = 2 }

Public Member Functions

 HStateVariableInfo ()
 HStateVariableInfo (const QString &name, HUpnpDataTypes::DataType dataType, HInclusionRequirement incReq, QString *err=0)
 HStateVariableInfo (const QString &name, HUpnpDataTypes::DataType dataType, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)
 HStateVariableInfo (const QString &name, HUpnpDataTypes::DataType dataType, const QVariant &defaultValue, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)
 HStateVariableInfo (const QString &name, const QVariant &defaultValue, const QStringList &allowedValueList, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)
 HStateVariableInfo (const QString &name, HUpnpDataTypes::DataType dataType, const QVariant &defaultValue, const QVariant &minimumValue, const QVariant &maximumValue, const QVariant &stepValue, EventingType eventingType=NoEvents, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)
 HStateVariableInfo (const HStateVariableInfo &)
HStateVariableInfooperator= (const HStateVariableInfo &)
 ~HStateVariableInfo ()
qint32 version () const
void setVersion (qint32 version)
QString name () const
HInclusionRequirement inclusionRequirement () const
void setInclusionRequirement (HInclusionRequirement arg)
qint32 maxEventRate () const
void setMaxEventRate (qint32 arg)
HUpnpDataTypes::DataType dataType () const
EventingType eventingType () const
void setEventingType (EventingType arg)
QStringList allowedValueList () const
bool setAllowedValueList (const QStringList &arg)
QVariant minimumValue () const
QVariant maximumValue () const
QVariant stepValue () const
bool setAllowedValueRange (const QVariant &minimumValue, const QVariant &maximumValue, const QVariant &stepValue, QString *err=0)
QVariant defaultValue () const
bool setDefaultValue (const QVariant &arg, QString *err=0)
bool isConstrained () const
bool isValidValue (const QVariant &value, QVariant *convertedValue=0, QString *err=0) const
bool isValid () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HStateVariableInfo &, const HStateVariableInfo &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HStateVariableInfo &obj1, const HStateVariableInfo &obj2)
H_UPNP_CORE_EXPORT quint32 qHash (const HStateVariableInfo &key)

Detailed Description

This class is used to contain information of a UPnP state variable found in a UPnP service description document.

UPnP service description documents specify the actions and state variables of the service. An instance of this class contain the information of a state variable found in a service description document, such as the name() and the dataType().

In addition to the information found in the service description document, the UPnP service containing the state variable that is depicted by the HStateVariableInfo object may have specified additional information about the state variable:

  • inclusionRequirement() details whether the state variable is considered as mandatory or optional.
  • maxEventRate() specifies the maximum rate at which an evented state variable may send events.

Further, the class contains a few helper methods:

  • isConstrained() indicates if the state variable is restricted either by a value range or a value list.
  • isValidValue() checks if a specified QVariant contains a value that could be inserted into the state variable taking into consideration the data types of the state variable and the specified value as well as any possible constraint set to the state variable.
Remarks:
This class is not thread-safe.
See also:
HDeviceInfo, HServiceInfo and HActionInfo.

Member Enumeration Documentation

Specifies different types of eventing.

See also:
Device Hosting
Enumerator:
NoEvents 

The state variable is not evented and it will never emit valueChanged() signal.

UnicastOnly 

The state variable is evented, valueChanged() signal is emitted upon value change and the HUPnP will propagate events over network to registered listeners through unicast only.

UnicastAndMulticast 

The state variable is evented, valueChanged() signal is emitted upon value change and the HUPnP will propagate events over network using uni- and multicast.


Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isValid()
HStateVariableInfo ( const QString &  name,
HUpnpDataTypes::DataType  dataType,
HInclusionRequirement  incReq,
QString *  err = 0 
)

Creates a new instance.

Parameters:
namespecifies the name of the state variable.
dataTypespecifies the UPnP data type of the state variable.
incReqspecifies whether the service is required or optional. This parameter is optional.
errspecifies a pointer to a QString that will contain an error description in case the construction failed. This is optional.
See also:
isValid()
HStateVariableInfo ( const QString &  name,
HUpnpDataTypes::DataType  dataType,
EventingType  eventingType = NoEvents,
HInclusionRequirement  incReq = InclusionMandatory,
QString *  err = 0 
)

Creates a new instance.

Parameters:
namespecifies the name of the state variable.
dataTypespecifies the UPnP data type of the state variable.
eventingTypespecifies the type of eventing used with the state variable. This is optional.
incReqspecifies whether the service is required or optional. This parameter is optional.
errspecifies a pointer to a QString that will contain an error description in case the construction failed. This is optional.
See also:
isValid()
HStateVariableInfo ( const QString &  name,
HUpnpDataTypes::DataType  dataType,
const QVariant &  defaultValue,
EventingType  eventingType = NoEvents,
HInclusionRequirement  incReq = InclusionMandatory,
QString *  err = 0 
)

Creates a new instance.

Parameters:
namespecifies the name of the state variable.
dataTypespecifies the UPnP data type of the state variable.
defaultValuespecifies the default value.
eventingTypespecifies the type of eventing used with the state variable. This is optional.
incReqspecifies whether the service is required or optional. This parameter is optional.
errspecifies a pointer to a QString that will contain an error description in case the construction failed. This is optional.
See also:
isValid()
HStateVariableInfo ( const QString &  name,
const QVariant &  defaultValue,
const QStringList &  allowedValueList,
EventingType  eventingType = NoEvents,
HInclusionRequirement  incReq = InclusionMandatory,
QString *  err = 0 
)

Creates a new instance with the data type set to HUpnpDataTypes::string.

Parameters:
namespecifies the name of the state variable.
defaultValuespecifies the default value.
allowedValueListspecifies the values the state variable accepts.
eventingTypespecifies the type of eventing used with the state variable. This is optional.
incReqspecifies whether the service is required or optional. This parameter is optional.
errspecifies a pointer to a QString that will contain an error description in case the construction failed. This is optional.
See also:
isValid()
HStateVariableInfo ( const QString &  name,
HUpnpDataTypes::DataType  dataType,
const QVariant &  defaultValue,
const QVariant &  minimumValue,
const QVariant &  maximumValue,
const QVariant &  stepValue,
EventingType  eventingType = NoEvents,
HInclusionRequirement  incReq = InclusionMandatory,
QString *  err = 0 
)
Parameters:
namespecifies the name of the state variable.
dataTypespecifies the UPnP data type of the state variable.
defaultValuespecifies the default value.
minimumValuespecifies the inclusive lower bound of an acceptable value. This cannot be larger than the maximumValue.
maximumValuespecifies the inclusive upper bound of an acceptable value. This cannot be smaller than the minimumValue.
stepValuespecifies the step value. This value cannot be larger than the subtraction of the maximum and minimum values.
eventingTypespecifies the type of eventing used with the state variable. This is optional.
incReqspecifies whether the service is required or optional. This parameter is optional.
errspecifies a pointer to a QString that will contain an error description in case the construction failed. This is optional.

Copy constructor.

Creates a new instance identical to the other object.

Destroys the instance.


Member Function Documentation

HStateVariableInfo& operator= ( const HStateVariableInfo )

Assignment operator.

Assigns the contents of the other to this.

qint32 version ( ) const

Returns the UPnP service version in which the state variable was first specified.

Returns:
The UPnP service version in which the state variable was first specified or -1, if the version is not defined.
Remarks:
It is perfectly normal that the version information is not defined.
See also:
setVersion()
void setVersion ( qint32  version)

Specifies the UPnP service version in which the state variable was first specified.

Parameters:
versionspecifies the UPnP service version in which the state variable was first specified. If a value smaller than -1 is given, the version value will be set to -1, which means that the version() is not defined.
See also:
version()
QString name ( ) const

Returns the name of the action.

This is the name specified in the corresponding service description file.

Returns:
The name of the action.
HInclusionRequirement inclusionRequirement ( ) const

Returns the type of the action, i.e.

is it required or optional.

This is the name specified in the corresponding service description file.

Returns:
The type of the action.
void setInclusionRequirement ( HInclusionRequirement  arg)

Specifies whether the depicted state variable is required or optional.

Parameters:
argspecifies whether the service is required or optional.
qint32 maxEventRate ( ) const

Returns the maximum rate at which an evented state variable may send events.

Returns:
The maximum rate at which an evented state variable may send events. The returned value is -1 if the state variable is not evented or the maximum rate has not been defined.
See also:
setMaxEventRate(), eventingType()
void setMaxEventRate ( qint32  arg)

Sets the maximum rate at which an evented state variable may send events.

Parameters:
argspecifies the maximum rate at which an evented state variable may send events. The rate is not set if the state variable is not evented.
See also:
maxEventRate(), eventingType()
HUpnpDataTypes::DataType dataType ( ) const

Returns the data type of the state variable.

Returns:
The data type of the state variable.
HStateVariableInfo::EventingType eventingType ( ) const

Returns the type of eventing the state variable supports, if any.

Returns:
The type of eventing the state variable supports, if any.
void setEventingType ( HStateVariableInfo::EventingType  arg)

Sets the type of eventing the state variable supports, if any.

Parameters:
argspecifies the type of eventing the state variable supports, if any.
QStringList allowedValueList ( ) const

Returns the list of allowed values.

Returns:
The list of allowed values if the contained data type is string or empty list otherwise.
Remarks:
This is only applicable on state variables, which data type is HUpnpDataTypes::string.
See also:
setAllowedValueList(), dataType()
bool setAllowedValueList ( const QStringList &  arg)

Specifies the values the state variable accepts.

Parameters:
argspecifies the values the state variable accepts.
Remarks:
This is only applicable on state variables, which data type is HUpnpDataTypes::string.
See also:
allowedValueList(), dataType()
QVariant minimumValue ( ) const

Returns the minimum value of the specified value range.

Returns:
The minimum value of the specified value range.
Remarks:
This is only applicable on state variables, which data type is numeric. In addition, it is optional and it may not be defined.
See also:
dataType()
QVariant maximumValue ( ) const

Returns the maximum value of the specified value range.

Returns:
The maximum value of the specified value range.
Remarks:
This is only applicable on state variables, which data type is numeric. In addition, it is optional and it may not be defined.
See also:
dataType()
QVariant stepValue ( ) const

Returns the step value of the specified value range.

Returns:
The step value of the specified value range.
Remarks:
This is only applicable on state variables, which data type is numeric. In addition, it is optional and it may not be defined.
See also:
dataType()
bool setAllowedValueRange ( const QVariant &  minimumValue,
const QVariant &  maximumValue,
const QVariant &  stepValue,
QString *  err = 0 
)

Sets the allowed value range.

Parameters:
minimumValuespecifies the inclusive lower bound of an acceptable value. This cannot be larger than the maximumValue.
maximumValuespecifies the inclusive upper bound of an acceptable value. This cannot be smaller than the minimumValue.
stepValuespecifies the step value. This value cannot be larger than the subtraction of the maximum and minimum values.
errspecifies a pointer to a QString, which contains an error description in case the any of the provided values is invalid. This parameter is optional.
Remarks:
This is only applicable on state variables, which data type is numeric. In addition, it is optional and it may not be defined.
Returns:
true in case the values were successfully set.
QVariant defaultValue ( ) const

Returns the default value of the state variable.

Returns:
The default value of the state variable. If no default has been specified, QVariant::Invalid is returned.
bool setDefaultValue ( const QVariant &  arg,
QString *  err = 0 
)

Sets the default value.

Parameters:
argspecifies the default value. If the value range has been specified the value has to be within the specified range.
errspecifies a pointer to a QString, which contains an error description in case the value is invalid. This parameter is optional.
Returns:
true in case the default value was successfully set.
bool isConstrained ( ) const

Indicates if the state variable's value is constrained either by minimum, maximum or by a list of allowed values.

Returns:
true in case the state variable's value is constrained either by minimum, maximum or by a list of allowed values.
See also:
minimumValue(), maximumValue(), allowedValueList()
bool isValidValue ( const QVariant &  value,
QVariant *  convertedValue = 0,
QString *  err = 0 
) const

Indicates whether or not the value is valid in terms of this particular state variable.

Parameters:
valuespecifies the value to be checked.
convertedValuespecifies a pointer to a QVariant that contains the value as a variant of the correct type. This is optional. Further, it will not be set if the value is invalid.
errspecifies a pointer to a QString, which contains an error description in case the value is invalid. This parameter is optional.
Return values:
\etrue in case the specified value is valid in terms of the state variable this info object depicts. In other words, setValue() will succeed with the value.
falseotherwise.
bool isValid ( ) const

Indicates if the object is valid.

Returns:
true in case the object is valid.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HStateVariableInfo ,
const HStateVariableInfo  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
bool operator!= ( const HStateVariableInfo obj1,
const HStateVariableInfo obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
H_UPNP_CORE_EXPORT quint32 qHash ( const HStateVariableInfo key) [related]

Returns a value that can be used as a unique key in a hash-map identifying the object.

Parameters:
keyspecifies the HStateVariableInfo object from which the hash value is created.
Returns:
a value that can be used as a unique key in a hash-map identifying the object.
herqq-1.0.0/hupnp/docs/html/hupnp__fwd_8h.html0000644000000000000000000001302711543637604020006 0ustar rootroot Herqq: src/general/hupnp_fwd.h File Reference

src/general/hupnp_fwd.h File Reference

This file contains forward-declarations to every public class HUPnP exposes and a few common type definitions. More...

Namespaces

namespace  Herqq
namespace  Herqq::Upnp

Typedefs

typedef QList< HEndpoint > HEndpoints
typedef QList< HClientService * > HClientServices
typedef QList< HServerService * > HServerServices
typedef QList< HClientDevice * > HClientDevices
typedef QList< HServerDevice * > HServerDevices
typedef QHash< QString, const
HClientStateVariable * > 
HClientStateVariables
typedef QHash< QString,
HServerStateVariable * > 
HServerStateVariables
typedef QHash< QString,
HStateVariableInfo > 
HStateVariableInfos
typedef QHash< QString,
HClientAction * > 
HClientActions
typedef QHash< QString,
HServerAction * > 
HServerActions

Detailed Description

This file contains forward-declarations to every public class HUPnP exposes and a few common type definitions.

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_host_runtime_status.html0000644000000000000000000001765211543637604027766 0ustar rootroot Herqq: HDeviceHostRuntimeStatus Class Reference

HDeviceHostRuntimeStatus Class Reference

This is a class for detailing information of the runtime status of an HDeviceHost instance. More...

#include <HDeviceHostRuntimeStatus>

List of all members.

Public Member Functions

virtual ~HDeviceHostRuntimeStatus ()
QList< HEndpointssdpEndpoints () const
QList< HEndpointhttpEndpoints () const

Protected Member Functions

 HDeviceHostRuntimeStatus ()

Detailed Description

This is a class for detailing information of the runtime status of an HDeviceHost instance.

See also:
HDeviceHost

Constructor & Destructor Documentation

HDeviceHostRuntimeStatus ( ) [protected]

Creates an instance.

~HDeviceHostRuntimeStatus ( ) [virtual]

Destroys the instance.


Member Function Documentation

QList< HEndpoint > ssdpEndpoints ( ) const

Returns the IP endpoints that the device host uses for SSDP communications.

Returns:
The IP endpoints that the device host uses for SSDP communications.
QList< HEndpoint > httpEndpoints ( ) const

Returns the IP endpoints that the device host uses for HTTP communications.

Returns:
The IP endpoints that the device host uses for HTTP communications.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_control_point_configuration-members.html0000644000000000000000000001607311543637604031570 0ustar rootroot Herqq: Member List

HControlPointConfiguration Member List

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_discovery_request-members.html0000644000000000000000000001317411543637604027526 0ustar rootroot Herqq: Member List

HDiscoveryRequest Member List

This is the complete list of members for HDiscoveryRequest, including all inherited members.
HDiscoveryRequest()HDiscoveryRequest
HDiscoveryRequest(qint32 mx, const HDiscoveryType &resource, const HProductTokens &userAgent)HDiscoveryRequest
HDiscoveryRequest(const HDiscoveryRequest &)HDiscoveryRequest
isValid(HValidityCheckLevel level) const HDiscoveryRequest
mx() const HDiscoveryRequest
operator!=(const HDiscoveryRequest &obj1, const HDiscoveryRequest &obj2)HDiscoveryRequest [related]
operator=(const HDiscoveryRequest &)HDiscoveryRequest
operator==(const HDiscoveryRequest &, const HDiscoveryRequest &)HDiscoveryRequest [friend]
searchTarget() const HDiscoveryRequest
userAgent() const HDiscoveryRequest
~HDiscoveryRequest()HDiscoveryRequest
herqq-1.0.0/hupnp/docs/html/annotated.html0000644000000000000000000003760111543637604017237 0ustar rootroot Herqq: Class List

Class List

Here are the classes, structs, unions and interfaces with brief descriptions:
Functor< ReturnValue, TypeList >A template class for generalizing the callable entity concept
HActionArgumentThis is a class that represents an argument used in a UPnP action invocation
HActionArgumentsA storage class for HActionArgument instances
HActionInfoThis class is used to contain information of a UPnP action found in a UPnP service description document
HActionSetupThis class is used to specify information that can be used to setup an HServerAction or validate a UPnP action
HActionsSetupDataThis class is used to specify information that can be used to setup HServerAction instances or generally validate the actions of a UPnP service
HAsyncOpThis abstract class is used as a base for identifying an asynchronous operation and detail information of it
HClientActionA client-side class that represents a server-side UPnP action
HClientActionOpThis class is used to identify a client-side action invocation and detail information of it
HClientDeviceThis is a client-side class that represents a server-side UPnP device
HClientServiceA client-side class that represents a server-side UPnP service
HClientStateVariableA client-side class that represents a server-side UPnP state variable
HClonableThis class defines an interface for cloning instances of polymorphic classes
HControlPointThis is a class for discovering and interacting with UPnP devices in the network
HControlPointConfigurationClass for specifying initialization information to HControlPoint instances
HDeviceConfigurationThis is a class for specifying a configuration to an HServerDevice that is to be created and hosted by an HDeviceHost
HDeviceHostThis is a class for creating and hosting HServerDevice instances on the network
HDeviceHostConfigurationThis class is used to specify one or more device configurations to an HDeviceHost instance and to configure the functionality of the HDeviceHost that affect every hosted HServerDevice
HDeviceHostRuntimeStatusThis is a class for detailing information of the runtime status of an HDeviceHost instance
HDeviceInfoThis class is used to contain information of a UPnP device found in a UPnP device description document
HDeviceModelCreatorA protocol class for creating HServerDevice and HServerService instances
HDeviceModelInfoProviderA protocol class for providing information that is used to validate components of UPnP's device architecture and to setup components of HUPnP's device model
HDeviceSetupThis class is used to specify information that can be used to validate a UPnP device
HDevicesSetupDataThis class is used to specify information that can be used to validate UPnP devices
HDiscoveryRequestClass representing an M-SEARCH (ssdp:discover) message
HDiscoveryResponseThis is a class that represents a response to a HDiscoveryRequest
HDiscoveryTypeThis is a class that depicts the different discovery types used in UPnP networking
HEndpointClass that represents a network endpoint, which is a combination of a host address and a port number
HExecArgsThis class is used to specify information used to control the execution of an asynchronous operation and the notification of its completion
HMulticastSocketThis is a class for multicast communication
HProductTokenThis class represents a product token as defined in the RFC 2616, section 3.8
HProductTokensThis class is used to parse the product tokens defined by HTTP/1.1
HResourceAvailableThis is a class that represents the resource available (ssdp:alive) message
HResourceTypeThis is a class used to depict a UPnP resource, which is either a UPnP device or a UPnP service
HResourceUnavailableClass that represents the device unavailable (ssdp:byebye) message
HResourceUpdateClass representing the device update (ssdp:update) message
HServerActionA class that represents a server-side UPnP action
HServerDeviceThis is an abstract base class for server-side UPnP devices hosted by HDeviceHost
HServerServiceThis is an abstract base class for server-side UPnP services
HServerStateVariableThis is a class that represents a server-side UPnP state variable
HServiceIdClass that represents the service identifier of a UPnP service
HServiceInfoThis class is used to contain information of a UPnP service found in a UPnP device description document
HServiceSetupThis class is used to specify information that can be used to validate a UPnP service
HServicesSetupDataThis class is used to specify information that can be used to validate UPnP services
HSsdpThis class is used for sending and receiving SSDP messages defined by the UPnP Device Architecture specification
HStateVariableEventThis is a class used to transfer state variable event information
HStateVariableInfoThis class is used to contain information of a UPnP state variable found in a UPnP service description document
HStateVariablesSetupDataThis class is used to specify information that can be used to validate UPnP state variables
HUdnThis is a class used to depict a Unique Device Name (UDN), which is a unique device identifier that has to remain the same over time for a specific device instance
HUpnpDataTypesAn utility class for working with UPnP data types
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_state_variable-members.html0000644000000000000000000001111311543637604030311 0ustar rootroot Herqq: Member List

HServerStateVariable Member List

This is the complete list of members for HServerStateVariable, including all inherited members.
HServerStateVariable(const HStateVariableInfo &info, HServerService *parent)HServerStateVariable [protected]
info() const HServerStateVariable
parentService() const HServerStateVariable
setValue(const QVariant &newValue)HServerStateVariable
value() const HServerStateVariable
valueChanged(Herqq::Upnp::HServerStateVariable *source, const Herqq::Upnp::HStateVariableEvent &event)HServerStateVariable [signal]
~HServerStateVariable()=0HServerStateVariable [pure virtual]
herqq-1.0.0/hupnp/docs/html/functions_eval.html0000644000000000000000000004506211543637604020301 0ustar rootroot Herqq: Class Members - Enumerator
 

- a -

- b -

- c -

- d -

- e -

- f -

- i -

- m -

  • MulticastDiscovery : HSsdp

- n -

- r -

- s -

- t -

- u -

- v -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_info.html0000644000000000000000000007212411543637604024607 0ustar rootroot Herqq: HActionInfo Class Reference

HActionInfo Class Reference

This class is used to contain information of a UPnP action found in a UPnP service description document. More...

#include <HActionInfo>

List of all members.

Public Member Functions

 HActionInfo ()
 HActionInfo (const QString &name, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)
 HActionInfo (const QString &name, const HActionArguments &inputArguments, const HActionArguments &outputArguments, bool hasRetVal, HInclusionRequirement incReq=InclusionMandatory, QString *err=0)
 HActionInfo (const HActionInfo &other)
 ~HActionInfo ()
HActionInfooperator= (const HActionInfo &other)
QString name () const
const HActionArgumentsinputArguments () const
const HActionArgumentsoutputArguments () const
QString returnArgumentName () const
HInclusionRequirement inclusionRequirement () const
bool isValid () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HActionInfo &, const HActionInfo &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HActionInfo &obj1, const HActionInfo &obj2)
H_UPNP_CORE_EXPORT quint32 qHash (const HActionInfo &key)

Detailed Description

This class is used to contain information of a UPnP action found in a UPnP service description document.

UPnP service description documents specify the actions and state variables of the service. An instance of this class contain the information of an action found in a service description document:

  • name() returns the name of the action.
  • inputArguments() return the arguments that has to be provided to the action when it is invoked.
  • outputArguments() return the arguments the action will provide after a successful action invocation.
  • returnArgumentName() identifies the output argument that has been designated as the return value. Note that this may not be defined.

In addition to the information found in the service description document, the UPnP service containing the action that is depicted by the HActionInfo object may have specified additional information about the action. Currently only inclusionRequirement() is available and it details whether the action is considered as mandatory or optional.

Remarks:
This class is not thread-safe.
See also:
HDeviceInfo, HServiceInfo and HStateVariableInfo.

Constructor & Destructor Documentation

Creates a new, invalid instance.

See also:
isValid()
HActionInfo ( const QString &  name,
HInclusionRequirement  incReq = InclusionMandatory,
QString *  err = 0 
)

Creates a new instance.

Parameters:
namespecifies the name of the action.
incReqspecifies whether the action is required by the containing service.
errspecifies a pointer to a QString, which contains an error description in case the construction failed. This parameter is optional.
See also:
isValid()
HActionInfo ( const QString &  name,
const HActionArguments inputArguments,
const HActionArguments outputArguments,
bool  hasRetVal,
HInclusionRequirement  incReq = InclusionMandatory,
QString *  err = 0 
)

Creates a new instance.

Parameters:
namespecifies the name of the action.
inputArgumentsspecifies the input arguments of the action. These are the arguments the user has to provide when the action is invoked.
outputArgumentsspecifies the output arguments of the action. These are the arguments the action will "return" when the action invocation is successfully completed.
hasRetValspecifies whether the action has a return value. If this is true the first element of the outputArguments is considered as the return value. Note also that if this is true the outputArguments cannot be empty.
incReqspecifies whether the action is required or optional.
errspecifies a pointer to a QString, which contains an error description in case the construction failed. This parameter is optional.
See also:
isValid()
HActionInfo ( const HActionInfo other)

Copies the contents of the other to this.

Parameters:
otherspecifies the object to be copied.

Destroys the instance.


Member Function Documentation

HActionInfo& operator= ( const HActionInfo other)

Assigns the contents of the other to this.

Parameters:
otherspecifies the object to be copied.
QString name ( ) const

Returns the name of the action.

This is the name specified in the corresponding service description file.

Returns:
The name of the action.
const HActionArguments& inputArguments ( ) const

Returns the input arguments the action expects.

These are the arguments the user has to provide when invoking the action that this info object portrays.

Returns:
The input arguments the action.
See also:
outputArguments()
const HActionArguments& outputArguments ( ) const

Returns the output arguments of the action.

These are the arguments each successful action invocation will "return" to user as output values.

Returns:
The output arguments of the action.
See also:
inputArguments()
QString returnArgumentName ( ) const

Returns the name of the output argument that is marked as the action's return value.

Returns:
The name of the output argument that is marked as the action's return value, or an empty string, if no output argument has been marked as the action's return value.
HInclusionRequirement inclusionRequirement ( ) const

Indicates whether the action is required or optional.

Returns:
value indicating whether the action is required or optional.
bool isValid ( ) const

Indicates if the object is empty.

Returns:
true in case the object is valid.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HActionInfo ,
const HActionInfo  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
bool operator!= ( const HActionInfo obj1,
const HActionInfo obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
H_UPNP_CORE_EXPORT quint32 qHash ( const HActionInfo key) [related]

Returns a value that can be used as a unique key in a hash-map identifying the object.

Parameters:
keyspecifies the HActionInfo object from which the hash value is created.
Returns:
a value that can be used as a unique key in a hash-map identifying the object.
Remarks:
the hash is calculated from the name() of the HActionInfo.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_info-members.html0000644000000000000000000002556311543637604026226 0ustar rootroot Herqq: Member List

HDeviceInfo Member List

This is the complete list of members for HDeviceInfo, including all inherited members.
deviceType() const HDeviceInfo
friendlyName() const HDeviceInfo
HDeviceInfo()HDeviceInfo
HDeviceInfo(const HResourceType &deviceType, const QString &friendlyName, const QString &manufacturer, const QString &modelName, const HUdn &udn, HValidityCheckLevel checkLevel=StrictChecks, QString *err=0)HDeviceInfo
HDeviceInfo(const HResourceType &deviceType, const QString &friendlyName, const QString &manufacturer, const QUrl &manufacturerUrl, const QString &modelDescription, const QString &modelName, const QString &modelNumber, const QUrl &modelUrl, const QString &serialNumber, const HUdn &udn, const QString &upc, const QList< QUrl > &icons, const QUrl &presentationUrl, HValidityCheckLevel checkLevel=StrictChecks, QString *err=0)HDeviceInfo
HDeviceInfo(const HDeviceInfo &other)HDeviceInfo
icons() const HDeviceInfo
isValid(HValidityCheckLevel level) const HDeviceInfo
manufacturer() const HDeviceInfo
manufacturerUrl() const HDeviceInfo
modelDescription() const HDeviceInfo
modelName() const HDeviceInfo
modelNumber() const HDeviceInfo
modelUrl() const HDeviceInfo
operator!=(const HDeviceInfo &obj1, const HDeviceInfo &obj2)HDeviceInfo [related]
operator=(const HDeviceInfo &other)HDeviceInfo
operator==(const HDeviceInfo &obj1, const HDeviceInfo &obj2)HDeviceInfo [friend]
presentationUrl() const HDeviceInfo
serialNumber() const HDeviceInfo
setIcons(const QList< QUrl > &arg)HDeviceInfo
setManufacturerUrl(const QUrl &arg)HDeviceInfo
setModelDescription(const QString &arg)HDeviceInfo
setModelNumber(const QString &arg)HDeviceInfo
setModelUrl(const QUrl &arg)HDeviceInfo
setPresentationUrl(const QUrl &arg)HDeviceInfo
setSerialNumber(const QString &arg)HDeviceInfo
setUpc(const QString &arg)HDeviceInfo
udn() const HDeviceInfo
upc() const HDeviceInfo
~HDeviceInfo()HDeviceInfo
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_functor.html0000644000000000000000000000556611543637604021774 0ustar rootroot Herqq: Functor< ReturnValue, TypeList > Class Template Reference

Functor< ReturnValue, TypeList > Class Template Reference

A template class for generalizing the callable entity concept. More...

#include <hfunctor.h>

List of all members.


Detailed Description

template<typename ReturnValue = void, class TypeList = NullType>
class Herqq::Functor< ReturnValue, TypeList >

A template class for generalizing the callable entity concept.

You can test if the object can be invoked simply by issuing if (FunctorObject) { ... }

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_model_info_provider.png0000644000000000000000000000076311543637604027503 0ustar rootroot‰PNG  IHDR¦P¤þAPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2‚IDATxíÝÝr„ `ÂÎðþÜ ~’#A™¶[M÷0Óª€ä{›^!Jzå…L2ÿSô¿ˆÈ¨Yõ\6ÿ³RŸÎá¥NlÎY²ôiÖ'm¾Ù8Ro§§³­ñ.f->–Z+ï`žÍ¦®12[²=‹9]~E¿šé¾ïֽ鞛æ®=ɽ™ÎK2É$óƒ™!JzC)ïôS™¥„pÆ`–„ÉL'“L2É$“L2É$“L2É$“L2Á”%I„õ!“ÌÇ3ëEZæ{Ø OM:äb|ó²}b.zÎÙ!þÓ‚/Çßg&©ßÝïlE¯7ÌÑ€ïIJ’¤®Œ×ÕB Î’ißu+4–v9¾Ð*–rc˜ú±VÊl§ýÓ†s˜sL¨ƒ½œÆEÿËÙlãu|JgŸi÷˜v êŸ;ƺàlš ugódvö˜Óq²ÌtØï˵½Ú›{LöæÆ¹9®˜ú˜ØàdºùvXG[‡‰™ÎK2É$“Ìo2C”/˶#ÿºR3ÂIEND®B`‚herqq-1.0.0/hupnp/docs/html/functions_func_0x6a.html0000644000000000000000000001035311543637604021136 0ustar rootroot Herqq: Class Members - Functions
 

- j -

herqq-1.0.0/hupnp/docs/html/namespacemembers_type.html0000644000000000000000000000732111543637604021626 0ustar rootroot Herqq: Namespace Members
 
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_async_op-members.html0000644000000000000000000001332711543637604025562 0ustar rootroot Herqq: Member List

HAsyncOp Member List

This is the complete list of members for HAsyncOp, including all inherited members.
abort()HAsyncOp [virtual]
errorDescription() const HAsyncOp
HAsyncOp()HAsyncOp [protected]
HAsyncOp(qint32 returnCode, const QString &errorDescription)HAsyncOp [protected]
HAsyncOp(const HAsyncOp &)HAsyncOp [protected]
id() const HAsyncOp
isNull() const HAsyncOp
operator!() const HAsyncOp [inline]
operator=(const HAsyncOp &)HAsyncOp [protected]
returnValue() const HAsyncOp
setErrorDescription(const QString &arg)HAsyncOp
setReturnValue(int returnValue)HAsyncOp
~HAsyncOp()=0HAsyncOp [pure virtual]
herqq-1.0.0/hupnp/docs/html/functions_func_0x70.html0000644000000000000000000001354111543637604021060 0ustar rootroot Herqq: Class Members - Functions
 

- p -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_state_variable.html0000644000000000000000000004045411543637604026643 0ustar rootroot Herqq: HClientStateVariable Class Reference

A client-side class that represents a server-side UPnP state variable. More...

#include <HClientStateVariable>

Inherited by HDefaultClientStateVariable.

List of all members.

Signals

void valueChanged (const Herqq::Upnp::HClientStateVariable *source, const Herqq::Upnp::HStateVariableEvent &event)

Public Member Functions

virtual ~HClientStateVariable ()=0
HClientServiceparentService () const
QVariant value () const
const HStateVariableInfoinfo () const

Protected Member Functions

 HClientStateVariable (const HStateVariableInfo &info, HClientService *parent)
bool setValue (const QVariant &newValue)

Detailed Description

A client-side class that represents a server-side UPnP state variable.

HClientStateVariable is a core component of the HUPnP's client-side Device Model and it models a UPnP state variable. The UPnP Device Architecture specifies a UPnP state variable as an item or aspect that models state in a service. In a way a state variable is an abstraction to a member variable inside a UPnP service.

A state variable can be evented in which case it notifies interested listeners of changes in its value. You can see if a state variable is evented by checking the HStateVariableInfo object using info() and you can connect to the signal valueChanged() to be notified when the value of the state variable changes. Note, only evented state variables emit the valueChanged() signal.

See also:
HClientService
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HClientStateVariable ( const HStateVariableInfo info,
HClientService parent 
) [protected]

Creates a new instance.

Parameters:
infospecifies information of the state variable. This is often read from a service description document.
parentspecifies the UPnP service instance that contains this state variable.
~HClientStateVariable ( ) [pure virtual]

Destroys the instance.

An HClientStateVariable is always destroyed by the HClientService that contains it when it is being deleted. Further, unless you hold the ownership of the HClientStateVariable instance, you should never destroy it.


Member Function Documentation

bool setValue ( const QVariant &  newValue) [protected]

Changes the value of the state variable.

If the instance is evented, the valueChanged() signal is emitted after the value has been changed.

Parameters:
newValuespecifies the new value of the state variable. The new value must have the same underlying data type as the previous value (and the default value). If the new value has different data type, the value is not changed, no event is sent and false is returned.
Return values:
truein case the new value was successfully set.
falsein case the new value could not be set.
Remarks:
the new value will be set if the value:
  • does not violate the defined constraints
  • has the same variant type or the type of the new value can be converted to the same variant type
  • is not QVariant::Invalid
HClientService* parentService ( ) const

Returns the HClientService that contains this state variable.

Returns:
The HClientService that contains this state variable.
Warning:
the pointer is guaranteed to point to a valid object as long as the HClientStateVariable exists, which ultimately is as long as the containing root device exists.
QVariant value ( ) const

Returns the current value of the state variable.

Returns:
The current value of the state variable.
const HStateVariableInfo& info ( ) const

Returns information about the state variable.

Returns:
information about the state variable. This information is often read from a service description document.
void valueChanged ( const Herqq::Upnp::HClientStateVariable source,
const Herqq::Upnp::HStateVariableEvent event 
) [signal]

This signal is emitted when the value of the state variable has changed.

Parameters:
sourcespecifies the state variable that sent the event.
eventspecifies information about the event that occurred.
Remarks:
This signal has thread affinity to the thread where the object resides. Do not connect to this signal from other threads.
herqq-1.0.0/hupnp/docs/html/tab_s.png0000644000000000000000000000027511543637604016167 0ustar rootroot‰PNG  IHDR$ÇÇ[„IDATxíÝë ‚P@áKg"%(IE|¡%¦I¡7iÚlmÐ" ÓäÛC¼ÞòÛ“\.dåOZ̤ÅBr‰/¿‰(ŸˆÎ#a6⟂ôŽ› 8q÷ØÇëÐaF-û°Et¿Aó4¯fçÖlŠ]±¶äJjJC¢%Š!¿<Å#üÀÄ«IEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_service_info.html0000644000000000000000000006176011543637604024776 0ustar rootroot Herqq: HServiceInfo Class Reference

HServiceInfo Class Reference

This class is used to contain information of a UPnP service found in a UPnP device description document. More...

#include <HServiceInfo>

List of all members.

Public Member Functions

 HServiceInfo ()
 HServiceInfo (const HServiceId &serviceId, const HResourceType &serviceType, const QUrl &controlUrl, const QUrl &eventSubUrl, const QUrl &scpdUrl, HInclusionRequirement incReq=InclusionMandatory, HValidityCheckLevel checkLevel=StrictChecks, QString *err=0)
 ~HServiceInfo ()
 HServiceInfo (const HServiceInfo &other)
HServiceInfooperator= (const HServiceInfo &other)
bool isValid (HValidityCheckLevel level) const
const HServiceIdserviceId () const
const HResourceTypeserviceType () const
QUrl scpdUrl () const
QUrl controlUrl () const
QUrl eventSubUrl () const
HInclusionRequirement inclusionRequirement () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HServiceInfo &obj1, const HServiceInfo &obj2)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HServiceInfo &obj1, const HServiceInfo &obj2)

Detailed Description

This class is used to contain information of a UPnP service found in a UPnP device description document.

A device description defines a UPnP device and among other things, the definition includes the declarations of the services the device contains. This class contains the service declaration information.

Remarks:
This class is not thread-safe.
See also:
HDeviceInfo, HActionInfo and HStateVariableInfo.

Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isValid()
HServiceInfo ( const HServiceId serviceId,
const HResourceType serviceType,
const QUrl &  controlUrl,
const QUrl &  eventSubUrl,
const QUrl &  scpdUrl,
HInclusionRequirement  incReq = InclusionMandatory,
HValidityCheckLevel  checkLevel = StrictChecks,
QString *  err = 0 
)

Constructs a new instance from the specified parameters that the UDA specification mandates for a UPnP service.

The parameters the constructor expects are arguments defined in the device description document and they are all mandatory for a valid UPnP service.

Parameters:
serviceIdspecifies the identifier of the service.
serviceTypespecifies the type of the service.
controlUrlspecifies the URL for control.
eventSubUrlspecifies the URL for eventing.
scpdUrlspecifies the URL for service description.
incReqspecifies whether the service is required or optional. This parameter is optional.
checkLevelspecifies the level of strictness used in validating the specified arguments. This parameter is optional.
errspecifies a pointer to a QString that will contain an error description in case the construction failed. This is optional.
Remarks:
in case any of the provided arguments does not meet the specified requirements, the created object is invalid.
See also:
isValid()

Destroys the instance.

HServiceInfo ( const HServiceInfo other)

Copy constructor.

Copies the contents of the other to this.

Parameters:
otherspecifies the object to be copied.

Member Function Documentation

HServiceInfo& operator= ( const HServiceInfo other)

Assignment operator.

Assigns the contents of the other to this.

Parameters:
otherspecifies the object to be copied.
bool isValid ( HValidityCheckLevel  level) const

Indicates if the object is valid.

A valid object contains the mandatory data of a UPnP service.

Parameters:
levelspecifies the level of strictness used in validating the object. This parameter is optional and the default level is strict.
Returns:
true in case the object is valid.
const HServiceId& serviceId ( ) const

Returns the service identifier found in the device description file.

Returns:
The service identifier found in the device description file.
const HResourceType& serviceType ( ) const

Returns the type of the service found in the device description file.

Returns:
The type of the service found in the device description file.
QUrl scpdUrl ( ) const

Returns the URL for service description.

This is the URL where the service description can be retrieved. This is defined in the device description.

Returns:
The URL for service description.
QUrl controlUrl ( ) const

Returns the URL for control.

This is the URL to which the action invocations must be sent. This is defined in the device description.

Returns:
The URL for control.
QUrl eventSubUrl ( ) const

Returns the URL for eventing.

This is the URL to which subscriptions and un-subscriptions are sent. This is defined in the device description.

Returns:
The URL for eventing.
HInclusionRequirement inclusionRequirement ( ) const

Indicates whether the service is required or optional.

Returns:
value indicating whether the service is required or optional.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HServiceInfo obj1,
const HServiceInfo obj2 
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HServiceInfo obj1,
const HServiceInfo obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/pages.html0000644000000000000000000000343511543637604016357 0ustar rootroot Herqq: Related Pages

Related Pages

Here is a list of all related documentation pages:
herqq-1.0.0/hupnp/docs/html/functions_func_0x75.html0000644000000000000000000001435411543637604021070 0ustar rootroot Herqq: Class Members - Functions
 

- u -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_upnp_data_types-members.html0000644000000000000000000005747111543637604027156 0ustar rootroot Herqq: Member List

HUpnpDataTypes Member List

This is the complete list of members for HUpnpDataTypes, including all inherited members.
bin_base64 enum valueHUpnpDataTypes
bin_base64_str()HUpnpDataTypes [inline, static]
bin_base64T typedefHUpnpDataTypes
bin_hex enum valueHUpnpDataTypes
bin_hex_str()HUpnpDataTypes [inline, static]
bin_hexT typedefHUpnpDataTypes
boolean enum valueHUpnpDataTypes
boolean_str()HUpnpDataTypes [inline, static]
booleanT typedefHUpnpDataTypes
character enum valueHUpnpDataTypes
character_str()HUpnpDataTypes [inline, static]
characterT typedefHUpnpDataTypes
dataType(const QString &dataTypeAsStr)HUpnpDataTypes [static]
DataType enum nameHUpnpDataTypes
date enum valueHUpnpDataTypes
date_str()HUpnpDataTypes [inline, static]
dateT typedefHUpnpDataTypes
dateTime enum valueHUpnpDataTypes
dateTime_str()HUpnpDataTypes [inline, static]
dateTimeT typedefHUpnpDataTypes
dateTimeTz enum valueHUpnpDataTypes
dateTimeTz_str()HUpnpDataTypes [inline, static]
fixed_14_4 enum valueHUpnpDataTypes
fixed_14_4_str()HUpnpDataTypes [inline, static]
fixed_14_4T typedefHUpnpDataTypes
fp enum valueHUpnpDataTypes
fp_str()HUpnpDataTypes [inline, static]
fpT typedefHUpnpDataTypes
i1_str()HUpnpDataTypes [inline, static]
i1T typedefHUpnpDataTypes
i2 enum valueHUpnpDataTypes
i2_str()HUpnpDataTypes [inline, static]
i2T typedefHUpnpDataTypes
i4 enum valueHUpnpDataTypes
i4_str()HUpnpDataTypes [inline, static]
i4T typedefHUpnpDataTypes
integer enum valueHUpnpDataTypes
integer_str()HUpnpDataTypes [inline, static]
integerT typedefHUpnpDataTypes
isInteger(DataType datatype)HUpnpDataTypes [inline, static]
isNumeric(DataType datatype)HUpnpDataTypes [inline, static]
isRational(DataType arg)HUpnpDataTypes [inline, static]
number enum valueHUpnpDataTypes
number_str()HUpnpDataTypes [inline, static]
numberT typedefHUpnpDataTypes
r4 enum valueHUpnpDataTypes
r4_str()HUpnpDataTypes [inline, static]
r4T typedefHUpnpDataTypes
r8 enum valueHUpnpDataTypes
r8_str()HUpnpDataTypes [inline, static]
r8T typedefHUpnpDataTypes
string enum valueHUpnpDataTypes
string_str()HUpnpDataTypes [inline, static]
stringT typedefHUpnpDataTypes
time enum valueHUpnpDataTypes
time_str()HUpnpDataTypes [inline, static]
time_tz_str()HUpnpDataTypes [inline, static]
time_tzT typedefHUpnpDataTypes
timeT typedefHUpnpDataTypes
timeTz enum valueHUpnpDataTypes
toString(DataType datatype)HUpnpDataTypes [static]
ui1 enum valueHUpnpDataTypes
ui1_str()HUpnpDataTypes [inline, static]
ui1T typedefHUpnpDataTypes
ui2 enum valueHUpnpDataTypes
ui2_str()HUpnpDataTypes [inline, static]
ui2T typedefHUpnpDataTypes
ui4 enum valueHUpnpDataTypes
ui4_str()HUpnpDataTypes [inline, static]
ui4T typedefHUpnpDataTypes
Undefined enum valueHUpnpDataTypes
uri enum valueHUpnpDataTypes
uri_str()HUpnpDataTypes [inline, static]
uriT typedefHUpnpDataTypes
uuid enum valueHUpnpDataTypes
uuid_str()HUpnpDataTypes [inline, static]
uuidT typedefHUpnpDataTypes
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_state_variable.html0000644000000000000000000004041111543637604026664 0ustar rootroot Herqq: HServerStateVariable Class Reference

This is a class that represents a server-side UPnP state variable. More...

#include <HServerStateVariable>

Inherited by HDefaultServerStateVariable.

List of all members.

Signals

void valueChanged (Herqq::Upnp::HServerStateVariable *source, const Herqq::Upnp::HStateVariableEvent &event)

Public Member Functions

virtual ~HServerStateVariable ()=0
HServerServiceparentService () const
QVariant value () const
const HStateVariableInfoinfo () const
bool setValue (const QVariant &newValue)

Protected Member Functions

 HServerStateVariable (const HStateVariableInfo &info, HServerService *parent)

Detailed Description

This is a class that represents a server-side UPnP state variable.

HServerStateVariable is a core component of the HUPnP's server-side Device Model and it models a UPnP state variable. The UPnP Device Architecture specifies a UPnP state variable as an item or aspect that models state in a service. In a way a state variable is an abstraction to a member variable inside a UPnP service.

A state variable can be evented in which case it notifies interested listeners of changes in its value. You can see if a state variable is evented by checking the HStateVariableInfo object using info() and you can connect to the signal valueChanged() to be notified when the value of the state variable changes. Note, only evented state variables emit the valueChanged() signal.

See also:
HServerStateVariable
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HServerStateVariable ( const HStateVariableInfo info,
HServerService parent 
) [protected]

Creates a new instance.

Parameters:
infospecifies information of the state variable. This is usually read from a service description document.
parentspecifies the UPnP service instance that contains this state variable.
~HServerStateVariable ( ) [pure virtual]

Destroys the instance.

An HServerStateVariable is always destroyed by the HServerService that contains it when it is being deleted. Further, unless you hold the ownership of the HServerStateVariable instance, you should never destroy it.


Member Function Documentation

HServerService * parentService ( ) const

Returns the HServerService that contains this state variable.

Returns:
The HServerService that contains this state variable.
Warning:
the pointer is guaranteed to point to a valid object as long as the HServerStateVariable exists, which ultimately is as long as the containing root device exists.
QVariant value ( ) const

Returns the current value of the state variable.

Returns:
The current value of the state variable.
const HStateVariableInfo & info ( ) const

Returns information about the state variable.

Returns:
information about the state variable. This information is often read from a service description document.
bool setValue ( const QVariant &  newValue)

Changes the value of the state variable.

If the instance is evented, the valueChanged() signal is emitted after the value has been changed.

Parameters:
newValuespecifies the new value of the state variable. The new value must have the same underlying data type as the previous value (and the default value). If the new value has different data type, the value is not changed, no event is sent and false is returned.
Return values:
truein case the new value was successfully set.
falsein case the new value could not be set.
Remarks:
the new value will be set if the value:
  • does not violate the defined constraints
  • has the same variant type or the type of the new value can be converted to the same variant type
  • is not QVariant::Invalid
void valueChanged ( Herqq::Upnp::HServerStateVariable source,
const Herqq::Upnp::HStateVariableEvent event 
) [signal]

This signal is emitted when the value of the state variable has changed.

Parameters:
sourcespecifies the state variable that sent the event.
eventspecifies information about the event that occurred.
Remarks:
This signal has thread affinity to the thread where the object resides. Do not connect to this signal from other threads.
herqq-1.0.0/hupnp/docs/html/functions.html0000644000000000000000000001757411543637604017301 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- a -

herqq-1.0.0/hupnp/docs/html/functions_0x70.html0000644000000000000000000001354311543637604020047 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- p -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_clonable.png0000644000000000000000000000226011543637604023710 0ustar rootroot‰PNG  IHDRfPEÀ–áPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2?IDATxíA—ƒ M÷½þÿŸ¼B Š[ÙÎwØvQÃ42p]Ƚ‘)Â{"sk$!¬`4#h$!hF+Íší=%˲,"";uÖñk¢ ùnÍ‚jhFÈ}š¥Ç%l˲È"ñ˜ËÿåËhFÐì‚f«N¾nþKgš4s=R×,W-ÑŒ Ù¸Ól½ž=\5 hFÐl˜f› ® ùjÍ·ìÑö#]Kw£A³>͉©oë²Èb.£A3 A3BÐ ÍA3BXÁhFÐ HBÐŒV0š‘¯ÔlŠðž)󦄠!Ó[öÆ3BÐŒù-Ã3BÐŒùE£„ !hFA3BÐŒ4#„ !hFA3BÐŒüÍ2 dæ°Û /¼´^xÁ„^4ƒ^xi+¼ð‚ /¼h/¼ðÒVxáE3xá…—¶Â /˜ð‹fð /m…^0á…Íà…÷[yÆç=¾$¼ðNÍûóš º­ðÂ;/m…^4cÀ‹f´^xÑ ^x£™ä¿"þÓ1#nS£ùk»ÈKÄÚ–=ÓÖDo ôã¼ÝŒê•ØÑÑðý=‰n/¸–HãuñÞ¨WwúÞ¨¯®\­hZàЬÕwý𹦨¥™³P[³áðnͼèë{šíÔº¤Ù8D³-ì-œú­fª¶„nHØ#^/Yw ó{ÔH¼u·HÜvc¯sÙø¨~è„f%Uš*TËã#»5s3Ã÷t·S3ºZÃÞ,–\=-« šªKúH³aˆªµú­”-ç(¦Zqv4‹ÏÆùÒ×D Š›[÷ŠèzÙò¡sšé_^ xJ3ceîñðÝš¢ç…X£2Ûy»^c#óh6±l­9]êsØæ—š…TÞañQ Y•+=¬©”Ì­Ù^÷hVÒ·šlš5УY7£~À>7þH³þöVÖpc‰XÒÍÂöivâ¶™qÙ[õZ÷{O³¦f›û®h–ztN³í^–6R,×fÒxî4ó0Ú½ñøþÓì=.`C¥Iô¯ˆõôå.ÍîA¬hVÛŠ9Ìô$Íö¶sš¥+¦ÉÅÇ0Àsšy‹yîéîÍÑkXŸXf½ÖÖÒÍF žÕ¬h\M³uû»¦Ù~ óú1^³r#¯’ŒìÖÌÁh5+×ßPø.Íœè-*û#7_Òl ¢_3=‡ª±§Ùzp¿^ùÜSçÑ<ŸIo·Z$~]íO›@¸OòÃé×,λÖÐm×@£»4s2ª/ç?cáÝšu gœ_Nž„ª—@Ó@·fãÍŽ§ßŠÁÖs­fzûZ9Òì〟ç½ÿiÞÙúÛÏûÌö)ð¶ö>hœG³¨Y:jÛÖnÀ'-ƒðhö5û‚¶Â /šÁ /š± àE3Ú /¼h/¼ÓlЍ¶Â ït¼¿À±;ží(‘IEND®B`‚herqq-1.0.0/hupnp/docs/html/functions_func_0x71.html0000644000000000000000000001132011543637604021052 0ustar rootroot Herqq: Class Members - Functions herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_argument.html0000644000000000000000000010361611543637604025477 0ustar rootroot Herqq: HActionArgument Class Reference

HActionArgument Class Reference

This is a class that represents an argument used in a UPnP action invocation. More...

#include <HActionArgument>

List of all members.

Public Member Functions

 HActionArgument ()
 HActionArgument (const QString &name, const HStateVariableInfo &stateVariableInfo, QString *err=0)
 HActionArgument (const HActionArgument &)
HActionArgumentoperator= (const HActionArgument &)
 ~HActionArgument ()
void detach ()
QString name () const
const HStateVariableInforelatedStateVariable () const
HUpnpDataTypes::DataType dataType () const
QVariant value () const
bool setValue (const QVariant &value)
bool isValid () const
bool operator! () const
QString toString () const
bool isValidValue (const QVariant &value)

Friends

H_UPNP_CORE_EXPORT bool operator== (const HActionArgument &, const HActionArgument &)

Related Functions

(Note that these are not member functions.)
H_UPNP_CORE_EXPORT bool operator!= (const HActionArgument &, const HActionArgument &)

Detailed Description

This is a class that represents an argument used in a UPnP action invocation.

A UPnP argument is defined in the UPnP service description within an action. If you picture a UPnP action as a function, then an action argument is a parameter to the function. In that sense a UPnP input argument is a single constant parameter that provides input for the function. An input argument is never modified during action invocation. On the other hand, a UPnP output argument relays information back from the callee to the caller and thus it is often modified during action invocation.

Basic Use

A UPnP argument has an unique name() within the definition of the action that contains it. A UPnP argument contains a value, which you can retrieve using value() and which you can set using setValue(). Note, the value of a UPnP argument is bound by its dataType().

A somewhat unusual aspect of a UPnP argument is the concept of a related state variable. According to the UDA specification, a UPnP argument is always associated with a state variable, even if the state variable does not serve any other purpose besides that. This type of a state variable is used to describe the data type of a UPnP argument and thus the value of a UPnP argument is bound by the data type of its related state variable. The dataType() method introduced in this class is equivalent for calling relatedStateVariable()->dataType().

Note:
relatedStateVariable() returns a const reference to an HStateVariableInfo object, rather than a reference or a pointer to an actual state variable. HStateVariableInfo is an object with value semantics that details information of a state variable.

Due to the strict typing of UPnP arguments, HUPnP attempts to make sure that invalid values are not entered into a UPnP argument. Because of this, you can call isValidValue() to check if a value you wish to set using setValue() will be accepted. In addition, setValue() returns false in case the value was not accepted. It is advised that you make sure your values are properly set before attempting to invoke an action, because the invocation may fail in case any of the provided arguments is invalid.

Finally, you can use isValid() to check if the object itself is valid, which is true if the object was constructed with a proper name and valid related state variable information.

Note:
Since it is common for actions to use both input and output arguments that are defined only for the duration of the action invocation, there are bound to be numerous state variables that exist only for UPnP action invocation. It is defined in the UDA specification that these types of state variables have to have a name that includes the prefix A_ARG_TYPE.

Copy Semantics

HActionArgument is designed to be used by value. However, the class uses explicit sharing, which essentially means that every copy of an HActionArgument instance accesses and modifies the same data until detach() is called. The detach() function effectively modifies an HActionArgument instance to use a "private" copy of the underlying data until the instance is copied via a copy constructor or an assignment operator.

Remarks:
This class is not thread-safe.
See also:
HActionArguments

Constructor & Destructor Documentation

Constructs a new, empty instance.

Remarks:
Object constructed using this method is always invalid.
See also:
isValid()
HActionArgument ( const QString &  name,
const HStateVariableInfo stateVariableInfo,
QString *  err = 0 
)

Initializes a new instance with the specified name and related state variable.

Parameters:
namespecifies the name of the argument.
stateVariableInfospecifies the related state variable.
errspecifies a pointer to a QString, which will contain an error description in case the provided arguments were not valid. This is optional
Remarks:
in case the name parameter fails the criteria specified for UPnP action arguments in UPnP Device Architecture 1.1 specification or the stateVariable is null, the object is constructed as "invalid"; isValid() always returns false.
See also:
isValid()

Copy constructor.

Creates a copy of other.

Destroys the instance.


Member Function Documentation

HActionArgument& operator= ( const HActionArgument )

Assignment operator.

Copies the contents of other to this.

void detach ( )

Creates a deep copy of the instance, if necessary.

If the underlying reference count of this instance is greater than one, this function creates a deep copy of the shared data and modifies this instance to refer to the copied data.

QString name ( ) const

Returns the name of the argument.

Returns:
The name of the argument. The return value is an empty string in case the object is invalid.
See also:
isValid()
const HStateVariableInfo & relatedStateVariable ( ) const

Returns information about the state variable that is associated with this action argument.

Returns:
information about the state variable that is associated with this action argument or a null pointer in case the object is invalid.
See also:
isValid()
HUpnpDataTypes::DataType dataType ( ) const

Helper method for accessing the data type of the related state variable info object directly.

Returns:
The data type of the state variable. The data type is HUpnpDataTypes::Undefined in case the object is invalid.
See also:
isValid()
QVariant value ( ) const

Returns the value of the argument.

Returns:
The value of the argument. The returned QVariant has a type of QVariant::Invalid in case the object is invalid.
See also:
isValid()
bool setValue ( const QVariant &  value)

Sets the value of the argument if the object is valid and the new value is of right type.

Parameters:
valuespecifies the new value of the argument.
Returns:
true in case the new value was successfully set.
bool isValid ( ) const

Indicates if the object is constructed with a proper name and a state variable.

Returns:
true in case the object has a proper name and the object refers to a valid state variable.
bool operator! ( ) const

Indicates whether or not the object is considered as invalid.

This is the opposite for calling isValid().

Returns:
true in case the object is invalid.
See also:
isValid()
QString toString ( ) const

Returns a string representation of the object.

The format of the return value is "name: theValue".

Returns:
a string representation of the object. An empty string is returned if the object is invalid.
bool isValidValue ( const QVariant &  value)

Indicates if the provided value can be set into this input argument successfully.

A value is considered valid, when:

  • the argument object is valid, i.e. isValid() returns true and
  • the data type of the provided value matches the data type of the argument or
  • the data type of the provided value can be converted to the data type of the argument.
Parameters:
valuespecifies the value to be checked.
Returns:
true in case the provided value can be set into this input argument successfully.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HActionArgument ,
const HActionArgument  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
H_UPNP_CORE_EXPORT bool operator!= ( const HActionArgument ,
const HActionArgument  
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_discovery_request.html0000644000000000000000000005146411543637604026102 0ustar rootroot Herqq: HDiscoveryRequest Class Reference

HDiscoveryRequest Class Reference

Class representing an M-SEARCH (ssdp:discover) message. More...

#include <HDiscoveryRequest>

List of all members.

Public Member Functions

 HDiscoveryRequest ()
 HDiscoveryRequest (qint32 mx, const HDiscoveryType &resource, const HProductTokens &userAgent)
 ~HDiscoveryRequest ()
 HDiscoveryRequest (const HDiscoveryRequest &)
HDiscoveryRequestoperator= (const HDiscoveryRequest &)
bool isValid (HValidityCheckLevel level) const
const HDiscoveryTypesearchTarget () const
qint32 mx () const
const HProductTokensuserAgent () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HDiscoveryRequest &, const HDiscoveryRequest &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HDiscoveryRequest &obj1, const HDiscoveryRequest &obj2)

Detailed Description

Class representing an M-SEARCH (ssdp:discover) message.

Usually, you create instances of this class to be sent by the Herqq::Upnp::HSsdp, or you receive instances of this class from the Herqq::Upnp::HSsdp.

Remarks:
the class provides an assignment operator, which is not thread-safe.
See also:
HSsdp

Constructor & Destructor Documentation

Constructs a new, empty instance.

The constructed object is not valid, i.e isValid() returns false.

See also:
isValid()
HDiscoveryRequest ( qint32  mx,
const HDiscoveryType resource,
const HProductTokens userAgent 
)

Creates a new instance based on the provided parameters.

The constructed object will be invalid, i.e. isValid() returns false in case the provided information is invalid.

Parameters:
mxspecifies the maximum wait time in seconds.
resourcespecifies the Search Target (ST). If the object is invalid, the created object will be invalid.
userAgentspecifies information about the requester.
Remarks:
  • if userAgent identifies a UPnP v1.1 requester:
    • if mx is smaller than 1 it is set to 1 and
    • if mx is larger than 5 it it set to 5.
  • if userAgent does not specify UPnP version (it always should however) or the userAgent identifies a UPnP v1.0 requester:
    • if mx is smaller than 0 it is set to 0 and
    • if mx is larger than 120 it it set to 120.
See also:
isValid(), mx(), searchTarget(), userAgent()

Destroys the instance.

Copy constructor.

Copies the contents of other to this.


Member Function Documentation

HDiscoveryRequest & operator= ( const HDiscoveryRequest other)

Assigns the contents of the other to this.

Returns:
a reference to this.
bool isValid ( HValidityCheckLevel  level) const

Indicates whether or not the object contains valid announcement information.

Parameters:
levelindicates whether the check should be strictly according to the UDA specification. If set to false some checks are omitted that are known to be poorly implemented in some UPnP software.
Returns:
true in case the objects contains valid announcement information in terms of the requested strictness.
const HDiscoveryType & searchTarget ( ) const

Returns the Search Target of the request.

Returns:
The Search Target of the request.
qint32 mx ( ) const

Returns the maximum wait time in seconds.

According to UDA, Device responses SHOULD be delayed a random duration between 0 and this many seconds to balance load for the control point when it processes responses.

Returns:
The maximum wait time in seconds.
const HProductTokens & userAgent ( ) const

Returns information about the maker of the request.

Returns:
information about the maker of the request.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HDiscoveryRequest ,
const HDiscoveryRequest  
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HDiscoveryRequest obj1,
const HDiscoveryRequest obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_service_id-members.html0000644000000000000000000001346211543637604026063 0ustar rootroot Herqq: Member List

HServiceId Member List

This is the complete list of members for HServiceId, including all inherited members.
HServiceId()HServiceId
HServiceId(const QString &serviceId)HServiceId
HServiceId(const HServiceId &other)HServiceId
isStandardType() const HServiceId
isValid(HValidityCheckLevel level) const HServiceId
operator!=(const HServiceId &obj1, const HServiceId &obj2)HServiceId [related]
operator=(const HServiceId &other)HServiceId
operator==(const HServiceId &, const HServiceId &)HServiceId [friend]
qHash(const HServiceId &key)HServiceId [friend]
suffix() const HServiceId
toString() const HServiceId
urn(bool completeUrn=true) const HServiceId
~HServiceId()HServiceId
herqq-1.0.0/hupnp/docs/html/doxygen.png0000644000000000000000000000754611543637604016564 0ustar rootroot‰PNG  IHDRh ;ˆØ-IDATxí]{XŒyÿ¾sZ%Ê”NF:¨´FåЪքbÝè@;~ÓŽÃ"DH‘ÚZ•ð–m_Œéè4ÄÙÚ!ë-‡2«U«Ce[Š"§š_ñÌ3óLSìõ¾ï¾öº|®««y>§ïý¹ïïá_ ™L†öþZ·¼ß¦ajëñ®¹L•oñúþ}«.Íë2Þãû$Zöå);*.d¥~Ûìß³wˆ—·'ˆâ0³Ëâþ@áû!ZZeÊÿÁÞͺwÓøÏÔÚ‰ù?ØO =\Lâ[òg²dxr0Ð —€¤Rrj·Jž€‘*í.WJN5¨äÉqÈMªÔ[mºÞ•’Sb58™Ä¼RB5½¥•’SRus[2<ÙÄ %·˜˜•²V'˜ê+%§$fv˜ØÄºR»«Kó$ ¡¥C 4ã+xº˜£½sQÙ}f¶ðÀ[²vôZ €ç6c}”½!,Lt×ï<ÂÅ«µ°dx†H)/ÎÙfí襧¥C«1¶v£ôº[~– ÏÑåÅ9%DÏDKgžrN}M9úY««3*/Îi謷%ÓU^œ#¶vôr'p²=]ÌÑ_§7®ßy„ìS¸ª½ëkÊaÉð´-/Î!E²vôâà902œíÁÉ–FæŸ*¸Å,ý­– O!1k>QÓÓ³¦°dx¦X:ûð¼=GÃÂD×ï<ÂþÃ'¸fvRªKó‚UZjbóièþ¤`èõýˆtº9cùœ‘xÕÚªV W­­°sžabóièw1ó1x%îæhŒ¹Þ¶¸9׉>oÕ®hkG¯~¥—Nl°sž"^™ÀdŽ2%sw…ø¨•¼W­­‹ìœ§D¸z¯àí W †Æç˜8c>‚í1”ô‡m·Bvêî«ÖÖ8܉ÞAˆZò þT…u—r­½ª´th9kÂÖRêåŸSfÛþ/d§–°‰¾äœ1kçb„A.ܸ@ø“+;:j ÛÚÑË«ôÒ‰|#­Ýp4i®â¨]¼â߯óV~éØÇŒ…xfv$Õ¥y| S[ö;BOK‡V“ÅßÖàÎÌa 4x0¶Ï:ÂßDN54>Çgœõxp÷ªo;Z:´¬œÃÉ”º€ÕÇðë™ïbÛ‡ªöü|Ñ^TŠ7=$4)L!Ü/åuü’#)9/rqÃ%îØÅï¬~a”çŽÅ-à¸poE ‚”®,|gŽ¥m /9/ŠsÃâ˜Ø|šœ±c Ó/åu¨ü Êë€P\…aÁÂ’ó¢‡1,¦¥Ó¢Ã;ueòyªKó\ä…°üÃ"7-K!3>õ2ÊËËamm åÚÈr7M.(~[2ÓÝÉ„Œ]©¨C<¿í»b9Ç[)v[~Ñ,_º@\|î8ËqÜ´{· Ð}QÞ”ugr7àÛÈJ]|Úe¤ïÚ`ƒ–­æçÿ¤à™4s5Ü+µÕÒ¡•©Æ\§áéãû¶Ù•ýxàJ,ûÌudùùs&@yŽõI…eD…Ÿ;ç8nZÁž={ʘfóQU|X ÞØÚ)ض˜"ÞtîVÜ-ÏwÐo¨ãç¢ý‰œöJy>¶6è°¹ ÌFrÊf¥ÑÍú’ KbÏà¼(!@~»ó³) F¹{€í€Ave'3£Hÿ£¦˜î»Íu @³¯Aò±¬$èj÷"s&û…½&ób~¶t”»w¢ÿ¼¼¥þŠ·öQÓ J~Iå âJÚö½˜Ÿ]=ÊÝ;=|S{ºû™Éç‘“nçÊÜ9ôË¿ÈõË„.{ù®‰Ü´`Œb³ßÅÊå ÅâÚž)†j\Þ€ÔΕ›ÞY_ÂE_¸â.gÚ0uõ‹‘Ÿ‰2ݪiDàWËÐÜX'ÖìkÀÌÿº©ü–ñqýòV¶gDO³¯Ý„¦âÁÔôçE 6È ä1cZŒ¦ÄÄ—n£¹±NXxú(¿] ±ãgL_ºM!ÓÐb4Ü+e´´Ê¤âŽdüƒç62[é£]Am­ž,b÷@Jáé£Õ„ÿð‘Ü_Ù,Wºˆr€‘®Îèr_g8ÕÕ&(ÁQAäÛ4·­Ÿò.«ö—¯­ajëAïghS–öÝFJËÛhheg©‹³;Lýcs é/¼RƒÈõËÄ¢ì,‘—¾84†íõ‰9™óõ:n–œ`‰²³Ä,o_ï~†6YIqaÐÑî¥vÊèã¸v>=V”E¹æXÞ¾5™é=uu›^À/ °A”eD䆸ÍX¹j®S¬‘#§Ï^Ëžç3œŒÇì-ÂÙ£[Ã@µövmæÏ ’X ÊÎÊW¤×vú9šÚúѽµõQ_{ͽ3žäW\ø¦æØ:p¤ajëeIÉ)tšâîŽåáܱ8Iû£>xødÆöEóöëd:ÛŒ4µõk¾OŽƒNI¼‰¨½q>m•á1!)[©›Vàb47ýa @æšṉ̃ p…%5Pþ~üä¾Z‚æ¦?| 3³•0DN  á}® Unû¬@ú® » 3¹ÌÁÃ'‹Tç(,©ÁÏ—ïÂÁÊ^.ŠM¤ÄA8a?šUÙ¾äJ<§à2S÷ þ~…@=hjë3-GÍÄ|ŸÈ8Y.¯—¨®]XRƒèËIT9X²A€›¿ž$ÚéÇÛÈõ™hIPvã!ÀvHÿ°}Úo)Ͷ‡8rŠßš ¶=…Ч*^÷˜éiEïŸÂ«8‘"<˜Ìö Ht™¶œ·"Б²æ–͘á¿Êx.üZ‹˜M!b~ƒé Ã!c ’bwÀ·zëqT\È L*a.ˆŒÙÁP7:Û*(FÁñøpáÁô8¶O@â¿5<å9•17>yö“1z¸a‡zs{/Q†9æ‘ ´j}S¹vYD*n]Í!rÐhyakÔj ™Ê„«úgúÍ‘ d¦©­_¾*llé]^&}ˆ˜¨ÍhnúÃÛpȨèí[¨ä.Y»µ7..ÐÔÖOŽÚ²ÆµÉX|Úeœ%¤ÈL%äL¿9e ‰Étå¼ÇO^ (ˆÛp 3U±%ßär ‡ŒJŽ ›§vÎ2éCÊ Äzá2SãfúÍ1êÃ]Ïõ™@ÝÈ™¼€ÄÜn’èÛp%®Ö"nËJR µß2GÛ+Z™Š[¥?’@„½[PèâÙcÐWKþÂÕZìÛó=’â×Q÷ŸšiøÏäôîÓ?yê¬E`3‡ª+Wá‡ý;ñìÉÃŽöîÓ¿fóæHŠÛÒ%¸x2!%#Mì?;p)î°™*à²u;p_zÉ%#M !pˆ‚WÇR†Š«phϦÝi‚Eª8ügFôîÓ?ÔÁíKÈïü²ëp)_+Ç©XÀPÅž‘&ˆ#jðÌí&q=˜n˜0ÚLí¬×n>Dá•\Ê¢á÷J[ts»I¢è5³)¼&~J ¤:Úè´µAB„î@‹PKÆ´×doCú)ñÑaSteLgÓ.㦶襩›Àÿ?MàÙ¿|Ö¸bÙšs+s’¤Ÿ¸†ÑtïÙ›À@€<öòyÓ¶_=ï ‡žok®Ô‡Û¶½ÚžŸ¿x¾Œª¢Ã=ä_C?ÝlÐßB™«WŠp·òœ‰ÙcK3=hh(b%ùÐ7u@}mEû»ÃtØxØØØâRÁ)ÔUÿ¢%“2™ ݺ)©Ø™¢;¸œŸnÝ{†®ÃÆÎ†‰¡î_2Ÿ´úªŠ ý‘ýLKϲַÆöEe÷¡A(ô¤ù%ž?iÀÓÆßÓ¸›`N·zýàëÑ,ñðÞo´w¯ÊNõ{elЧ‡òÉ«}ð·êq¥ì&ªKsñüÉÃän=>º`á°±³Ýÿ*q:½âht§¿Õw_Z”ÞòòÙ^š:cå¾nÝ{âùÓ†‹Ýº÷Ì`N£;‘×›Üj*ÿµ½¥å¥K¯Þ}^4?&ý=zi¡—¦zkõCcýPBht'×ÿÑ|UE‡ä1 ý;ž&5v›øßõëÛµ]@kS}ðÿpŽªª¢ÃâÕ¥y &þ>Ø{fÝ>Pð~ÛÿÞžk˜^œIEND®B`‚herqq-1.0.0/hupnp/docs/html/group__hupnp__devicehosting.html0000644000000000000000000004427411543637604023045 0ustar rootroot Herqq: Device Hosting

Device Hosting

This page explains the concept of device hosts, which encapsulate the technical details of UPnP networking. More...

Classes

class  HControlPoint
 This is a class for discovering and interacting with UPnP devices in the network. More...
class  HControlPointConfiguration
 Class for specifying initialization information to HControlPoint instances. More...
class  HDeviceHost
 This is a class for creating and hosting HServerDevice instances on the network. More...
class  HDeviceHostRuntimeStatus
 This is a class for detailing information of the runtime status of an HDeviceHost instance. More...
class  HDeviceConfiguration
 This is a class for specifying a configuration to an HServerDevice that is to be created and hosted by an HDeviceHost. More...
class  HDeviceHostConfiguration
 This class is used to specify one or more device configurations to an HDeviceHost instance and to configure the functionality of the HDeviceHost that affect every hosted HServerDevice. More...

Detailed Description

This page explains the concept of device hosts, which encapsulate the technical details of UPnP networking.

A few notes about the design

The logical core of HUPnP is divided into two major modules; a collection of classes that enable the hosting of UPnP device model and the collection of classes that form up the Device Model. The separation is very distinct. The device hosts provide the technical foundation for the UPnP networking. They encapsulate and implement the protocols the UPnP Device Architecture specification details. The device model, on the other hand, is about the logical structure of the UPnP core concepts, which is clearly independent of the technical details of communication. Because of this HUPnP uses highly similar device models both at the server and client side.

HUPnP introduces two types of hosts.

The difference between these two classes is important to notice. You could picture an HDeviceHost as a server and an HControlPoint as a client. The HDeviceHost publishes instances of HServerDevice for UPnP control points to use and the HControlPoint uses instances of HClientDevice to communicate with UPnP devices. But as implied, the APIs of client and server side device models are very similar and once you get familiar either one, using the other should be simple as well.

Note:
While a Herqq::Upnp::HServerDevice published by a HDeviceHost is always usable by UPnP control points over the network, the same device can also be accesed and used simultaneously in process. See HDeviceHost for more information.

Basic use

The basic use of the HDeviceHost is straightforward. You only need to initialize it by providing information that enables one or more UPnP devices to be created and hosted.

In other words, you could create and initialize an HDeviceHost like this:

 #include <HUpnpCore/HDeviceHost>
 #include <HUpnpCore/HDeviceModelCreator>

 #include "my_hserverdevice.h" // your code

 namespace
 {
 class MyDeviceModelCreator :
     public Herqq::Upnp::HDeviceModelCreator
 {
 private:

     // overridden from HDeviceModelCreator
     virtual MyDeviceModelCreator* newInstance() const
     {
         return new MyDeviceModelCreator();
     }

 public:

     // overridden from HDeviceModelCreator
     virtual Herqq::Upnp::HServerDevice* createDevice(
         const Herqq::Upnp::HDeviceInfo& info) const
     {
         // You should check the info object to see what object HUPnP wants
         // created and return null if your creator cannot create it.
         return new MyHServerDevice(); // your class derived from HServerDevice
     }

     // overridden from HDeviceModelCreator
     virtual HServerService* createService(
         const Herqq::Upnp::HServiceInfo& serviceInfo,
         const Herqq::Upnp::HDeviceInfo& parentDeviceInfo) const
     {
         // You should check the info objects to see what object HUPnP wants
         // created and return null if your creator cannot create it.
         return new MyHServerService();
     }
 };

 Herqq::Upnp::HDeviceHost* createDeviceHost()
 {
     Herqq::Upnp::HDeviceHostConfiguration hostConf;
     hostConf.setDeviceModelCreator(MyDeviceModelCreator());
     // This specifies the factory type that the HDeviceHost uses to create
     // HServerDevice and HServerService instances.

     Herqq::Upnp::HDeviceConfiguration deviceConf;
     deviceConf.setPathToDeviceDescription("my_hdevice_devicedescription.xml");
     // This is the device description for our custom UPnP device type
     // the device host uses this file to build the device tree.

     hostConf.add(deviceConf);
     // The same HDeviceHost can host multiple UPnP root devices at the same time.
     // To do that you only need to create and add other HDeviceConfiguration
     // objects to the HDeviceHostConfiguration instance as shown above.

     Herqq::Upnp::HDeviceHost* deviceHost = new HDeviceHost();
     if (!deviceHost->init(hostConf))
     {
         // The initialization failed. Perhaps something should be done?
         // You can call error() to check the type of the error and errorDescription()
         // to get a human-readable description of the error.
     }

     return deviceHost;
 }
 }

and an HControlPoint like this:

 #include <HUpnpCore/HControlPoint>

 Herqq::Upnp::HControlPoint* createControlPoint()
 {
     Herqq::Upnp::HControlPoint* controlPoint = new HControlPoint();

     if (!controlPoint->init())
     {
         // The initialization failed. Perhaps something should be done?
         // You can call error() to check the type of the error and errorDescription()
         // to get a human-readable description of the error.
     }

     return controlPoint;
 }
 }

The above shows the simplest way to initialize an HControlPoint instance. However, you can configure the behavior of an HControlPoint instance in various ways by providing it an HControlPointConfiguration instance upon construction.

See also:
Herqq::Upnp::HDeviceHost, Herqq::Upnp::HControlPoint, Device Model
herqq-1.0.0/hupnp/docs/html/functions_func_0x65.html0000644000000000000000000001416411543637604021066 0ustar rootroot Herqq: Class Members - Functions
 

- e -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_action.html0000644000000000000000000003334611543637604025165 0ustar rootroot Herqq: HServerAction Class Reference

A class that represents a server-side UPnP action. More...

#include <HServerAction>

Inherited by HDefaultServerAction.

List of all members.

Public Member Functions

virtual ~HServerAction ()=0
HServerServiceparentService () const
const HActionInfoinfo () const
qint32 invoke (const HActionArguments &inArgs, HActionArguments *outArgs=0)

Protected Member Functions

 HServerAction (const HActionInfo &info, HServerService *parentService)

Detailed Description

A class that represents a server-side UPnP action.

HServerAction is a core component of the HUPnP's server-side Device Model and it models a UPnP action. The UPnP Device Architecture specifies a UPnP action as command, which takes one or more input or output arguments and that may have a return value.

This class is used to invoke the server-side UPnP actions directly in process. You can get information of the action using info(), which includes the action's input and output arguments. You can invoke an action synchronously using invoke().

See also:
HActionInfo, HServerService
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HServerAction ( const HActionInfo info,
HServerService parentService 
) [protected]

Creates a new instance.

Parameters:
infospecifies information of the action. This is usually read from a service description document.
parentServicespecifies the UPnP service instance that contains this action.
~HServerAction ( ) [pure virtual]

Destroys the instance.

An HServerAction is always destroyed by the HServerService that contains it when it is being deleted. Further, unless you hold the ownership of the HServerAction instance, you should never destroy it.


Member Function Documentation

HServerService* parentService ( ) const

Returns the parent service of the action.

Returns:
The parent service of the action.
Warning:
the pointer is guaranteed to point to a valid object as long as the HServerAction exists, which ultimately is as long as the containing root device exists.
See also:
HServerDevice
const HActionInfo& info ( ) const

Returns information about the action that is read from the service description.

Returns:
information about the action that is read from the service description.
qint32 invoke ( const HActionArguments inArgs,
HActionArguments outArgs = 0 
)

Invokes the action synchronously.

For example,

 Herqq::Upnp::HActionArguments inArgs = action->info().inputArguments();
 inArgs.setValue("EchoInArgument", "Ping");

 Herqq::Upnp::HActionArguments outArgs;

 qint32 retVal = action->invoke(inArgs, &outArgs);
 if (retVal == Herqq::Upnp::HServerAction::Success)
 {
     qDebug() << outArgs.value("EchoOutArgument").toString();
 }
Parameters:
inArgsspecifies the input arguments for the action.
outArgsspecifies a pointer to HActionArguments instance created by the user. This can be null in which case the output arguments will not be set even if the action has output arguments. If the parameter is specified and the action has output arguments, the values of the arguments will be set accordingly. If the action doesn't have output arguments, the parameter is ignored.
Returns:
UpnpSuccess on success. Any other value indicates that an error occurred.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_product_token.html0000644000000000000000000004620411543637604025177 0ustar rootroot Herqq: HProductToken Class Reference

HProductToken Class Reference

This class represents a product token as defined in the RFC 2616, section 3.8. More...

#include <HProductToken>

List of all members.

Public Member Functions

 HProductToken ()
 HProductToken (const QString &token, const QString &productVersion)
 ~HProductToken ()
bool isValid (HValidityCheckLevel checkLevel) const
QString token () const
QString version () const
QString toString () const
qint32 minorVersion ()
qint32 majorVersion ()

Friends

H_UPNP_CORE_EXPORT bool operator== (const HProductToken &obj1, const HProductToken &obj2)

Related Functions

(Note that these are not member functions.)
H_UPNP_CORE_EXPORT bool operator!= (const HProductToken &, const HProductToken &)

Detailed Description

This class represents a product token as defined in the RFC 2616, section 3.8.

Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new, empty instance.

An object created with the default constructor is invalid.

See also:
isValid()
HProductToken ( const QString &  token,
const QString &  productVersion 
)

Creates a new object based on the provided token data.

If the token data is invalid, the object will be invalid as well.

Parameters:
tokenspecifies the token part, which is supposed to identify a product. If this is empty, the created object will be invalid.
productVersionspecifies the version part. If this is empty, the created object will be invalid.
See also:
isValid()

Destroys the instance.


Member Function Documentation

bool isValid ( HValidityCheckLevel  checkLevel) const

Indicates if the object is valid, i.e both the token and the product version are defined.

Parameters:
checkLevelspecifies whether the contents of the object are checked for strict validity. Only an object that is strictly valid contains information as defined in the UDA. In other words, a strictly valid product token takes the form UPnP/majorVersion.minorVersion, where currently major version is always 1 and minor version is either 0 or 1.
Returns:
true in case both the token and product version are appropriately specified.
See also:
token(), productVersion()
QString token ( ) const [inline]

Returns the token part.

Returns:
The token part in case the object is valid. The token part is used to identify the product and an example of a token is for instance "Apache". An empty string is returned in case the object is invalid.
See also:
isValid()
QString version ( ) const [inline]

Returns the version part.

Returns:
The version part in case the object is valid. An example of a version part is "1.0". An empty string is returned in case the object is invalid.
See also:
isValid()
QString toString ( ) const

Returns a string representation of the object.

The format of the returned string is "token"/"version".

Returns:
a string representation of the object.
qint32 minorVersion ( )

Attempts to parse the version part of a product token to a major and minor component and returns the minor component if the function succeeded.

For the function to succeed the specified product token has to contain a version string that follows the format "major.minor". The function ignores any further "version information" after the "minor" component separated by a dot. The "minor" component has to be convertible to an integer.

Returns:
The minor version component of the specified product token or -1 if the specified token does not contain a minor version component that can be represented as an integer.
qint32 majorVersion ( )

Attempts to parse the version part of a product token to a major and minor component and returns the major component if the function succeeded.

For the function to succeed the specified product token has to contain a version string that either

  • can be directly converted to an integer or
  • contains information following the format "major.minor", where the major component can be converted to an integer. Any data following the "minor" component and separated from it by a dot is ignored.
Returns:
The major version component of the specified product token or -1 if the specified token does not contain a major version component that can be represented as an integer.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HProductToken obj1,
const HProductToken obj2 
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
H_UPNP_CORE_EXPORT bool operator!= ( const HProductToken ,
const HProductToken  
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_discovery_type.html0000644000000000000000000014320711543637604025370 0ustar rootroot Herqq: HDiscoveryType Class Reference

This is a class that depicts the different discovery types used in UPnP networking. More...

#include <HDiscoveryType>

List of all members.

Public Types

enum  Type {
  Undefined = 0, All, RootDevices, SpecificRootDevice,
  SpecificDevice, DeviceType, SpecificDeviceWithType, ServiceType,
  SpecificServiceWithType
}

Public Member Functions

 HDiscoveryType ()
 HDiscoveryType (const HUdn &udn, bool isRootDevice=false, HValidityCheckLevel checkLevel=StrictChecks)
 HDiscoveryType (const HResourceType &resourceType)
 HDiscoveryType (const HUdn &udn, const HResourceType &resourceType, HValidityCheckLevel checkLevel=StrictChecks)
 HDiscoveryType (const QString &resource, HValidityCheckLevel checkLevel=StrictChecks)
 ~HDiscoveryType ()
 HDiscoveryType (const HDiscoveryType &)
HDiscoveryTypeoperator= (const HDiscoveryType &)
Type type () const
const HUdnudn () const
void setUdn (const HUdn &udn, HValidityCheckLevel checkLevel=StrictChecks)
const HResourceTyperesourceType () const
void setResourceType (const HResourceType &resourceType)
QString toString () const

Static Public Member Functions

static HDiscoveryType createDiscoveryTypeForRootDevices ()
static HDiscoveryType createDiscoveryTypeForAllResources ()

Friends

H_UPNP_CORE_EXPORT bool operator== (const HDiscoveryType &, const HDiscoveryType &)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HDiscoveryType &obj1, const HDiscoveryType &obj2)

Detailed Description

This is a class that depicts the different discovery types used in UPnP networking.

The UPnP discovery is based on SSDP messages that provide information about UPnP devices and services the UPnP devices provide. When UPnP devices use SSDP messages they advertise themselves and the embedded devices and services they contain. When UPnP control points use SSDP messages they search UPnP devices or services matching some criteria. In HUPnP these different search and and advertisement types are called discovery types represented by instances of this class.

For instance, if a UPnP device advertises itself to the network the discovery type is HDiscoveryType::SpecificDevice, since the Unique Device Name that identifies the device is known. On the other hand, a control point may be interested in searching all UPnP root devices on a network in which case the discovery type would be HDiscoveryType::RootDevices. Then again, if a control point is interested in searching some specific UPnP root device it can issue a search with the discovery type set to HDiscoveryType::SpecificRootDevice and the UDN set to the desired value.

The above example implies that a discovery type may identify a UPnP device. If a discovery type identifies a UPnP device you can call udn() to retrieve the Unique Device Name. Similarly, you can call setUdn() to specify the desired UDN.

A discovery type may also have a resource type associated with it. A resource type specifies the exact type of a device or a service and whether it is standard or vendor defined. If the resource type is specified you can call resourceType() to retrieve it. Similarly, you can call setResourceType() to specify it.

Remarks:
This class is not thread-safe.
See also:
Type, type()

Member Enumeration Documentation

enum Type

Specifies the discovery type.

See UPnP v1.1 Device Architecture specification chapter 1 for more information.

Enumerator:
Undefined 

The discovery type is unspecified.

This value is used when the discovery type is invalid.

All 

The discovery type is "ssdp:all".

This is used when the discovery type specifies all UPnP devices and services. This value is used by control points to perform a device discovery for all UPnP devices and services.

RootDevices 

The discovery type is "upnp:rootdevice".

This is used when the discovery type specifies all UPnP root devices. This value is used by control points to perform a device discovery for all UPnP root devices.

SpecificRootDevice 

The discovery type is "uuid:device-UUID::upnp:rootdevice".

This is used when the discovery type specifies a particular UPnP root device.

This value is used by control points and UPnP devices to search or advertise a specific UPnP root device.

SpecificDevice 

The discovery type is "uuid:device-UUID".

This is used when the discovery type specifies a particular UPnP device, which may be a root or an embedded device.

This value is used by control points and UPnP devices to search or advertise a specific UPnP device.

DeviceType 

The discovery type is "urn:schemas-upnp-org:device:deviceType:ver" or "urn:domain-name:device:deviceType:ver".

This is used when the discovery type specifies devices of certain type.

This value is used by control points to perform discovery for specific type of UPnP devices.

SpecificDeviceWithType 

The discovery type is "uuid-device-UUID::urn:schemas-upnp-org:device:deviceType:ver" or "uuid-device-UUID::urn:domain-name:device:deviceType:ver".

This is used when the discovery type specifies a particular device that is of certain type.

This value is used by control points and UPnP devices to search or advertise a specific UPnP device that is of specific type.

ServiceType 

The discovery type is "urn:schemas-upnp-org:service:serviceType:ver" or "urn:domain-name:service:serviceType:ver".

This is used when the discovery type specifies services of certain type.

This value is used by control points to perform discovery for specific type of UPnP services.

SpecificServiceWithType 

The discovery type is "uuid-device-UUID::urn:schemas-upnp-org:service:serviceType:ver" or "uuid-device-UUID::urn:domain-name:service:serviceType:ver".

This is used when the discovery type specifies particular service that is of certain type.

This value is used by control points and UPnP devices to search or advertise a specific type of UPnP service within a specific UPnP device.


Constructor & Destructor Documentation

Creates a new empty instance.

The type is set to HDiscoveryType::Undefined.

See also:
type()
HDiscoveryType ( const HUdn udn,
bool  isRootDevice = false,
HValidityCheckLevel  checkLevel = StrictChecks 
) [explicit]

Creates a new instance.

A discovery type created using a valid UDN identifies a UPnP device as the resource. The resource type is not specified.

Parameters:
udnspecifies the contents of the object. In case the provided argument is valid the type() of the created object is HDiscoveryType::SpecificDevice. Otherwise the type is set to HDiscoveryType::Undefined.
isRootDeviceindicates whether the specified UDN belongs to a root device. If the value is true the type() is set to HDiscoveryType::SpecificRootDevice. If the value is false the type is set to HDiscoveryType::SpecificDevice.
checkLevelspecifies the level of strictness used in validating the specified arguments. This parameter is optional.
See also:
type()
HDiscoveryType ( const HResourceType resourceType) [explicit]

Creates a new instance.

A discovery type created using a valid resource type specifies the device or service type. No UDN is provided, which means the discovery type does not specify a UPnP device.

Parameters:
resourceTypespecifies the contents of the object. In case the provided argument is valid the type() of the created object is either

See also:
type(), setUdn()
HDiscoveryType ( const HUdn udn,
const HResourceType resourceType,
HValidityCheckLevel  checkLevel = StrictChecks 
)

Creates a new instance.

A discovery type created with a valid UDN and a valid resource type identifies a specific UPnP device or UPnP service that is of certain type. Both of the provided arguments have to be valid in order to create a valid type. Otherwise the type() is set to HDiscoveryType::Undefined.

Parameters:
udnspecifies the Unique Device Name.
resourceTypespecifies the resource type.
checkLevelspecifies the level of strictness used in validating the specified arguments. This parameter is optional.
See also:
type(), udn(), resourceType()
HDiscoveryType ( const QString &  resource,
HValidityCheckLevel  checkLevel = StrictChecks 
) [explicit]

Creates a new instance.

Parameters:
resourcespecifies the contents of the object. In case the the provided argument cannot be parsed to a valid resource identifier the type() is set to HDiscoveryType::Undefined.
checkLevelspecifies the level of strictness used in validating the specified arguments. This parameter is optional.

Valid string formats are:

  • ssdp:all to specify "any UPnP device and service",
  • [uuid:device-UUID] to spesify a specific UPnP device,
  • [uuid:device-UUID::]upnp:rootdevice to specify a specific UPnP root device,
  • [uuid:device-UUID::]urn:schemas-upnp-org:device:deviceType:ver to specify a specific UPnP device, which type is standard defined.
  • [uuid:device-UUID::]urn:domain-name:device:deviceType:ver to specify a specific UPnP device that, which type is vendor defined.
  • [uuid:device-UUID::]urn:schemas-upnp-org:service:serviceType:ver to specify a specific UPnP service, which type is standard defined.
  • [uuid:device-UUID::]urn:domain-name:service:serviceType:ver to specify a specific UPnP device, which type is vendor defined.

The content inside square brackets (uuid:device-UUID) is optional and does not have to be provided.

Destroys the instance.

Copies the contents of the other object to this.


Member Function Documentation

HDiscoveryType& operator= ( const HDiscoveryType )

Assigns the contents of the other object to this.

Returns:
a reference to this object.
Type type ( ) const

Returns the type of the object.

Returns:
The type of the object. If the resource is not specified the type returned is HDiscoveryType::Undefined.
const HUdn& udn ( ) const

Returns the Unique Device Name of the resource.

Returns:
The Unique Device Name of the resource if it is set. Note, the UDN is never set when the type() is either HDiscoveryType::AllDevices or HDiscoveryType::Undefined.
See also:
setUdn()
void setUdn ( const HUdn udn,
HValidityCheckLevel  checkLevel = StrictChecks 
)

Sets the UDN of the object.

Note:
Changing the UDN may change the resourceType() and the type(). For instance, if the object did not have UDN set before, changing the UDN will change the type() of the object.
Parameters:
udnspecifies the new UDN. The specified UDN has to be valid in terms of the level of validity checks being run. Otherwise the UDN will not be set.
checkLevelspecifies the level of strictness used in validating the specified UDN. This parameter is optional, but by default the UDN is verified strictly.
See also:
udn()
const HResourceType & resourceType ( ) const

Returns the resource type associated with this identifier, if any.

Returns:
The resource type associated with this identifier if it is set. Note, the returned object is valid only when the type() is either standard or vendor specified device or service type.
See also:
setResourceType()
void setResourceType ( const HResourceType resourceType)

Sets the resource type of the object.

Parameters:
resourceTypespecifies the new resource type.
See also:
resourceType()
QString toString ( ) const

Returns a string representation of the object.

Returns:
a string representation of the object or an empty string, if the object does not specify a valid resource.
See also:
Type
HDiscoveryType createDiscoveryTypeForRootDevices ( ) [static]

Creates an object, which type is set to HDiscoveryType::RootDevices.

Returns:
an object, which type is set to HDiscoveryType::RootDevices.
Remarks:
This is only a helper method. A logically equivalent object can be constructed with the string "upnp:rootdevice".
HDiscoveryType createDiscoveryTypeForAllResources ( ) [static]

Creates an object, which type is set to HDiscoveryType::All.

Returns:
an object, which type is set to HDiscoveryType::All.
Remarks:
This is only a helper method. A logically equivalent object can be constructed with the string "ssdp:all".

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HDiscoveryType ,
const HDiscoveryType  
) [friend]

Compares the two objects for equality.

Returns:
true in case the objects are logically equivalent.
bool operator!= ( const HDiscoveryType obj1,
const HDiscoveryType obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/open.png0000644000000000000000000000016611543637604016037 0ustar rootroot‰PNG  IHDR à‘=IDATxí1 “ت¦@@   ]01ÀQXY~Jr?D>„¥¶þ’n¼ áFÍ  }ÈúÂéãÏ\ ÄáÿòIEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_service.html0000644000000000000000000007655611543637604025362 0ustar rootroot Herqq: HServerService Class Reference

This is an abstract base class for server-side UPnP services. More...

#include <HServerService>

List of all members.

Public Slots

void notifyListeners ()

Signals

void stateChanged (const Herqq::Upnp::HServerService *source)

Public Member Functions

virtual ~HServerService ()=0
HServerDeviceparentDevice () const
const HServiceInfoinfo () const
const QString & description () const
const HServerActionsactions () const
const HServerStateVariablesstateVariables () const
bool isEvented () const
QVariant value (const QString &stateVarName, bool *ok=0) const
bool setValue (const QString &stateVarName, const QVariant &value)

Protected Types

typedef QHash< QString,
HActionInvoke
HActionInvokes

Protected Member Functions

virtual HActionInvokes createActionInvokes ()
virtual bool finalizeInit (QString *errDescription)
 HServerService ()
bool init (const HServiceInfo &info, HServerDevice *parentDevice)

Detailed Description

This is an abstract base class for server-side UPnP services.

HServerService is a core component of the HUPnP's server-side Device Model and it models a UPnP service. The UPnP Device Architecture specifies a UPnP service as "Logical functional unit. Smallest units of control. Exposes actions and models the state of a physical device with state variables". In other words, a UPnP service is the entry point for accessing certain type of functionality and state of the containing device.

Using the class

You can retrieve the containing device, the parent device, using parentDevice(). You can retrieve all the actions the service contains by calling actions(), Similarly, you can retrieve all the state variables of the service by calling stateVariables().

The class exposes all the details in the device description concerning a service through info(). From the returned HServiceInfo object you can retrieve the serviceId and serviceType along with various URLs found in the device description, such as the:

  • scpdUrl, which returns the URL for fetching the service description,
  • controlUrl, which returns the URL to be used in action invocation and
  • eventSubUrl, which returns the URL used in event (un)subscriptions.

However, the above URLs usually provide informational value only, since HUPnP provides a simpler interface for everything those URLs expose:

  • You can retrieve the service description of a service using description().
  • Action invocation is abstracted into the HServerAction class.
  • You can receive all the event notifications from a UPnP service by connecting to the stateChanged() signal.

Sub-classing

Writing a custom HServerService is simple, because you only have to provide the implementations of the actions the service exposes. You can do this by overriding createActionInvokes() in which you create the callable entities that will be called upon action invocation. You can also mark member functions implementing actions of a service as Q_INVOKABLE, which enables HUPnP to automatically create the previsously mentioned callable entities for you. See Tutorial for Building a UPnP Device and Setting Up the Device Model for more information about creating your own HServerService types with custom functionality.

See also:
Device Model
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

HServerService ( ) [protected]

Creates a new instance.

You have to call init() to fully initialize the instance.

See also:
init()
~HServerService ( ) [pure virtual]

Destroys the instance.


Member Function Documentation

HServerService::HActionInvokes createActionInvokes ( ) [protected, virtual]

Creates and returns the "action implementations" of the actions the service exposes.

It is very important to note that the overrides of this method should always call the implementation of the super class too. For instance,

 void HServerService::HActionInvokes MyServiceType::createActionInvokes()
 {
     HActionInvokes retVal = SuperClass::createActionInvokes();

     // create and add the actions of this class to the "retVal" variable

     return retVal;
 }
Returns:
The implementations of the actions this HServerService exposes.
bool finalizeInit ( QString *  errDescription) [protected, virtual]

Provides an opportunity to do post-construction initialization routines in derived classes.

As HServerService is part of the HUPnP's server-side Device Model, its initialization process is usually driven by HUPnP. If this is the case, at the time of instantiation of a descendant HServerService the base HServerService sub-object is not yet fully set up. In other words, at that time it is not guaranteed that every private or protected member of a HServerService are set to their "final" values that are used once the object is fully initialized and ready to be used.

Because of the above, descendants of HServerService should not reference or rely on values of HServerService at the time of construction. If the initialization of a HServerService descendant needs to do something that rely on HServerService being fully set up, you can override this method. This method is called once right after the base HServerService is fully initialized.

Parameters:
errDescription
Returns:
true in case the initialization succeeded.
Note:
It is advisable to keep the constructors of the descendants of HServerService small and fast, and do more involved initialization routines here.
bool init ( const HServiceInfo info,
HServerDevice parentDevice 
) [protected]

Initializes the instance.

This method will succeed only once after construction. Subsequent calls will do nothing.

Parameters:
infospecifies information of the service. This is usually read from a device description document.
parentDevicespecifies the UPnP device instance that contains this service.
HServerDevice * parentDevice ( ) const

Returns the parent HServerDevice that contains this service instance.

Returns:
The parent HServerDevice that contains this service instance.
const HServiceInfo & info ( ) const

Returns information about the service.

Returns:
information about the service. This information is usually read from a device description document.
const QString & description ( ) const

Returns the full service description.

Returns:
The full service description.
const HServerActions & actions ( ) const

Returns the actions the service contains.

Returns:
The actions the service contains.
Remarks:
The ownership of the returned objects is not transferred. Do not delete the returned objects.
const HServerStateVariables & stateVariables ( ) const

Returns the state variables of the service.

Returns:
The state variables of the service.
Remarks:
The ownership of the returned objects is not transferred. Do not delete the returned objects.
bool isEvented ( ) const

Indicates whether or not the service contains state variables that are evented.

Returns:
true in case the service contains one or more state variables that are evented.
Remarks:
In case the service is not evented, the stateChanged() signal will never be emitted and the notifyListeners() method does nothing.
QVariant value ( const QString &  stateVarName,
bool *  ok = 0 
) const

Returns the value of the specified state variable, if such exists.

This is a convenience method for retrieving a state variable by name and getting its value.

Parameters:
stateVarNamespecifies the name of the state variable.
okspecifies a pointer to a bool, which will contain true if the specified state variable was found and its value was returned. This is optional.
Returns:
The value of the specified state variable, if such exists. If this service does not contain the specified state variable, an invalid QVariant is returned.
Remarks:
The value of the state variable may be represented by an invalid QVariant. Because of this, if you want to be sure that the specified state variable was found and its value was returned, you should use the ok parameter.
bool setValue ( const QString &  stateVarName,
const QVariant &  value 
)

Sets the value of the specified state variable, if such exists.

This is a convenience method for retrieving a state variable by name and setting its value.

Parameters:
stateVarNamespecifies the name of the state variable.
valuespecifies the new value of the state variable.
Returns:
true in case the specified state variable was found and its value was changed.
void notifyListeners ( ) [slot]

Explicitly forces stateChanged() event to be emitted if the service is evented.

Otherwise this method does nothing.

void stateChanged ( const Herqq::Upnp::HServerService source) [signal]

This signal is emitted when the state of one or more state variables has changed.

Parameters:
sourcespecifies the source of the event.
Remarks:
This signal has thread affinity to the thread where the object resides. Do not connect to this signal from other threads.
herqq-1.0.0/hupnp/docs/html/group__hupnp__core.html0000644000000000000000000000553711543637604021141 0ustar rootroot Herqq: HUPnP Core

HUPnP Core

HUPnP Core is a library that provides an implementation of the UPnP Device Architecture version 1.1 specification. More...

Modules

 Device Model
 Device Hosting
 Common
 Ssdp

Detailed Description

HUPnP Core is a library that provides an implementation of the UPnP Device Architecture version 1.1 specification.

herqq-1.0.0/hupnp/docs/html/functions_0x6e.html0000644000000000000000000002002211543637604020121 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- n -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_service_setup-members.html0000644000000000000000000001633711543637604026633 0ustar rootroot Herqq: Member List

HServiceSetup Member List

This is the complete list of members for HServiceSetup, including all inherited members.
HServiceSetup()HServiceSetup
HServiceSetup(const HServiceId &id, const HResourceType &serviceType, HInclusionRequirement incReq=InclusionMandatory)HServiceSetup
HServiceSetup(const HServiceId &id, const HResourceType &serviceType, int version, HInclusionRequirement incReq=InclusionMandatory)HServiceSetup
HServiceSetup(const HServiceSetup &)HServiceSetup
inclusionRequirement() const HServiceSetup
isValid(HValidityCheckLevel checkLevel) const HServiceSetup
operator!=(const HServiceSetup &obj1, const HServiceSetup &obj2)HServiceSetup [related]
operator=(const HServiceSetup &)HServiceSetup
operator==(const HServiceSetup &, const HServiceSetup &)HServiceSetup [related]
serviceId() const HServiceSetup
serviceType() const HServiceSetup
setInclusionRequirement(HInclusionRequirement arg)HServiceSetup
setServiceId(const HServiceId &arg)HServiceSetup
setServiceType(const HResourceType &arg)HServiceSetup
setVersion(int version)HServiceSetup
version() const HServiceSetup
~HServiceSetup()HServiceSetup
herqq-1.0.0/hupnp/docs/html/functions_func_0x66.html0000644000000000000000000001161111543637604021061 0ustar rootroot Herqq: Class Members - Functions
 

- f -

herqq-1.0.0/hupnp/docs/html/functions_0x63.html0000644000000000000000000002336111543637604020050 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- c -

herqq-1.0.0/hupnp/docs/html/functions_func_0x6d.html0000644000000000000000000001345311543637604021145 0ustar rootroot Herqq: Class Members - Functions
 

- m -

herqq-1.0.0/hupnp/docs/html/functions_0x66.html0000644000000000000000000001325511543637604020054 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- f -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_action_op.png0000644000000000000000000000066411543637604025450 0ustar rootroot‰PNG  IHDRjPÆnPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2CIDATxíÝà …‹M|ÿGÞ `µvÆ’µƒd?ô|‚ho·ÝͶ=9Y ^€‚ÃóÔ`äucù-CФØK AÔøÊJËö%½ë(´ gÄ £D5aÞrÛ0¢êRÄ»U„*TQÇ,‰ŠjKdKʹš©ÀÁš˜üu~PW¢WÂÒ¨â#ò(7Û¦,ϽöÛ¨œÝX~¨œÝXލ—V` ¨@*P T ž7ÛÀ+z ÿ€kÛ‡e(/5ÔX-i Pˆk ðœžjf…5ÎQÅÚ"€jóÊñQ»)M¸„âTšžþõÜÌ€Eщî¡ÌŸ$ºïf_¸•,@2zÈÒ”LëZo ¥+°¥aP7©Àæ^õΕd wY­ glZfÞvE¸]LïDÅ÷ê©(7û çAÍžFcIEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_arguments.html0000644000000000000000000012725611543637604025670 0ustar rootroot Herqq: HActionArguments Class Reference

HActionArguments Class Reference

A storage class for HActionArgument instances. More...

#include <HActionArguments>

List of all members.

Public Member Functions

 HActionArguments ()
 HActionArguments (const QVector< HActionArgument > &args)
 HActionArguments (const HActionArguments &)
 ~HActionArguments ()
HActionArgumentsoperator= (const HActionArguments &)
bool contains (const QString &argumentName) const
HActionArgument get (const QString &argumentName) const
HActionArgument get (qint32 index) const
HActionArguments::const_iterator constBegin () const
HActionArguments::const_iterator constEnd () const
HActionArguments::iterator begin ()
HActionArguments::const_iterator begin () const
HActionArguments::iterator end ()
HActionArguments::const_iterator end () const
qint32 size () const
HActionArgument operator[] (qint32 index) const
HActionArgument operator[] (const QString &argName) const
QStringList names () const
bool isEmpty () const
void clear ()
bool remove (const QString &name)
bool append (const HActionArgument &arg)
QVariant value (const QString &name, bool *ok=0) const
bool setValue (const QString &name, const QVariant &value)
QString toString () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HActionArguments &, const HActionArguments &)

Related Functions

(Note that these are not member functions.)
H_UPNP_CORE_EXPORT void swap (HActionArguments &, HActionArguments &)
bool operator!= (const HActionArguments &obj1, const HActionArguments &obj2)

Detailed Description

A storage class for HActionArgument instances.

Instances of this class are used to contain the input and output arguments for an action invocation.

Note:
The class provides iterative and keyed access to the stored HActionArgument instances. The order of action arguments during iteration is the order in which the HActionArgument objects are provided to the instance. If the class is instantiated by HUPnP, the order of the contained arguments during iteration is the order in which they are defined in the service description document.
See also:
HActionArgument
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new, empty instance.

See also:
isEmpty()
HActionArguments ( const QVector< HActionArgument > &  args)

Creates a new instance from the specified input arguments.

Parameters:
argsspecifies the action argument objects this instance will contain.
See also:
isEmpty()

Copy constructor.

Creates a copy of other.

Destroys the instance.


Member Function Documentation

HActionArguments& operator= ( const HActionArguments )

Assignment operator.

Copies the contents of other to this.

Returns:
a reference to this object.
bool contains ( const QString &  argumentName) const

Indicates if the object contains an argument with the specified name.

Parameters:
argumentNamespecifies the name of the action argument.
Returns:
true in case the object contains an argument with the specified name.
Remarks:
This is a constant-time operation.
HActionArgument get ( const QString &  argumentName) const

Returns an action argument with the specified name.

Parameters:
argumentNamespecifies the name of the argument to be retrieved.
Returns:
an action argument with the specified name. If no argument is found with the specified name, the returned instance is invalid, i.e. HActionArgument::isValid() returns false.
Remarks:
This is a constant-time operation.
HActionArgument get ( qint32  index) const

Returns an action argument at the specified index.

Parameters:
indexspecifies the index of the action argument to return. The index has to be valid position in the container, i.e. it must be 0 <= i < size().
Returns:
an action argument at the specified index.
Remarks:
This is a constant-time operation.
HActionArguments::const_iterator constBegin ( ) const

Returns a const STL-style iterator pointing to the first item.

Returns:
a const STL-style iterator pointing to the first item.

Returns a const STL-style iterator pointing to the imaginary item after the last item.

Returns:
a const STL-style iterator pointing to the imaginary item after the last item.

Returns an STL-style iterator pointing to the first item.

Returns:
an STL-style iterator pointing to the first item.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Returns:
an STL-style iterator pointing to the first item.

Returns an STL-style iterator pointing to the imaginary item after the last item.

Returns:
an STL-style iterator pointing to the imaginary item after the last item.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Returns:
an STL-style iterator pointing to the imaginary item after the last item.
qint32 size ( ) const

Returns the number of contained action arguments.

Returns:
The number of contained action arguments.
HActionArgument operator[] ( qint32  index) const

Returns an action argument at the specified index.

This is the same as calling get() with the specified index. This method is provided for convenience.

Parameters:
indexspecifies the index of the action argument to return. The index has to be valid position in the container, i.e. it must be 0 <= i < size().
Returns:
an action argument at the specified index.
HActionArgument operator[] ( const QString &  argName) const

Returns an action argument with the specified name.

This is the same as calling get() with the specified argument name. This method is provided for convenience.

Parameters:
argNamespecifies the name of the argument to be retrieved.
Returns:
an action argument with the specified name. If no argument is found with the specified name, the returned instance is invalid, i.e. HActionArgument::isValid() returns false.
Remarks:
This is a constant-time operation.
QStringList names ( ) const

Returns the names of all the contained action arguments.

Returns:
The names of all the contained action arguments.
bool isEmpty ( ) const

Indicates if the object is empty, i.e.

it has no action arguments.

Returns:
true when the object has no action arguments.
void clear ( )

Removes every contained HActionArgument from this instance.

Remarks:
A call to this function makes active iterators invalid and
bool remove ( const QString &  name)

Removes an HActionArgument with the specified name.

Parameters:
namespecifies the name of the HActionArgument to be removed.
Returns:
true if an HActionArgument was found and removed.
Remarks:
A call to this function makes active iterators invalid and
bool append ( const HActionArgument arg)

Inserts an HActionArgument to this instance.

Parameters:
argspecifies the HActionArgument to be added.
Returns:
true if the specified argument was added. The action argument will not be added if the instance already contains an action argument instance with the same name or the provided instance is invalid.
Remarks:
A call to this function makes active iterators invalid and
QVariant value ( const QString &  name,
bool *  ok = 0 
) const

Returns the value of the specified state variable, if such exists.

This is a convenience method for retrieving the value of the specified state variable. Semantically this call is comparable to get("stateVariable_name").value().

Parameters:
namespecifies the name of the state variable.
okspecifies a pointer to bool, which will be true if the specified state variable was found. This parameter is optional.
Returns:
The value of the specified state variable, if such exists. Otherwise the returned QVariant is invalid.
bool setValue ( const QString &  name,
const QVariant &  value 
)

Attempts to set the value of the specified state variable.

This is a convenience method for setting the value of the specified state variable. Semantically this call is comparable to get("stateVariable_name").setValue(value).

Parameters:
namespecifies the name of the state variable.
valuespecifies the value of the state variable.
Returns:
true in case the value of the specified state variable was found and its value was changed.
QString toString ( ) const

Returns a string representation of the object.

Returns:
a string representation of the object. The returned string contains all the arguments represented as strings and separated from each other by a new-line. The string representation of an argument is retrieved using HActionArgument::toString().
Remarks:
An empty string is returned if the object is invalid.

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HActionArguments ,
const HActionArguments  
) [friend]

Compares the two objects for equality.

Returns:
true in case the object are logically equivalent.
H_UPNP_CORE_EXPORT void swap ( HActionArguments ,
HActionArguments  
) [friend]

Swaps the contents of the two containers.

bool operator!= ( const HActionArguments obj1,
const HActionArguments obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the objects are not logically equivalent.
herqq-1.0.0/hupnp/docs/html/functions_func_0x73.html0000644000000000000000000004435011543637604021065 0ustar rootroot Herqq: Class Members - Functions
 

- s -

herqq-1.0.0/hupnp/docs/html/hupnp__global_8h.html0000644000000000000000000002354511543637604020474 0ustar rootroot Herqq: src/general/hupnp_global.h File Reference

src/general/hupnp_global.h File Reference

This file contains public functions and enumerations. More...

#include <HUpnpCore/public/hupnp_fwd.h>
#include <HUpnpCore/public/hupnp_defs.h>

Namespaces

namespace  Herqq
namespace  Herqq::Upnp

Enumerations

enum  UpnpErrorCode {
  UpnpSuccess = 200, UpnpInvalidAction = 401, UpnpInvalidArgs = 402, UpnpActionFailed = 501,
  UpnpArgumentValueInvalid = 600, UpnpArgumentValueOutOfRange = 601, UpnpOptionalActionNotImplemented = 602, UpnpOutOfMemory = 603,
  UpnpHumanInterventionRequired = 604, UpnpStringArgumentTooLong = 605, UpnpInvocationInProgress = 0x00f00000, UpnpUndefinedFailure = 0x0ff00000
}
enum  DeviceVisitType { VisitThisOnly = 0, VisitThisAndDirectChildren, VisitThisRecursively }
enum  TargetDeviceType { AllDevices, EmbeddedDevices, RootDevices }
enum  LocationUrlType { AbsoluteUrl, BaseUrl }
enum  HValidityCheckLevel { StrictChecks, LooseChecks }
enum  HInclusionRequirement { InclusionRequirementUnknown = 0, InclusionMandatory, InclusionOptional }
enum  HLogLevel {
  None = 0, Fatal = 1, Critical = 2, Warning = 3,
  Information = 4, Debug = 5, All = 6
}

Functions

QString upnpErrorCodeToString (qint32 errCode)
void SetLoggingLevel (HLogLevel level)
void EnableNonStdBehaviourWarnings (bool arg)

Detailed Description

This file contains public functions and enumerations.

herqq-1.0.0/hupnp/docs/html/index.html0000644000000000000000000002540011543637604016363 0ustar rootroot Herqq: Herqq UPnP (HUPnP) Reference Documentation for Version 1.0

Herqq UPnP (HUPnP) Reference Documentation for Version 1.0

Introduction

Herqq UPnP Library (thereafter HUPnP) is a collection of reusable classes that provide UPnP connectivity conforming to the UPnP Device Architecture version 1.1.

Above everything else, HUPnP is designed to be simple to use and robust in operation. HUPnP does its best to enable you, the user, to focus on the business logic of your domain, rather than to the details of UPnP. However, not everything can be hidden and some UPnP knowledge is required to fully understand the system mechanics and the terms used in this documentation. To fill such gaps you can check the aforementioned UDA specification and other documents available at the UPnP Forum.

HUPnP is tightly integrated into the Qt Framework and follows closely the very same design principles and programming practices Qt follows. You will get the most out of HUPnP by using it alongside with Qt. You can use HUPnP from other environments as well, assuming the appropriate Qt headers and libraries are available.

Setting Up

First, it is important to point out that at the moment HUPnP is officially distributed in source code only. If you come across a binary of HUPnP, it is not made by the author of HUPnP. Second, HUPnP uses the QtSoap library under the LGPLv2.1 license. The QtSoap library is distributed along the HUPnP in source code and the library is built into a shared library during the compilation of HUPnP.

Attention:
At the moment, HUPnP uses a modified version of QtSoap version 2.7. This is because the original version 2.7 contains few severe bugs in regard to thread-safety. Until the errors are fixed in the official QtSoap release, the users of HUPnP must use the modified version distributed with HUPnP.

In order to use HUPnP, you need to build it first. By far the simplest way to do this is to download the Qt SDK, install it, start QtCreator and open the HUPnP project file herqq.pro located in the root of the HUPnP package. To build HUPnP from the command-line you need to run:

  • qmake -recursive herqq.pro to create the make files. You'll find the herqq.pro project file under the project's root directory.
  • make to build HUPnP and
  • make install to install HUPnP. This step is optional and can be omitted if you do not want to install the HUPnP headers and binaries anywhere. See Deployment for further information.

The build produces two shared libraries to which you need to link in order to use HUPnP. Currently, static linking is not an option. The created libraries are placed in bin directory and they are named [lib]HUPnP[-majVer.minVer.patchVer].x and [lib]QtSolutions_SOAP-2.7.x, where ".x" is the platform dependent suffix for shared libraries. In addition, your compiler must be aware of the HUPnP includes, which can be found in the include directory. It is very important that you do not directly include anything that is not found in the include directory. In any case, once your compiler finds the HUPnP includes and your linker finds the HUPnP shared library, you are good to go.

Attention:
You do not need to include the QtSoap includes. HUPnP does not expose the types declared in QtSoap.

Important notes

Before starting to use HUPnP, there are a few things you have to know.

#include

HUPnP follows similar include pattern to that of Qt. When you want to use a a class in HUPnP, you have to use

#include <HClassName> 

where HClassName matches the name of the class you wish to use exactly.

Memory management

Some of the key classes in HUPnP are always instantiated by HUPnP and the instances are always destroyed by HUPnP. You should never delete these. The API documentation of HUPnP is clear about object ownership and these classes are identified in documentation.

The HUpnp include file

HUpnp introduce a number of types, functions, enums and type definitions under the root namespace Herqq. For instance, all the HUPnP core types can be found under the namespace Herqq::Upnp.

In several occasions, you do not need to include the full HUPnP type definitions for your code to work. More specifically, if the compiler doesn't need to see the layout of a HUPnP type to compile your code, you should only forward-declare such HUPnP types. In that case, you can include the HUpnp file, which provides forward-declarations to every public HUPnP type and function.

Logging

In many situations it is useful to see some log output to have some idea what is going on under the hood, especially when something appears to be malfunctioning. You can enable logging in HUPnP by calling the function Herqq::Upnp::SetLoggingLevel() with a desired level argument. Include HUpnp to use the Herqq::Upnp::SetLoggingLevel().

Deployment

You can run make install after compiling the project to copy the public headers and created dynamic libraries into hupnp/deploy folder. More specifically, hupnp/deploy/include will contain all the public headers and hupnp/deploy/lib/ will contain the dynamic libraries. Alternatively, you can run qmake -recursive "PREFIX = /usr" before running make install to install the headers and binaries under the /usr/include and /usr/lib respectively. This may be useful to you in case you do not want to include the full HUPnP source tree with your software. You can run make uninstall to remove HUPnP from the selected location.

Versioning

Until the first stable release (1.0) is made, HUPnP follows a versioning practise where the major component is always zero, the minor component is incremented whenever an API or ABI breaking change is introduced and the patch component is increment upon each update that preserves the API and ABI.

By including HUpnpInfo, you can call hupnpCoreVersion() to query the exact version of a HUPnP Core library at runtime. At compile-time you can use the macros HUPNP_CORE_MAJOR_VERSION, HUPNP_CORE_MINOR_VERSION, HUPNP_CORE_PATCH_VERSION and HUPNP_CORE_VERSION for checking the version of the API.

Getting Started

Often the best explanation is demonstration. So without further ado, the following links should get you started.

For more detailed information, you can check

From there, the API reference is the way to go.

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_udn-members.html0000644000000000000000000001234711543637604024536 0ustar rootroot Herqq: Member List

HUdn Member List

This is the complete list of members for HUdn, including all inherited members.
createUdn()HUdn [static]
HUdn()HUdn
HUdn(const QUuid &value)HUdn
HUdn(const QString &value)HUdn
isValid(HValidityCheckLevel checkLevel) const HUdn [inline]
operator!=(const HUdn &obj1, const HUdn &obj2)HUdn [related]
operator==(const HUdn &, const HUdn &)HUdn [friend]
qHash(const HUdn &)HUdn [friend]
toSimpleUuid() const HUdn
toString() const HUdn
value() const HUdn
~HUdn()HUdn
herqq-1.0.0/hupnp/docs/html/functions_func_0x72.html0000644000000000000000000001642411543637604021065 0ustar rootroot Herqq: Class Members - Functions
 

- r -

herqq-1.0.0/hupnp/docs/html/namespacemembers_eval.html0000644000000000000000000002155511543637604021601 0ustar rootroot Herqq: Namespace Members
 

- a -

- b -

- c -

- d -

- e -

- f -

- i -

- l -

- n -

- r -

- s -

- u -

- v -

- w -

herqq-1.0.0/hupnp/docs/html/hactioninvoke_8h.html0000644000000000000000000000673211543637604020523 0ustar rootroot Herqq: src/devicemodel/hactioninvoke.h File Reference

src/devicemodel/hactioninvoke.h File Reference

This file contains the type definition and usage documentation for the functor used in action invocation. More...

#include <HUpnpCore/HUpnp>
#include <HUpnpCore/HFunctor>

Namespaces

namespace  Herqq
namespace  Herqq::Upnp

Typedefs

typedef Functor< int,
H_TYPELIST_2(const
Herqq::Upnp::HActionArguments
&, Herqq::Upnp::HActionArguments *) 
HActionInvoke )

Detailed Description

This file contains the type definition and usage documentation for the functor used in action invocation.

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_server_device-members.html0000644000000000000000000001522711543637604026575 0ustar rootroot Herqq: Member List

HServerDevice Member List

This is the complete list of members for HServerDevice, including all inherited members.
description() const HServerDevice
deviceStatus() const HServerDevice
embeddedDevices() const HServerDevice
embeddedDevicesByType(const HResourceType &deviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const HServerDevice
finalizeInit(QString *errDescription)HServerDevice [protected, virtual]
HServerDevice()HServerDevice [protected]
info() const HServerDevice
init(const HDeviceInfo &info, HServerDevice *parentDevice=0)HServerDevice [protected]
locations(LocationUrlType urlType=AbsoluteUrl) const HServerDevice
parentDevice() const HServerDevice
rootDevice() const HServerDevice
serviceById(const HServiceId &serviceId) const HServerDevice
services() const HServerDevice
servicesByType(const HResourceType &serviceType, HResourceType::VersionMatch versionMatch=HResourceType::Inclusive) const HServerDevice
~HServerDevice()=0HServerDevice [pure virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_host-members.html0000644000000000000000000002331111543637604026235 0ustar rootroot Herqq: Member List

HDeviceHost Member List

This is the complete list of members for HDeviceHost, including all inherited members.
acceptSubscription(HServerService *targetService, const HEndpoint &source, bool isNew)HDeviceHost [private, virtual]
add(const HDeviceConfiguration &configuration)HDeviceHost
AlreadyInitializedError enum valueHDeviceHost
CommunicationsError enum valueHDeviceHost
configuration() const HDeviceHost [protected]
device(const HUdn &udn, TargetDeviceType target=RootDevices) const HDeviceHost
DeviceHostError enum nameHDeviceHost
doInit()HDeviceHost [private, virtual]
doQuit()HDeviceHost [private, virtual]
error() const HDeviceHost
errorDescription() const HDeviceHost
HDeviceHost(QObject *parent=0)HDeviceHost [explicit]
init(const HDeviceHostConfiguration &configuration)HDeviceHost
InvalidConfigurationError enum valueHDeviceHost
InvalidDeviceDescriptionError enum valueHDeviceHost
InvalidServiceDescriptionError enum valueHDeviceHost
isStarted() const HDeviceHost
NoError enum valueHDeviceHost
NotStarted enum valueHDeviceHost
quit()HDeviceHost [slot]
ResourceConflict enum valueHDeviceHost
rootDevices() const HDeviceHost
runtimeStatus() const HDeviceHost [protected]
setError(DeviceHostError error, const QString &errorDescr)HDeviceHost [protected]
UndefinedError enum valueHDeviceHost
~HDeviceHost()HDeviceHost [virtual]
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_state_variables_setup_data-members.html0000644000000000000000000001472611543637604031334 0ustar rootroot Herqq: Member List

HStateVariablesSetupData Member List

This is the complete list of members for HStateVariablesSetupData, including all inherited members.
Accept enum valueHStateVariablesSetupData
contains(const QString &name) const HStateVariablesSetupData
DefaultInclusionPolicy enum nameHStateVariablesSetupData
defaultInclusionPolicy() const HStateVariablesSetupData
Deny enum valueHStateVariablesSetupData
get(const QString &name) const HStateVariablesSetupData
HStateVariablesSetupData(DefaultInclusionPolicy defIncPol=Accept)HStateVariablesSetupData
insert(const HStateVariableInfo &newItem)HStateVariablesSetupData
isEmpty() const HStateVariablesSetupData
names() const HStateVariablesSetupData
remove(const QString &name)HStateVariablesSetupData
setInclusionRequirement(const QString &name, HInclusionRequirement incReq)HStateVariablesSetupData
size() const HStateVariablesSetupData
herqq-1.0.0/hupnp/docs/html/functions_func_0x6c.html0000644000000000000000000001202311543637604021134 0ustar rootroot Herqq: Class Members - Functions
 

- l -

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_service_id.html0000644000000000000000000005712111543637604024433 0ustar rootroot Herqq: HServiceId Class Reference

Class that represents the service identifier of a UPnP service. More...

#include <HServiceId>

List of all members.

Public Member Functions

 HServiceId ()
 HServiceId (const QString &serviceId)
 HServiceId (const HServiceId &other)
HServiceIdoperator= (const HServiceId &other)
 ~HServiceId ()
bool isValid (HValidityCheckLevel level) const
bool isStandardType () const
QString urn (bool completeUrn=true) const
QString suffix () const
QString toString () const

Friends

H_UPNP_CORE_EXPORT bool operator== (const HServiceId &, const HServiceId &)
H_UPNP_CORE_EXPORT quint32 qHash (const HServiceId &key)

Related Functions

(Note that these are not member functions.)
bool operator!= (const HServiceId &obj1, const HServiceId &obj2)

Detailed Description

Class that represents the service identifier of a UPnP service.

Service identifiers are found in UPnP device descriptions and they use the following format within services defined by the UPnP Forum:

urn:upnp-org:serviceId:serviceID 

In the above format only the tailing serviceID varies. Every service identifier of a standard service type has to begin with urn:upnp-org:serviceId:.

With a vendor defined service the format for a service identifier is:

urn:domain-name:serviceId:serviceID 

Note, according to the UDA specification Period characters in the Vendor Domain Name MUST be replaced with hyphens in accordance with RFC 2141.

In both formats, the last serviceID component is the service identifier suffix.

Note:
For interoperability reasons the class does not enforce the prefix prior to the actual serviceID to be exactly as defined in the UDA. However, you can call isValid() to check if the instance contains strictly valid information.
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Constructs a new, empty instance.

Instance created by this constructor is not valid, i.e. isValid() will return false.

See also:
isValid
HServiceId ( const QString &  serviceId)

Constructs a new instance.

Parameters:
serviceIdspecifies the contents of the object. If the provided argument is invalid an empty instance is created. For an object to be strictly valid the parameter has to follow either of the formats exactly:
  • urn:upnp-org:serviceId:serviceID for service identifiers belonging to a standard service type.
  • urn:domain-name:serviceId:serviceID for service identifiers belonging to a vendor defined service type.

The postfix serviceID is the service identifier suffix.

Note:
a valid object will be constructed when the specified string contains the following tokens separated by a colon: "urn", "domain-name", "some string" and "some string". Case sensitivity is forced only when checking for strict validity.
See also:
isValid()
HServiceId ( const HServiceId other)

Creates a new instance based on the other instance provided.

Parameters:
otherspecifies the other instance.
~HServiceId ( )

Destroys the instance.


Member Function Documentation

HServiceId& operator= ( const HServiceId other)

Assigns the contents of the other instance to this.

Parameters:
otherspecifies the other instance.
Returns:
a reference to this instance.
bool isValid ( HValidityCheckLevel  level) const

Indicates if the service identifier is properly defined.

Parameters:
levelspecifies whether the contents of the object are checked for strict validity. Only an object that is strictly valid contains information as defined in the UDA.
Returns:
true in case the object is considered valid in terms of the requested strictness.
bool isStandardType ( ) const

Indicates whether the service identifier belongs to a standard service type defined by the UPnP forum or to a vendor defined service.

Return values:
truein case the service identifier belongs to a standard service type defined by the UPnP forum.
falsein case the service identifier belongs to a vendor defined service type or the object is invalid.
See also:
isValid()
QString urn ( bool  completeUrn = true) const

Returns the URN of the service identifier.

Parameters:
completeUrnspecifies whether the prefix urn is returned as well. If the argument is false, only the actual URN is returned. i.e if the service identifier is defined as urn:upnp-org:serviceId:MyServiceId only upnp-org is returned.
Returns:
the URN of the service identifier if the object is valid. If the object is not valid, an empty string is returned.
See also:
isValid()
QString suffix ( ) const

Returns the service identifier suffix.

Returns:
the service identifier suffix if the object is valid. For instance, if the service identifier is defined as urn:upnp-org:serviceId:MyServiceId, the suffix identifier and thus the value returned is "MyServiceId". If the object is not valid, an empty string is returned.
See also:
isValid()
QString toString ( ) const

Returns a string representation of the instance.

Returns:
a string representation of the instance. The returned string follows the format defined by UDA if the object is valid. In case of a valid object, the return value is the string that was used to construct the object. If the object is invalid, the returned string is empty.
See also:
isValid()

Friends And Related Function Documentation

H_UPNP_CORE_EXPORT bool operator== ( const HServiceId ,
const HServiceId  
) [friend]

Compares the two objects for equality.

Returns:
true in case the provided objects are equal, false otherwise.
H_UPNP_CORE_EXPORT quint32 qHash ( const HServiceId key) [friend]

Returns a value that can be used as a unique key in a hash-map identifying the resource type object.

Parameters:
keyspecifies the service ID from which the hash value is created.
Returns:
a value that can be used as a unique key in a hash-map identifying the resource type object.
bool operator!= ( const HServiceId obj1,
const HServiceId obj2 
) [related]

Compares the two objects for inequality.

Returns:
true in case the provided objects are not equal, false otherwise.
herqq-1.0.0/hupnp/docs/html/tab_h.png0000644000000000000000000000030011543637604016141 0ustar rootroot‰PNG  IHDR$ÇÇ[‡IDATxíÝÛ ‚`€áÿ¥ºˆFŠ¢‚hšYÒ ÿÌ26@c´HwÍñì!ïÏ—K1ê^‰©HtO’÷ÄyG˜µD׎ k9¦ç?iðâ7zá„vPaŸž˜þãÏðJŒ}ÉÆ)غwV»‚õ®`ai–Ö¥¥™›Z‰ˆšŒP³éøC"àèP=€IEND®B`‚herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_functor-members.html0000644000000000000000000000441511543637604023414 0ustar rootroot Herqq: Member List

Functor< ReturnValue, TypeList > Member List

This is the complete list of members for Functor< ReturnValue, TypeList >, including all inherited members.
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_state_variable_event-members.html0000644000000000000000000001133011543637604030125 0ustar rootroot Herqq: Member List

HStateVariableEvent Member List

This is the complete list of members for HStateVariableEvent, including all inherited members.
HStateVariableEvent()HStateVariableEvent
HStateVariableEvent(const QVariant &previousValue, const QVariant &newValue)HStateVariableEvent
HStateVariableEvent(const HStateVariableEvent &)HStateVariableEvent
isEmpty() const HStateVariableEvent
newValue() const HStateVariableEvent
operator=(const HStateVariableEvent &)HStateVariableEvent
previousValue() const HStateVariableEvent
~HStateVariableEvent()HStateVariableEvent
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_product_token-members.html0000644000000000000000000001264311543637604026627 0ustar rootroot Herqq: Member List

HProductToken Member List

This is the complete list of members for HProductToken, including all inherited members.
HProductToken()HProductToken
HProductToken(const QString &token, const QString &productVersion)HProductToken
isValid(HValidityCheckLevel checkLevel) const HProductToken
majorVersion()HProductToken
minorVersion()HProductToken
operator!=(const HProductToken &, const HProductToken &)HProductToken [related]
operator==(const HProductToken &obj1, const HProductToken &obj2)HProductToken [friend]
token() const HProductToken [inline]
toString() const HProductToken
version() const HProductToken [inline]
~HProductToken()HProductToken
herqq-1.0.0/hupnp/docs/html/files.html0000644000000000000000000000554011543637604016361 0ustar rootroot Herqq: File List

File List

Here is a list of all documented files with brief descriptions:
src/devicemodel/hactioninvoke.hThis file contains the type definition and usage documentation for the functor used in action invocation
src/devicemodel/hactioninvoke_callback.h
src/general/hupnp_fwd.hThis file contains forward-declarations to every public class HUPnP exposes and a few common type definitions
src/general/hupnp_global.hThis file contains public functions and enumerations
src/general/hupnpinfo.hThis file contains information of the HUPnP core library
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_actions_setup_data-members.html0000644000000000000000000001241211543637604027612 0ustar rootroot Herqq: Member List

HActionsSetupData Member List

This is the complete list of members for HActionsSetupData, including all inherited members.
clear()HActionsSetupData [inline]
contains(const QString &name) const HActionsSetupData [inline]
get(const QString &name) const HActionsSetupData
HActionsSetupData()HActionsSetupData
insert(const HActionSetup &newItem)HActionsSetupData
isEmpty() const HActionsSetupData [inline]
names() const HActionsSetupData
remove(const QString &name)HActionsSetupData
setInclusionRequirement(const QString &name, HInclusionRequirement incReq)HActionsSetupData
size() const HActionsSetupData [inline]
herqq-1.0.0/hupnp/docs/html/globals_defs.html0000644000000000000000000000457011543637604017705 0ustar rootroot Herqq: File Members
 
herqq-1.0.0/hupnp/docs/html/namespacemembers_enum.html0000644000000000000000000000605011543637604021607 0ustar rootroot Herqq: Namespace Members
 
herqq-1.0.0/hupnp/docs/html/functions_0x67.html0000644000000000000000000001156611543637604020060 0ustar rootroot Herqq: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- g -

herqq-1.0.0/hupnp/docs/html/bc_s.png0000644000000000000000000000130111543637604015774 0ustar rootroot‰PNG  IHDR /ð9ЈIDATxíÝÝK“Qðï9ÏÙö Herqq: HClonable Class Reference

This class defines an interface for cloning instances of polymorphic classes. More...

#include <HClonable>

Inheritance diagram for HClonable:
HControlPointConfiguration HDeviceConfiguration HDeviceHostConfiguration HDeviceModelCreator HDeviceModelInfoProvider

List of all members.

Public Member Functions

 HClonable ()
virtual ~HClonable ()
virtual HClonableclone () const

Protected Member Functions

virtual void doClone (HClonable *target) const
virtual HClonablenewInstance () const =0

Detailed Description

This class defines an interface for cloning instances of polymorphic classes.

Remarks:
This class is thread-safe.

Constructor & Destructor Documentation

HClonable ( )

Creates a new instance.

virtual ~HClonable ( ) [virtual]

Destroys the instance.


Member Function Documentation

virtual void doClone ( HClonable target) const [protected, virtual]

Clones the contents of this to the target object.

Every derived class that introduces member variables that should be copied as part of a cloning operation should override this method. The implementation should be something along these lines:

 void MyClonable::doClone(HClonable* target) const
 {
    MyClonable* myClonable = dynamic_cast<MyClonable*>(target);
    if (!myClonable)
    {
        return;
    }

    BaseClassOfMyClonable::doClone(target);

    // copy the variables introduced in *this* MyClonable
    // instance to "myClonable".
 }
Parameters:
targetspecifies the target object to which the contents of this instance are cloned.

Reimplemented in HControlPointConfiguration, HDeviceConfiguration, and HDeviceHostConfiguration.

HDeviceHostConfiguration * newInstance ( ) const [protected, pure virtual]

Creates a new instance.

This method is used as part of object cloning. Because of that, it is important that every concrete (non-abstract) descendant class overrides this method regardless of the type location in the inheritance tree:

 MyClonable* MyClonable::newInstance() const
 {
     return new MyClonable();
 }
Remarks:
  • the object has to be heap-allocated and
  • the ownership of the object is passed to the caller.

Implemented in HControlPointConfiguration, HDeviceConfiguration, and HDeviceHostConfiguration.

virtual HClonable* clone ( ) const [virtual]

Returns a deep copy of the instance.

Returns:
a deep copy of the instance.
Remarks:
  • the ownership of the returned object is transferred to the caller.

Reimplemented in HControlPointConfiguration, HDeviceConfiguration, HDeviceHostConfiguration, HDeviceModelInfoProvider, and HDeviceModelCreator.

herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_arguments-members.html0000644000000000000000000002434411543637604027312 0ustar rootroot Herqq: Member List

HActionArguments Member List

This is the complete list of members for HActionArguments, including all inherited members.
append(const HActionArgument &arg)HActionArguments
begin()HActionArguments
begin() const HActionArguments
clear()HActionArguments
constBegin() const HActionArguments
constEnd() const HActionArguments
contains(const QString &argumentName) const HActionArguments
end()HActionArguments
end() const HActionArguments
get(const QString &argumentName) const HActionArguments
get(qint32 index) const HActionArguments
HActionArguments()HActionArguments
HActionArguments(const QVector< HActionArgument > &args)HActionArguments
HActionArguments(const HActionArguments &)HActionArguments
isEmpty() const HActionArguments
names() const HActionArguments
operator!=(const HActionArguments &obj1, const HActionArguments &obj2)HActionArguments [related]
operator=(const HActionArguments &)HActionArguments
operator==(const HActionArguments &, const HActionArguments &)HActionArguments [friend]
operator[](qint32 index) const HActionArguments
operator[](const QString &argName) const HActionArguments
remove(const QString &name)HActionArguments
setValue(const QString &name, const QVariant &value)HActionArguments
size() const HActionArguments
swap(HActionArguments &, HActionArguments &)HActionArguments [friend]
toString() const HActionArguments
value(const QString &name, bool *ok=0) const HActionArguments
~HActionArguments()HActionArguments
herqq-1.0.0/hupnp/docs/html/functions_0x6f.html0000644000000000000000000003100311543637604020123 0ustar rootroot Herqq: Class Members herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_device_model_info_provider-members.html0000644000000000000000000001365311543637604031315 0ustar rootroot Herqq: Member List

HDeviceModelInfoProvider Member List

This is the complete list of members for HDeviceModelInfoProvider, including all inherited members.
actionsSetupData(const HServiceInfo &serviceInfo, const HDeviceInfo &parentDeviceInfo) const HDeviceModelInfoProvider [virtual]
clone() const HDeviceModelInfoProvider [virtual]
doClone(HClonable *target) const HClonable [protected, virtual]
embedddedDevicesSetupData(const HDeviceInfo &info) const HDeviceModelInfoProvider [virtual]
HClonable()HClonable
HDeviceModelInfoProvider()HDeviceModelInfoProvider
newInstance() const =0HClonable [protected, pure virtual]
servicesSetupData(const HDeviceInfo &info) const HDeviceModelInfoProvider [virtual]
stateVariablesSetupData(const HServiceInfo &serviceInfo, const HDeviceInfo &parentDeviceInfo) const HDeviceModelInfoProvider [virtual]
~HClonable()HClonable [virtual]
~HDeviceModelInfoProvider()=0HDeviceModelInfoProvider [pure virtual]
herqq-1.0.0/hupnp/docs/html/namespace_herqq.html0000644000000000000000000000640711543637604020416 0ustar rootroot Herqq: Herqq Namespace Reference

Herqq Namespace Reference

The main namespace of Herqq libraries. More...

Namespaces

namespace  Upnp

Classes

class  Functor
 A template class for generalizing the callable entity concept. More...

Detailed Description

The main namespace of Herqq libraries.

This namespace contains the global enumerations, typedefs, functions and classes that are used and referenced throughout the Herqq libraries.

herqq-1.0.0/hupnp/docs/html/functions_func_0x7e.html0000644000000000000000000002575611543637604021160 0ustar rootroot Herqq: Class Members - Functions
 

- ~ -

herqq-1.0.0/hupnp/docs/html/functions_type.html0000644000000000000000000001311411543637604020324 0ustar rootroot Herqq: Class Members - Typedefs
 
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_action_setup-members.html0000644000000000000000000001576011543637604026447 0ustar rootroot Herqq: Member List

HActionSetup Member List

This is the complete list of members for HActionSetup, including all inherited members.
HActionSetup()HActionSetup
HActionSetup(const QString &name, HInclusionRequirement incReq=InclusionMandatory)HActionSetup [explicit]
HActionSetup(const QString &name, int version, HInclusionRequirement incReq=InclusionMandatory)HActionSetup
HActionSetup(const HActionSetup &)HActionSetup
inclusionRequirement() const HActionSetup
inputArguments() const HActionSetup
isValid() const HActionSetup
name() const HActionSetup
operator=(const HActionSetup &)HActionSetup
outputArguments() const HActionSetup
setInclusionRequirement(HInclusionRequirement arg)HActionSetup
setInputArguments(const HActionArguments &args)HActionSetup
setName(const QString &name, QString *err=0)HActionSetup
setOutputArguments(const HActionArguments &args)HActionSetup
setVersion(int version)HActionSetup
version() const HActionSetup
~HActionSetup()HActionSetup
herqq-1.0.0/hupnp/docs/html/class_herqq_1_1_upnp_1_1_h_client_action_op.html0000644000000000000000000003505011543637604025625 0ustar rootroot Herqq: HClientActionOp Class Reference

HClientActionOp Class Reference

This class is used to identify a client-side action invocation and detail information of it. More...

#include <HClientActionOp>

Inheritance diagram for HClientActionOp:
HAsyncOp

List of all members.

Public Member Functions

 HClientActionOp ()
 HClientActionOp (const HActionArguments &inArgs)
 HClientActionOp (const HClientActionOp &)
virtual ~HClientActionOp ()
HClientActionOpoperator= (const HClientActionOp &)
const HActionArgumentsinputArguments () const
const HActionArgumentsoutputArguments () const
void setOutputArguments (const HActionArguments &outArgs)

Detailed Description

This class is used to identify a client-side action invocation and detail information of it.

When you call HClientAction::beginInvoke() you get an instance of this class that uniquely identifies the asynchronous operation within the running process. Once the operation completes and the HClientAction::invokeComplete() signal is sent, you get a copy of the instance that was provided by the beginInvoke(). You can use either of the objects and any other copy you may have made to query the UPnP return code of the operation by calling returnValue(). You can call inputArguments() to get the arguments you provided to the HClientAction::beginInvoke() and you can call outputArguments() to get any output arguments the action invocation may have returned.

See also:
HClientAction, HAsyncOp
Remarks:
This class is not thread-safe.

Constructor & Destructor Documentation

Creates a new instance.

HClientActionOp ( const HActionArguments inArgs)

Creates a new instance based on the provided values.

Parameters:
inArgsspecifies the input arguments of the action invocation.

Copy constructor.

Copies the contents of the other to this.

~HClientActionOp ( ) [virtual]

Destroys the instance.


Member Function Documentation

HClientActionOp& operator= ( const HClientActionOp )

Assigns the contents of the other object to this.

Returns:
reference to this object.
const HActionArguments& inputArguments ( ) const

Returns the input arguments of the action invocation.

Returns:
The input arguments of the action invocation.
const HActionArguments& outputArguments ( ) const

Returns the output arguments of the action invocation.

Returns:
The output arguments of the action invocation.
void setOutputArguments ( const HActionArguments outArgs)

Sets the output arguments of the action invocation.

Parameters:
outArgs
herqq-1.0.0/hupnp/lib/0000755000000000000000000000000011543637460013237 5ustar rootrootherqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/0000755000000000000000000000000011543637460017232 5ustar rootrootherqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/0000755000000000000000000000000011543637460020021 5ustar rootrootherqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapNamespaces0000644000000000000000000000002411543637310023141 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapHttpTransport0000644000000000000000000000002411543637310023716 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapMessage0000644000000000000000000000002411543637310022446 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/qtsoap.pri0000644000000000000000000000061511543637310022040 0ustar rootrootinclude(../common.pri) INCLUDEPATH += $$PWD DEPENDPATH += $$PWD QT += xml network qtsoap-uselib:!qtsoap-buildlib { LIBS += -L$$QTSOAP_LIBDIR -l$$QTSOAP_LIBNAME } else { SOURCES += $$PWD/qtsoap.cpp HEADERS += $$PWD/qtsoap.h } win32 { contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSOAP_EXPORT else:qtsoap-uselib:DEFINES += QT_QTSOAP_IMPORT } herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapArrayIterator0000644000000000000000000000002411543637310023652 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapType0000644000000000000000000000002411543637310022003 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapArray0000644000000000000000000000002411543637310022140 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapSimpleType0000644000000000000000000000002411543637310023155 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapStruct0000644000000000000000000000002411543637310022346 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapTypeFactory0000644000000000000000000000002411543637310023333 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapQName0000644000000000000000000000002411543637310022063 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapTypeConstructor0000644000000000000000000000002411543637310024251 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapTypeConstructorBase0000644000000000000000000000002411543637310025044 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/qtsoap.h0000644000000000000000000004125711543637310021504 0ustar rootroot/**************************************************************************** ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact Nokia at qt-info@nokia.com. ** ****************************************************************************/ #ifndef QTSOAP_H #define QTSOAP_H #include #include #include #include #include #include #include #include #include #ifdef QT_QTSOAP_EXPORT # undef QT_QTSOAP_EXPORT # ifdef Q_OS_WIN # define QT_QTSOAP_EXPORT __declspec(dllexport) # elif defined(QT_VISIBILITY_AVAILABLE) # define QT_QTSOAP_EXPORT __attribute__((visibility("default"))) # endif # ifndef QT_QTSOAP_EXPORT # define QT_QTSOAP_EXPORT # endif #else # if defined(Q_OS_WIN) # define QT_QTSOAP_EXPORT __declspec(dllimport) # else # define QT_QTSOAP_EXPORT # endif #endif #define SOAPv11_ENVELOPE "http://schemas.xmlsoap.org/soap/envelope/" #define SOAPv11_ENCODING "http://schemas.xmlsoap.org/soap/encoding/" #define SOAPv11_ACTORNEXT "http://schemas.xmlsoap.org/soap/actor/next" #define XML_SCHEMA "http://www.w3.org/1999/XMLSchema" #define XML_SCHEMA_INSTANCE "http://www.w3.org/1999/XMLSchema-instance" #define XML_NAMESPACE "http://www.w3.org/XML/1998/namespace" template class QtSmartPtr { public: inline QtSmartPtr(T *data = 0) { d = data; r = new int; *r = 1; } inline QtSmartPtr(const QtSmartPtr ©) { if (*copy.r != 0) ++(*copy.r); r = copy.r; d = copy.d; } inline ~QtSmartPtr() { if ((*r) == 0) delete r; else if ((*r) != 0 && --(*r) == 0) { delete r; if (d) delete d; } } inline QtSmartPtr &operator =(const QtSmartPtr ©) { if (*copy.r != 0) ++(*copy.r); if ((*r) == 0) delete r; else if ((*r) != 0 && --(*r) == 0) { delete r; if (d) delete d; } r = copy.r; d = copy.d; return *this; } inline T &operator *() const { return *d; } inline T *operator ->() const { return d; } inline T *ptr() const { return d; } inline T &ref() const { return *d; } inline T *releasedPtr() const { (*r) = 0; return d; } inline bool isNull() const { return d == 0; } private: int *r; T *d; }; class QT_QTSOAP_EXPORT QtSoapQName { public: QtSoapQName(const QString &name = QString::null, const QString &uri = QString::null); ~QtSoapQName(); QtSoapQName &operator =(const QString &s); QString name() const; QString uri() const; private: QString n; QString nuri; }; bool operator ==(const QtSoapQName &n1, const QtSoapQName &n2); bool operator <(const QtSoapQName &n1, const QtSoapQName &n2); class QT_QTSOAP_EXPORT QtSoapType { public: enum Type { Duration, DateTime, Time, Date, GYearMonth, GYear, GMonthDay, GDay, GMonth, Boolean, Base64Binary, HexBinary, Float, Double, AnyURI, QName, NOTATION, String, NormalizedString, Token, Language, Name, NMTOKEN, NCName, ID, IDREF, ENTITY, Decimal, Integer, NonPositiveInteger, NegativeInteger, Long, Int, Short, Byte, NonNegativeInteger, UnsignedLong, PositiveInteger, UnsignedInt, UnsignedShort, UnsignedByte, Array, Struct, Other }; QtSoapType(); QtSoapType(const QtSoapQName &name, Type t = Other); QtSoapType(const QtSoapType ©); QtSoapType &operator =(const QtSoapType ©); virtual ~QtSoapType(); virtual void clear(); virtual bool parse(QDomNode); virtual bool isValid() const; virtual int count() const; virtual QVariant value() const; virtual QtSoapType &operator [](int); virtual QtSoapType &operator [](const QtSoapQName &s); virtual QtSoapType &operator [](const QString &name); virtual const QtSoapType &operator [](int) const; virtual const QtSoapType &operator [](const QtSoapQName &s) const; virtual const QtSoapType &operator [](const QString &name) const; virtual QDomElement toDomElement(QDomDocument) const; virtual Type type() const; virtual QString id() const; virtual QString href() const; virtual QString typeName() const; virtual QtSoapQName name() const; virtual QString toString() const; virtual int toInt() const; virtual bool toBool() const; void setName(const QtSoapQName &); void setId(const QString &); void setHref(const QString &); QString errorString() const; static QString typeToName(QtSoapType::Type t); static Type nameToType(const QString &); protected: Type t; QString errorStr; QString i; QtSoapQName n; QString u; QString h; }; class QtSoapArrayIterator; class QT_QTSOAP_EXPORT QtSoapArray : public QtSoapType { public: QtSoapArray(); QtSoapArray(const QtSoapQName &name, QtSoapType::Type type = Other, int size0 = -1, int size1 = -1, int size2 = -1, int size3 = -1, int size4 = -1); QtSoapArray(const QtSoapArray ©); QtSoapArray &operator = (const QtSoapArray ©); ~QtSoapArray(); void clear(); bool parse(QDomNode node); bool isValid() const; int count() const; QtSoapType &at(int pos0); QtSoapType &at(int pos0, int pos1); QtSoapType &at(int pos0, int pos1, int pos2); QtSoapType &at(int pos0, int pos1, int pos2, int pos3); QtSoapType &at(int pos0, int pos1, int pos2, int pos3, int pos4); QtSoapType &operator [](int i); QtSoapType &operator [](const QString &); QtSoapType &operator [](const QtSoapQName &); const QtSoapType &at(int pos) const; const QtSoapType &at(int pos0, int pos1) const; const QtSoapType &at(int pos0, int pos1, int pos2) const; const QtSoapType &at(int pos0, int pos1, int pos2, int pos3) const; const QtSoapType &at(int pos0, int pos1, int pos2, int pos3, int pos4) const; const QtSoapType &operator [](int i) const; const QtSoapType &operator [](const QString &) const; const QtSoapType &operator [](const QtSoapQName &) const; void append(QtSoapType *item); void insert(int pos0, QtSoapType *item); void insert(int pos0,int pos1, QtSoapType *item); void insert(int pos0,int pos1,int pos2, QtSoapType *item); void insert(int pos0,int pos1,int pos2,int pos3, QtSoapType *item); void insert(int pos0,int pos1,int pos2,int pos3,int pos4, QtSoapType *item); QDomElement toDomElement(QDomDocument doc) const; friend class QtSoapArrayIterator; protected: QString arraySizeString() const; QString arrayTypeString() const; QHash > array; int lastIndex; private: Type arrayType; int order; int siz0, siz1, siz2, siz3, siz4; }; class QT_QTSOAP_EXPORT QtSoapArrayIterator { public: QtSoapArrayIterator(QtSoapArray &); QtSoapArrayIterator(const QtSoapArrayIterator ©); QtSoapArrayIterator &operator =(const QtSoapArrayIterator &j); ~QtSoapArrayIterator(); int pos() const; void pos(int *pos0, int *pos1 = 0, int *pos2 = 0, int *pos3 = 0, int *pos4 = 0) const; QtSoapType *data(); const QtSoapType *current() const; void operator ++(); bool operator !=(const QtSoapArrayIterator &j) const; bool operator ==(const QtSoapArrayIterator &j) const; bool atEnd() const; private: QHash >::Iterator it; QtSoapArray *arr; }; class QtSoapStructIterator; class QT_QTSOAP_EXPORT QtSoapStruct : public QtSoapType { public: QtSoapStruct(); QtSoapStruct(const QtSoapQName &name); QtSoapStruct(const QtSoapStruct ©); QtSoapStruct &operator =(const QtSoapStruct ©); ~QtSoapStruct(); void clear(); bool parse(QDomNode node); bool isValid() const; int count() const; QtSoapType &at(const QtSoapQName &key); const QtSoapType &at(const QtSoapQName &key) const; QtSoapType &operator [](int); QtSoapType &operator [](const QtSoapQName &key); QtSoapType &operator [](const QString &key); const QtSoapType &operator [](int) const; const QtSoapType &operator [](const QtSoapQName &key) const; const QtSoapType &operator [](const QString &key) const; void insert(QtSoapType *item); QDomElement toDomElement(QDomDocument doc) const; friend class QtSoapStructIterator; protected: QList > dict; }; class QT_QTSOAP_EXPORT QtSoapStructIterator { public: QtSoapStructIterator(QtSoapStruct &); ~QtSoapStructIterator(); QtSoapQName key() const; QtSoapType *data(); const QtSoapType *current() const; void operator ++(); bool operator !=(const QtSoapStructIterator &j) const; bool operator ==(const QtSoapStructIterator &j) const; private: QList >::Iterator it; QList >::Iterator itEnd; }; class QT_QTSOAP_EXPORT QtSoapSimpleType : public QtSoapType { public: QtSoapSimpleType(); QtSoapSimpleType(const QtSoapQName &name); QtSoapSimpleType(const QtSoapQName &name, int n); QtSoapSimpleType(const QtSoapQName &name, bool n, int dummy); QtSoapSimpleType(const QtSoapQName &name, const QString &n); QtSoapSimpleType(const QtSoapSimpleType ©); QtSoapSimpleType &operator =(const QtSoapSimpleType ©); ~QtSoapSimpleType(); void clear(); bool parse(QDomNode node); bool isValid() const; QString toString() const; int toInt() const; bool toBool() const; QVariant value() const; QDomElement toDomElement(QDomDocument doc) const; protected: QVariant v; }; class QT_QTSOAP_EXPORT QtSoapMessage { friend class QtSoapHttpServer; public: QtSoapMessage(); QtSoapMessage(const QtSoapMessage ©); ~QtSoapMessage(); QtSoapMessage &operator =(const QtSoapMessage ©); bool setContent(const QByteArray &buffer); bool setContent(QDomDocument &d); void addBodyItem(QtSoapType *); void addHeaderItem(QtSoapType *); // Method and response const QtSoapType &method() const; const QtSoapType &returnValue() const; void setMethod(const QtSoapQName &); void setMethod(const QString &name, const QString &url = QString::null); void addMethodArgument(QtSoapType *); void addMethodArgument(const QString &uri, const QString &name, const QString &value); void addMethodArgument(const QString &uri, const QString &name, bool value, int dummy); void addMethodArgument(const QString &uri, const QString &name, int value); // Fault enum FaultCode { VersionMismatch, MustUnderstand, Client, Server, Other }; bool isFault() const; FaultCode faultCode() const; const QtSoapType &faultString() const; const QtSoapType &faultDetail() const; void setFaultCode(FaultCode code); void setFaultString(const QString &fstring); void addFaultDetail(QtSoapType *detail); // Generating void clear(); QString toXmlString(int indent = 0) const; // Errors QString errorString() const; protected: enum MessageType { Fault, MethodRequest, MethodResponse, OtherType }; bool isValidSoapMessage(const QDomDocument &candidate); QtSoapStruct &body() const; QtSoapStruct &header() const; void init(); private: MessageType type; mutable QtSoapStruct envelope; QtSoapQName m; QtSoapStruct margs; QString errorStr; }; class QT_QTSOAP_EXPORT QtSoapTypeConstructorBase { public: inline QtSoapTypeConstructorBase() { } virtual inline ~QtSoapTypeConstructorBase() { } virtual QtSoapType *createObject(QDomNode) = 0; virtual QString errorString() const = 0; }; template class QT_QTSOAP_EXPORT QtSoapTypeConstructor : public QtSoapTypeConstructorBase { public: QtSoapTypeConstructor() { } QtSoapType *createObject(QDomNode node) { T *t = new T(); if (t->parse(node)) { return t; } else { errorStr = t->errorString(); delete t; return 0; } } QString errorString() const { return errorStr; } private: mutable QString errorStr; }; class QT_QTSOAP_EXPORT QtSoapTypeFactory { private: QtSoapTypeFactory(); static QScopedPointer s_instance; static QMutex s_initMutex; public: ~QtSoapTypeFactory(); static QtSoapTypeFactory &instance(); bool registerHandler(const QString &name, QtSoapTypeConstructorBase *handler); QtSmartPtr soapType(QDomNode node) const; QString errorString() const; private: mutable QString errorStr; QHash typeHandlers; QLinkedList deleteList; }; class QT_QTSOAP_EXPORT QtSoapNamespaces { public: void registerNamespace(const QString &prefix, const QString &uri); QString prefixFor(const QString &ns); static QtSoapNamespaces &instance(); private: static QScopedPointer s_instance; static QMutex s_initMutex; QMap namespaces; mutable QMutex namespacesMutex; QtSoapNamespaces(); }; class QT_QTSOAP_EXPORT QtSoapHttpTransport : public QObject { Q_OBJECT public: QtSoapHttpTransport(QObject *parent = 0); ~QtSoapHttpTransport(); void setHost(const QString &host, bool useSecureHTTP = false, int port = 0); void setHost(const QString &host, int port); //obsolete void setAction(const QString &action); void submitRequest(QtSoapMessage &request, const QString &path); const QtSoapMessage &getResponse() const; QNetworkAccessManager *networkAccessManager(); QNetworkReply *networkReply(); Q_SIGNALS: void responseReady(); void responseReady(const QtSoapMessage &response); private Q_SLOTS: void readResponse(QNetworkReply *reply); private: QNetworkAccessManager networkMgr; QPointer networkRep; QUrl url; QString soapAction; QtSoapMessage soapResponse; }; #endif herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/qtsoap.cpp0000644000000000000000000027020111543637310022030 0ustar rootroot/**************************************************************************** ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact Nokia at qt-info@nokia.com. ** ****************************************************************************/ #include "qtsoap.h" #include #include #include /*! \page qtsoap-overview.html \title Qt SOAP component \tableofcontents \target overview \section1 Overview of the SOAP support in the QtSoap classes QtSoapMessage provides an interface for creating, inspecting and modifying SOAP messages. It has convenience functions for generating method requests and inspecting method response messages, and also functions that provide easy access to SOAP Fault messages. The QtSoapType class allows you to inspect SOAP messages with no knowledge of XML or DOM. Header and body items are all derived from QtSoapType, and through easy accessors and iterators, this class and its derivatives make it easy to build arrays (QtSoapArray), structs (QtSoapStruct) and simple types like String, Integer and Boolean (QtSoapSimpleType). Finally, QtSoapHttpTransport provides a convenient way to submit SOAP messages to a host via the HTTP protocol. \target classes \section1 The SOAP classes \table \header \i Class \i Short description \row \i \l QtSoapMessage \i Represents a SOAP message \row \i \l QtSoapQName \i Represents qualified names (QNames) \row \i \l QtSoapType \i A superclass for all data constructs in a SOAP message. \row \i \l QtSoapArray \i Represents a SOAP array \row \i \l QtSoapArrayIterator \i Lets you iterate over all the values in a SOAP array \row \i \l QtSoapStruct \i Represents a SOAP struct \row \i \l QtSoapStructIterator \i Lets you iterate over all the values in a SOAP array \row \i \l QtSoapSimpleType \i Represents simple SOAP types such as String, Integer and Boolean. \row \i \l QtSoapHttpTransport \i Provides a method for transmitting SOAP messages to an HTTP server and for getting the SOAP reply. \endtable \target partial \section1 Status of the SOAP component This is a partial implementation of the SOAP v1.1 protocol. \list \i Server side SOAP is not supported. \i References to values (id and href attributes) are not supported. \i Only arrays with less than 5 dimensions are supported. \i Namespaces for types are not checked. Only the type names are used. \i The encodingStyle attribute is ignored. The serialization and encoding rules from section 5 in the SOAP v1.1 specification are assumed regardless of the value of the encodingStyle attribute. \i QtSoapType does not have accessors for attributes, which means for example that actor, mustUnderstand and so on are not accessible in headers. \i The SOAP root attribute is not supported. \endlist */ namespace { QString localName(const QString &tagName) { int pos; if ((pos = tagName.indexOf(':'))) return tagName.right(tagName.length() - pos - 1); return tagName; } QString prefix(const QString &tagName) { int pos; if ((pos = tagName.indexOf(':'))) return tagName.left(pos); return tagName; } } /*! \class QtSoapQName qtsoap.h \brief The QtSoapQName class provides a wrapper for QNames (names with namespaces). This class is used extensively in QtSoap to define and identify header and body elements, including method and argument names. The QtSoapQName consists of a name and a URI. The URI is used as the name's namespace, i.e. the name is qualified (hence 'Q'-Name) by the URI. The name() and uri() functions return the QNames's name and URI. The QtSoapQName can be empty. It can also have just a name with no URI. Special handling is often applied to a QtSoapQName that has no URI. Typically, if a QName with no namespace is used in an element in a SOAP document that already has a default namespace defined, then that namespace will be applied to the QName. \code QtSoapMessage message; message.setMethod(QtSoapQName("sendMessage", "http://messenging.example.com/")); message.addMethodArgument(QtSoapSimpleType(QtSoapQName("a"), 15)); \endcode */ /*! Constructs a QName. Sets the QName name to \a name and the URI to \a uri. */ QtSoapQName::QtSoapQName(const QString &name, const QString &uri) : n(name), nuri(uri) { } /*! Destructs the QtSoapQName. */ QtSoapQName::~QtSoapQName() { } /*! Returns QName's name. */ QString QtSoapQName::name() const { return n; } /*! Returns the QName's URI. */ QString QtSoapQName::uri() const { return nuri; } /*! Sets the QName's name to \a s, and sets the URI to an empty string. */ QtSoapQName &QtSoapQName::operator =(const QString &s) { n = s; nuri = ""; return *this; } /*! \fn bool operator==(const QtSoapQName &s1, const QtSoapQName &s2) \relates QtSoapQName If \a s2 has a non-empty URI, this function returns true if the merge of the URI and the name of \a s1 is equal to that of \a s2; otherwise it returns false. If \a s2 has an empty URI, this function returns true if the name of \a s1 is equal to the name of \a s2; otherwise it returns false. The comparison is case-insensitive. */ bool operator ==(const QtSoapQName &s1, const QtSoapQName &s2) { if (s2.uri() == "") return s1.name().toLower() == s2.name().toLower(); return s1.name().toLower() == s2.name().toLower() && s1.uri().toLower() == s2.uri().toLower(); } /*! \fn bool operator<(const QtSoapQName &s1, const QtSoapQName &s2) \relates QtSoapQName If \a s2 has a non-empty URI, this function returns true if the merge of the URI and the name of \a s1 is lexically less than that of \a s2; otherwise it returns false. If \a s2 has an empty URI, this function returns true if the name of \a s1 is lexically less than the name of \a s2; otherwise it returns false. The comparison is case-insensitive. */ bool operator <(const QtSoapQName &s1, const QtSoapQName &s2) { if (s2.uri() == "") return s1.name().toLower() < s2.name().toLower(); return (s1.uri().toLower()+s1.name().toLower()) < (s2.uri().toLower()+s2.name().toLower()); } /*! \class QtSoapType qtsoap.h \brief The QtSoapType class is the base class for all SOAP types in QtSoap. Although it is not used to create data types, a QtSoapType reference can be conveniently used to inspect a tree of QtSoapType subclasses. Accessors from this base class, such as operator[](), allow safe navigation. \code const QtSoapType &root = message.returnValue(); if (root["fault"].isValid()) { qWarning("Warning: %s", root["fault"]["faultstring"].toString().toLatin1().constData()); } \endcode This class holds the name(), type(), id() and href() of all its derived types. If a QtSoapType reference or pointer points to a QtSoapStruct, a QtSoapArray or a QtSoapSimpleType, isValid() returns true. \sa QtSoapStruct, QtSoapArray, QtSoapSimpleType */ /*! \class QtSoapStruct qtsoap.h \brief The QtSoapStruct class is an implementation of the SOAP struct type. A SOAP struct is a dictionary of QtSoapTypes where entries are looked up by name. Entries in a struct can be of any QtSoapType type, such as QtSoapArray, QtSoapStruct or QtSoapSimpleType. The struct can be created in several ways. parse() generates a struct by analyzing a QDomNode. insert() is used to add items manually. \code QtSoapStruct myStruct(QtSoapQName("myStruct")); myStruct.insert(new QtSoapSimpleType(QtSoapQName("item1"), 5)); myStruct.insert(new QtSoapSimpleType(QtSoapQName("item2"), "hello")); myStruct.insert(new QtSoapSimpleType(QtSoapQName("item3"), true)); \endcode Use the operator[]() or at() when looking up entries in a struct by name. If the names are unknown, QtSoapStructIterator lets you iterate through all the items. \code QtSoapType &helloItem = myStruct["Hello"]; \endcode toDomElement() converts the QtSoapStruct to a DomElement. \sa QtSoapStructIterator, QtSoapType, QtSoapArray, QtSoapSimpleType */ /*! \class QtSoapStructIterator \brief The QtSoapStructIterator class provides an iterator for traversing the items in a QtSoapStruct. The iterator is created by passing a QtSoapStruct to the constructor. It it not defined which item the iterator initially will point to. Neither is the order in which the items are processed. key() returns the name of the current item. data() and current() return a pointer to the current item, or 0 if there is none. operator++() navigates to the next item in the struct. \code for (QtSoapStructIterator it(myStruct); it.current(); ++it) { QtSoapType *item = it.data(); // process item } \endcode \sa QtSoapArrayIterator */ /*! \class QtSoapArray qtsoap.h \brief The QtSoapArray class is an implementation of the SOAP array type. A SOAP array is a sequence of QtSoapType objects such as QtSoapArrays, QtSoapStructs or QtSoapSimpleTypes, and they are accessible through their ordinal position. An array can be consecutive (0, 1, 2, 3, ...) or sparse (1, 5, 6, 10, ...) and they can be multidimensional ((0, 0), (0, 1), ...). QtSoapArray supports arrays of up to 5 dimensions. The size and dimensions of the array are set in the constructor. The default constructor produces a one dimensional array, with an unset size, meaning that the array can grow as required. All elements in a SOAP array must be of the same type. Inserting different types will result in a run time error. The parse() function builds the array by analyzing a QDomNode from a SOAP document. count() returns the number of items in the array. Retrieve items in the array with at() or operator[](). Note that operator[]() only works with one dimensional arrays, but there are at() functions for arrays of up to 5 dimensions. QtSoapArrayIterator lets you iterate through all items in an array. Use insert() or append() to insert items into an array manually. append() only works with one dimensional arrays. toDomElement() returns a QDomElement representation of the SOAP array. \code QtSoapArray array; array.insert(0, new QtSoapSimpleType(QtSoapQName("Peter"), "peter")); array.insert(1, new QtSoapSimpleType(QtSoapQName("Lisa"), "lisa")); array.insert(2, new QtSoapSimpleType(QtSoapQName("Paul"), "paul")); array.insert(3, new QtSoapSimpleType(QtSoapQName("Heather"), "heather")); \endcode \sa QtSoapType, QtSoapStruct, QtSoapSimpleType */ /*! \class QtSoapArrayIterator qtsoap.h \brief The QtSoapArrayIterator class provides an iterator for traversing the items in a QtSoapArray. The items are traversed in ascending order of index position, depth first. \code // Construct a 2x2 array of Strings. QtSoapArray array("Array of strings", String, 2, 2); array.insert(0, 0, new QtSoapSimpleType(Q4SoapQName("top left"), "top left"); array.insert(0, 1, new QtSoapSimpleType(Q4SoapQName("top right"), "top right"); array.insert(1, 0, new QtSoapSimpleType(Q4SoapQName("bottom left"), "bottom left"); array.insert(1, 1, new QtSoapSimpleType(Q4SoapQName("bottom right"), "bottom right"); // Traverse all items. QtSoapArrayIterator it(array); while (!it.current()) { // Find the position of the current element. int pos1, pos2; it.pos(&pos1, &pos2); qDebug() << "Position (" << pos1 << ", " << pos2 << ") is " << "the " << it.current()->toString() << " coordinate of the grid." << endl; ++it; } \endcode */ /*! \class QtSoapSimpleType qtsoap.h \brief The QtSoapSimpleType class provides a container for all simple SOAP types, such as strings, integers and booleans. \sa QtSoapType, QtSoapStruct, QtSoapArray */ /*! \enum QtSoapType::Type SOAP supports the types described in XML Schema Part 2: Datatypes listed at \l http://www.w3.org/TR/xmlschema-2/. The following values are represented using QtSoapSimpleType, except where noted. \value AnyURI \value Array Represented by QtSoapArray \value Base64Binary \value Boolean \value Byte \value Date \value DateTime \value Decimal \value Double \value Duration \value ENTITY \value Float \value GDay \value GMonth \value GMonthDay \value GYear \value GYearMonth \value HexBinary \value ID \value IDREF \value Int \value Integer \value Language \value Long \value NCName \value NMTOKEN \value NOTATION \value Name \value NegativeInteger \value NonNegativeInteger \value NonPositiveInteger \value NormalizedString \value Other \value PositiveInteger \value QName \value Short \value String \value Struct Represented by QtSoapStruct \value Time \value Token \value UnsignedByte \value UnsignedInt \value UnsignedLong \value UnsignedShort */ /*! Constructs a QtSoapType. */ QtSoapType::QtSoapType() { t = Other; errorStr = "Unknown error"; } /*! Constructs a QtSoapType whose name is \a name and type is \a type. This contructor is usually only called by constructors in subclasses. */ QtSoapType::QtSoapType(const QtSoapQName &name, Type type) : t(type), n(name) { errorStr = "Unknown error"; } /*! Creates a QtSoapType copy of \a copy. */ QtSoapType::QtSoapType(const QtSoapType ©) : t(copy.t), errorStr(copy.errorStr), i(copy.i), n(copy.n), u(copy.u), h(copy.h) { } /*! Destructs a QtSoapType. */ QtSoapType::~QtSoapType() { } /*! Clears any contents. In this base implementation, clear() does nothing. */ void QtSoapType::clear() { } /*! Makes this QtSoapType equal to \a copy. */ QtSoapType &QtSoapType::operator =(const QtSoapType ©) { t = copy.t; errorStr = copy.errorStr; i = copy.i; n = copy.n; u = copy.u; h = copy.h; return *this; } /*! Returns true if this object is of type QtSoapStruct, QtSoapArray or QtSoapSimpletype; otherwise returns false. */ bool QtSoapType::isValid() const { return false; } /*! Returns the QString equivalent of type \a t. */ QString QtSoapType::typeToName(QtSoapType::Type t) { switch (t) { case Duration: return "duration"; case DateTime: return "dateTime"; case Time: return "time"; case Date: return "date"; case GYearMonth: return "gYearMonth"; case GYear: return "gYear"; case GMonthDay: return "gMonthDay"; case GDay: return "gDay"; case GMonth: return "gMonth"; case Boolean: return "boolean"; case Base64Binary: return "base64Binary"; case HexBinary: return "hexBinary"; case Float: return "float"; case Double: return "double"; case AnyURI: return "anyURI"; case QName: return "QName"; case NOTATION: return "NOTATION"; case String: return "string"; case NormalizedString: return "normalizedString"; case Token: return "token"; case Language: return "language"; case Name: return "name"; case NMTOKEN: return "NMToken"; case NCName: return "NCName"; case ID: return "ID"; case IDREF: return "IDREF"; case ENTITY: return "ENTITY"; case Decimal: return "decimal"; case Integer: return "integer"; case NonPositiveInteger: return "nonPositiveInteger"; case NegativeInteger: return "negativeInteger"; case Long: return "long"; case Int: return "int"; case Short: return "short"; case Byte: return "byte"; case NonNegativeInteger: return "nonNegativeInteger"; case UnsignedLong: return "unsignedLong"; case PositiveInteger: return "positiveInteger"; case UnsignedInt: return "unsignedInt"; case UnsignedShort: return "unsignedShort"; case UnsignedByte: return "unsignedByte"; case Array: return "array"; case Struct: return "struct"; default: return "other"; } } /*! Returns the QtSoapType::Type called \a name. */ QtSoapType::Type QtSoapType::nameToType(const QString &name) { const QString type = name.trimmed().toLower(); if (type == "string") return String; else if (type == "normalizedstring") return NormalizedString; else if (type == "token") return Token; else if (type == "language") return Language; else if (type == "name") return Name; else if (type == "ncname") return NCName; else if (type == "nmtoken") return NMTOKEN; else if (type == "id") return ID; else if (type == "idref") return IDREF; else if (type == "entity") return ENTITY; else if (type == "base64binary") return Base64Binary; else if (type == "hexBinary") return HexBinary; else if (type == "anyuri") return AnyURI; else if (type == "qname") return QName; else if (type == "notation") return NOTATION; else if (type == "duration") return Duration; else if (type == "datetime") return DateTime; else if (type == "time") return Time; else if (type == "date") return Date; else if (type == "gyearmonth") return GYearMonth; else if (type == "gyear") return GYear; else if (type == "gmonthday") return GMonthDay; else if (type == "gday") return GDay; else if (type == "gmonth") return GMonth; else if (type == "decimal") return Decimal; else if (type == "integer") return Integer; else if (type == "nonPositiveinteger") return NonPositiveInteger; else if (type == "negativeinteger") return NegativeInteger; else if (type == "long") return Long; else if (type == "int") return Int; else if (type == "short") return Short; else if (type == "byte") return Byte; else if (type == "nonnegativeinteger") return NonNegativeInteger; else if (type == "unsignedlong") return UnsignedLong; else if (type == "unsignedint") return UnsignedInt; else if (type == "unsignedshort") return UnsignedShort; else if (type == "unsignedbyte") return UnsignedByte; else if (type == "positiveinteger") return PositiveInteger; else if (type == "float") return Float; else if (type == "double") return Double; else if (type == "boolean") return Boolean; else return Other; } /*! Returns QString::null. */ QString QtSoapType::toString() const { return QString::null; } /*! Returns 0. */ int QtSoapType::toInt() const { return 0; } /*! Returns false. */ bool QtSoapType::toBool() const { return false; } /*! Returns the QDomElement representation of this QtSoapType as a child of \a document. */ QDomElement QtSoapType::toDomElement(QDomDocument document) const { Q_UNUSED(document); return QDomElement(); } /*! Returns the QString representation of this QtSoapType's type. */ QString QtSoapType::typeName() const { return QtSoapType::typeToName(type()); } /*! Returns the type as a QtSoapType::Type. */ QtSoapType::Type QtSoapType::type() const { return t; } /*! Returns the QName (qualified name) of this QtSoapType. */ QtSoapQName QtSoapType::name() const { return n; } /*! Returns the ID of this QtSoapType. */ QString QtSoapType::id() const { return i; } /*! Returns the href attribute of this QtSoapType. */ QString QtSoapType::href() const { return h; } /*! Sets the QName (qualified name) of this QtSoapType to \a name. */ void QtSoapType::setName(const QtSoapQName &name) { this->n = name; } /*! Sets the ID of this QtSoapType to \a i. */ void QtSoapType::setId(const QString &i) { this->i = i; } /*! Sets the href attribute of this QtSoapType to \a h. */ void QtSoapType::setHref(const QString &h) { this->h = h; } /*! Returns the value of this QtSoapType. In the base implementation, an invalid QVariant() is returned. */ QVariant QtSoapType::value() const { return QVariant(); } /*! Returns a human readable explanation of the most recent error. */ QString QtSoapType::errorString() const { return errorStr; } /*! Returns the number of child items in this QtSoapType. In the base implementation, this returns 0. */ int QtSoapType::count() const { return 0; } /*! Returns a reference to the child item at ordinal position \a pos. If no item exists at this position, returns an empty QtSoapType. */ QtSoapType &QtSoapType::operator [](int /* pos */ ) { static QtSoapType NIL; return NIL; } /*! \overload Returns a reference to the child item whose QName (qualified name) is \a key. If no item exists with this key an empty QtSoapType is returned. */ QtSoapType &QtSoapType::operator [](const QtSoapQName & /* key */) { static QtSoapType NIL; return NIL; } /*! \overload Returns a reference to the child item whose QName (qualified name) is \a key, regardless of the qualified name's URI. If no item exists with this key, an empty QtSoapType is returned. */ QtSoapType &QtSoapType::operator [](const QString & /* key */) { static QtSoapType NIL; return NIL; } /*! \overload Returns a reference to the child item at ordinal position \a pos. If no item exists at this position, returns an empty QtSoapType. */ const QtSoapType &QtSoapType::operator [](int /* pos */) const { static QtSoapType NIL; return NIL; } /*! \overload Returns a reference to the child item whose QName (qualified name) is \a key. If no item exists with this key, returns an empty QtSoapType. */ const QtSoapType &QtSoapType::operator [](const QtSoapQName & /* key */) const { static QtSoapType NIL; return NIL; } /*! \overload Returns a reference to the child item whose QName (qualified name) is \a key, regardless of the qualified name's URI. If no item exists with this key, returns an empty QtSoapType. */ const QtSoapType &QtSoapType::operator [](const QString & /* key */) const { static QtSoapType NIL; return NIL; } /*! Attempts to interpret \a node as a QtSoapType, and returns true if successful. This base implementation always returns false. */ bool QtSoapType::parse(QDomNode /* node */) { return false; } /*! \overload Constructs an empty one dimensional QtSoapArray whose element type is undefined. The first insert will decide what type of elements the array can contain. */ QtSoapArray::QtSoapArray() : QtSoapType(QtSoapQName(), Array), arrayType(Other), order(1) { lastIndex = 0; siz0 = 0; siz1 = 0; siz2 = 0; siz3 = 0; siz4 = 0; } /*! Constructs an empty QtSoapArray whose QName (qualified name) is \a name, that contains elements of type \a type, and whose dimensions are given by \a size0, \a size1, \a size2, \a size3 and \a size4. To construct a one dimensional array of size 5, set \a size0 = 5. To create a two dimensional array of size 5x10, set \a size0 = 5 and \a size1 = 10. The maximum dimension of a QtSoapArray is 5. */ QtSoapArray::QtSoapArray(const QtSoapQName &name, QtSoapType::Type type, int size0, int size1, int size2, int size3, int size4) : QtSoapType(name, Array), lastIndex(0), arrayType(type), siz0(size0), siz1(size1), siz2(size2), siz3(size3), siz4(size4) { if (size4 != -1) order = 5; else if (size3 != -1) order = 4; else if (size2 != -1) order = 3; else if (size1 != -1) order = 2; else order = 1; } /*! Create a QtSoapArray that is a copy of \a copy. */ QtSoapArray::QtSoapArray(const QtSoapArray ©) : QtSoapType(copy) { *this = copy; } /*! Destructs the QtSoapArray. */ QtSoapArray::~QtSoapArray() { } /*! Clears the contents, and the dimensions of the QtSoapArray. */ void QtSoapArray::clear() { array.clear(); lastIndex = 0; arrayType = Other; siz0 = siz1 = siz2 = siz3 = siz4 = 0; order = -1; } /*! Makes this QtSoapArray a copy of \a copy. */ QtSoapArray &QtSoapArray::operator = (const QtSoapArray ©) { if (this == ©) return *this; t = copy.t; errorStr = copy.errorStr; i = copy.i; n = copy.n; u = copy.u; h = copy.h; lastIndex = copy.lastIndex; order = copy.order; siz0 = copy.siz0; siz1 = copy.siz1; siz2 = copy.siz2; siz3 = copy.siz3; siz4 = copy.siz4; array = copy.array; return *this; } /*! Appends the QtSoapType \a item to the end of this array, which must be one dimensional. \sa insert() */ void QtSoapArray::append(QtSoapType *item) { if (order != 1) { qWarning("Attempted to insert item at position (%i) in %i-dimensional QtSoapArray.", lastIndex, order); return; } if (array.count() == 0) { array.insert(0, item); } else { array.insert(lastIndex + 1, item); ++lastIndex; } } /*! Inserts the QtSoapType \a item at the absolute position \a pos in the array. Note that this function can be used to insert items into arrays with any number of dimensions. If the array is one dimensional, then \a pos is simply the index position in the array. But if the array is multi-dimensional then \a pos is the absolute position. For example, if we have a two dimensional array [['a', 'b'], ['c', 'd'], ['e', 'f']], the element at position 0 is 'a', at position 1 is 'b', at position 2 is 'c', and so on. (There are other insert() overloads that allow for each dimension to be specified individually.) */ void QtSoapArray::insert(int pos, QtSoapType *item) { if (arrayType == Other) arrayType = item->type(); if (item->type() != arrayType) { qWarning("Attempted to insert item of type \"%s\" in QtSoapArray of type \"%s\".", item->typeName().toLatin1().constData(), QtSoapType::typeToName(arrayType).toLatin1().constData()); return; } if (order == -1) order = 1; else if (order == 1 && pos > lastIndex) lastIndex = pos; array.insert(pos, item); } /*! \overload Insert the QtoSoapType \a item at position \a pos0 x \a pos1 in a two dimensional array. */ void QtSoapArray::insert(int pos0, int pos1, QtSoapType *item) { if (order != 2) { qWarning("Attempted to insert item at position (%i, %i)" " in %i-dimensional QtSoapArray.", pos0, pos1, order); return; } if (pos0 < 0 || pos0 >= siz0 || pos1 < 0 || pos1 >= siz1) { qWarning("Attempted to insert item at position (%i, %i)" " when range of QtSoapArray is (0..%i, 0..%i)", pos0, pos1, siz0 - 1, siz1 - 1); return; } insert((pos0 * siz1) + pos1, item); } /*! \overload Insert the QtoSoapType \a item at position \a pos0 x \a pos1 x \a pos2 in a three dimensional array. */ void QtSoapArray::insert(int pos0, int pos1, int pos2, QtSoapType *item) { if (order != 3) { qWarning("Attempted to insert item at position (%i, %i, %i)" " in %i-dimensional QtSoapArray.", pos0, pos1, pos2, order); return; } if (pos0 < 0 || pos0 >= siz0 || pos1 < 0 || pos1 >= siz1 || pos2 < 0 || pos2 >= siz2) { qWarning("Attempted to insert item at position (%i, %i, %i)" " when range of QtSoapArray is (0..%i, 0..%i, 0..%i)", pos0, pos1, pos2, siz0 - 1, siz1 - 1, siz2 - 1); return; } insert((pos0 * siz2 * siz1) + (pos1 * siz2) + pos2, item); } /*! \overload Insert the QtoSoapType \a item at position \a pos0 x \a pos1 x \a pos2 x \a pos3 in a four dimensional array. */ void QtSoapArray::insert(int pos0, int pos1, int pos2, int pos3, QtSoapType *item) { if (order != 4) { qWarning("Attempted to insert item at position (%i, %i, %i, %i)" " in %i-dimensional QtSoapArray.", pos0, pos1, pos2, pos3, order); return; } insert((pos0 * siz3 * siz2 * siz1) + (pos1 * siz3 * siz2) + (pos2 * siz3) + pos3, item); } /*! \overload Insert the QtoSoapType \a item at position \a pos0 x \a pos1 x \a pos2 x \a pos3 x \a pos4 in a five dimensional array. */ void QtSoapArray::insert(int pos0, int pos1, int pos2, int pos3, int pos4, QtSoapType *item) { if (order != 5) { qWarning("Attempted to insert item at position (%i, %i, %i, %i, %i)" " in %i-dimensional QtSoapArray.", pos0, pos1, pos2, pos3, pos4, order); return; } insert((pos0 * siz4 * siz3 * siz2 * siz1) + (pos1 * siz4 * siz3 * siz2) + (pos2 * siz4 * siz3) + (pos3 * siz4) + pos4, item); } /*! \internal Given the size and dimensions of the array, generates a string used to represent the array in XML. For example, a 1-dimensional array of size 5 would get [5], a 2-dimensional array of size 5x10 would get [5,10]. */ QString QtSoapArray::arraySizeString() const { QString arraySize = "["; if (siz0 != -1) { arraySize += QString::number(siz0); if (order > 1) arraySize += "," + QString::number(siz1); if (order > 2) arraySize += "," + QString::number(siz2); if (order > 3) arraySize += "," + QString::number(siz3); if (order > 4) arraySize += "," + QString::number(siz4); } arraySize += "]"; return arraySize; } /*! \internal Recursively inspects the items and any child arrays' items to generate the aggregate type of items in this array. It the array contains ints, returns "int[5]", but if the array is of arrays of arrays of ints, the function returns "int[][][5]". */ QString QtSoapArray::arrayTypeString() const { if (arrayType != Array) return QtSoapType::typeToName(arrayType); QString atString; QtSoapArray *ar = const_cast(this); do { if (ar->count() == 0) break; atString += ar->arraySizeString(); QtSoapArrayIterator it(*const_cast(this)); if (it.data()->type() != Array) break; ar = (QtSoapArray *)it.data(); } while (ar); QtSoapArrayIterator it(*const_cast(this)); if (ar->count() == 0) atString = QtSoapSimpleType::typeToName(Int) + atString; else atString = it.data()->typeName() + atString; return atString; } /*! Returns the QDomElement representation of this QtSoapArray. The returned QDomElement is created using \a doc. */ QDomElement QtSoapArray::toDomElement(QDomDocument doc) const { QString prefix = QtSoapNamespaces::instance().prefixFor(n.uri()); QDomElement a = n.uri() == "" ? doc.createElement( n.name()) : doc.createElementNS(n.uri(), prefix + ":" + n.name()); QString schemaprefix = QtSoapNamespaces::instance().prefixFor(XML_SCHEMA_INSTANCE); a.setAttributeNS(XML_SCHEMA_INSTANCE, schemaprefix + ":type", "xsd:Array"); QString encprefix = QtSoapNamespaces::instance().prefixFor(SOAPv11_ENCODING); a.setAttributeNS(SOAPv11_ENCODING, encprefix + ":arrayType", "xsd:" + arrayTypeString()); for (QtSoapArrayIterator i(*const_cast(this)); !i.atEnd(); ++i) { QDomElement item = i.data()->toDomElement(doc); item.setTagName("item"); int pos0, pos1, pos2, pos3, pos4; i.pos(&pos0, &pos1, &pos2, &pos3, &pos4); QString position = "[" + QString::number(pos0); if (order > 1) position += "," + QString::number(pos1); if (order > 2) position += "," + QString::number(pos2); if (order > 3) position += "," + QString::number(pos3); if (order > 4) position += "," + QString::number(pos4); position += "]"; QString envprefix = QtSoapNamespaces::instance().prefixFor(SOAPv11_ENVELOPE); item.setAttributeNS(SOAPv11_ENVELOPE, envprefix + ":position", position); a.appendChild(item); } return a; } /*! \reimp For this class, always returns true. */ bool QtSoapArray::isValid() const { return true; } /*! Inspects \a node and builds the content of the QtSoapArray if \a node qualifies as a SOAP array. Returns true if it does; otherwise returns false. */ bool QtSoapArray::parse(QDomNode node) { if (node.isNull() || !node.isElement()) return false; QDomElement e = node.toElement(); QDomAttr typeattr = e.attributeNode("type"); if (!typeattr.isNull() && (localName(typeattr.value()).toLower() != "array")) return false; QDomNodeList children = e.childNodes(); int c = children.count(); array.clear(); // ### array.resize(c); int pos = 0; for (int i = 0; i < c; ++i) { QDomNode n = children.item(i); if (n.isComment()) continue; if (!n.isElement()){ // ### An error in the soap document. return false; } QDomElement elem = n.toElement(); QtSmartPtr type = QtSoapTypeFactory::instance().soapType(elem); if (!type.ptr()) { // ### An error in the soap document. return false; } // ### Check namespace QDomAttr posattr = elem.attributeNode("position"); if (!posattr.isNull()) pos = posattr.value().toInt(); array.insert(pos, type); ++pos; } setName(QtSoapQName(localName(e.tagName()), e.namespaceURI())); return true; } /*! Returns the number of items in the array. Note that this is not the same as the size of the array, because the array may be sparse. */ int QtSoapArray::count() const { return array.count(); } /*! Returns a reference to the item at ordinal position \a pos. If there is no item at position \a pos, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::operator [](int pos) { return at(pos); } /*! \overload Returns a reference to the child item whose local name is \a s. If there is no item with this local name, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::operator [](const QString &s) { return QtSoapType::operator[](s); } /*! \overload Returns a reference to the child item whose QName (qualified name) is \a s. If there is no item with this name, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::operator [](const QtSoapQName &s) { return QtSoapType::operator[](s); } /*! \overload Returns a reference to the item at ordinal position \a pos. If there is no item at position \a pos, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::operator [] (int pos) const { return at(pos); } /*! \overload Returns a reference to the child item whose local name is \a s. If there is no item with this local name, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::operator [](const QString &s) const { return QtSoapType::operator[](s); } /*! \overload Returns a reference to the child item whose QName (qualified name) is \a s. If there is no item with this name, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::operator [](const QtSoapQName &s) const { return QtSoapType::operator[](s); } /*! Returns a reference to the item at ordinal position \a pos. If there is no item at position \a pos, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::at(int pos) { static QtSoapType NIL; if (array.find(pos) != array.end()) return *array[pos]; else return NIL; } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 in a two dimensional array. If there is no such item, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::at(int pos0, int pos1) { return at(pos0 * siz1 + pos1); } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 x \a pos2 in a three dimensional array. If there is no such item, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::at(int pos0, int pos1, int pos2) { return at((pos0 * siz2 * siz1) + (pos1 * siz2) + pos2); } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 x \a pos2 x \a pos3 in a four dimensional array. If there is no such item, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::at(int pos0, int pos1, int pos2, int pos3) { return at((pos0 * siz3 * siz2 * siz1) + (pos1 * siz3 * siz2) + (pos2 * siz3) + pos3); } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 x \a pos2 x \a pos3 x \a pos4 in a five dimensional array. If there is no such item, returns an empty QtSoapType. */ QtSoapType &QtSoapArray::at(int pos0, int pos1, int pos2, int pos3, int pos4) { return at((pos0 * siz4 * siz3 * siz2 * siz1) + (pos1 * siz4 * siz3 * siz2) + (pos2 * siz4 * siz3) + (pos3 * siz4) + pos4); } /*! \overload Returns a reference to the item at ordinal position \a pos. If there is no item at position \a pos, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::at(int pos) const { static QtSoapType NIL; if (array.find(pos) != array.end()) return *array[pos]; else return NIL; } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 in a two dimensional array. If there is no such item, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::at(int pos0, int pos1) const { return at(pos0 * siz1 + pos1); } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 x \a pos2 in a three dimensional array. If there is no such item, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::at(int pos0, int pos1, int pos2) const { return at((pos0 * siz2 * siz1) + (pos1 * siz2) + pos2); } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 x \a pos2 x \a pos3 in a four dimensional array. If there is no such item, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::at(int pos0, int pos1, int pos2, int pos3) const { return at((pos0 * siz3 * siz2 * siz1) + (pos1 * siz3 * siz2) + (pos2 * siz3) + pos3); } /*! \overload Returns a reference to the item at ordinal position \a pos0 x \a pos1 x \a pos2 x \a pos3 x \a pos4 in a five dimensional array. If there is no such item, returns an empty QtSoapType. */ const QtSoapType &QtSoapArray::at(int pos0, int pos1, int pos2, int pos3, int pos4) const { return at((pos0 * siz4 * siz3 * siz2 * siz1) + (pos1 * siz4 * siz3 * siz2) + (pos2 * siz4 * siz3) + (pos3 * siz4) + pos4); } /*! Constructs a QtSoapArrayIterator on \a array, initializing the iterator to point to the first element. */ QtSoapArrayIterator::QtSoapArrayIterator(QtSoapArray &array) : it(array.array.begin()), arr(&array) { } /*! Constructs a QtSoapArrayIterator that is a copy of \a copy. */ QtSoapArrayIterator::QtSoapArrayIterator(const QtSoapArrayIterator ©) : it(copy.it), arr(copy.arr) { } /*! Returns false if this iterator points to an item in the array, otherwise true. */ bool QtSoapArrayIterator::atEnd() const { return (it == arr->array.end()); } /*! Assignment operator of QtSoapArrayIterator. Makes this iterator a copy of \a copy. */ QtSoapArrayIterator &QtSoapArrayIterator::operator =(const QtSoapArrayIterator ©) { it = copy.it; arr = copy.arr; return *this; } /*! Destructs the QtSoapArrayIterator. */ QtSoapArrayIterator::~QtSoapArrayIterator() { } /*! \overload Returns the ordinal position of the iterator. Works for arrays of any dimension, but is only useful for one dimensional arrays. */ int QtSoapArrayIterator::pos() const { return it.key(); } /*! Populates the arguments \a pos0, \a pos1, \a pos2, \a pos3 and \a pos4 with the coordinate of the current position of the iterator. For a one dimensional array, only \a pos0 is populated. For a two dimensional array, \a pos0 and \a pos1 are populated, and so on. Any of the arguments that are 0-pointers are ignored. */ void QtSoapArrayIterator::pos(int *pos0, int *pos1, int *pos2, int *pos3, int *pos4) const { const int key = it.key(); switch (arr->order) { case 1: if (pos0) *pos0 = key; break; case 2: { const int tmp = key / arr->siz1; if (pos0) *pos0 = tmp; if (pos1) *pos1 = key - (tmp * arr->siz1); } break; case 3: { const int tmp0 = key / (arr->siz2 * arr->siz1); const int tmp1 = key - (tmp0 * (arr->siz2 * arr->siz1)); const int tmp2 = tmp1 / arr->siz2; if (pos0) *pos0 = tmp0; if (pos1) *pos1 = tmp2; if (pos2) *pos2 = tmp1 - (tmp2 * arr->siz2); } break; case 4: { const int tmp0 = key / (arr->siz3 * arr->siz2 * arr->siz1); const int tmp1 = key - (tmp0 * (arr->siz3 * arr->siz2 * arr->siz1)); const int tmp2 = tmp1 / (arr->siz3 * arr->siz2); const int tmp3 = tmp1 - (tmp2 * (arr->siz3 * arr->siz2)); const int tmp4 = tmp3 / arr->siz3; const int tmp5 = tmp3 - (tmp4 * arr->siz3); if (pos0) *pos0 = tmp0; if (pos1) *pos1 = tmp2; if (pos2) *pos2 = tmp4; if (pos3) *pos3 = tmp5; } break; case 5: { const int tmp0 = key / (arr->siz4 * arr->siz3 * arr->siz2 * arr->siz1); const int tmp1 = key - (tmp0 * (arr->siz4 * arr->siz3 * arr->siz2 * arr->siz1)); const int tmp2 = tmp1 / (arr->siz4 * arr->siz3 * arr->siz2); const int tmp3 = tmp1 - (tmp2 * (arr->siz4 * arr->siz3 * arr->siz2)); const int tmp4 = tmp3 / (arr->siz4 * arr->siz3); const int tmp5 = tmp3 - (tmp4 * arr->siz4 * arr->siz3); const int tmp6 = tmp5 / arr->siz3; const int tmp7 = tmp5 - (tmp6 * arr->siz3); if (pos0) *pos0 = tmp0; if (pos1) *pos1 = tmp2; if (pos2) *pos2 = tmp4; if (pos3) *pos3 = tmp6; if (pos4) *pos4 = tmp7; } break; default: break; } } /*! Returns a reference to the item that the iterator is currently pointing to. */ QtSoapType *QtSoapArrayIterator::data() { if (it == arr->array.end()) return 0; return it.value().ptr(); } /*! Returns a reference to the item that the iterator is currently pointing to. */ const QtSoapType *QtSoapArrayIterator::current() const { if (it == arr->array.end()) return 0; return it.value().ptr(); } /*! Moves the iterator position to the next item in the array. */ void QtSoapArrayIterator::operator ++() { ++it; } /*! Returns true if this Iterator's position is not equal to the position of \a j; otherwise returns false. */ bool QtSoapArrayIterator::operator != (const QtSoapArrayIterator &j) const { return it != j.it; } /*! Returns true if this Iterator's position is equal to the position of \a j; otherwise returns false. */ bool QtSoapArrayIterator::operator == (const QtSoapArrayIterator &j) const { return it == j.it; } /*! Constructs an empty QtSoapStruct. */ QtSoapStruct::QtSoapStruct() : QtSoapType(QtSoapQName(), Struct) { } /*! Constructs an empty QtSoapStruct and sets its QName (qualified name) to \a name. */ QtSoapStruct::QtSoapStruct(const QtSoapQName &name) : QtSoapType(name, Struct) { } /*! Constructs a QtSoapStruct that is a copy of \a copy. */ QtSoapStruct::QtSoapStruct(const QtSoapStruct ©) : QtSoapType(copy) { *this = copy; } /*! Destructs the QtSoapStruct. */ QtSoapStruct::~QtSoapStruct() { } /*! Removes all items from the struct. */ void QtSoapStruct::clear() { dict.clear(); } /*! Makes this struct a copy of \a copy. */ QtSoapStruct &QtSoapStruct::operator =(const QtSoapStruct ©) { if (this == ©) return *this; t = copy.t; errorStr = copy.errorStr; i = copy.i; n = copy.n; u = copy.u; h = copy.h; i = copy.i; dict = copy.dict; return *this; } /*! Inserts the QtSoapType \a item into this struct. Any existing item with the same QName (qualified name) will be erased. */ void QtSoapStruct::insert(QtSoapType *item) { dict.append(item); } /*! Generates the QDomElement representation of this struct. The returned QDomElement is created using \a doc. */ QDomElement QtSoapStruct::toDomElement(QDomDocument doc) const { QString prefix = QtSoapNamespaces::instance().prefixFor(n.uri()); QDomElement a = n.uri() == "" ? doc.createElement(n.name()) : doc.createElementNS(n.uri(), prefix + ":" + n.name()); for (QtSoapStructIterator i(*const_cast(this)); i.data(); ++i) a.appendChild(i.data()->toDomElement(doc)); return a; } /*! \reimp */ bool QtSoapStruct::isValid() const { return true; } /*! Inspects \a node and constructs the equivalent QtSoapStruct if \a node qualifies as a SOAP struct. Returns true if it does; otherwise returns false. */ bool QtSoapStruct::parse(QDomNode node) { if (node.isNull() || !node.isElement()) return false; QDomElement e = node.toElement(); QDomNodeList children = e.childNodes(); int c = children.count(); dict.clear(); for (int i = 0; i < c; ++i) { QDomNode n = children.item(i); if (n.isComment()) continue; if (!n.isElement()){ errorStr = "In the struct element " + e.tagName(); errorStr += ", the " + QString::number(i) + "th child "; errorStr += "is not an element."; return false; } QtSmartPtr type = QtSoapTypeFactory::instance().soapType(n.toElement()); if (!type.ptr()) { errorStr = "In the struct element " + e.tagName(); errorStr += ", child #" + QString::number(i) + ", "; errorStr += n.toElement().tagName() + ", was not recognized as a SOAP type."; return false; } dict.append(type); } setName(QtSoapQName(localName(e.tagName()), e.namespaceURI())); return true; } /*! Returns the number of items in this struct. */ int QtSoapStruct::count() const { return dict.count(); } /*! Returns a reference to the item in this struct whose QName (qualified name) is \a key. If no such item exists, an empty QtSoapType is returned. */ QtSoapType &QtSoapStruct::operator [](const QtSoapQName &key) { return at(key); } /*! \overload Returns a reference to the item in this struct whose QName (qualified name) is \a key. If no such item exists, an empty QtSoapType is returned. */ const QtSoapType &QtSoapStruct::operator [](const QtSoapQName &key) const { return at(key); } /*! \overload Returns a reference to the item in this struct whose QName (qualified name) is \a key. If no such item exists, an empty QtSoapType is returned. */ QtSoapType &QtSoapStruct::operator [](const QString &key) { return at(QtSoapQName(key, "")); } /*! \overload Returns a reference to the item in this struct whose QName (qualified name) is \a key. If no such item exists, an empty QtSoapType is returned. */ const QtSoapType &QtSoapStruct::operator [](const QString &key) const { return at(QtSoapQName(key, "")); } /*! \overload Returns a reference to item number \a i in this struct. If no such item exists, an empty QtSoapType is returned. The items are ordered in the sequence in which they were inserted, starting from 0. */ QtSoapType &QtSoapStruct::operator [](int i) { static QtSoapType NIL; if (i < 0 || i >= dict.count()) return NIL; return *dict[i].ptr(); } /*! \overload Returns a reference to item number \a i in this struct. If no such item exists, an empty QtSoapType is returned. The items are ordered in the sequence in which they were inserted, starting from 0. */ const QtSoapType &QtSoapStruct::operator [](int i) const { static QtSoapType NIL; if (i < 0 || i >= dict.count()) return NIL; return *dict[i].ptr(); } /*! Returns a reference to the item in this struct whose QName (qualified name) is \a key. If no such item exists, an empty QtSoapType is returned. */ QtSoapType &QtSoapStruct::at(const QtSoapQName &key) { static QtSoapType NIL; QListIterator > it(dict); while (it.hasNext()) { QtSoapType *ret = it.next().ptr(); if (ret->name() == key) return *ret; } return NIL; } /*! \overload Returns a reference to the item in this struct whose QName (qualified name) is \a key. If no such item exists, an empty QtSoapType is returned. */ const QtSoapType &QtSoapStruct::at(const QtSoapQName &key) const { static QtSoapType NIL; for (QtSoapStructIterator i(*const_cast(this)); i.current(); ++i) if (i.key() == key) return *i.current(); return NIL; } /*! Constructs a QtSoapStructIterator and initializes it to point to the first element in the struct \a s. */ QtSoapStructIterator::QtSoapStructIterator(QtSoapStruct &s) : it(s.dict.begin()), itEnd(s.dict.end()) { } /*! Destructs the QtSoapStructIterator. */ QtSoapStructIterator::~QtSoapStructIterator() { } /*! Returns the QName (qualified name) of the current item. */ QtSoapQName QtSoapStructIterator::key() const { if (it == itEnd) return QtSoapQName(); return (*it)->name(); } /*! Returns a pointer to the current item, or 0 if there is none. */ QtSoapType *QtSoapStructIterator::data() { if (it == itEnd) return 0; return it->ptr(); } /*! Returns a pointer to the current item, or 0 if there is none. */ const QtSoapType *QtSoapStructIterator::current() const { if (it == itEnd) return 0; return it->ptr(); } /*! Moves the iterator to the next item in the struct. */ void QtSoapStructIterator::operator ++() { if (it == itEnd) return; ++it; } /*! Returns true if this iterator's position is not equal to that of \a j; otherwise returns false. */ bool QtSoapStructIterator::operator !=(const QtSoapStructIterator &j) const { return it != j.it; } /*! Returns true if this iterator's position is equal to that of \a j; otherwise returns false. */ bool QtSoapStructIterator::operator ==(const QtSoapStructIterator &j) const { return it == j.it; } /*! Constructs an empty QtSoapSimpleType. */ QtSoapSimpleType::QtSoapSimpleType() { } /*! \overload Constructs an empty QtSoapSimpleType, and sets its QName (qualified name) to \a name. */ QtSoapSimpleType::QtSoapSimpleType(const QtSoapQName &name) : QtSoapType(name) { } /*! \overload Constructs a QtSoapSimpleType of type Int. Sets its QName (qualified name) to \a name and its value to \a n. */ QtSoapSimpleType::QtSoapSimpleType(const QtSoapQName &name, int n) : QtSoapType(name, Int), v(QVariant(n)) { } /*! \overload Constructs a QtSoapSimpleType of type Boolean. Sets its QName (qualified name) to \a name and its value to \a n. \a dummy is an unused variable that should be set to 0; it is needed for older compilers that cannot distinguish between bool and int. */ QtSoapSimpleType::QtSoapSimpleType(const QtSoapQName &name, bool n, int) : QtSoapType(name, Boolean), v(QVariant(n)) { } /*! \overload Constructs a QtSoapSimpleType of type String. Sets its QName (qualified name) to \a name and its value to \a n. */ QtSoapSimpleType::QtSoapSimpleType(const QtSoapQName &name, const QString &n) : QtSoapType(name, String), v(QVariant(n)) { } /*! Constructs a QtSoapSimpleType that is a copy of \a copy. */ QtSoapSimpleType::QtSoapSimpleType(const QtSoapSimpleType ©) : QtSoapType(copy), v(copy.v) { } /*! Destructs the QtSoapSimpleType. */ QtSoapSimpleType::~QtSoapSimpleType() { } /*! Erases the value of this QtSoapSimpleType. */ void QtSoapSimpleType::clear() { v.clear(); } /*! Returns the QDomElement representation of this QtSoapSimpleType. The returned QDomElement is created using \a doc. */ QDomElement QtSoapSimpleType::toDomElement(QDomDocument doc) const { QString prefix = QtSoapNamespaces::instance().prefixFor(n.uri()); QDomElement a = n.uri() == "" ? doc.createElement(n.name()) : doc.createElementNS(n.uri(), prefix + ":" + n.name()); QString schemaprefix = QtSoapNamespaces::instance().prefixFor(XML_SCHEMA_INSTANCE); a.setAttributeNS(XML_SCHEMA_INSTANCE, schemaprefix + ":type", "xsd:" + typeName()); a.appendChild(doc.createTextNode(v.toString())); return a; } /*! \reimp */ bool QtSoapSimpleType::isValid() const { return true; } /*! Makes this QtSoapSimpleType a copy of \a copy. */ QtSoapSimpleType &QtSoapSimpleType::operator =(const QtSoapSimpleType ©) { t = copy.t; errorStr = copy.errorStr; i = copy.i; n = copy.n; u = copy.u; h = copy.h; v = copy.v; return *this; } /*! Inspects \a node and constructs the QtSoapSimpleType content if \a node qualifies as a SOAP simple type. Returns true if it does; otherwise returns false. */ bool QtSoapSimpleType::parse(QDomNode node) { if (node.isNull() || !node.isElement()) return false; QDomElement e = node.toElement(); QDomAttr typeattr = e.attributeNode("type"); QString type = typeattr.isNull() ? QString("string") : localName(typeattr.value()).toLower(); t = QtSoapType::nameToType(type); switch (t) { case Duration: case DateTime: case Time: case Date: case GYearMonth: case GYear: case GMonthDay: case GDay: case GMonth: case Base64Binary: case HexBinary: case AnyURI: case QName: case NOTATION: case String: case NormalizedString: case Token: case Language: case Name: case NMTOKEN: case NCName: case ID: case IDREF: case ENTITY: v = QVariant(e.text()); break; case Float: v = QVariant(e.text().toFloat()); break; case Double: v = QVariant(e.text().toDouble()); break; case Decimal: case Integer: case NonPositiveInteger: case NegativeInteger: case Long: case Int: case Short: case Byte: case NonNegativeInteger: case UnsignedLong: case PositiveInteger: case UnsignedInt: case UnsignedShort: case UnsignedByte: if (e.text() == "" || (e.text() != "" && (e.text()[0].isNumber() || e.text()[0] == '-'))) v = QVariant(e.text().toInt()); else { errorStr = "Type error at element \"" + e.tagName() + "\""; return false; } break; case Boolean: { QString val = e.text().trimmed().toLower(); if (val == "false") v = QVariant(false); else if (val == "true") v = QVariant(true); } break; default: v = e.text(); break; } setName(QtSoapQName(localName(e.tagName()), e.namespaceURI())); return true; } /*! Returns the value of the simple type as a QString. */ QString QtSoapSimpleType::toString() const { return v.toString(); } /*! Returns the value of the simple type as an int. */ int QtSoapSimpleType::toInt() const { return v.toInt(); } /*! Returns the value of the simple type as a bool. */ bool QtSoapSimpleType::toBool() const { return v.toBool(); } /*! Returns the QVariant value of this QtSoapSimpleType. */ QVariant QtSoapSimpleType::value() const { return v; } /*! \class QtSoapMessage qtsoap.h \brief The QtSoapMessage class provides easy access to SOAP messages. With this class, you can create and inspect any SOAP message. There are convenience functions available for generating the most common types of SOAP messages, and any other messages can be constructed manually using addBodyItem(). Use setMethod() and addMethodArgument() to construct a method request. The return value of a method response is available from returnValue(). Use setFaultCode(), setFaultString() and addFaultDetail() to construct a Fault message. To inspect a Fault message, use faultCode(), faultString() and faultDetail(). To add items to the body part of the SOAP message, use addBodyItem(). To add items to the header, use addHeaderItem(). toXmlString() returns a QString XML representation of the SOAP message. clear() resets all content in the message, creating an empty SOAP message. \code QtSoapMessage message; message.setMethod("getTemperature", "http://weather.example.com/temperature"); message.addMethodArgument("city", "Oslo"); // Get the SOAP message as an XML string. QString xml = message.toXmlString(); \endcode QtSoap provides a partial implementation of version 1.1 of the SOAP protocol as defined in \l http://www.w3.org/TR/SOAP/. \list \i Server side SOAP is not supported. \i References to values (id and href attributes) are not supported. \i Arrays support a maximum of five dimensions. \i Namespaces for types are not checked. Only the type names are used. \i The encodingStyle attribute is ignored. The serialization and encoding rules from section 5 in the SOAP v1.1 specification are assumed regardless of the value of the encodingStyle attribute. \i QtSoapType does not have accessors for attributes, which means for example that actor, mustUnderstand and so on are not accessible in headers. \i The SOAP root attribute is not supported. \endlist \sa QtSoapType, QtSoapQName, QtSoapHttpTransport */ /*! \enum QtSoapMessage::FaultCode This enum describes all the supported SOAP Fault codes: \value VersionMismatch The namespace for the Envelope element was unrecognized by the remote SOAP server. This usually means that the remote server does not support version 1.1 of the SOAP protocol. \value MustUnderstand One of the header items in the SOAP message with a "MustUnderstand" attribute was not recognized by the remote server. \value Client An error in the SOAP message or transport prevents further processing by the remote SOAP server. \value Server An error in the remote SOAP server prevents it from processing the SOAP message. \omitvalue Other */ /*! \enum QtSoapMessage::MessageType \value Fault \value MethodRequest \value MethodResponse \value OtherType */ /*! Constructs an empty QtSoapMessage. The message only contains the Envelope element, with no header and no body. */ QtSoapMessage::QtSoapMessage() : type(OtherType), envelope(QtSoapQName("Envelope", SOAPv11_ENVELOPE)) { init(); } /*! Constructs a copy of \a copy. */ QtSoapMessage::QtSoapMessage(const QtSoapMessage ©) : type(copy.type), envelope(copy.envelope), m(copy.m), margs(copy.margs), errorStr(copy.errorStr) { init(); } /*! Destructs a QtSoapMessage. */ QtSoapMessage::~QtSoapMessage() { } /*! \internal Registers the standard SOAP namespaces with prefixes. */ void QtSoapMessage::init() { QtSoapNamespaces::instance().registerNamespace("SOAP-ENV", SOAPv11_ENVELOPE); QtSoapNamespaces::instance().registerNamespace("SOAP-ENC", SOAPv11_ENCODING); QtSoapNamespaces::instance().registerNamespace("xsi", XML_SCHEMA_INSTANCE); QtSoapNamespaces::instance().registerNamespace("xsd", XML_SCHEMA); } /*! Clears the content of the SOAP message. */ void QtSoapMessage::clear() { type = OtherType; envelope.clear(); m = QtSoapQName(); margs.clear(); errorStr = "Unknown error"; } /*! Makes this message a copy of \a copy. */ QtSoapMessage &QtSoapMessage::operator =(const QtSoapMessage ©) { envelope = copy.envelope; m = copy.m; margs = copy.margs; errorStr = copy.errorStr; return *this; } /*! Imports the QDomDocument \a d if it validates as a SOAP message. Any existing message content is replaced. If the import fails, this message becomes a Fault message. Returns true if the import succeeds, otherwise false. */ bool QtSoapMessage::setContent(QDomDocument &d) { if (isValidSoapMessage(d)) { clear(); QDomNode node = d.firstChild(); if (!node.isElement()) node = node.nextSibling(); if (envelope.parse(node)) return true; } return false; } /*! \overload Parses the XML document in \a buffer. Imports the document if it validates as a SOAP message. Any existing message content is replaced. If the import fails, this message becomes a Fault message. Returns true if the import succeeds, otherwise false. */ bool QtSoapMessage::setContent(const QByteArray &buffer) { int errorLine, errorColumn; QString errorMsg; QDomDocument doc; if (!doc.setContent(buffer, true, &errorMsg, &errorLine, &errorColumn)) { QString s; s.sprintf("%s at line %i, column %i", errorMsg.toLatin1().constData(), errorLine, errorColumn); setFaultCode(VersionMismatch); setFaultString("XML parse error"); addFaultDetail(new QtSoapSimpleType(QtSoapQName("ParseError"), s)); return false; } if (!isValidSoapMessage(doc)) return false; QDomNode node = doc.firstChild(); if (!node.isElement()) node = node.nextSibling(); bool res = envelope.parse(node); if (!res) qDebug("QtSoapMessage::setContent(), parsing failed: %s", envelope.errorString().toLatin1().constData()); return res; } /*! Validates the QDomDocument \a candidate using some simple heuristics. Returns true if the document is a valid SOAP message; otherwise returns false. */ bool QtSoapMessage::isValidSoapMessage(const QDomDocument &candidate) { QDomNode tmp = candidate.firstChild(); if (tmp.isNull()) return false; // Skip the initial processing instruction if there is one. Most // likely this isn't actually a processing instruction, but rather // the initial xml declaration (node); fault.insert(new QtSoapSimpleType(QtSoapQName("Faultcode"), codeStr)); } /*! Sets the Fault faultstring of the SOAP Fault message to \a s. */ void QtSoapMessage::setFaultString(const QString &s) { if (type != Fault && type != OtherType) { clear(); type = Fault; } if (!body()[QtSoapQName("Fault", SOAPv11_ENVELOPE)].isValid()) addBodyItem(new QtSoapStruct(QtSoapQName("Fault", SOAPv11_ENVELOPE))); QtSoapType &node = body()[QtSoapQName("Fault", SOAPv11_ENVELOPE)]; QtSoapStruct &fault = reinterpret_cast(node); fault.insert(new QtSoapSimpleType(QtSoapQName("Faultstring"), s)); } /*! Adds the QtSoapType \a detail to the end of the list of faultdetail items in a SOAP Fault message. */ void QtSoapMessage::addFaultDetail(QtSoapType *detail) { if (type != Fault && type != OtherType) { clear(); type = Fault; } if (!body()[QtSoapQName("Fault", SOAPv11_ENVELOPE)].isValid()) addBodyItem(new QtSoapStruct(QtSoapQName("Fault", SOAPv11_ENVELOPE))); QtSoapType &node = body()[QtSoapQName("Fault", SOAPv11_ENVELOPE)]; QtSoapStruct &fault = reinterpret_cast(node); if (!fault[QtSoapQName("Faultdetail", SOAPv11_ENVELOPE)].isValid()) fault.insert(new QtSoapStruct(QtSoapQName("Faultdetail", SOAPv11_ENVELOPE))); QtSoapType &node2 = fault[QtSoapQName("Faultdetail", SOAPv11_ENVELOPE)]; QtSoapStruct &fdetail = reinterpret_cast(node2); fdetail.insert(detail); } /*! Returns the method of a SOAP method request or response as a QtSoapType. */ const QtSoapType &QtSoapMessage::method() const { static QtSoapType NIL; if (body().count() == 0) return NIL; QtSoapStructIterator it(body()); return *it.data(); } /*! Sets the QName (qualified name) of the method to call in a SOAP method request to \a meth. This function \e must be called before calling addMethodArgument(). */ void QtSoapMessage::setMethod(const QtSoapQName &meth) { if (type != MethodRequest && type != OtherType) { clear(); type = MethodRequest; } addBodyItem(new QtSoapStruct(meth)); } /*! \overload Sets the method name to \a name and uri to \a uri. */ void QtSoapMessage::setMethod(const QString &name, const QString &uri) { setMethod(QtSoapQName(name, uri)); } /*! Adds argument \a arg to the list of arguments that are passed in a SOAP method request. \warning setMethod() must be called before calling this function. */ void QtSoapMessage::addMethodArgument(QtSoapType *arg) { if (body().count() == 0) { qWarning("Attempted to add argument (%s:%s) without first setting method", arg->name().uri().toLatin1().constData(), arg->name().name().toLatin1().constData()); return; } QtSoapStructIterator it(body()); QtSoapType &node = *it.data(); QtSoapStruct &meth = static_cast(node); meth.insert(arg); } /*! \overload Adds an argument called \a name with a uri of \a uri. The type of the argument is QtSoapType::String and its value is \a value. */ void QtSoapMessage::addMethodArgument(const QString &name, const QString &uri, const QString &value) { addMethodArgument(new QtSoapSimpleType(QtSoapQName(name, uri), value)); } /*! \overload Adds an argument called \a name with a uri of \a uri. The type of the argument is QtSoapType::Boolean and its value is \a value. The \a dummy argument is used to distinguish this function from the overload which takes an int. */ void QtSoapMessage::addMethodArgument(const QString &name, const QString &uri, bool value, int dummy) { addMethodArgument(new QtSoapSimpleType(QtSoapQName(name, uri), value, dummy)); } /*! \overload Adds an argument called \a name with a uri of \a uri. The type of the argument is QtSoapType::Integer and its value is \a value. */ void QtSoapMessage::addMethodArgument(const QString &name, const QString &uri, int value) { addMethodArgument(new QtSoapSimpleType(QtSoapQName(name, uri), value)); } /*! Constructs a QtSoapTypeFactory and initializes it with all the known SOAP types. */ QtSoapTypeFactory::QtSoapTypeFactory() { QtSoapTypeConstructor *structConstructor = new QtSoapTypeConstructor(); deleteList.append(structConstructor); QtSoapTypeConstructor *arrayConstructor = new QtSoapTypeConstructor(); deleteList.append(arrayConstructor); QtSoapTypeConstructor *basicTypeConstructor = new QtSoapTypeConstructor(); deleteList.append(basicTypeConstructor); registerHandler("struct", structConstructor); registerHandler("array", arrayConstructor); registerHandler("string", basicTypeConstructor); registerHandler("normalizedstring", basicTypeConstructor); registerHandler("token", basicTypeConstructor); registerHandler("language", basicTypeConstructor); registerHandler("name", basicTypeConstructor); registerHandler("ncname", basicTypeConstructor); registerHandler("id", basicTypeConstructor); registerHandler("idref", basicTypeConstructor); registerHandler("entity", basicTypeConstructor); registerHandler("nmtoken", basicTypeConstructor); registerHandler("nmtokens", basicTypeConstructor); registerHandler("boolean", basicTypeConstructor); registerHandler("decimal", basicTypeConstructor); registerHandler("integer", basicTypeConstructor); registerHandler("nonpositiveinteger", basicTypeConstructor); registerHandler("negativeinteger", basicTypeConstructor); registerHandler("int", basicTypeConstructor); registerHandler("long", basicTypeConstructor); registerHandler("short", basicTypeConstructor); registerHandler("byte", basicTypeConstructor); registerHandler("nonnegativeinteger", basicTypeConstructor); registerHandler("unsignedlong", basicTypeConstructor); registerHandler("unsignedint", basicTypeConstructor); registerHandler("unsignedshort", basicTypeConstructor); registerHandler("unsignedbyte", basicTypeConstructor); registerHandler("positiveinteger", basicTypeConstructor); registerHandler("float", basicTypeConstructor); registerHandler("double", basicTypeConstructor); //registerHandler("hexBinary", basicTypeConstructor); //registerHandler("base64Binary", basicTypeConstructor); registerHandler("other", structConstructor); } /*! Destructs the QtSoapTypeFactory. This destructor is called when the application exits. */ QtSoapTypeFactory::~QtSoapTypeFactory() { QLinkedList::ConstIterator it = deleteList.begin(); while (it != deleteList.end()) { delete *it; ++it; } } QScopedPointer QtSoapTypeFactory::s_instance; QMutex QtSoapTypeFactory::s_initMutex(QMutex::Recursive); /*! Returns a reference to the QtSoapTypeFactory singleton. */ QtSoapTypeFactory &QtSoapTypeFactory::instance() { QMutexLocker lock(&s_initMutex); if (s_instance) { return *s_instance; } s_instance.reset(new QtSoapTypeFactory()); return *s_instance; } /*! Registers a handler \a handler for a QtSoapType called \a name. */ bool QtSoapTypeFactory::registerHandler(const QString &name, QtSoapTypeConstructorBase *handler) { if (typeHandlers.find(name) != typeHandlers.end()) { errorStr = "A handler for " + name + " is already registered."; return false; } typeHandlers.insert(name, handler); return true; } /*! \internal */ QtSmartPtr QtSoapTypeFactory::soapType(QDomNode node) const { if (node.isNull() || !node.isElement()) return QtSmartPtr(); QDomElement elem = node.toElement(); QDomAttr attr = elem.attributeNode("type"); QtSoapTypeConstructorBase *constructor = 0; if (!attr.isNull()) { QHash::ConstIterator it; it = typeHandlers.find(localName(attr.value().toLower())); if (it != typeHandlers.end()) constructor = *it; } if (attr.isNull() || !constructor) { QHash::ConstIterator it; if (node.firstChild().isElement()) { if (localName(node.nodeName().toLower()) == "array") { it = typeHandlers.find("array"); } else it = typeHandlers.find("struct"); } else it = typeHandlers.find("string"); if (it != typeHandlers.end()) constructor = *it; } if (!constructor) { return QtSmartPtr(); } QtSoapType *type = constructor->createObject(node); if (!type) errorStr = constructor->errorString(); return QtSmartPtr(type); } /*! Returns a human readable interpretation of the last error that occurred. */ QString QtSoapTypeFactory::errorString() const { return errorStr; } /*! \class QtSoapHttpTransport \brief The QtSoapHttpTransport class provides a mechanism for transporting SOAP messages to and from other hosts using the HTTP protocol. Use this class to submit SOAP messages to a web service. Set the hostname of the SOAP server with setHost(). Some servers also require the SOAPAction header to be set, and you can do this with setAction(). Next, submit the request with submitRequest(), passing the message to submit together with the path that you want to submit the message to. The responseReady() signal is emitted when a response has been received. Call getResponse() to get the reponse from the service. QtSoapHttpTransport usage example: If a SOAP weather service was running on the host weather.example.com, the following code might be used to find the temperature in any given city: \code void WeatherFetcher::findTemperature(const QString &city) { QtSoapMessage message; message.setMethod("getTemperature", "http://weather.example.com/temperature"); message.setMethodArgument("city", "", city); // transport is a private member of WeatherFetcher, of type QtSoapHttpTransport transport.setHost("www.example.com"); connect(&transport, SIGNAL(responseReady()), SLOT(readResponse())); transport.submitRequest(message, "/weatherfetcher/fetch.asp"); } \endcode This is an example implementation of the readResponse() slot in the WeatherFetcher class: \code void WeatherFetcher::readResponse() { const QtSoapMessage &response = transport.getResponse(); if (response.isFault()) { cout << response.faultString().toString().toLatin1().constData() << endl; return; } const QtSoapType &returnValue = response.returnValue(); if (returnValue["temperature"].isValid()) { cout << "The current temperature is " << returnValue["temperature"].toString().toLatin1().constData() << " degrees Celcius." << endl; } \endcode \sa QtSoapMessage, QtSoapType */ /*! \fn void QtSoapHttpTransport::responseReady() This signal is emitted when a SOAP response is received from a remote peer. \sa getResponse() */ /*! \fn void QtSoapHttpTransport::responseReady(const QtSoapMessage &response) This signal is emitted when a SOAP response is received from a remote peer. The received response is available in \a response. This signal is emitted in tandem with the argument-less responseReady() signal. \sa responseReady() */ /*! Constructs a QtSoapHttpTransport object. Passes \a parent to QObject's constructor. */ QtSoapHttpTransport::QtSoapHttpTransport(QObject *parent) : QObject(parent), networkMgr(this) { connect(&networkMgr, SIGNAL(finished(QNetworkReply *)), SLOT(readResponse(QNetworkReply *))); } /*! Destructs a QtSoapHttpTransport. */ QtSoapHttpTransport::~QtSoapHttpTransport() { } /*! \obsolete */ void QtSoapHttpTransport::setHost(const QString &host, int port) { setHost(host, false, port); } /*! Sets the \a host this transport should connect to. The transport mode will be HTTP, unless \a useSecureHTTP is set, in which case it will be HTTPS. This transport will connect to the well-known ports by default (80 for HTTP, 443 for HTTPS), unless a different, non-zero port is specified in \a port. */ void QtSoapHttpTransport::setHost(const QString &host, bool useSecureHTTP, int port) { url.setHost(host); url.setScheme(useSecureHTTP ? QLatin1String("https") : QLatin1String("http")); if (port) url.setPort(port); else url.setPort(useSecureHTTP ? 443 : 80); } /*! Sets the HTTP header SOAPAction to \a action. */ void QtSoapHttpTransport::setAction(const QString &action) { soapAction = action; } /*! Submits the SOAP message \a request to the path \a path on the HTTP server set using setHost(). */ void QtSoapHttpTransport::submitRequest(QtSoapMessage &request, const QString &path) { QNetworkRequest networkReq; networkReq.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("text/xml;charset=utf-8")); networkReq.setRawHeader("SOAPAction", soapAction.toAscii()); url.setPath(path); networkReq.setUrl(url); soapResponse.clear(); networkRep = networkMgr.post(networkReq, request.toXmlString().toUtf8().constData()); } /*! Returns the most recently received response SOAP message. This message could be a Fault message, so it is wise to check using QtSoapMessage::isFault() before processing the response. */ const QtSoapMessage &QtSoapHttpTransport::getResponse() const { return soapResponse; } /*! Returns a pointer to the QNetworkAccessManager object used by this transport. This is useful if the application needs to connect to its signals, or set or read its cookie jar, etc. */ QNetworkAccessManager *QtSoapHttpTransport::networkAccessManager() { return &networkMgr; } /*! Returns a pointer to the QNetworkReply object of the current (or last) request, or 0 if no such object is currently available. This is useful if the application needs to access the raw header data etc. */ QNetworkReply *QtSoapHttpTransport::networkReply() { return networkRep; } /*! */ void QtSoapHttpTransport::readResponse(QNetworkReply *reply) { networkRep = reply; switch (reply->error()) { case QNetworkReply::NoError: case QNetworkReply::ContentAccessDenied: case QNetworkReply::ContentOperationNotPermittedError: case QNetworkReply::ContentNotFoundError: case QNetworkReply::UnknownContentError: { soapResponse.setContent(reply->readAll()); int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (httpStatus != 200 && httpStatus != 100) { if (soapResponse.faultCode() == QtSoapMessage::Other) soapResponse.setFaultCode(QtSoapMessage::Client); /* QString httpReason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); soapResponse.setFaultString(QString("HTTP status %2 (%3).\n%1").arg(soapResponse.faultString().toString()).arg(httpStatus).arg(httpReason)); */ } } break; default: { soapResponse.setFaultCode(QtSoapMessage::Client); soapResponse.setFaultString(QString("Network transport error (%1): %2").arg(reply->error()).arg(reply->errorString())); } break; } emit responseReady(); emit responseReady(soapResponse); reply->deleteLater(); } /*! \class QtSoapNamespaces qtsoap.h \brief The QtSoapNamespaces class provides a registry for XML namespaces and prefixes for use in QtSoap. When a QtSoapMessage is converted to XML via QtSoapMessage::toXmlString(), this class is used to find appropriate XML namespace prefixes for the QNames (qualified names) in the message. To register a namespace with a prefix, call register(). prefixFor() will then return the prefix that is registered for the given namespace, if any. To access the QtSoapNamespaces registry, call QtSoapNamespaces::instance(). \code QtSoapNamespaces ®istry = QtSoapNamespaces::instance(); registry.register("pre", "http://www.example.com/"); QString prefix = registry.prefixFor("http://www.example.com/"); // returns "pre" \endcode \sa QtSoapMessage */ QScopedPointer QtSoapNamespaces::s_instance; QMutex QtSoapNamespaces::s_initMutex(QMutex::Recursive); /*! Returns a reference to the QtSoapNamespaces singleton. */ QtSoapNamespaces &QtSoapNamespaces::instance() { QMutexLocker lock(&s_initMutex); if (s_instance) { return *s_instance; } s_instance.reset(new QtSoapNamespaces()); return *s_instance; } /*! \internal Constructs a QtSoapNamespaces object. */ QtSoapNamespaces::QtSoapNamespaces() : namespacesMutex(QMutex::Recursive) { } /*! Registers the namespace \a uri with the prefix \a prefix. */ void QtSoapNamespaces::registerNamespace(const QString &prefix, const QString &uri) { QMutexLocker lock(&namespacesMutex); namespaces.insert(uri, prefix); } /*! Returns the prefix for the namespace \a uri, or an empty string if no prefix has been registered for \a uri. */ QString QtSoapNamespaces::prefixFor(const QString &uri) { QMutexLocker lock(&namespacesMutex); return namespaces.value(uri); } herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/src/QtSoapStructIterator0000644000000000000000000000002411543637310024060 0ustar rootroot#include "qtsoap.h" herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/.licenseAccepted0000644000000000000000000000002311543637310022273 0ustar rootrootlicense accepted herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/LICENSE.LGPL0000644000000000000000000006447411543637310021005 0ustar rootroot GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/INSTALL.TXT0000644000000000000000000002277611543637310020751 0ustar rootrootINSTALLATION INSTRUCTIONS These instructions refer to the package you are installing as some-package.tar.gz or some-package.zip. The .zip file is intended for use on Windows. The directory you choose for the installation will be referred to as your-install-dir. Note to Qt Visual Studio Integration users: In the instructions below, instead of building from command line with nmake, you can use the menu command 'Qt->Open Solution from .pro file' on the .pro files in the example and plugin directories, and then build from within Visual Studio. Unpacking and installation -------------------------- 1. Unpacking the archive (if you have not done so already). On Unix and Mac OS X (in a terminal window): cd your-install-dir gunzip some-package.tar.gz tar xvf some-package.tar This creates the subdirectory some-package containing the files. On Windows: Unpack the .zip archive by right-clicking it in explorer and choosing "Extract All...". If your version of Windows does not have zip support, you can use the infozip tools available from www.info-zip.org. If you are using the infozip tools (in a command prompt window): cd your-install-dir unzip some-package.zip 2. Configuring the package. The configure script is called "configure" on unix/mac and "configure.bat" on Windows. It should be run from a command line after cd'ing to the package directory. You can choose whether you want to use the component by including its source code directly into your project, or build the component as a dynamic shared library (DLL) that is loaded into the application at run-time. The latter may be preferable for technical or licensing (LGPL) reasons. If you want to build a DLL, run the configure script with the argument "-library". Also see the note about usage below. (Components that are Qt plugins, e.g. styles and image formats, are by default built as a plugin DLL.) The configure script will prompt you in some cases for further information. Answer these questions and carefully read the license text before accepting the license conditions. The package cannot be used if you do not accept the license conditions. 3. Building the component and examples (when required). If a DLL is to be built, or if you would like to build the examples, next give the commands qmake make [or nmake if your are using Microsoft Visual C++] The example program(s) can be found in the directory called "examples" or "example". Components that are Qt plugins, e.g. styles and image formats, are ready to be used as soon as they are built, so the rest of this installation instruction can be skipped. 4. Building the Qt Designer plugin (optional). Some of the widget components are provided with plugins for Qt Designer. To build and install the plugin, cd into the some-package/plugin directory and give the commands qmake make [or nmake if your are using Microsoft Visual C++] Restart Qt Designer to make it load the new widget plugin. Note: If you are using the built-in Qt Designer from the Qt Visual Studio Integration, you will need to manually copy the plugin DLL file, i.e. copy %QTDIR%\plugins\designer\some-component.dll to the Qt Visual Studio Integration plugin path, typically: C:\Program Files\Trolltech\Qt VS Integration\plugins Note: If you for some reason are using a Qt Designer that is built in debug mode, you will need to build the plugin in debug mode also. Edit the file plugin.pro in the plugin directory, changing 'release' to 'debug' in the CONFIG line, before running qmake. Solutions components are intended to be used directly from the package directory during development, so there is no 'make install' procedure. Using a component in your project --------------------------------- To use this component in your project, add the following line to the project's .pro file (or do the equivalent in your IDE): include(your-install-dir/some-package/src/some-package.pri) This adds the package's sources and headers to the SOURCES and HEADERS project variables respectively (or, if the component has been configured as a DLL, it adds that library to the LIBS variable), and updates INCLUDEPATH to contain the package's src directory. Additionally, the .pri file may include some dependencies needed by the package. To include a header file from the package in your sources, you can now simply use: #include or alternatively, in pre-Qt 4 style: #include Refer to the documentation to see the classes and headers this components provides. Install documentation (optional) -------------------------------- The HTML documentation for the package's classes is located in the your-install-dir/some-package/doc/html/index.html. You can open this file and read the documentation with any web browser. To install the documentation into Qt Assistant (for Qt version 4.4 and later): 1. In Assistant, open the Edit->Preferences dialog and choose the Documentation tab. Click the Add... button and select the file your-install-dir/some-package/doc/html/some-package.qch For Qt versions prior to 4.4, do instead the following: 1. The directory your-install-dir/some-package/doc/html contains a file called some-package.dcf. Execute the following commands in a shell, command prompt or terminal window: cd your-install-dir/some-package/doc/html/ assistant -addContentFile some-package.dcf The next time you start Qt Assistant, you can access the package's documentation. Removing the documentation from assistant ----------------------------------------- If you have installed the documentation into Qt Assistant, and want to uninstall it, do as follows, for Qt version 4.4 and later: 1. In Assistant, open the Edit->Preferences dialog and choose the Documentation tab. In the list of Registered Documentation, select the item com.trolltech.qtsolutions.some-package_version, and click the Remove button. For Qt versions prior to 4.4, do instead the following: 1. The directory your-install-dir/some-package/doc/html contains a file called some-package.dcf. Execute the following commands in a shell, command prompt or terminal window: cd your-install-dir/some-package/doc/html/ assistant -removeContentFile some-package.dcf Using the component as a DLL ---------------------------- 1. Normal components The shared library (DLL) is built and placed in the some-package/lib directory. It is intended to be used directly from there during development. When appropriate, both debug and release versions are built, since the run-time linker will in some cases refuse to load a debug-built DLL into a release-built application or vice versa. The following steps are taken by default to help the dynamic linker to locate the DLL at run-time (during development): Unix: The some-package.pri file will add linker instructions to add the some-package/lib directory to the rpath of the executable. (When distributing, or if your system does not support rpath, you can copy the shared library to another place that is searched by the dynamic linker, e.g. the "lib" directory of your Qt installation.) Mac: The full path to the library is hardcoded into the library itself, from where it is copied into the executable at link time, and ready by the dynamic linker at run-time. (When distributing, you will want to edit these hardcoded paths in the same way as for the Qt DLLs. Refer to the document "Deploying an Application on Mac OS X" in the Qt Reference Documentation.) Windows: the .dll file(s) are copied into the "bin" directory of your Qt installation. The Qt installation will already have set up that directory to be searched by the dynamic linker. 2. Plugins For Qt Solutions plugins (e.g. image formats), both debug and release versions of the plugin are built by default when appropriate, since in some cases the release Qt library will not load a debug plugin, and vice versa. The plugins are automatically copied into the plugins directory of your Qt installation when built, so no further setup is required. Plugins may also be built statically, i.e. as a library that will be linked into your application executable, and so will not need to be redistributed as a separate plugin DLL to end users. Static building is required if Qt itself is built statically. To do it, just add "static" to the CONFIG variable in the plugin/plugin.pro file before building. Refer to the "Static Plugins" section in the chapter "How to Create Qt Plugins" for explanation of how to use a static plugin in your application. The source code of the example program(s) will also typically contain the relevant instructions as comments. Uninstalling ------------ The following command will remove any fils that have been automatically placed outside the package directory itself during installation and building make distclean [or nmake if your are using Microsoft Visual C++] If Qt Assistant documentation or Qt Designer plugins have been installed, they can be uninstalled manually, ref. above. Enjoy! :) - The Qt Solutions Team. herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/LICENSE.GPL30000644000000000000000000010575511543637310020752 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/common.pri0000644000000000000000000000037211543637310021232 0ustar rootrootinfile(config.pri, SOLUTIONS_LIBRARY, yes): CONFIG += qtsoap-uselib TEMPLATE += fakelib QTSOAP_LIBNAME = $$qtLibraryTarget(QtSolutions_SOAP-2.7) TEMPLATE -= fakelib QTSOAP_LIBDIR = ../lib unix:qtsoap-uselib:!qtsoap-buildlib:QMAKE_RPATHDIR += . herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/README.TXT0000644000000000000000000000143611543637310020566 0ustar rootrootSOAP v2.7 The Qt SOAP project provides basic web service support with version 1.1 of the SOAP protocol. Notes: This is a partial implementation of SOAP v1.1. - Server side SOAP is not supported. - References to values (id & href attributes) are not supported. - Only arrays with less than 5 dimensions are supported. - Namespaces for types are not checked. Only the type names are used. - The encodingStyle attribute is ignored. The serialization and encoding rules from section 5 in the SOAP v1.1 specification are assumed regardless of the value of the encodingStyle attribute. - QtSoapType does not have accessors for attributes, which means for example that actor, mustUnderstand and so on are not accessible in headers. - The SOAP root attribute is not supported. herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/buildlib/0000755000000000000000000000000011543637460021020 5ustar rootrootherqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/buildlib/debug/0000755000000000000000000000000011543637460022106 5ustar rootrootherqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/buildlib/release/0000755000000000000000000000000011543637460022440 5ustar rootrootherqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/buildlib/buildlib.pro0000644000000000000000000000112211543637306023323 0ustar rootrootTEMPLATE=lib DEFINES += QT_QTSOAP_EXPORT CONFIG += qt dll qtsoap-buildlib QT -= gui mac:CONFIG += absolute_library_soname win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release build_all include(../src/qtsoap.pri) TARGET = $$QTSOAP_LIBNAME DESTDIR = $$QTSOAP_LIBDIR #win32 { # DLLDESTDIR = $$[QT_INSTALL_BINS] # QMAKE_DISTCLEAN += $$[QT_INSTALL_BINS]\\$${QTSOAP_LIBNAME}.dll #} #target.path = $$DESTDIR #INSTALLS += target isEmpty(PREFIX) { PREFIX = ../../../deploy } INSTLOC_LIB = $$PREFIX/lib target.path = $$INSTLOC_LIB INSTALLS += target herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/qtsoap.pro0000644000000000000000000000015511543637310021256 0ustar rootrootTEMPLATE=subdirs CONFIG += ordered include(common.pri) qtsoap-uselib:SUBDIRS=buildlib SUBDIRS+=examples herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/LGPL_EXCEPTION.txt0000644000000000000000000000221511543637310022141 0ustar rootrootNokia Qt LGPL Exception version 1.1 As an additional permission to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that: (i) the header files of the Library have not been modified; and (ii) the incorporated material is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates; and (iii) you comply with the terms of Section 6 of the GNU Lesser General Public License version 2.1. Moreover, you may apply this exception to a modified version of the Library, provided that such modification does not involve copying material from the Library into the modified Library?s header files unless such material is limited to (i) numerical parameters; (ii) data structure layouts; (iii) accessors; and (iv) small macros, templates and inline functions of five lines or less in length. Furthermore, you are not required to apply this additional permission to a modified version of the Library. herqq-1.0.0/hupnp/lib/qtsoap-2.7-opensource/configure.bat0000644000000000000000000000632211543637310021700 0ustar rootroot@echo off rem rem "Main" rem if not "%1"=="" ( if not "%1"=="-library" ( call :PrintUsage goto EOF ) ) rem only ask to accept the license text once if exist .licenseAccepted goto HandleArgs rem determine if free or commercial package set edition=commercial if exist LICENSE.LGPL. set edition=free if %edition%==free ( call :HandleFree ) else ( call :RegionLoop call :Comm ) echo . if not exist .licenseAccepted ( echo You are not licensed to use this software. goto EOF ) :HandleArgs if exist config.pri. del config.pri if "%1"=="-library" ( echo Configuring to build this component as a dynamic library. echo SOLUTIONS_LIBRARY = yes > config.pri ) echo . echo This component is now configured. echo . echo To build the component library (if requested) and example(s), echo run qmake and your make or nmake command. echo . echo To remove or reconfigure, run make (nmake) distclean. echo . goto EOF rem rem "License acceptance loops" rem :RegionLoop echo . echo Please choose your region. echo . echo Type 1 for North or South America. echo Type 2 for anywhere outside North and South America. echo . set /p region=Select: if %region%==1 ( set licenseFile=LICENSE.US goto EOF ) if %region%==2 ( set licenseFile=LICENSE.NO goto EOF ) goto RegionLoop :HandleFree echo . echo You are licensed to use this software under the terms of echo the GNU General Public License (GPL) version 3, or echo the GNU Lesser General Public License (LGPL) version 2.1 echo with certain additional extra rights as specified in the echo Nokia Qt LGPL Exception version 1.0. echo . echo Type 'G' to view the GNU General Public License (GPL) version 3 echo Type 'L' to view the GNU Lesser General Public License (LGPL) version 2.1 echo Type 'E' to view the Nokia Qt LGPL Exception version 1.0. echo Type 'yes' to accept this license offer. echo Type 'no' to decline this license offer. echo . set /p answer=Do you accept the terms of this license? if %answer%==no goto EOF if %answer%==yes ( echo license accepted > .licenseAccepted goto EOF ) if %answer%==g more LICENSE.GPL3 if %answer%==G more LICENSE.GPL3 if %answer%==l more LICENSE.LGPL if %answer%==L more LICENSE.LGPL if %answer%==e more LGPL_EXCEPTION.txt if %answer%==E more LGPL_EXCEPTION.txt goto HandleFree :Comm echo . echo License Agreement echo . echo Type '?' to view the Qt Solutions Commercial License. echo Type 'yes' to accept this license offer. echo Type 'no' to decline this license offer. echo . set /p answer=Do you accept the terms of this license? if %answer%==no goto EOF if %answer%==yes ( echo license accepted > .licenseAccepted copy %licenseFile% LICENSE del LICENSE.US del LICENSE.NO goto EOF ) if %answer%==? more %licenseFile% goto Comm :PrintUsage echo Usage: configure.bat [-library] echo . echo -library: Build the component as a dynamic library (DLL). Default is to echo include the component source directly in the application. echo A DLL may be preferable for technical or licensing (LGPL) reasons. echo . goto EOF :EOF herqq-1.0.0/apps/0000755000000000000000000000000011543637460012302 5ustar rootrootherqq-1.0.0/apps/simple_test-app/0000755000000000000000000000000011543637460015410 5ustar rootrootherqq-1.0.0/apps/simple_test-app/allowedvaluelist_input.h0000644000000000000000000000276711543637306022373 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef ALLOWEDVALUELIST_INPUT_H_ #define ALLOWEDVALUELIST_INPUT_H_ #include "i_dataholder.h" namespace Ui { class AllowedValueListInput; } class QStringList; // // // class AllowedValueListInput : public IDataHolder { Q_OBJECT private: Ui::AllowedValueListInput* m_ui; protected: void changeEvent(QEvent *e); public: AllowedValueListInput(const QStringList& values, QWidget* parent = 0); virtual ~AllowedValueListInput(); virtual QVariant data() const; }; #endif // ALLOWEDVALUELIST_INPUT_H_ herqq-1.0.0/apps/simple_test-app/device_window.ui0000644000000000000000000000735611543637306020607 0ustar rootroot DeviceWindow 0 0 486 325 Hosting a simple HDevice 0 0 16777215 100 QFrame::Box QFrame::Plain <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">This is a simple example for demonstrating how to a host an HDevice. As you see this window, the simple test HServerDevice is being hosted and it is ready to be found by UPnP control points.</span></p> <p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You can try that by starting an HControlPoint in the main window.</span></p></body></html> Qt::Vertical QSizePolicy::Fixed 20 29 0 0 QFrame::Box QFrame::Plain 0 0 486 21 herqq-1.0.0/apps/simple_test-app/i_dataholder.cpp0000644000000000000000000000210611543637306020531 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "i_dataholder.h" IDataHolder::IDataHolder(QWidget* parent) : QWidget(parent) { } IDataHolder::~IDataHolder() { } herqq-1.0.0/apps/simple_test-app/i_dataholder.h0000644000000000000000000000236011543637306020200 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef IIDATAHOLDER_H_ #define IIDATAHOLDER_H_ #include class QVariant; // // // class IDataHolder : public QWidget { public: IDataHolder(QWidget* parent = 0); virtual ~IDataHolder() = 0; virtual QVariant data() const = 0; }; #endif /* IIDATAHOLDER_H_ */ herqq-1.0.0/apps/simple_test-app/mainwindow.cpp0000644000000000000000000000425611543637306020276 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "mainwindow.h" #include "ui_mainwindow.h" #include "device_window.h" #include "controlpoint_window.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::MainWindow) { m_ui->setupUi(this); } MainWindow::~MainWindow() { delete m_ui; } void MainWindow::changeEvent(QEvent* e) { QMainWindow::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } void MainWindow::deviceWindowClosed() { m_ui->hostDeviceButton->setEnabled(true); } void MainWindow::on_hostDeviceButton_clicked() { DeviceWindow* dw = new DeviceWindow(this); bool ok = connect(dw, SIGNAL(closed()), dw, SLOT(deleteLater())); Q_ASSERT(ok); Q_UNUSED(ok); ok = connect(dw, SIGNAL(closed()), this, SLOT(deviceWindowClosed())); Q_ASSERT(ok); dw->show(); m_ui->hostDeviceButton->setEnabled(false); } void MainWindow::on_startControlPointButton_clicked() { ControlPointWindow* cpw = new ControlPointWindow(this); bool ok = connect(cpw, SIGNAL(closed()), cpw, SLOT(deleteLater())); Q_ASSERT(ok); Q_UNUSED(ok); cpw->show(); } herqq-1.0.0/apps/simple_test-app/main.cpp0000644000000000000000000000232411543637306017040 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "mainwindow.h" #include #include #include #include int main(int argc, char* argv[]) { Herqq::Upnp::SetLoggingLevel(Herqq::Upnp::Warning); QApplication app(argc, argv); MainWindow mw; mw.show(); return app.exec(); } herqq-1.0.0/apps/simple_test-app/controlpoint_navigator.cpp0000644000000000000000000001477511543637306022735 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "controlpoint_navigator.h" #include "controlpoint_navigatoritem.h" #include #include #include #include #include using namespace Herqq::Upnp; ControlPointNavigator::ControlPointNavigator(QObject* parent) : QAbstractItemModel(parent), m_rootItem(new RootItem()) { } ControlPointNavigator::~ControlPointNavigator() { delete m_rootItem; } ControlPointNavigatorItem* ControlPointNavigator::buildModel( HClientDevice* device, ControlPointNavigatorItem* parentItem) { DeviceItem* deviceItem = new DeviceItem(device, parentItem); HClientServices services(device->services()); for(qint32 i = 0; i < services.size(); ++i) { HClientService* service = services.at(i); ServiceItem* serviceItem = new ServiceItem(service, deviceItem); ContainerItem* stateVariablesItem = new ContainerItem("State Variables", serviceItem); HClientStateVariables stateVars = service->stateVariables(); foreach(const QString& name, stateVars.keys()) { StateVariableItem* stateVarItem = new StateVariableItem(stateVars.value(name), stateVariablesItem); stateVariablesItem->appendChild(stateVarItem); } ContainerItem* actionsItem = new ContainerItem("Actions", serviceItem); HClientActions actions = service->actions(); foreach(const QString& name, actions.keys()) { ActionItem* actionItem = new ActionItem(actions.value(name), actionsItem); actionsItem->appendChild(actionItem); } serviceItem->appendChild(stateVariablesItem); serviceItem->appendChild(actionsItem); deviceItem->appendChild(serviceItem); } foreach(HClientDevice* embeddedDevice, device->embeddedDevices()) { ControlPointNavigatorItem* childItem = buildModel(embeddedDevice, deviceItem); deviceItem->appendChild(childItem); } return deviceItem; } void ControlPointNavigator::rootDeviceOnline(HClientDevice* newDevice) { ControlPointNavigatorItem* childItem = buildModel(newDevice, m_rootItem); beginInsertRows( QModelIndex(), m_rootItem->childCount(), m_rootItem->childCount()); m_rootItem->appendChild(childItem); endInsertRows(); } void ControlPointNavigator::rootDeviceOffline(HClientDevice* device) { for(qint32 i = 0; i < m_rootItem->childCount(); ++i) { DeviceItem* deviceItem = static_cast(m_rootItem->child(i)); if (deviceItem->device() == device) { beginRemoveRows(QModelIndex(), i, i); m_rootItem->removeChild(i); endRemoveRows(); break; } } } int ControlPointNavigator::columnCount(const QModelIndex& parent) const { if (parent.isValid()) { return static_cast( parent.internalPointer())->columnCount(); } else { return m_rootItem->columnCount(); } } QVariant ControlPointNavigator::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } if (role != Qt::DisplayRole) { return QVariant(); } ControlPointNavigatorItem *item = static_cast(index.internalPointer()); return item->data(index.column()); } Qt::ItemFlags ControlPointNavigator::flags(const QModelIndex& index) const { if (!index.isValid()) { return 0; } return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QVariant ControlPointNavigator::headerData( int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { return m_rootItem->data(section); } return QVariant(); } QModelIndex ControlPointNavigator::index( int row, int column, const QModelIndex& parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); } ControlPointNavigatorItem* parentItem; if (!parent.isValid()) { parentItem = m_rootItem; } else { parentItem = static_cast(parent.internalPointer()); } ControlPointNavigatorItem* childItem = parentItem->child(row); if (childItem) { return createIndex(row, column, childItem); } else { return QModelIndex(); } } QModelIndex ControlPointNavigator::parent(const QModelIndex& index) const { if (!index.isValid()) { return QModelIndex(); } ControlPointNavigatorItem* childItem = static_cast(index.internalPointer()); ControlPointNavigatorItem* parentItem = childItem->parent(); if (parentItem == m_rootItem) { return QModelIndex(); } return createIndex(parentItem->row(), 0, parentItem); } int ControlPointNavigator::rowCount(const QModelIndex& parent) const { ControlPointNavigatorItem* parentItem; if (parent.column() > 0) { return 0; } if (!parent.isValid()) { parentItem = m_rootItem; } else { parentItem = static_cast(parent.internalPointer()); } return parentItem->childCount(); } herqq-1.0.0/apps/simple_test-app/mainwindow.h0000644000000000000000000000304111543637306017732 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include namespace Ui { class MainWindow; } // // Main window for the test application. // class MainWindow : public QMainWindow { Q_OBJECT Q_DISABLE_COPY(MainWindow) public: explicit MainWindow(QWidget* parent = 0); virtual ~MainWindow(); protected: virtual void changeEvent(QEvent*); private: Ui::MainWindow* m_ui; private slots: void on_startControlPointButton_clicked(); void on_hostDeviceButton_clicked(); void deviceWindowClosed(); }; #endif // MAINWINDOW_H herqq-1.0.0/apps/simple_test-app/controlpoint_navigator.h0000644000000000000000000000464311543637306022373 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef CONTROLPOINT_NAVIGATOR_H_ #define CONTROLPOINT_NAVIGATOR_H_ #include #include class QVariant; class QModelIndex; class DeviceItem; class ControlPointNavigatorItem; // // Primitive tree model for displaying the HControlPoint's "data model" // class ControlPointNavigator : public QAbstractItemModel { Q_OBJECT H_DISABLE_COPY(ControlPointNavigator) private: ControlPointNavigatorItem* m_rootItem; ControlPointNavigatorItem* buildModel( Herqq::Upnp::HClientDevice*, ControlPointNavigatorItem*); public: explicit ControlPointNavigator(QObject* parent = 0); virtual ~ControlPointNavigator(); void rootDeviceOnline(Herqq::Upnp::HClientDevice*); void rootDeviceOffline(Herqq::Upnp::HClientDevice*); virtual QVariant data (const QModelIndex& index, int role) const; virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex()) const; virtual QModelIndex parent(const QModelIndex& index) const; virtual int rowCount (const QModelIndex& parent = QModelIndex()) const; virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; }; #endif /* CONTROLPOINT_NAVIGATOR_H_ */ herqq-1.0.0/apps/simple_test-app/allowedvaluelist_input.ui0000644000000000000000000000243311543637306022547 0ustar rootroot AllowedValueListInput 0 0 87 23 0 0 Form 0 0 0 0 QComboBox::AdjustToContents false herqq-1.0.0/apps/simple_test-app/device_window.cpp0000644000000000000000000001715711543637306020754 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "device_window.h" #include "ui_device_window.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace Herqq::Upnp; /******************************************************************************* * HTestService *******************************************************************************/ HTestService::HTestService() { } HTestService::~HTestService() { } HServerService::HActionInvokes HTestService::createActionInvokes() { HActionInvokes retVal; // // This is where it is defined what are to be called when the actions // identified by their names are invoked. // In this example, public member functions are used. retVal.insert( "Echo", HActionInvoke(this, &HTestService::echoAction)); retVal.insert( "Register", HActionInvoke(this, &HTestService::registerAction)); retVal.insert( "Chargen", HActionInvoke(this, &HTestService::chargenAction)); return retVal; } qint32 HTestService::echoAction( const HActionArguments& inArgs, HActionArguments* outArgs) { // Simple implementation of the echo service: // merely echos the received message back to the invoker. QString echoMsg = inArgs["MessageIn"].value().toString(); (*outArgs)["MessageOut"].setValue(echoMsg); emit actionInvoked( "Echo", QString("Argument was set to [%1].").arg(echoMsg)); // This signal is sent so that the user interface can react to this // particular invocation somehow. return UpnpSuccess; } qint32 HTestService::registerAction( const HActionArguments& /*inArgs*/, HActionArguments* /*outArgs*/) { // Simple implementation of the Register service: // modifies an evented state variable, which causes events to be sent to // all registered listeners. bool ok = false; HServerStateVariable* sv = stateVariables().value("RegisteredClientCount"); Q_ASSERT(sv); // fetch the state variable we want to modify quint32 count = sv->value().toUInt(&ok); Q_ASSERT(ok); // check its current value ok = sv->setValue(++count); Q_ASSERT(ok); // and increment it emit actionInvoked( "Register", QString("Register invoked %1 times.").arg(QString::number(count))); // This signal is sent so that the user interface can react to this // particular invocation somehow. return UpnpSuccess; } qint32 HTestService::chargenAction( const HActionArguments& inArgs, HActionArguments* outArgs) { qint32 charCount = inArgs["Count"].value().toInt(); (*outArgs)["Characters"].setValue(QString(charCount, 'z')); emit actionInvoked( "Chargen", QString("Character count set to %1.").arg( QString::number(charCount))); // This signal is sent so that the user interface can react to this // particular invocation somehow. return UpnpSuccess; } /******************************************************************************* * HTestDevice ******************************************************************************/ HTestDevice::HTestDevice() : HServerDevice() { } HTestDevice::~HTestDevice() { } /******************************************************************************* * DeviceWindow *******************************************************************************/ namespace { class Creator : public HDeviceModelCreator { protected: virtual Creator* newInstance() const { return new Creator(); } public: virtual HServerDevice* createDevice(const HDeviceInfo& info) const { if (info.deviceType().toString() == "urn:herqq-org:device:HTestDevice:1") { return new HTestDevice(); } return 0; } virtual HServerService* createService( const HServiceInfo& serviceInfo, const HDeviceInfo&) const { if (serviceInfo.serviceType().toString() == "urn:herqq-org:service:HTestService:1") { return new HTestService(); } return 0; } }; } DeviceWindow::DeviceWindow(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::DeviceWindow), m_deviceHost(0), m_testDevice() { m_ui->setupUi(this); HDeviceHostConfiguration hostConfiguration; Creator creator; hostConfiguration.setDeviceModelCreator(creator); HDeviceConfiguration config; config.setPathToDeviceDescription( "./descriptions/hupnp_testdevice.xml"); // the path to the device description file we want to be instantiated config.setCacheControlMaxAge(30); hostConfiguration.add(config); m_deviceHost = new HDeviceHost(this); if (!m_deviceHost->init(hostConfiguration)) { qWarning() << m_deviceHost->errorDescription(); Q_ASSERT(false); return; } m_testDevice = m_deviceHost->rootDevices().at(0); // since we know there is at least one device if the initialization succeeded... HServerService* service = m_testDevice->serviceById(HServiceId("urn:herqq-org:serviceId:HTestService")); // our user interface is supposed to react when our actions are invoked, so // let's connect the signal introduced in HTestService to this class. // (note that the connection works although the static type of our "service" // is not HTestService during the connect() call) bool ok = connect( service, SIGNAL(actionInvoked(QString, QString)), this, SLOT(actionInvoked(QString, QString))); Q_ASSERT(ok); Q_UNUSED(ok) } DeviceWindow::~DeviceWindow() { delete m_ui; delete m_deviceHost; } void DeviceWindow::actionInvoked(const QString& actionName, const QString& text) { // // okay, one of our actions was invoked, let's display something. QString textToDisplay = QString("%1 Action [%2] invoked: %3").arg( QDateTime::currentDateTime().toString(), actionName, text); m_ui->statusDisplay->append(textToDisplay); } void DeviceWindow::changeEvent(QEvent *e) { QMainWindow::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } void DeviceWindow::closeEvent(QCloseEvent*) { emit closed(); } herqq-1.0.0/apps/simple_test-app/controlpoint_navigatoritem.h0000644000000000000000000001126711543637306023252 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef CONTROLPOINT_NAVIGATORITEM_H_ #define CONTROLPOINT_NAVIGATORITEM_H_ #include #include #include template class QList; class QVariant; class ActionItem; class DeviceItem; class ServiceItem; class StateVariableItem; // // // class ControlPointNavigatorItemVisitor { public: virtual void visit(ActionItem*) = 0; virtual void visit(ServiceItem*) = 0; virtual void visit(DeviceItem*) = 0; virtual void visit(StateVariableItem*) = 0; }; // // // class ControlPointNavigatorItem { protected: QList m_childItems; ControlPointNavigatorItem* m_parentItem; public: explicit ControlPointNavigatorItem(ControlPointNavigatorItem* parent = 0); virtual ~ControlPointNavigatorItem(); virtual QVariant data(int column) const = 0; void appendChild(ControlPointNavigatorItem* child); void removeChild(qint32 row); ControlPointNavigatorItem* child (int row); int childCount () const; int columnCount() const; int row () const; ControlPointNavigatorItem* parent(); int rowCount () const; virtual void accept(ControlPointNavigatorItemVisitor*) = 0; }; // // // class RootItem : public ControlPointNavigatorItem { private: public: explicit RootItem(ControlPointNavigatorItem* parent = 0); virtual ~RootItem(); virtual QVariant data (int column) const; virtual void accept(ControlPointNavigatorItemVisitor*); }; // // // class ContainerItem : public ControlPointNavigatorItem { private: QString m_name; public: explicit ContainerItem( const QString& name, ControlPointNavigatorItem* parent = 0); virtual ~ContainerItem(); virtual QVariant data (int column) const; virtual void accept(ControlPointNavigatorItemVisitor*); }; // // // class DeviceItem : public ControlPointNavigatorItem { private: Herqq::Upnp::HClientDevice* m_device; public: explicit DeviceItem( Herqq::Upnp::HClientDevice* device, ControlPointNavigatorItem* parent = 0); virtual ~DeviceItem(); virtual QVariant data (int column) const; inline Herqq::Upnp::HClientDevice* device() const { return m_device; } virtual void accept(ControlPointNavigatorItemVisitor*); }; // // // class ServiceItem : public ControlPointNavigatorItem { private: Herqq::Upnp::HClientService* m_service; public: explicit ServiceItem( Herqq::Upnp::HClientService* service, ControlPointNavigatorItem* parent = 0); virtual ~ServiceItem(); virtual QVariant data (int column) const; inline Herqq::Upnp::HClientService* service() const { return m_service; } virtual void accept(ControlPointNavigatorItemVisitor*); }; // // // class ActionItem : public ControlPointNavigatorItem { private: Herqq::Upnp::HClientAction* m_action; public: explicit ActionItem( Herqq::Upnp::HClientAction* action, ControlPointNavigatorItem* parent = 0); virtual ~ActionItem(); virtual QVariant data (int column) const; inline Herqq::Upnp::HClientAction* action() const { return m_action; } virtual void accept(ControlPointNavigatorItemVisitor*); }; // // // class StateVariableItem : public ControlPointNavigatorItem { private: const Herqq::Upnp::HClientStateVariable* m_stateVar; public: explicit StateVariableItem( const Herqq::Upnp::HClientStateVariable* stateVar, ControlPointNavigatorItem* parent = 0); virtual ~StateVariableItem(); virtual QVariant data (int column) const; inline const Herqq::Upnp::HClientStateVariable* stateVariable() const { return m_stateVar; } virtual void accept(ControlPointNavigatorItemVisitor*); }; #endif /* CONTROLPOINT_NAVIGATORITEM_H_ */ herqq-1.0.0/apps/simple_test-app/genericinput.ui0000644000000000000000000000162011543637306020441 0ustar rootroot GenericInput 0 0 241 38 Form 0 0 0 0 herqq-1.0.0/apps/simple_test-app/controlpoint.ui0000644000000000000000000000542111543637306020502 0ustar rootroot ControlPointWindow 0 0 674 447 Testing HControlPoint 0 0 0 0 Qt::Horizontal true true false true false 0 0 16777215 120 0 0 QFrame::Box QFrame::Plain herqq-1.0.0/apps/simple_test-app/descriptions/0000755000000000000000000000000011543637460020116 5ustar rootrootherqq-1.0.0/apps/simple_test-app/descriptions/hupnp_testservice_scpd.xml0000644000000000000000000000452711543637306025432 0ustar rootroot 1 1 Register Echo MessageIn in A_ARG_TYPE_Echo MessageOut out A_ARG_TYPE_Echo Chargen Count in A_ARG_TYPE_Count Characters out A_ARG_TYPE_Characters A_ARG_TYPE_Echo string A_ARG_TYPE_Characters string RegisteredClientCount ui4 A_ARG_TYPE_Count 1 ui1 herqq-1.0.0/apps/simple_test-app/descriptions/hupnp_testdevice.xml0000644000000000000000000000223311543637306024210 0ustar rootroot 1 1 urn:herqq-org:device:HTestDevice:1 HUPnP Test Device Herqq www.herqq.org Simple UPnP device for testing HUPnP HTestDevice 0.1 www.herqq.org 0123456789 uuid:5d794fc2-5c5e-4460-a023-f04a51363300 urn:herqq-org:service:HTestService:1 urn:herqq-org:serviceId:HTestService hupnp_testservice_scpd.xml HTestService/Control HTestService/Events herqq-1.0.0/apps/simple_test-app/controlpoint_window.cpp0000644000000000000000000001340311543637306022235 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "controlpoint_window.h" #include "invokeactiondialog.h" #include "ui_controlpoint.h" #include "dataitem_display.h" #include "controlpoint_navigator.h" #include "controlpoint_navigatoritem.h" #include #include #include #include #include #include #include #include #include using namespace Herqq::Upnp; ControlPointWindow::ControlPointWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::ControlPointWindow), m_controlPoint(0), m_controlpointNavigator(0), m_dataItemDisplay(0) { m_ui->setupUi(this); HControlPointConfiguration configuration; //configuration.setDesiredSubscriptionTimeout(30); // you can uncomment this ^^ to test subscription renewal with UPnP devices // that respect the subscription timeout requests of control points m_controlPoint = new HControlPoint(configuration, this); bool ok = connect( m_controlPoint, SIGNAL(rootDeviceOnline(Herqq::Upnp::HClientDevice*)), this, SLOT(rootDeviceOnline(Herqq::Upnp::HClientDevice*))); Q_ASSERT(ok); ok = connect( m_controlPoint, SIGNAL(rootDeviceOffline(Herqq::Upnp::HClientDevice*)), this, SLOT(rootDeviceOffline(Herqq::Upnp::HClientDevice*))); Q_ASSERT(ok); m_controlpointNavigator = new ControlPointNavigator(this); m_ui->navigatorTreeView->setModel(m_controlpointNavigator); m_dataItemDisplay = new DataItemDisplay(this); m_ui->dataTableView->setModel(m_dataItemDisplay); m_controlPoint->init(); } ControlPointWindow::~ControlPointWindow() { delete m_ui; delete m_controlpointNavigator; delete m_dataItemDisplay; delete m_controlPoint; } void ControlPointWindow::connectToEvents(HClientDevice* device) { HClientServices services = device->services(); for (qint32 i = 0; i < services.size(); ++i) { HClientStateVariables stateVars = services[i]->stateVariables(); foreach(const QString& name, stateVars.keys()) { bool ok = connect( stateVars.value(name), SIGNAL(valueChanged(const Herqq::Upnp::HClientStateVariable*, Herqq::Upnp::HStateVariableEvent)), this, SLOT(stateVariableChanged(const Herqq::Upnp::HClientStateVariable*, Herqq::Upnp::HStateVariableEvent))); Q_ASSERT(ok); Q_UNUSED(ok) } } QList embeddedDevices = device->embeddedDevices(); for(qint32 i = 0; i < embeddedDevices.size(); ++i) { connectToEvents(embeddedDevices[i]); } } void ControlPointWindow::stateVariableChanged( const HClientStateVariable* source, const HStateVariableEvent& event) { m_ui->status->append(QString( "State variable [%1] changed value from [%2] to [%3]").arg( source->info().name(), event.previousValue().toString(), event.newValue().toString())); } void ControlPointWindow::rootDeviceOnline(HClientDevice* newDevice) { m_controlpointNavigator->rootDeviceOnline(newDevice); connectToEvents(newDevice); } void ControlPointWindow::rootDeviceOffline(HClientDevice* device) { m_controlpointNavigator->rootDeviceOffline(device); m_dataItemDisplay->deviceRemoved(device->info().udn()); emit contentSourceRemoved(device); } void ControlPointWindow::changeEvent(QEvent *e) { QMainWindow::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } void ControlPointWindow::closeEvent(QCloseEvent*) { emit closed(); } void ControlPointWindow::on_navigatorTreeView_clicked(QModelIndex index) { ControlPointNavigatorItem* navItem = static_cast(index.internalPointer()); if (!navItem) { return; } m_dataItemDisplay->setData(navItem); } void ControlPointWindow::on_navigatorTreeView_doubleClicked(QModelIndex index) { ControlPointNavigatorItem* navItem = static_cast(index.internalPointer()); if (!navItem) { return; } ActionItem* ai = dynamic_cast(navItem); if (ai) { InvokeActionDialog* dlg = new InvokeActionDialog(ai->action(), this); bool ok = connect(dlg, SIGNAL(finished(int)), dlg, SLOT(deleteLater())); Q_ASSERT(ok); Q_UNUSED(ok) ok = connect( this, SIGNAL(contentSourceRemoved(Herqq::Upnp::HClientDevice*)), dlg , SLOT(contentSourceRemoved(Herqq::Upnp::HClientDevice*))); Q_ASSERT(ok); dlg->show(); } } herqq-1.0.0/apps/simple_test-app/allowedvaluelist_input.cpp0000644000000000000000000000327211543637306022716 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "allowedvaluelist_input.h" #include "ui_allowedvaluelist_input.h" AllowedValueListInput::AllowedValueListInput( const QStringList& values, QWidget* parent) : IDataHolder(parent), m_ui(new Ui::AllowedValueListInput) { m_ui->setupUi(this); m_ui->argumentValuescomboBox->addItems(values); } AllowedValueListInput::~AllowedValueListInput() { delete m_ui; } void AllowedValueListInput::changeEvent(QEvent* e) { QWidget::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } QVariant AllowedValueListInput::data() const { return m_ui->argumentValuescomboBox->currentText(); } herqq-1.0.0/apps/simple_test-app/invokeactiondialog.cpp0000644000000000000000000002237311543637306021773 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "invokeactiondialog.h" #include "ui_invokeactiondialog.h" #include "genericinput.h" #include "allowedvaluelist_input.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Herqq::Upnp; InvokeActionDialog::InvokeActionDialog(HClientAction* action, QWidget* parent) : QDialog(parent), m_ui(new Ui::InvokeActionDialog), m_action(action), m_inputWidgets() { Q_ASSERT(action); m_ui->setupUi(this); setupArgumentWidgets(); bool ok = connect( action, SIGNAL(invokeComplete(Herqq::Upnp::HClientAction*, Herqq::Upnp::HClientActionOp)), this, SLOT(invokeComplete(Herqq::Upnp::HClientAction*, Herqq::Upnp::HClientActionOp))); Q_ASSERT(ok); Q_UNUSED(ok) } void InvokeActionDialog::invokeComplete( HClientAction*, const HClientActionOp& eventInfo) { if (eventInfo.returnValue() == UpnpSuccess) { HActionArguments outArgs = eventInfo.outputArguments(); for(qint32 i = 0; i < outArgs.size(); ++i) { m_ui->outputArguments->item(i, 2)->setText( outArgs[i].value().toString()); } } else { QMessageBox* msgBox = new QMessageBox(this); msgBox->setText(QString("Action invocation [id: %1] failed: %2").arg( QString::number(eventInfo.id()), upnpErrorCodeToString(eventInfo.returnValue()))); msgBox->show(); } m_ui->invokeButton->setEnabled(true); } void InvokeActionDialog::setupArgumentWidgets() { HActionArguments inputArgs = m_action->info().inputArguments(); m_ui->inputArguments->setRowCount(inputArgs.size()); for(qint32 i = 0; i < inputArgs.size(); ++i) { HActionArgument inputArg = inputArgs[i]; const HStateVariableInfo& stateVar = inputArg.relatedStateVariable(); QTableWidgetItem* item = new QTableWidgetItem(HUpnpDataTypes::toString(stateVar.dataType())); item->setFlags(Qt::NoItemFlags); m_ui->inputArguments->setItem(i, 0, item); item = new QTableWidgetItem(stateVar.name()); item->setFlags(Qt::NoItemFlags); m_ui->inputArguments->setItem(i, 1, item); IDataHolder* dh = createDataHolder(stateVar); Q_ASSERT(dh); m_inputWidgets[inputArg.name()] = dh; m_ui->inputArguments->setCellWidget(i, 2, dh); //m_ui->inputArguments->resizeColumnsToContents(); } HActionArguments outputArgs = m_action->info().outputArguments(); m_ui->outputArguments->setRowCount(outputArgs.size()); for(qint32 i = 0; i < outputArgs.size(); ++i) { HActionArgument outputArg = outputArgs[i]; const HStateVariableInfo& stateVar = outputArg.relatedStateVariable(); QTableWidgetItem* item = new QTableWidgetItem(HUpnpDataTypes::toString(stateVar.dataType())); item->setFlags(Qt::NoItemFlags); m_ui->outputArguments->setItem(i, 0, item); item = new QTableWidgetItem(stateVar.name()); item->setFlags(Qt::NoItemFlags); m_ui->outputArguments->setItem(i, 1, item); item = new QTableWidgetItem(); item->setFlags(Qt::NoItemFlags); m_ui->outputArguments->setItem(i, 2, item); } } void InvokeActionDialog::contentSourceRemoved(HClientDevice* device) { Q_ASSERT(device); if (device == m_action->parentService()->parentDevice()->rootDevice()) { done(0); } } namespace { void minMaxValues(HUpnpDataTypes::DataType dt, qint32* max, qint32* min) { switch(dt) { case HUpnpDataTypes::ui1: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); break; case HUpnpDataTypes::ui2: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); break; case HUpnpDataTypes::ui4: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); // for this example, the signed int range is acceptable. break; case HUpnpDataTypes::i1: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); break; case HUpnpDataTypes::i2: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); break; case HUpnpDataTypes::i4: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); break; default: Q_ASSERT(false); } } void minMaxValues(HUpnpDataTypes::DataType dt, qreal* max, qreal* min) { switch(dt) { case HUpnpDataTypes::r4: case HUpnpDataTypes::fp: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); break; case HUpnpDataTypes::r8: case HUpnpDataTypes::number: case HUpnpDataTypes::fixed_14_4: *max = std::numeric_limits::max(); *min = std::numeric_limits::min(); break; default: Q_ASSERT(false); } } } IDataHolder* InvokeActionDialog::createDataHolder( const HStateVariableInfo& stateVar) { IDataHolder* content = 0; if (HUpnpDataTypes::isInteger(stateVar.dataType())) { if (stateVar.isConstrained()) { content = new GenericInput( new QIntValidator( stateVar.minimumValue().toInt(), stateVar.maximumValue().toInt(), 0)); } else { qint32 max = 0, min = 0; minMaxValues(stateVar.dataType(), &max, &min); content = new GenericInput(new QIntValidator(min, max, 0)); } } else if (HUpnpDataTypes::isRational(HUpnpDataTypes::string)) { if (stateVar.isConstrained()) { content = new GenericInput( new QDoubleValidator( stateVar.minimumValue().toDouble(), stateVar.maximumValue().toDouble(), 0, 0)); } else { qreal max = 0, min = 0; minMaxValues(stateVar.dataType(), &max, &min); content = new GenericInput(new QDoubleValidator(min, max, 0, 0)); } } else if (stateVar.dataType() == HUpnpDataTypes::string) { if (stateVar.isConstrained()) { content = new AllowedValueListInput(stateVar.allowedValueList()); } else { content = new GenericInput(); } } else if (stateVar.dataType() == HUpnpDataTypes::boolean) { QStringList allowedValues; allowedValues.append("True"); allowedValues.append("False"); content = new AllowedValueListInput(allowedValues); } else { content = new GenericInput(); } return content; } InvokeActionDialog::~InvokeActionDialog() { delete m_ui; } void InvokeActionDialog::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } void InvokeActionDialog::on_invokeButton_clicked() { HActionArguments inputArgs = m_action->info().inputArguments(); for(qint32 i = 0; i < inputArgs.size(); ++i) { HActionArgument inputArg = inputArgs[i]; IDataHolder* dataHolder = m_inputWidgets[inputArg.name()]; QVariant data = dataHolder->data(); if (inputArg.isValidValue(data)) { bool ok = inputArg.setValue(data); Q_ASSERT(ok); Q_UNUSED(ok) } else { QMessageBox mbox; mbox.setText(QObject::tr("Check your arguments!")); mbox.setWindowTitle(QObject::tr("Error")); mbox.exec(); return; } } m_action->beginInvoke(inputArgs); m_ui->invokeButton->setEnabled(false); } herqq-1.0.0/apps/simple_test-app/mainwindow.ui0000644000000000000000000000357711543637306020136 0ustar rootroot MainWindow 0 0 250 111 0 0 250 100 250 111 HUPnP Launcher Starts an HDeviceHost and instructs it to host a simple test HDevice Host a Simple HDevice Starts an HControlPoint for monitoring UPnP devices on the network Start HControlPoint 0 0 250 21 herqq-1.0.0/apps/simple_test-app/invokeactiondialog.h0000644000000000000000000000373411543637306021440 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef INVOKEACTIONDIALOG_H #define INVOKEACTIONDIALOG_H #include "i_dataholder.h" #include #include #include #include #include struct QUuid; namespace Ui { class InvokeActionDialog; } // // // class InvokeActionDialog : public QDialog { Q_OBJECT Q_DISABLE_COPY(InvokeActionDialog) private: Ui::InvokeActionDialog* m_ui; Herqq::Upnp::HClientAction* m_action; QHash m_inputWidgets; void setupArgumentWidgets(); IDataHolder* createDataHolder(const Herqq::Upnp::HStateVariableInfo&); public: explicit InvokeActionDialog( Herqq::Upnp::HClientAction*, QWidget* parent = 0); virtual ~InvokeActionDialog(); public Q_SLOTS: void contentSourceRemoved(Herqq::Upnp::HClientDevice*); protected: virtual void changeEvent(QEvent*); private slots: void on_invokeButton_clicked(); void invokeComplete( Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&); }; #endif // INVOKEACTIONDIALOG_H herqq-1.0.0/apps/simple_test-app/controlpoint_navigatoritem.cpp0000644000000000000000000001462611543637306023607 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "controlpoint_navigatoritem.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Herqq::Upnp; /******************************************************************************* * ControlPointNavigatorItem ******************************************************************************/ ControlPointNavigatorItem::ControlPointNavigatorItem( ControlPointNavigatorItem *parent) : m_childItems(), m_parentItem(parent) { } ControlPointNavigatorItem::~ControlPointNavigatorItem() { qDeleteAll(m_childItems); } void ControlPointNavigatorItem::appendChild(ControlPointNavigatorItem* item) { Q_ASSERT(item); m_childItems.append(item); } void ControlPointNavigatorItem::removeChild(qint32 index) { Q_ASSERT(index < m_childItems.size()); delete m_childItems.at(index); m_childItems.removeAt(index); } ControlPointNavigatorItem* ControlPointNavigatorItem::child(int row) { return m_childItems.value(row); } int ControlPointNavigatorItem::childCount() const { return m_childItems.count(); } int ControlPointNavigatorItem::columnCount() const { return 1; } ControlPointNavigatorItem* ControlPointNavigatorItem::parent() { return m_parentItem; } int ControlPointNavigatorItem::row() const { if (m_parentItem) { return m_parentItem->m_childItems.indexOf( const_cast(this)); } return 0; } int ControlPointNavigatorItem::rowCount() const { qint32 rowCount = childCount(); foreach(ControlPointNavigatorItem* child, m_childItems) { rowCount += child->rowCount(); } return rowCount; } /******************************************************************************* * RootItem ******************************************************************************/ RootItem::RootItem(ControlPointNavigatorItem* parent) : ControlPointNavigatorItem(parent) { } RootItem::~RootItem() { } QVariant RootItem::data (int /*column*/) const { return "Devices"; } void RootItem::accept(ControlPointNavigatorItemVisitor* /*visitor*/) { } /******************************************************************************* * ContainerItem ******************************************************************************/ ContainerItem::ContainerItem( const QString& name, ControlPointNavigatorItem* parent) : ControlPointNavigatorItem(parent), m_name(name) { } ContainerItem::~ContainerItem() { } QVariant ContainerItem::data (int /*column*/) const { return m_name; } void ContainerItem::accept(ControlPointNavigatorItemVisitor* /*visitor*/) { } /******************************************************************************* * DeviceItem ******************************************************************************/ DeviceItem::DeviceItem( HClientDevice* device, ControlPointNavigatorItem* parent) : ControlPointNavigatorItem(parent), m_device(device) { Q_ASSERT(m_device); } DeviceItem::~DeviceItem() { } QVariant DeviceItem::data(int /*column*/) const { return m_device->info().friendlyName(); } void DeviceItem::accept(ControlPointNavigatorItemVisitor* visitor) { visitor->visit(this); } /******************************************************************************* * ServiceItem ******************************************************************************/ ServiceItem::ServiceItem( HClientService* service, ControlPointNavigatorItem* parent) : ControlPointNavigatorItem(parent), m_service(service) { Q_ASSERT(service); } ServiceItem::~ServiceItem() { } QVariant ServiceItem::data (int /*column*/) const { return m_service->info().serviceId().toString(); } void ServiceItem::accept(ControlPointNavigatorItemVisitor* visitor) { visitor->visit(this); } /******************************************************************************* * ActionItem ******************************************************************************/ ActionItem::ActionItem( HClientAction* action, ControlPointNavigatorItem* parent) : ControlPointNavigatorItem(parent), m_action(action) { Q_ASSERT(action); } ActionItem::~ActionItem() { } QVariant ActionItem::data (int /*column*/) const { return m_action->info().name(); } void ActionItem::accept(ControlPointNavigatorItemVisitor* visitor) { visitor->visit(this); } /******************************************************************************* * StateVariableItem ******************************************************************************/ StateVariableItem::StateVariableItem( const HClientStateVariable* stateVar, ControlPointNavigatorItem* parent) : ControlPointNavigatorItem(parent), m_stateVar(stateVar) { Q_ASSERT(stateVar); } StateVariableItem::~StateVariableItem() { } QVariant StateVariableItem::data (int /*column*/) const { return m_stateVar->info().name(); } void StateVariableItem::accept(ControlPointNavigatorItemVisitor* visitor) { visitor->visit(this); } herqq-1.0.0/apps/simple_test-app/dataitem_display.h0000644000000000000000000000471311543637306021102 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef DATAITEM_DISPLAY_H_ #define DATAITEM_DISPLAY_H_ #include "controlpoint_navigatoritem.h" #include #include #include #include #include #include class QVariant; class QModelIndex; // // // class DataItemDisplay : public QAbstractTableModel { Q_OBJECT H_DISABLE_COPY(DataItemDisplay) friend class NavItemVisitor; private: class NavItemVisitor : public ControlPointNavigatorItemVisitor { H_DISABLE_COPY(NavItemVisitor) private: DataItemDisplay* m_owner; public: NavItemVisitor(DataItemDisplay* owner); virtual ~NavItemVisitor(); virtual void visit(ActionItem*); virtual void visit(ServiceItem*); virtual void visit(DeviceItem*); virtual void visit(StateVariableItem*); }; QList > m_modelData; Herqq::Upnp::HUdn m_rootDeviceUdn; public: DataItemDisplay(QObject* parent = 0); virtual ~DataItemDisplay(); void deviceRemoved(const Herqq::Upnp::HUdn&); void setData(ControlPointNavigatorItem*); Qt::ItemFlags flags(const QModelIndex& index) const; QVariant data( const QModelIndex& index, int role = Qt::DisplayRole) const; QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; int rowCount (const QModelIndex& parent = QModelIndex()) const; int columnCount(const QModelIndex& parent = QModelIndex()) const; }; #endif // DATAITEM_DISPLAY_H_ herqq-1.0.0/apps/simple_test-app/genericinput.cpp0000644000000000000000000000331411543637306020610 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "genericinput.h" #include "ui_genericinput.h" GenericInput::GenericInput(QValidator* inputValidator, QWidget* parent) : IDataHolder(parent), m_ui(new Ui::GenericInput), m_inputValidator(inputValidator) { m_ui->setupUi(this); if (m_inputValidator) { m_inputValidator->setParent(this); m_ui->inputLineEdit->setValidator(m_inputValidator); } } GenericInput::~GenericInput() { delete m_ui; } void GenericInput::changeEvent(QEvent* e) { QWidget::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: m_ui->retranslateUi(this); break; default: break; } } QVariant GenericInput::data() const { return m_ui->inputLineEdit->text(); } herqq-1.0.0/apps/simple_test-app/invokeactiondialog.ui0000644000000000000000000000665611543637306021634 0ustar rootroot InvokeActionDialog Qt::NonModal 0 0 426 420 Testing action invocation true Input arguments false true false false true false Data type Name Value Output arguments true false false true Data type Name Value &Invoke true herqq-1.0.0/apps/simple_test-app/simple_test-app.pro0000644000000000000000000000331311543637306021237 0ustar rootrootTEMPLATE = app TARGET = HUpnpSimpleTestApp QT += network testlib xml CONFIG += warn_on INCLUDEPATH += ../../hupnp/include LIBS += -L"../../hupnp/bin" -lHUpnp \ -L"../../hupnp/lib/qtsoap-2.7-opensource/lib" win32 { debug { LIBS += -lQtSolutions_SOAP-2.7d } else { LIBS += -lQtSolutions_SOAP-2.7 } LIBS += -lws2_32 DESCRIPTIONS = $$PWD\\descriptions DESCRIPTIONS = $${replace(DESCRIPTIONS, /, \\)} QMAKE_POST_LINK += xcopy $$DESCRIPTIONS bin\\descriptions /E /Y /C /I $$escape_expand(\\n\\t) QMAKE_POST_LINK += copy ..\\..\\hupnp\\bin\\* bin /Y } else { LIBS += -lQtSolutions_SOAP-2.7 !macx:QMAKE_LFLAGS += -Wl,--rpath=\\\$\$ORIGIN QMAKE_POST_LINK += cp -Rf $$PWD/descriptions bin & QMAKE_POST_LINK += cp -Rf ../../hupnp/bin/* bin } macx { CONFIG -= app_bundle #CONFIG += x86 x86_64 } OBJECTS_DIR = obj MOC_DIR = obj DESTDIR = ./bin HEADERS += \ mainwindow.h \ controlpoint_window.h \ device_window.h \ controlpoint_navigator.h \ controlpoint_navigatoritem.h \ dataitem_display.h \ invokeactiondialog.h \ allowedvaluelist_input.h \ genericinput.h \ i_dataholder.h SOURCES += \ main.cpp \ mainwindow.cpp \ controlpoint_window.cpp \ device_window.cpp \ controlpoint_navigator.cpp \ controlpoint_navigatoritem.cpp \ dataitem_display.cpp \ invokeactiondialog.cpp \ allowedvaluelist_input.cpp \ genericinput.cpp \ i_dataholder.cpp FORMS += \ mainwindow.ui \ controlpoint.ui \ device_window.ui \ invokeactiondialog.ui \ genericinput.ui \ allowedvaluelist_input.ui herqq-1.0.0/apps/simple_test-app/genericinput.h0000644000000000000000000000300211543637306020247 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef GENERICINPUT_H #define GENERICINPUT_H #include "i_dataholder.h" #include namespace Ui { class GenericInput; } class QValidator; // // // class GenericInput : public IDataHolder { Q_OBJECT Q_DISABLE_COPY(GenericInput) private: Ui::GenericInput* m_ui; QValidator* m_inputValidator; protected: void changeEvent(QEvent *e); public: GenericInput(QValidator* inputValidator = 0, QWidget* parent = 0); virtual ~GenericInput(); virtual QVariant data() const; }; #endif // GENERICINPUT_H herqq-1.0.0/apps/simple_test-app/device_window.h0000644000000000000000000000710411543637306020410 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef DEVICE_WINDOW_H #define DEVICE_WINDOW_H #include #include #include #include namespace Ui { class DeviceWindow; } class DeviceWindow; // // Test HService created by the HTestDevice. This is the only service // exposed by the HTestDevice // class HTestService : public Herqq::Upnp::HServerService { Q_OBJECT Q_DISABLE_COPY(HTestService) private: virtual HActionInvokes createActionInvokes(); public: HTestService (); virtual ~HTestService(); // // The following methods could very well be private. In fact, they // could be regular functions or functors defined elsewhere as well. // It is a design decision whether you wish your service type to be used directly, // in which case exposing its UPnP actions as methods of the service // like in the following case ease the use of the class. qint32 echoAction( const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs = 0); qint32 registerAction( const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs = 0); qint32 chargenAction( const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs = 0); Q_SIGNALS: void actionInvoked(const QString& actionName, const QString& text); }; // // A class created internally to represent our UPnP test device. // class HTestDevice : public Herqq::Upnp::HServerDevice { Q_OBJECT Q_DISABLE_COPY(HTestDevice) public: explicit HTestDevice(); virtual ~HTestDevice(); }; // // // class DeviceWindow : public QMainWindow { Q_OBJECT Q_DISABLE_COPY(DeviceWindow) private: Ui::DeviceWindow* m_ui; Herqq::Upnp::HDeviceHost* m_deviceHost; // ^^ This is needed to host the HTestDevice Herqq::Upnp::HServerDevice* m_testDevice; // A root HServerDevice hosted by a HDeviceHost will not be deleted // until the device host is shutdown or deleted. The root device is stored // here just for this example to demonstrate that you may use the // hosted HServerDevice directly while control points may be // accessing it through the network. protected: virtual void changeEvent(QEvent*); virtual void closeEvent(QCloseEvent*); public: explicit DeviceWindow(QWidget *parent = 0); virtual ~DeviceWindow(); private slots: void actionInvoked(const QString&, const QString&); Q_SIGNALS: void closed(); }; #endif // DEVICE_WINDOW_H herqq-1.0.0/apps/simple_test-app/controlpoint_window.h0000644000000000000000000000442011543637306021701 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #ifndef CONTROLPOINT_WINDOW_H #define CONTROLPOINT_WINDOW_H #include #include #include class DataItemDisplay; class ControlPointNavigator; namespace Ui { class ControlPointWindow; } // // // class ControlPointWindow : public QMainWindow { Q_OBJECT Q_DISABLE_COPY(ControlPointWindow) private: Ui::ControlPointWindow* m_ui; Herqq::Upnp::HControlPoint* m_controlPoint; ControlPointNavigator* m_controlpointNavigator; DataItemDisplay* m_dataItemDisplay; private: void connectToEvents(Herqq::Upnp::HClientDevice*); protected: virtual void changeEvent(QEvent*); virtual void closeEvent(QCloseEvent*); private slots: void rootDeviceOnline(Herqq::Upnp::HClientDevice*); void rootDeviceOffline(Herqq::Upnp::HClientDevice*); void stateVariableChanged( const Herqq::Upnp::HClientStateVariable*, const Herqq::Upnp::HStateVariableEvent&); void on_navigatorTreeView_doubleClicked(QModelIndex); void on_navigatorTreeView_clicked(QModelIndex); public: explicit ControlPointWindow(QWidget* parent = 0); virtual ~ControlPointWindow(); Q_SIGNALS: void contentSourceRemoved(Herqq::Upnp::HClientDevice*); void closed(); }; #endif // CONTROLPOINT_WINDOW_H herqq-1.0.0/apps/simple_test-app/dataitem_display.cpp0000644000000000000000000001625711543637306021443 0ustar rootroot/* * Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved. * * Author: Tuomo Penttinen * * This file is part of an application named HUpnpSimpleTestApp * used for demonstrating how to use the Herqq UPnP (HUPnP) library. * * HUpnpSimpleTestApp 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. * * HUpnpSimpleTestApp 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 HUpnpSimpleTestApp. If not, see . */ #include "dataitem_display.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace Herqq::Upnp; DataItemDisplay::NavItemVisitor::NavItemVisitor(DataItemDisplay* owner) : m_owner(owner) { Q_ASSERT(m_owner); } DataItemDisplay::NavItemVisitor::~NavItemVisitor() { } void DataItemDisplay::NavItemVisitor::visit(ActionItem* item) { Q_ASSERT(item); m_owner->m_modelData.clear(); HClientAction* action = item->action(); m_owner->m_rootDeviceUdn = action->parentService()->parentDevice()-> rootDevice()->info().udn(); m_owner->m_modelData.clear(); m_owner->reset(); m_owner->m_modelData.push_back(qMakePair( QString("Name"), action->info().name())); m_owner->m_modelData.push_back(qMakePair( QString("Number of input arguments"), QString::number(action->info().inputArguments().size()))); m_owner->m_modelData.push_back(qMakePair( QString("Number of output arguments"), QString::number(action->info().outputArguments().size()))); m_owner->m_modelData.push_back(qMakePair( QString("Return argument name"), action->info().returnArgumentName())); m_owner->reset(); } void DataItemDisplay::NavItemVisitor::visit(ServiceItem* item) { Q_ASSERT(item); m_owner->m_modelData.clear(); HClientService* service = item->service(); m_owner->m_rootDeviceUdn = service->parentDevice()-> rootDevice()->info().udn(); m_owner->m_modelData.push_back(qMakePair( QString("Service ID"), service->info().serviceId().toString())); m_owner->m_modelData.push_back(qMakePair( QString("Service type"), service->info().serviceType().toString())); m_owner->m_modelData.push_back(qMakePair( QString("SCPD URL"), service->info().scpdUrl().toString())); m_owner->m_modelData.push_back(qMakePair( QString("Event Sub URL"), service->info().eventSubUrl().toString())); m_owner->m_modelData.push_back(qMakePair( QString("Control URL"), service->info().controlUrl().toString())); m_owner->reset(); } void DataItemDisplay::NavItemVisitor::visit(DeviceItem* item) { Q_ASSERT(item); m_owner->m_modelData.clear(); HClientDevice* device = item->device(); HDeviceInfo deviceInfo = device->info(); m_owner->m_rootDeviceUdn = device->rootDevice()->info().udn(); m_owner->m_modelData.push_back( qMakePair(QString("Friendly name"), deviceInfo.friendlyName())); m_owner->m_modelData.push_back( qMakePair(QString("Device type"), deviceInfo.deviceType().toString())); m_owner->m_modelData.push_back( qMakePair(QString("Model name"), deviceInfo.modelName())); m_owner->m_modelData.push_back( qMakePair(QString("Manufacturer"), deviceInfo.manufacturer())); m_owner->m_modelData.push_back( qMakePair(QString("UDN"), deviceInfo.udn().toString())); QList locations = device->locations(); for (qint32 i = 0; i < locations.size(); ++i) { m_owner->m_modelData.push_back( qMakePair( QString("Device description URL"), locations.at(i).toString())); } m_owner->reset(); } void DataItemDisplay::NavItemVisitor::visit(StateVariableItem* item) { Q_ASSERT(item); m_owner->m_modelData.clear(); const HClientStateVariable* stateVar = item->stateVariable(); m_owner->m_rootDeviceUdn = stateVar->parentService()->parentDevice()-> rootDevice()->info().udn(); m_owner->m_modelData.push_back( qMakePair(QString("Name"), stateVar->info().name())); m_owner->m_modelData.push_back( qMakePair(QString("Minimum value"), stateVar->info().minimumValue().toString())); m_owner->m_modelData.push_back( qMakePair(QString("Maximum value"), stateVar->info().maximumValue().toString())); m_owner->m_modelData.push_back( qMakePair(QString("Step value"), stateVar->info().stepValue().toString())); m_owner->m_modelData.push_back( qMakePair(QString("Default value"), stateVar->info().defaultValue().toString())); QString boolStr = stateVar->info().eventingType() != HStateVariableInfo::NoEvents ? "Yes" : "No"; m_owner->m_modelData.push_back( qMakePair(QString("Is evented"), boolStr)); m_owner->m_modelData.push_back( qMakePair(QString("Allowed values"), stateVar->info().allowedValueList().join(";"))); m_owner->reset(); } DataItemDisplay::DataItemDisplay(QObject* parent) : QAbstractTableModel(parent) { } DataItemDisplay::~DataItemDisplay() { } void DataItemDisplay::setData(ControlPointNavigatorItem* navItem) { NavItemVisitor visitor(this); navItem->accept(&visitor); } void DataItemDisplay::deviceRemoved(const Herqq::Upnp::HUdn& udn) { if (udn == m_rootDeviceUdn) { m_modelData.clear(); reset(); } } Qt::ItemFlags DataItemDisplay::flags(const QModelIndex& /*index*/) const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } QVariant DataItemDisplay::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant::Invalid; } if (role == Qt::DisplayRole) { switch (index.column()) { case 0: return m_modelData[index.row()].first; case 1: return m_modelData[index.row()].second; } } return QVariant::Invalid; } QVariant DataItemDisplay::headerData ( int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole) { if (orientation == Qt::Horizontal) { switch(section) { case 0: return QString("Name"); case 1: return QString("Value"); } } } return QVariant::Invalid; } int DataItemDisplay::rowCount(const QModelIndex& /*parent*/) const { return m_modelData.size(); } int DataItemDisplay::columnCount (const QModelIndex& /*parent*/) const { return 2; } herqq-1.0.0/herqq.pro0000644000000000000000000000077311543637310013202 0ustar rootrootTEMPLATE = subdirs CONFIG += ordered exists(hupnp/options.pri) { win32 { system(type nul > hupnp/options.pri) } else { system(echo "" > hupnp/options.pri) } } CONFIG(DISABLE_QTSOAP) { system(echo "CONFIG += DISABLE_QTSOAP" > hupnp/options.pri) } CONFIG(USE_QT_INSTALL_LOC) { system(echo "CONFIG += USE_QT_INSTALL_LOC" >> hupnp/options.pri) } !CONFIG(DISABLE_CORE) : SUBDIRS += hupnp !CONFIG(DISABLE_TESTAPP) : SUBDIRS += apps/simple_test-app