2 // This file is part of the aMule Project.
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 )
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
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
36 #include "UPnPCompatibility.h"
38 #include <common/SmartPtr.h> // Needed for CSmartPtr
41 extern std::string stdEmptyString
;
44 class CUPnPPortMapping
48 std::string m_protocol
;
49 std::string m_enabled
;
50 std::string m_description
;
56 const std::string
&protocol
= stdEmptyString
,
58 const std::string
&description
= stdEmptyString
);
59 ~CUPnPPortMapping() {}
61 const std::string
&getPort() const
63 const std::string
&getProtocol() const
64 { return m_protocol
; }
65 const std::string
&getEnabled() const
67 const std::string
&getDescription() const
68 { return m_description
; }
69 const std::string
&getKey() const
77 IXML_Element
*GetRootElement(IXML_Document
*doc
);
78 void Free(IXML_Document
*doc
);
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
*>
101 const CUPnPControlPoint
&upnpControlPoint
,
102 IXML_Element
*parent
,
103 const std::string
&url
);
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
);
116 for ( IXML_Element
*element
= IXML::Element::GetFirstChildByTag(elementList
, XML_ELEMENT_NAME
);
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
;
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
) {
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
[];
156 typedef CXML_List
<CUPnPArgument
, s_argument
, s_argumentList
> ArgumentList
;
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
;
164 typedef CXML_List
<CUPnPService
, s_service
, s_serviceList
> ServiceList
;
166 typedef CXML_List
<CUPnPDevice
, s_device
, s_deviceList
> DeviceList
;
172 IXML_Element
*m_root
;
173 const std::string m_ErrorCode
;
174 const std::string m_ErrorDescription
;
176 CUPnPError(IXML_Document
*errorDoc
);
178 const std::string
&getErrorCode() const
179 { return m_ErrorCode
; }
180 const std::string
&getErrorDescription() const
181 { return m_ErrorDescription
; }
188 const std::string m_name
;
189 const std::string m_direction
;
191 const std::string m_relatedStateVariable
;
195 const CUPnPControlPoint
&upnpControlPoint
,
196 IXML_Element
*argument
,
197 const std::string
&SCPDURL
);
199 const std::string
&GetName() const
201 const std::string
&GetDirection() const
202 { return m_direction
; }
203 bool GetRetVal() const
205 const std::string
&GetRelatedStateVariable() const
206 { return m_relatedStateVariable
; }
207 const std::string
&GetKey() const
216 ArgumentList m_ArgumentList
;
217 const std::string m_name
;
221 const CUPnPControlPoint
&upnpControlPoint
,
222 IXML_Element
*action
,
223 const std::string
&SCPDURL
);
225 const std::string
&GetName() const
227 const std::string
&GetKey() const
229 const ArgumentList
&GetArgumentList() const
230 { return m_ArgumentList
; }
234 class CUPnPAllowedValue
237 const std::string m_allowedValue
;
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
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
;
263 const CUPnPControlPoint
&upnpControlPoint
,
264 IXML_Element
*stateVariable
,
265 const std::string
&URLBase
);
266 ~CUPnPStateVariable() {}
267 const std::string
&GetNname() const
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
275 const AllowedValueList
&GetAllowedValueList() const
276 { return m_AllowedValueList
; }
283 ActionList m_ActionList
;
284 ServiceStateTable m_ServiceStateTable
;
285 const std::string m_SCPDURL
;
289 const CUPnPControlPoint
&upnpControlPoint
,
291 const std::string
&SCPDURL
);
293 const ActionList
&GetActionList() const
294 { return m_ActionList
; }
295 const ServiceStateTable
&GetServiceStateTable() const
296 { return m_ServiceStateTable
; }
300 class CUPnPArgumentValue
303 std::string m_argument
;
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
; }
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
;
332 CSmartPtr
<CUPnPSCPD
> m_SCPD
;
336 const CUPnPControlPoint
&upnpControlPoint
,
337 IXML_Element
*service
,
338 const std::string
&URLBase
);
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
)
361 int *GetTimeoutAddr()
362 { return &m_timeout
; }
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
); }
375 const std::string
&ActionName
,
376 const std::vector
<CUPnPArgumentValue
> &ArgValue
) const;
377 const std::string
GetStateVariable(
378 const std::string
&stateVariableName
) const;
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
;
404 const CUPnPControlPoint
&upnpControlPoint
,
405 IXML_Element
*device
,
406 const std::string
&URLBase
);
409 const std::string
&GetUDN() const
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
422 class CUPnPRootDevice
: public CUPnPDevice
425 const std::string m_URLBase
;
426 const std::string m_location
;
431 const CUPnPControlPoint
&upnpControlPoint
,
432 IXML_Element
*rootDevice
,
433 const std::string
&OriginalURLBase
,
434 const std::string
&FixedURLBase
,
435 const char *location
,
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
458 static CUPnPControlPoint
*s_CtrlPoint
;
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
;
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
; }
494 #if UPNP_VERSION >= 10800
495 Upnp_EventType_e EventType
,
499 Upnp_EventType EventType
,
505 void OnEventReceived(
506 const std::string
&Sid
,
508 IXML_Document
*ChangedVariables
);
510 IXML_Element
*rootDevice
,
511 const std::string
&urlBase
,
512 const char *location
,
514 void RemoveRootDevice(
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