Mercurial > projects > hoofbaby
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3425707ddbf6 |
---|---|
1 /***************************************************************** | |
2 | | |
3 | Platinum - Control/Event | |
4 | | |
5 | Copyright (c) 2004-2008, Plutinosoft, LLC. | |
6 | All rights reserved. | |
7 | http://www.plutinosoft.com | |
8 | | |
9 | This program is free software; you can redistribute it and/or | |
10 | modify it under the terms of the GNU General Public License | |
11 | as published by the Free Software Foundation; either version 2 | |
12 | of the License, or (at your option) any later version. | |
13 | | |
14 | OEMs, ISVs, VARs and other distributors that combine and | |
15 | distribute commercially licensed software with Platinum software | |
16 | and do not wish to distribute the source code for the commercially | |
17 | licensed software under version 2, or (at your option) any later | |
18 | version, of the GNU General Public License (the "GPL") must enter | |
19 | into a commercial license agreement with Plutinosoft, LLC. | |
20 | | |
21 | This program is distributed in the hope that it will be useful, | |
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | GNU General Public License for more details. | |
25 | | |
26 | You should have received a copy of the GNU General Public License | |
27 | along with this program; see the file LICENSE.txt. If not, write to | |
28 | the Free Software Foundation, Inc., | |
29 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
30 | http://www.gnu.org/licenses/gpl-2.0.html | |
31 | | |
32 ****************************************************************/ | |
33 | |
34 /*---------------------------------------------------------------------- | |
35 | includes | |
36 +---------------------------------------------------------------------*/ | |
37 #include "PltTaskManager.h" | |
38 #include "PltEvent.h" | |
39 #include "PltService.h" | |
40 #include "PltUPnP.h" | |
41 #include "PltDeviceData.h" | |
42 #include "PltXmlHelper.h" | |
43 | |
44 NPT_SET_LOCAL_LOGGER("platinum.core.event") | |
45 | |
46 /*---------------------------------------------------------------------- | |
47 | PLT_EventSubscriber::PLT_EventSubscriber | |
48 +---------------------------------------------------------------------*/ | |
49 PLT_EventSubscriber::PLT_EventSubscriber(PLT_TaskManager* task_manager, | |
50 PLT_Service* service, | |
51 const char* sid, | |
52 int timeout /* = -1 */) : | |
53 m_TaskManager(task_manager), | |
54 m_Service(service), | |
55 m_EventKey(0), | |
56 m_SubscriberTask(NULL), | |
57 m_SID(sid) | |
58 { | |
59 NPT_LOG_FINE_1("Creating new subscriber (%s)", m_SID.GetChars()); | |
60 SetTimeout(timeout); | |
61 } | |
62 | |
63 /*---------------------------------------------------------------------- | |
64 | PLT_EventSubscriber::~PLT_EventSubscriber | |
65 +---------------------------------------------------------------------*/ | |
66 PLT_EventSubscriber::~PLT_EventSubscriber() | |
67 { | |
68 NPT_LOG_FINE_1("Deleting subscriber (%s)", m_SID.GetChars()); | |
69 if (m_SubscriberTask) { | |
70 m_SubscriberTask->Kill(); | |
71 m_SubscriberTask = NULL; | |
72 } | |
73 } | |
74 | |
75 /*---------------------------------------------------------------------- | |
76 | PLT_EventSubscriber::GetService | |
77 +---------------------------------------------------------------------*/ | |
78 PLT_Service* | |
79 PLT_EventSubscriber::GetService() | |
80 { | |
81 return m_Service; | |
82 } | |
83 | |
84 /*---------------------------------------------------------------------- | |
85 | PLT_EventSubscriber::GetEventKey | |
86 +---------------------------------------------------------------------*/ | |
87 NPT_Ordinal | |
88 PLT_EventSubscriber::GetEventKey() | |
89 { | |
90 return m_EventKey; | |
91 } | |
92 | |
93 /*---------------------------------------------------------------------- | |
94 | PLT_EventSubscriber::SetEventKey | |
95 +---------------------------------------------------------------------*/ | |
96 NPT_Result | |
97 PLT_EventSubscriber::SetEventKey(NPT_Ordinal value) | |
98 { | |
99 m_EventKey = value; | |
100 return NPT_SUCCESS; | |
101 } | |
102 | |
103 /*---------------------------------------------------------------------- | |
104 | PLT_EventSubscriber::GetLocalIf | |
105 +---------------------------------------------------------------------*/ | |
106 NPT_SocketAddress | |
107 PLT_EventSubscriber::GetLocalIf() | |
108 { | |
109 return m_LocalIf; | |
110 } | |
111 | |
112 /*---------------------------------------------------------------------- | |
113 | PLT_EventSubscriber::SetLocalIf | |
114 +---------------------------------------------------------------------*/ | |
115 NPT_Result | |
116 PLT_EventSubscriber::SetLocalIf(NPT_SocketAddress value) | |
117 { | |
118 m_LocalIf = value; | |
119 return NPT_SUCCESS; | |
120 } | |
121 | |
122 /*---------------------------------------------------------------------- | |
123 | PLT_EventSubscriber::GetExpirationTime | |
124 +---------------------------------------------------------------------*/ | |
125 // a TimeStamp of 0 means no expiration | |
126 NPT_TimeStamp | |
127 PLT_EventSubscriber::GetExpirationTime() | |
128 { | |
129 return m_ExpirationTime; | |
130 } | |
131 | |
132 /*---------------------------------------------------------------------- | |
133 | PLT_EventSubscriber::SetExpirationTime | |
134 +---------------------------------------------------------------------*/ | |
135 NPT_Result | |
136 PLT_EventSubscriber::SetTimeout(int timeout /* = -1 */) | |
137 { | |
138 NPT_LOG_FINE_2("subscriber (%s) expiring in %d seconds", | |
139 m_SID.GetChars(), | |
140 timeout); | |
141 | |
142 // -1 means infinite so we set an expiration time of 0 | |
143 if (timeout == -1) { | |
144 m_ExpirationTime = NPT_TimeStamp(0, 0); | |
145 } else { | |
146 NPT_System::GetCurrentTimeStamp(m_ExpirationTime); | |
147 m_ExpirationTime += NPT_TimeInterval(timeout, 0); | |
148 } | |
149 return NPT_SUCCESS; | |
150 } | |
151 | |
152 /*---------------------------------------------------------------------- | |
153 | PLT_EventSubscriber::FindCallbackURL | |
154 +---------------------------------------------------------------------*/ | |
155 NPT_Result | |
156 PLT_EventSubscriber::FindCallbackURL(const char* callback_url) | |
157 { | |
158 NPT_String res; | |
159 return NPT_ContainerFind(m_CallbackURLs, | |
160 NPT_StringFinder(callback_url), | |
161 res); | |
162 } | |
163 | |
164 /*---------------------------------------------------------------------- | |
165 | PLT_EventSubscriber::AddCallbackURL | |
166 +---------------------------------------------------------------------*/ | |
167 NPT_Result | |
168 PLT_EventSubscriber::AddCallbackURL(const char* callback_url) | |
169 { | |
170 NPT_CHECK_POINTER_FATAL(callback_url); | |
171 | |
172 NPT_LOG_FINE_2("Adding callback \"%s\" to subscriber %s", | |
173 callback_url, | |
174 m_SID.GetChars()); | |
175 return m_CallbackURLs.Add(callback_url); | |
176 } | |
177 | |
178 /*---------------------------------------------------------------------- | |
179 | PLT_EventSubscriber::Notify | |
180 +---------------------------------------------------------------------*/ | |
181 NPT_Result | |
182 PLT_EventSubscriber::Notify(NPT_List<PLT_StateVariable*>& vars) | |
183 { | |
184 // verify we have eventable variables | |
185 bool foundVars = false; | |
186 NPT_XmlElementNode* propertyset = new NPT_XmlElementNode("e", "propertyset"); | |
187 NPT_CHECK_SEVERE(propertyset->SetNamespaceUri("e", "urn:schemas-upnp-org:event-1-0")); | |
188 | |
189 NPT_List<PLT_StateVariable*>::Iterator var = vars.GetFirstItem(); | |
190 while (var) { | |
191 if ((*var)->IsSendingEvents()) { | |
192 NPT_XmlElementNode* property = new NPT_XmlElementNode("e", "property"); | |
193 propertyset->AddChild(property); | |
194 PLT_XmlHelper::AddChildText(property, (*var)->GetName(), (*var)->GetValue()); | |
195 foundVars = true; | |
196 } | |
197 ++var; | |
198 } | |
199 | |
200 // no eventable state variables found! | |
201 if (foundVars == false) { | |
202 delete propertyset; | |
203 return NPT_FAILURE; | |
204 } | |
205 | |
206 // format the body with the xml | |
207 NPT_String xml; | |
208 if (NPT_FAILED(PLT_XmlHelper::Serialize(*propertyset, xml))) { | |
209 delete propertyset; | |
210 NPT_CHECK_FATAL(NPT_FAILURE); | |
211 } | |
212 delete propertyset; | |
213 | |
214 | |
215 // parse the callback url | |
216 NPT_HttpUrl url(m_CallbackURLs[0]); | |
217 if (!url.IsValid()) { | |
218 NPT_CHECK_FATAL(NPT_FAILURE); | |
219 } | |
220 // format request | |
221 NPT_HttpRequest* request = new NPT_HttpRequest(url, | |
222 "NOTIFY", | |
223 NPT_HTTP_PROTOCOL_1_0); | |
224 request->GetHeaders().SetHeader(NPT_HTTP_HEADER_CONNECTION, "keep-alive"); | |
225 | |
226 // add the extra headers | |
227 PLT_HttpHelper::SetContentType(*request, "text/xml"); | |
228 PLT_UPnPMessageHelper::SetNT(*request, "upnp:event"); | |
229 PLT_UPnPMessageHelper::SetNTS(*request, "upnp:propchange"); | |
230 PLT_UPnPMessageHelper::SetSID(*request, m_SID); | |
231 PLT_UPnPMessageHelper::SetSeq(*request, m_EventKey); | |
232 | |
233 // wrap around sequence to 1 | |
234 if (++m_EventKey == 0) m_EventKey = 1; | |
235 | |
236 PLT_HttpHelper::SetBody(*request, xml); | |
237 | |
238 // start the task now if not started already | |
239 if (!m_SubscriberTask) { | |
240 m_SubscriberTask = new PLT_HttpClientSocketTask(request, true); | |
241 NPT_TimeInterval delay(0.5f); | |
242 // delay start to make sure ctrlpoint receives response to subscription | |
243 // before our first NOTIFY. Also make sure task is not auto-destroy | |
244 // since we want to destroy it ourselves when the subscriber goes away. | |
245 NPT_CHECK_FATAL(m_TaskManager->StartTask(m_SubscriberTask, &delay, false)); | |
246 } else { | |
247 m_SubscriberTask->AddRequest(request); | |
248 } | |
249 | |
250 return NPT_SUCCESS; | |
251 } | |
252 | |
253 /*---------------------------------------------------------------------- | |
254 | PLT_EventSubscriberFinderByService::operator() | |
255 +---------------------------------------------------------------------*/ | |
256 bool | |
257 PLT_EventSubscriberFinderByService::operator()(PLT_EventSubscriber* const & eventSub) const | |
258 { | |
259 return m_Service->GetDevice()->GetUUID().Compare( | |
260 eventSub->GetService()->GetDevice()->GetUUID(), true) ? false : true; | |
261 } |