Mercurial > projects > hoofbaby
view deps/Platinum/Source/Core/PltEvent.cpp @ 0:3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
author | fraserofthenight |
---|---|
date | Mon, 06 Jul 2009 08:06:28 -0700 |
parents | |
children |
line wrap: on
line source
/***************************************************************** | | Platinum - Control/Event | | Copyright (c) 2004-2008, Plutinosoft, LLC. | All rights reserved. | http://www.plutinosoft.com | | 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 2 | of the License, or (at your option) any later version. | | OEMs, ISVs, VARs and other distributors that combine and | distribute commercially licensed software with Platinum software | and do not wish to distribute the source code for the commercially | licensed software under version 2, or (at your option) any later | version, of the GNU General Public License (the "GPL") must enter | into a commercial license agreement with Plutinosoft, LLC. | | 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; see the file LICENSE.txt. If not, write to | the Free Software Foundation, Inc., | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | http://www.gnu.org/licenses/gpl-2.0.html | ****************************************************************/ /*---------------------------------------------------------------------- | includes +---------------------------------------------------------------------*/ #include "PltTaskManager.h" #include "PltEvent.h" #include "PltService.h" #include "PltUPnP.h" #include "PltDeviceData.h" #include "PltXmlHelper.h" NPT_SET_LOCAL_LOGGER("platinum.core.event") /*---------------------------------------------------------------------- | PLT_EventSubscriber::PLT_EventSubscriber +---------------------------------------------------------------------*/ PLT_EventSubscriber::PLT_EventSubscriber(PLT_TaskManager* task_manager, PLT_Service* service, const char* sid, int timeout /* = -1 */) : m_TaskManager(task_manager), m_Service(service), m_EventKey(0), m_SubscriberTask(NULL), m_SID(sid) { NPT_LOG_FINE_1("Creating new subscriber (%s)", m_SID.GetChars()); SetTimeout(timeout); } /*---------------------------------------------------------------------- | PLT_EventSubscriber::~PLT_EventSubscriber +---------------------------------------------------------------------*/ PLT_EventSubscriber::~PLT_EventSubscriber() { NPT_LOG_FINE_1("Deleting subscriber (%s)", m_SID.GetChars()); if (m_SubscriberTask) { m_SubscriberTask->Kill(); m_SubscriberTask = NULL; } } /*---------------------------------------------------------------------- | PLT_EventSubscriber::GetService +---------------------------------------------------------------------*/ PLT_Service* PLT_EventSubscriber::GetService() { return m_Service; } /*---------------------------------------------------------------------- | PLT_EventSubscriber::GetEventKey +---------------------------------------------------------------------*/ NPT_Ordinal PLT_EventSubscriber::GetEventKey() { return m_EventKey; } /*---------------------------------------------------------------------- | PLT_EventSubscriber::SetEventKey +---------------------------------------------------------------------*/ NPT_Result PLT_EventSubscriber::SetEventKey(NPT_Ordinal value) { m_EventKey = value; return NPT_SUCCESS; } /*---------------------------------------------------------------------- | PLT_EventSubscriber::GetLocalIf +---------------------------------------------------------------------*/ NPT_SocketAddress PLT_EventSubscriber::GetLocalIf() { return m_LocalIf; } /*---------------------------------------------------------------------- | PLT_EventSubscriber::SetLocalIf +---------------------------------------------------------------------*/ NPT_Result PLT_EventSubscriber::SetLocalIf(NPT_SocketAddress value) { m_LocalIf = value; return NPT_SUCCESS; } /*---------------------------------------------------------------------- | PLT_EventSubscriber::GetExpirationTime +---------------------------------------------------------------------*/ // a TimeStamp of 0 means no expiration NPT_TimeStamp PLT_EventSubscriber::GetExpirationTime() { return m_ExpirationTime; } /*---------------------------------------------------------------------- | PLT_EventSubscriber::SetExpirationTime +---------------------------------------------------------------------*/ NPT_Result PLT_EventSubscriber::SetTimeout(int timeout /* = -1 */) { NPT_LOG_FINE_2("subscriber (%s) expiring in %d seconds", m_SID.GetChars(), timeout); // -1 means infinite so we set an expiration time of 0 if (timeout == -1) { m_ExpirationTime = NPT_TimeStamp(0, 0); } else { NPT_System::GetCurrentTimeStamp(m_ExpirationTime); m_ExpirationTime += NPT_TimeInterval(timeout, 0); } return NPT_SUCCESS; } /*---------------------------------------------------------------------- | PLT_EventSubscriber::FindCallbackURL +---------------------------------------------------------------------*/ NPT_Result PLT_EventSubscriber::FindCallbackURL(const char* callback_url) { NPT_String res; return NPT_ContainerFind(m_CallbackURLs, NPT_StringFinder(callback_url), res); } /*---------------------------------------------------------------------- | PLT_EventSubscriber::AddCallbackURL +---------------------------------------------------------------------*/ NPT_Result PLT_EventSubscriber::AddCallbackURL(const char* callback_url) { NPT_CHECK_POINTER_FATAL(callback_url); NPT_LOG_FINE_2("Adding callback \"%s\" to subscriber %s", callback_url, m_SID.GetChars()); return m_CallbackURLs.Add(callback_url); } /*---------------------------------------------------------------------- | PLT_EventSubscriber::Notify +---------------------------------------------------------------------*/ NPT_Result PLT_EventSubscriber::Notify(NPT_List<PLT_StateVariable*>& vars) { // verify we have eventable variables bool foundVars = false; NPT_XmlElementNode* propertyset = new NPT_XmlElementNode("e", "propertyset"); NPT_CHECK_SEVERE(propertyset->SetNamespaceUri("e", "urn:schemas-upnp-org:event-1-0")); NPT_List<PLT_StateVariable*>::Iterator var = vars.GetFirstItem(); while (var) { if ((*var)->IsSendingEvents()) { NPT_XmlElementNode* property = new NPT_XmlElementNode("e", "property"); propertyset->AddChild(property); PLT_XmlHelper::AddChildText(property, (*var)->GetName(), (*var)->GetValue()); foundVars = true; } ++var; } // no eventable state variables found! if (foundVars == false) { delete propertyset; return NPT_FAILURE; } // format the body with the xml NPT_String xml; if (NPT_FAILED(PLT_XmlHelper::Serialize(*propertyset, xml))) { delete propertyset; NPT_CHECK_FATAL(NPT_FAILURE); } delete propertyset; // parse the callback url NPT_HttpUrl url(m_CallbackURLs[0]); if (!url.IsValid()) { NPT_CHECK_FATAL(NPT_FAILURE); } // format request NPT_HttpRequest* request = new NPT_HttpRequest(url, "NOTIFY", NPT_HTTP_PROTOCOL_1_0); request->GetHeaders().SetHeader(NPT_HTTP_HEADER_CONNECTION, "keep-alive"); // add the extra headers PLT_HttpHelper::SetContentType(*request, "text/xml"); PLT_UPnPMessageHelper::SetNT(*request, "upnp:event"); PLT_UPnPMessageHelper::SetNTS(*request, "upnp:propchange"); PLT_UPnPMessageHelper::SetSID(*request, m_SID); PLT_UPnPMessageHelper::SetSeq(*request, m_EventKey); // wrap around sequence to 1 if (++m_EventKey == 0) m_EventKey = 1; PLT_HttpHelper::SetBody(*request, xml); // start the task now if not started already if (!m_SubscriberTask) { m_SubscriberTask = new PLT_HttpClientSocketTask(request, true); NPT_TimeInterval delay(0.5f); // delay start to make sure ctrlpoint receives response to subscription // before our first NOTIFY. Also make sure task is not auto-destroy // since we want to destroy it ourselves when the subscriber goes away. NPT_CHECK_FATAL(m_TaskManager->StartTask(m_SubscriberTask, &delay, false)); } else { m_SubscriberTask->AddRequest(request); } return NPT_SUCCESS; } /*---------------------------------------------------------------------- | PLT_EventSubscriberFinderByService::operator() +---------------------------------------------------------------------*/ bool PLT_EventSubscriberFinderByService::operator()(PLT_EventSubscriber* const & eventSub) const { return m_Service->GetDevice()->GetUUID().Compare( eventSub->GetService()->GetDevice()->GetUUID(), true) ? false : true; }