Don't allow autoconf 2.70, it's known to fail
[amule.git] / src / UPnPBase.h
blob7554d660903ccf50436bf9de1e97022f0becb0ca
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2004-2011 Marcelo Roberto Jimenez ( phoenix@amule.org )
5 // Copyright (c) 2006-2011 aMule Team ( admin@amule.org / http://www.amule.org )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 // This define must not conflict with the one in the standard header
28 #ifndef AMULE_UPNP_H
29 #define AMULE_UPNP_H
32 #include <map>
33 #include <string>
34 #include <sstream>
36 #include "UPnPCompatibility.h"
38 #include <common/SmartPtr.h> // Needed for CSmartPtr
41 extern std::string stdEmptyString;
44 class CUPnPPortMapping
46 private:
47 std::string m_port;
48 std::string m_protocol;
49 std::string m_enabled;
50 std::string m_description;
51 std::string m_key;
53 public:
54 CUPnPPortMapping(
55 int port = 0,
56 const std::string &protocol = stdEmptyString,
57 bool enabled = false,
58 const std::string &description = stdEmptyString);
59 ~CUPnPPortMapping() {}
61 const std::string &getPort() const
62 { return m_port; }
63 const std::string &getProtocol() const
64 { return m_protocol; }
65 const std::string &getEnabled() const
66 { return m_enabled; }
67 const std::string &getDescription() const
68 { return m_description; }
69 const std::string &getKey() const
70 { return m_key; }
74 namespace IXML
76 namespace Document {
77 IXML_Element *GetRootElement(IXML_Document *doc);
78 void Free(IXML_Document *doc);
81 namespace Element {
82 IXML_Element *GetFirstChild(IXML_Element *parent);
83 IXML_Element *GetNextSibling(IXML_Element *child);
84 const DOMString GetTag(IXML_Element *element);
85 const std::string GetTextValue(IXML_Element *element);
86 const std::string GetChildValueByTag(IXML_Element *element, const DOMString tag);
87 IXML_Element *GetFirstChildByTag(IXML_Element *element, const DOMString tag);
88 IXML_Element *GetNextSiblingByTag(IXML_Element *element, const DOMString tag);
89 const std::string GetAttributeByTag(IXML_Element *element, const DOMString tag);
94 class CUPnPControlPoint;
96 template <typename T, char const *XML_ELEMENT_NAME, char const *XML_LIST_NAME>
97 class CXML_List : public std::map<const std::string, T *>
99 public:
100 CXML_List(
101 const CUPnPControlPoint &upnpControlPoint,
102 IXML_Element *parent,
103 const std::string &url);
104 ~CXML_List();
108 template <typename T, char const *XML_ELEMENT_NAME, char const *XML_LIST_NAME>
109 CXML_List<T, XML_ELEMENT_NAME, XML_LIST_NAME>::CXML_List(
110 const CUPnPControlPoint &upnpControlPoint,
111 IXML_Element *parent,
112 const std::string &url)
114 IXML_Element *elementList = IXML::Element::GetFirstChildByTag(parent, XML_LIST_NAME);
115 unsigned int i = 0;
116 for ( IXML_Element *element = IXML::Element::GetFirstChildByTag(elementList, XML_ELEMENT_NAME);
117 element;
118 element = IXML::Element::GetNextSiblingByTag(element, XML_ELEMENT_NAME)) {
119 // Add a new element to the element list
120 T *upnpElement = new T(upnpControlPoint, element, url);
121 (*this)[upnpElement->GetKey()] = upnpElement;
122 ++i;
124 std::ostringstream msg;
125 msg << "\n " << XML_LIST_NAME << ": " <<
126 i << " " << XML_ELEMENT_NAME << "s.";
127 AddDebugLogLineN(logUPnP, msg);
131 template <typename T, char const *XML_ELEMENT_NAME, char const *XML_LIST_NAME>
132 CXML_List<T, XML_ELEMENT_NAME, XML_LIST_NAME>::~CXML_List()
134 typename CXML_List<T, XML_ELEMENT_NAME, XML_LIST_NAME>::iterator it;
135 for(it = this->begin(); it != this->end(); ++it) {
136 delete (*it).second;
140 extern const char s_argument[];
141 extern const char s_argumentList[];
142 extern const char s_action[];
143 extern const char s_actionList[];
144 extern const char s_allowedValue[];
145 extern const char s_allowedValueList[];
146 extern const char s_stateVariable[];
147 extern const char s_serviceStateTable[];
148 extern const char s_service[];
149 extern const char s_serviceList[];
150 extern const char s_device[];
151 extern const char s_deviceList[];
155 class CUPnPArgument;
156 typedef CXML_List<CUPnPArgument, s_argument, s_argumentList> ArgumentList;
157 class CUPnPAction;
158 typedef CXML_List<CUPnPAction, s_action, s_actionList> ActionList;
159 class CUPnPStateVariable;
160 typedef CXML_List<CUPnPStateVariable, s_stateVariable, s_serviceStateTable> ServiceStateTable;
161 class CUPnPAllowedValue;
162 typedef CXML_List<CUPnPAllowedValue, s_allowedValue, s_allowedValueList> AllowedValueList;
163 class CUPnPService;
164 typedef CXML_List<CUPnPService, s_service, s_serviceList> ServiceList;
165 class CUPnPDevice;
166 typedef CXML_List<CUPnPDevice, s_device, s_deviceList> DeviceList;
169 class CUPnPError
171 private:
172 IXML_Element *m_root;
173 const std::string m_ErrorCode;
174 const std::string m_ErrorDescription;
175 public:
176 CUPnPError(IXML_Document *errorDoc);
177 ~CUPnPError() {}
178 const std::string &getErrorCode() const
179 { return m_ErrorCode; }
180 const std::string &getErrorDescription() const
181 { return m_ErrorDescription; }
185 class CUPnPArgument
187 private:
188 const std::string m_name;
189 const std::string m_direction;
190 bool m_retval;
191 const std::string m_relatedStateVariable;
193 public:
194 CUPnPArgument(
195 const CUPnPControlPoint &upnpControlPoint,
196 IXML_Element *argument,
197 const std::string &SCPDURL);
198 ~CUPnPArgument() {}
199 const std::string &GetName() const
200 { return m_name; }
201 const std::string &GetDirection() const
202 { return m_direction; }
203 bool GetRetVal() const
204 { return m_retval; }
205 const std::string &GetRelatedStateVariable() const
206 { return m_relatedStateVariable; }
207 const std::string &GetKey() const
208 { return m_name; }
213 class CUPnPAction
215 private:
216 ArgumentList m_ArgumentList;
217 const std::string m_name;
219 public:
220 CUPnPAction(
221 const CUPnPControlPoint &upnpControlPoint,
222 IXML_Element *action,
223 const std::string &SCPDURL);
224 ~CUPnPAction() {}
225 const std::string &GetName() const
226 { return m_name; }
227 const std::string &GetKey() const
228 { return m_name; }
229 const ArgumentList &GetArgumentList() const
230 { return m_ArgumentList; }
234 class CUPnPAllowedValue
236 private:
237 const std::string m_allowedValue;
239 public:
240 CUPnPAllowedValue(
241 const CUPnPControlPoint &upnpControlPoint,
242 IXML_Element *allowedValue,
243 const std::string &SCPDURL);
244 ~CUPnPAllowedValue() {}
245 const std::string &GetAllowedValue() const
246 { return m_allowedValue; }
247 const std::string &GetKey() const
248 { return m_allowedValue; }
252 class CUPnPStateVariable
254 private:
255 AllowedValueList m_AllowedValueList;
256 const std::string m_name;
257 const std::string m_dataType;
258 const std::string m_defaultValue;
259 const std::string m_sendEvents;
261 public:
262 CUPnPStateVariable(
263 const CUPnPControlPoint &upnpControlPoint,
264 IXML_Element *stateVariable,
265 const std::string &URLBase);
266 ~CUPnPStateVariable() {}
267 const std::string &GetNname() const
268 { return m_name; }
269 const std::string &GetDataType() const
270 { return m_dataType; }
271 const std::string &GetDefaultValue() const
272 { return m_defaultValue; }
273 const std::string &GetKey() const
274 { return m_name; }
275 const AllowedValueList &GetAllowedValueList() const
276 { return m_AllowedValueList; }
280 class CUPnPSCPD
282 private:
283 ActionList m_ActionList;
284 ServiceStateTable m_ServiceStateTable;
285 const std::string m_SCPDURL;
287 public:
288 CUPnPSCPD(
289 const CUPnPControlPoint &upnpControlPoint,
290 IXML_Element *scpd,
291 const std::string &SCPDURL);
292 ~CUPnPSCPD() {}
293 const ActionList &GetActionList() const
294 { return m_ActionList; }
295 const ServiceStateTable &GetServiceStateTable() const
296 { return m_ServiceStateTable; }
300 class CUPnPArgumentValue
302 private:
303 std::string m_argument;
304 std::string m_value;
306 public:
307 CUPnPArgumentValue();
308 CUPnPArgumentValue(const std::string &argument, const std::string &value);
309 ~CUPnPArgumentValue() {}
311 const std::string &GetArgument() const { return m_argument; }
312 const std::string &GetValue() const { return m_value; }
313 const std::string &SetArgument(const std::string& argument) { return m_argument = argument; }
314 const std::string &SetValue(const std::string &value) { return m_value = value; }
318 class CUPnPService
320 private:
321 const CUPnPControlPoint &m_UPnPControlPoint;
322 const std::string m_serviceType;
323 const std::string m_serviceId;
324 const std::string m_SCPDURL;
325 const std::string m_controlURL;
326 const std::string m_eventSubURL;
327 std::string m_absSCPDURL;
328 std::string m_absControlURL;
329 std::string m_absEventSubURL;
330 int m_timeout;
331 Upnp_SID m_SID;
332 CSmartPtr<CUPnPSCPD> m_SCPD;
334 public:
335 CUPnPService(
336 const CUPnPControlPoint &upnpControlPoint,
337 IXML_Element *service,
338 const std::string &URLBase);
339 ~CUPnPService();
341 const std::string &GetServiceType() const
342 { return m_serviceType; }
343 const std::string &GetServiceId() const
344 { return m_serviceId; }
345 const std::string &GetSCPDURL() const
346 { return m_SCPDURL; }
347 const std::string &GetAbsSCPDURL() const
348 { return m_absSCPDURL; }
349 const std::string &GetControlURL() const
350 { return m_controlURL; }
351 const std::string &GetEventSubURL() const
352 { return m_eventSubURL; }
353 const std::string &GetAbsControlURL() const
354 { return m_absControlURL; }
355 const std::string &GetAbsEventSubURL() const
356 { return m_absEventSubURL; }
357 int GetTimeout() const
358 { return m_timeout; }
359 void SetTimeout(int t)
360 { m_timeout = t; }
361 int *GetTimeoutAddr()
362 { return &m_timeout; }
363 char *GetSID()
364 { return m_SID; }
365 void SetSID(const char *s)
366 { memcpy(m_SID, s, sizeof(Upnp_SID)); }
367 const std::string &GetKey() const
368 { return m_serviceId; }
369 bool IsSubscribed() const
370 { return m_SCPD.get() != NULL; }
371 void SetSCPD(CUPnPSCPD *SCPD)
372 { m_SCPD.reset(SCPD); }
374 bool Execute(
375 const std::string &ActionName,
376 const std::vector<CUPnPArgumentValue> &ArgValue) const;
377 const std::string GetStateVariable(
378 const std::string &stateVariableName) const;
382 class CUPnPDevice
384 private:
385 // Please, lock these lists before use
386 DeviceList m_DeviceList;
387 ServiceList m_ServiceList;
389 const std::string m_deviceType;
390 const std::string m_friendlyName;
391 const std::string m_manufacturer;
392 const std::string m_manufacturerURL;
393 const std::string m_modelDescription;
394 const std::string m_modelName;
395 const std::string m_modelNumber;
396 const std::string m_modelURL;
397 const std::string m_serialNumber;
398 const std::string m_UDN;
399 const std::string m_UPC;
400 std::string m_presentationURL;
402 public:
403 CUPnPDevice(
404 const CUPnPControlPoint &upnpControlPoint,
405 IXML_Element *device,
406 const std::string &URLBase);
407 ~CUPnPDevice() {}
409 const std::string &GetUDN() const
410 { return m_UDN; }
411 const std::string &GetDeviceType() const
412 { return m_deviceType; }
413 const std::string &GetFriendlyName() const
414 { return m_friendlyName; }
415 const std::string &GetPresentationURL() const
416 { return m_presentationURL; }
417 const std::string &GetKey() const
418 { return m_UDN; }
422 class CUPnPRootDevice : public CUPnPDevice
424 private:
425 const std::string m_URLBase;
426 const std::string m_location;
427 int m_expires;
429 public:
430 CUPnPRootDevice(
431 const CUPnPControlPoint &upnpControlPoint,
432 IXML_Element *rootDevice,
433 const std::string &OriginalURLBase,
434 const std::string &FixedURLBase,
435 const char *location,
436 int expires);
437 ~CUPnPRootDevice() {}
439 const std::string &GetURLBase() const
440 { return m_URLBase; }
441 const std::string &GetLocation() const
442 { return m_location; }
443 int GetExpires() const
444 { return m_expires; }
445 void SetExpires(int expires)
446 { m_expires = expires; }
450 typedef std::map<const std::string, CUPnPRootDevice *> RootDeviceMap;
451 typedef std::map<const std::string, CUPnPService *> ServiceMap;
452 typedef std::map<const std::string, CUPnPPortMapping> PortMappingMap;
455 class CUPnPControlPoint
457 private:
458 static CUPnPControlPoint *s_CtrlPoint;
459 // upnp stuff
460 UpnpClient_Handle m_UPnPClientHandle;
461 RootDeviceMap m_RootDeviceMap;
462 ServiceMap m_ServiceMap;
463 PortMappingMap m_ActivePortMappingsMap;
464 CUPnPMutex m_RootDeviceListMutex;
465 bool m_IGWDeviceDetected;
466 //#warning This variable is for testing purposes only and should disappear on release.
467 CUPnPService *m_WanService;
468 CUPnPMutex m_WaitForSearchTimeoutMutex;
470 public:
471 CUPnPControlPoint(unsigned short udpPort);
472 ~CUPnPControlPoint();
473 void Subscribe(CUPnPService &service);
474 void Unsubscribe(CUPnPService &service);
475 bool AddPortMappings(
476 std::vector<CUPnPPortMapping> &upnpPortMapping);
477 bool DeletePortMappings(
478 std::vector<CUPnPPortMapping> &upnpPortMapping);
480 UpnpClient_Handle GetUPnPClientHandle() const
481 { return m_UPnPClientHandle; }
483 bool GetIGWDeviceDetected() const
484 { return m_IGWDeviceDetected; }
485 void SetIGWDeviceDetected(bool b)
486 { m_IGWDeviceDetected = b; }
487 bool WanServiceDetected() const
488 { return !m_ServiceMap.empty(); }
489 void SetWanService(CUPnPService *service)
490 { m_WanService = service; }
492 // Callback function
493 static int Callback(
494 #if UPNP_VERSION >= 10800
495 Upnp_EventType_e EventType,
496 const void *Event,
497 void *Cookie);
498 #else
499 Upnp_EventType EventType,
500 void* Event,
501 void* Cookie);
502 #endif
504 private:
505 void OnEventReceived(
506 const std::string &Sid,
507 int EventKey,
508 IXML_Document *ChangedVariables);
509 void AddRootDevice(
510 IXML_Element *rootDevice,
511 const std::string &urlBase,
512 const char *location,
513 int expires);
514 void RemoveRootDevice(
515 const char *udn);
516 void RefreshPortMappings();
517 bool PrivateAddPortMapping(
518 CUPnPPortMapping &upnpPortMapping);
519 bool PrivateDeletePortMapping(
520 CUPnPPortMapping &upnpPortMapping);
524 #endif /* AMULE_UPNP_H */
526 // File_checked_for_headers