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
37 #include "UPnPCompatibility.h"
39 extern std::string stdEmptyString
;
43 * Case insensitive std::string comparison
45 bool stdStringIsEqualCI(
46 const std::string
&s1
,
47 const std::string
&s2
);
50 class CUPnPPortMapping
54 std::string m_protocol
;
55 std::string m_enabled
;
56 std::string m_description
;
62 const std::string
&protocol
= stdEmptyString
,
64 const std::string
&description
= stdEmptyString
);
65 ~CUPnPPortMapping() {}
67 const std::string
&getPort() const
69 const std::string
&getProtocol() const
70 { return m_protocol
; }
71 const std::string
&getEnabled() const
73 const std::string
&getDescription() const
74 { return m_description
; }
75 const std::string
&getKey() const
80 class CUPnPControlPoint
;
86 static const std::string
&UPNP_ROOT_DEVICE
;
87 static const std::string
&UPNP_DEVICE_IGW
;
88 static const std::string
&UPNP_DEVICE_WAN
;
89 static const std::string
&UPNP_DEVICE_WAN_CONNECTION
;
90 static const std::string
&UPNP_DEVICE_LAN
;
91 static const std::string
&UPNP_SERVICE_LAYER3_FORWARDING
;
92 static const std::string
&UPNP_SERVICE_WAN_COMMON_INTERFACE_CONFIG
;
93 static const std::string
&UPNP_SERVICE_WAN_IP_CONNECTION
;
94 static const std::string
&UPNP_SERVICE_WAN_PPP_CONNECTION
;
95 CUPnPControlPoint
&m_ctrlPoint
;
98 CUPnPLib(CUPnPControlPoint
&ctrlPoint
);
101 // Convenience function so we don't have to write explicit calls
102 // to char2unicode every time
103 std::string
GetUPnPErrorMessage(int code
) const;
105 // Convenience function to avoid repetitive processing of error
107 std::string
processUPnPErrorMessage(
108 const std::string
&messsage
,
110 const DOMString errorString
,
111 IXML_Document
*doc
) const;
113 // Processing response to actions
114 void ProcessActionResponse(
115 IXML_Document
*RespDoc
,
116 const std::string
&actionName
) const;
119 IXML_Element
*Element_GetRootElement(
120 IXML_Document
*doc
) const;
121 IXML_Element
*Element_GetFirstChild(
122 IXML_Element
*parent
) const;
123 IXML_Element
*Element_GetNextSibling(
124 IXML_Element
*child
) const;
125 const DOMString
Element_GetTag(
126 IXML_Element
*element
) const;
127 const std::string
Element_GetTextValue(
128 IXML_Element
*element
) const;
129 const std::string
Element_GetChildValueByTag(
130 IXML_Element
*element
,
131 const DOMString tag
) const;
132 IXML_Element
*Element_GetFirstChildByTag(
133 IXML_Element
*element
,
134 const DOMString tag
) const;
135 IXML_Element
*Element_GetNextSiblingByTag(
136 IXML_Element
*element
,
137 const DOMString tag
) const;
138 const std::string
Element_GetAttributeByTag(
139 IXML_Element
*element
,
140 const DOMString tag
) const;
144 class CUPnPControlPoint
;
147 * Even though we can retrieve the upnpLib handler from the upnpControlPoint,
148 * we must pass it separetly at this point, because the class CUPnPControlPoint
149 * must be declared after.
151 * CUPnPLib can only be removed from the constructor once we agree to link to
152 * UPnPLib explicitly, making this dlopen() stuff unnecessary.
154 template <typename T
, char const *XML_ELEMENT_NAME
, char const *XML_LIST_NAME
>
155 class CXML_List
: public std::map
<const std::string
, T
*>
159 const CUPnPControlPoint
&upnpControlPoint
,
161 IXML_Element
*parent
,
162 const std::string
&url
);
167 template <typename T
, char const *XML_ELEMENT_NAME
, char const *XML_LIST_NAME
>
168 CXML_List
<T
, XML_ELEMENT_NAME
, XML_LIST_NAME
>::CXML_List(
169 const CUPnPControlPoint
&upnpControlPoint
,
171 IXML_Element
*parent
,
172 const std::string
&url
)
174 IXML_Element
*elementList
=
175 upnpLib
.Element_GetFirstChildByTag(parent
, XML_LIST_NAME
);
177 for ( IXML_Element
*element
= upnpLib
.Element_GetFirstChildByTag(elementList
, XML_ELEMENT_NAME
);
179 element
= upnpLib
.Element_GetNextSiblingByTag(element
, XML_ELEMENT_NAME
)) {
180 // Add a new element to the element list
181 T
*upnpElement
= new T(upnpControlPoint
, upnpLib
, element
, url
);
182 (*this)[upnpElement
->GetKey()] = upnpElement
;
185 std::ostringstream msg
;
186 msg
<< "\n " << XML_LIST_NAME
<< ": " <<
187 i
<< " " << XML_ELEMENT_NAME
<< "s.";
188 AddDebugLogLineN(logUPnP
, msg
);
192 template <typename T
, char const *XML_ELEMENT_NAME
, char const *XML_LIST_NAME
>
193 CXML_List
<T
, XML_ELEMENT_NAME
, XML_LIST_NAME
>::~CXML_List()
195 typename CXML_List
<T
, XML_ELEMENT_NAME
, XML_LIST_NAME
>::iterator it
;
196 for(it
= this->begin(); it
!= this->end(); ++it
) {
201 extern const char s_argument
[];
202 extern const char s_argumentList
[];
203 extern const char s_action
[];
204 extern const char s_actionList
[];
205 extern const char s_allowedValue
[];
206 extern const char s_allowedValueList
[];
207 extern const char s_stateVariable
[];
208 extern const char s_serviceStateTable
[];
209 extern const char s_service
[];
210 extern const char s_serviceList
[];
211 extern const char s_device
[];
212 extern const char s_deviceList
[];
217 typedef CXML_List
<CUPnPArgument
, s_argument
, s_argumentList
> ArgumentList
;
219 typedef CXML_List
<CUPnPAction
, s_action
, s_actionList
> ActionList
;
220 class CUPnPStateVariable
;
221 typedef CXML_List
<CUPnPStateVariable
, s_stateVariable
, s_serviceStateTable
> ServiceStateTable
;
222 class CUPnPAllowedValue
;
223 typedef CXML_List
<CUPnPAllowedValue
, s_allowedValue
, s_allowedValueList
> AllowedValueList
;
225 typedef CXML_List
<CUPnPService
, s_service
, s_serviceList
> ServiceList
;
227 typedef CXML_List
<CUPnPDevice
, s_device
, s_deviceList
> DeviceList
;
233 IXML_Element
*m_root
;
234 const std::string m_ErrorCode
;
235 const std::string m_ErrorDescription
;
238 const CUPnPLib
&upnpLib
,
239 IXML_Document
*errorDoc
);
241 const std::string
&getErrorCode() const
242 { return m_ErrorCode
; }
243 const std::string
&getErrorDescription() const
244 { return m_ErrorDescription
; }
251 const CUPnPControlPoint
&m_UPnPControlPoint
;
252 const std::string m_name
;
253 const std::string m_direction
;
255 const std::string m_relatedStateVariable
;
259 const CUPnPControlPoint
&upnpControlPoint
,
261 IXML_Element
*argument
,
262 const std::string
&SCPDURL
);
264 const std::string
&GetName() const
266 const std::string
&GetDirection() const
267 { return m_direction
; }
268 bool GetRetVal() const
270 const std::string
&GetRelatedStateVariable() const
271 { return m_relatedStateVariable
; }
272 const std::string
&GetKey() const
281 const CUPnPControlPoint
&m_UPnPControlPoint
;
282 ArgumentList m_ArgumentList
;
283 const std::string m_name
;
287 const CUPnPControlPoint
&upnpControlPoint
,
289 IXML_Element
*action
,
290 const std::string
&SCPDURL
);
292 const std::string
&GetName() const
294 const std::string
&GetKey() const
296 const ArgumentList
&GetArgumentList() const
297 { return m_ArgumentList
; }
301 class CUPnPAllowedValue
304 const CUPnPControlPoint
&m_UPnPControlPoint
;
305 const std::string m_allowedValue
;
309 const CUPnPControlPoint
&upnpControlPoint
,
311 IXML_Element
*allowedValue
,
312 const std::string
&SCPDURL
);
313 ~CUPnPAllowedValue() {}
314 const std::string
&GetAllowedValue() const
315 { return m_allowedValue
; }
316 const std::string
&GetKey() const
317 { return m_allowedValue
; }
321 class CUPnPStateVariable
324 const CUPnPControlPoint
&m_UPnPControlPoint
;
325 AllowedValueList m_AllowedValueList
;
326 const std::string m_name
;
327 const std::string m_dataType
;
328 const std::string m_defaultValue
;
329 const std::string m_sendEvents
;
333 const CUPnPControlPoint
&upnpControlPoint
,
335 IXML_Element
*stateVariable
,
336 const std::string
&URLBase
);
337 ~CUPnPStateVariable() {}
338 const std::string
&GetNname() const
340 const std::string
&GetDataType() const
341 { return m_dataType
; }
342 const std::string
&GetDefaultValue() const
343 { return m_defaultValue
; }
344 const std::string
&GetKey() const
346 const AllowedValueList
&GetAllowedValueList() const
347 { return m_AllowedValueList
; }
354 const CUPnPControlPoint
&m_UPnPControlPoint
;
355 ActionList m_ActionList
;
356 ServiceStateTable m_ServiceStateTable
;
357 const std::string m_SCPDURL
;
361 const CUPnPControlPoint
&upnpControlPoint
,
364 const std::string
&SCPDURL
);
366 const ActionList
&GetActionList() const
367 { return m_ActionList
; }
368 const ServiceStateTable
&GetServiceStateTable() const
369 { return m_ServiceStateTable
; }
373 class CUPnPArgumentValue
376 std::string m_argument
;
380 CUPnPArgumentValue();
381 CUPnPArgumentValue(const std::string
&argument
, const std::string
&value
);
382 ~CUPnPArgumentValue() {}
384 const std::string
&GetArgument() const { return m_argument
; }
385 const std::string
&GetValue() const { return m_value
; }
386 const std::string
&SetArgument(const std::string
& argument
) { return m_argument
= argument
; }
387 const std::string
&SetValue(const std::string
&value
) { return m_value
= value
; }
394 const CUPnPControlPoint
&m_UPnPControlPoint
;
396 const std::string m_serviceType
;
397 const std::string m_serviceId
;
398 const std::string m_SCPDURL
;
399 const std::string m_controlURL
;
400 const std::string m_eventSubURL
;
401 std::string m_absSCPDURL
;
402 std::string m_absControlURL
;
403 std::string m_absEventSubURL
;
406 std::auto_ptr
<CUPnPSCPD
> m_SCPD
;
410 const CUPnPControlPoint
&upnpControlPoint
,
412 IXML_Element
*service
,
413 const std::string
&URLBase
);
416 const std::string
&GetServiceType() const
417 { return m_serviceType
; }
418 const std::string
&GetServiceId() const
419 { return m_serviceId
; }
420 const std::string
&GetSCPDURL() const
421 { return m_SCPDURL
; }
422 const std::string
&GetAbsSCPDURL() const
423 { return m_absSCPDURL
; }
424 const std::string
&GetControlURL() const
425 { return m_controlURL
; }
426 const std::string
&GetEventSubURL() const
427 { return m_eventSubURL
; }
428 const std::string
&GetAbsControlURL() const
429 { return m_absControlURL
; }
430 const std::string
&GetAbsEventSubURL() const
431 { return m_absEventSubURL
; }
432 int GetTimeout() const
433 { return m_timeout
; }
434 void SetTimeout(int t
)
436 int *GetTimeoutAddr()
437 { return &m_timeout
; }
440 void SetSID(const char *s
)
441 { memcpy(m_SID
, s
, sizeof(Upnp_SID
)); }
442 const std::string
&GetKey() const
443 { return m_serviceId
; }
444 bool IsSubscribed() const
445 { return m_SCPD
.get() != NULL
; }
446 void SetSCPD(CUPnPSCPD
*SCPD
)
447 { m_SCPD
.reset(SCPD
); }
450 const std::string
&ActionName
,
451 const std::vector
<CUPnPArgumentValue
> &ArgValue
) const;
452 const std::string
GetStateVariable(
453 const std::string
&stateVariableName
) const;
460 const CUPnPControlPoint
&m_UPnPControlPoint
;
462 // Please, lock these lists before use
463 DeviceList m_DeviceList
;
464 ServiceList m_ServiceList
;
466 const std::string m_deviceType
;
467 const std::string m_friendlyName
;
468 const std::string m_manufacturer
;
469 const std::string m_manufacturerURL
;
470 const std::string m_modelDescription
;
471 const std::string m_modelName
;
472 const std::string m_modelNumber
;
473 const std::string m_modelURL
;
474 const std::string m_serialNumber
;
475 const std::string m_UDN
;
476 const std::string m_UPC
;
477 std::string m_presentationURL
;
481 const CUPnPControlPoint
&upnpControlPoint
,
483 IXML_Element
*device
,
484 const std::string
&URLBase
);
487 const std::string
&GetUDN() const
489 const std::string
&GetDeviceType() const
490 { return m_deviceType
; }
491 const std::string
&GetFriendlyName() const
492 { return m_friendlyName
; }
493 const std::string
&GetPresentationURL() const
494 { return m_presentationURL
; }
495 const std::string
&GetKey() const
500 class CUPnPRootDevice
: public CUPnPDevice
503 const CUPnPControlPoint
&m_UPnPControlPoint
;
504 const std::string m_URLBase
;
505 const std::string m_location
;
510 const CUPnPControlPoint
&upnpControlPoint
,
512 IXML_Element
*rootDevice
,
513 const std::string
&OriginalURLBase
,
514 const std::string
&FixedURLBase
,
515 const char *location
,
517 ~CUPnPRootDevice() {}
519 const std::string
&GetURLBase() const
520 { return m_URLBase
; }
521 const std::string
&GetLocation() const
522 { return m_location
; }
523 int GetExpires() const
524 { return m_expires
; }
525 void SetExpires(int expires
)
526 { m_expires
= expires
; }
530 typedef std::map
<const std::string
, CUPnPRootDevice
*> RootDeviceMap
;
531 typedef std::map
<const std::string
, CUPnPService
*> ServiceMap
;
532 typedef std::map
<const std::string
, CUPnPPortMapping
> PortMappingMap
;
535 class CUPnPControlPoint
538 static CUPnPControlPoint
*s_CtrlPoint
;
541 UpnpClient_Handle m_UPnPClientHandle
;
542 RootDeviceMap m_RootDeviceMap
;
543 ServiceMap m_ServiceMap
;
544 PortMappingMap m_ActivePortMappingsMap
;
545 CUPnPMutex m_RootDeviceListMutex
;
546 bool m_IGWDeviceDetected
;
547 //#warning This variable is for testing purposes only and should disappear on release.
548 CUPnPService
*m_WanService
;
549 CUPnPMutex m_WaitForSearchTimeoutMutex
;
552 CUPnPControlPoint(unsigned short udpPort
);
553 ~CUPnPControlPoint();
554 void Subscribe(CUPnPService
&service
);
555 void Unsubscribe(CUPnPService
&service
);
556 bool AddPortMappings(
557 std::vector
<CUPnPPortMapping
> &upnpPortMapping
);
558 bool DeletePortMappings(
559 std::vector
<CUPnPPortMapping
> &upnpPortMapping
);
561 UpnpClient_Handle
GetUPnPClientHandle() const
562 { return m_UPnPClientHandle
; }
564 bool GetIGWDeviceDetected() const
565 { return m_IGWDeviceDetected
; }
566 void SetIGWDeviceDetected(bool b
)
567 { m_IGWDeviceDetected
= b
; }
568 bool WanServiceDetected() const
569 { return !m_ServiceMap
.empty(); }
570 void SetWanService(CUPnPService
*service
)
571 { m_WanService
= service
; }
575 Upnp_EventType EventType
,
580 void OnEventReceived(
581 const std::string
&Sid
,
583 IXML_Document
*ChangedVariables
);
585 IXML_Element
*rootDevice
,
586 const std::string
&urlBase
,
587 const char *location
,
589 void RemoveRootDevice(
591 void RefreshPortMappings();
592 bool PrivateAddPortMapping(
593 CUPnPPortMapping
&upnpPortMapping
);
594 bool PrivateDeletePortMapping(
595 CUPnPPortMapping
&upnpPortMapping
);
599 #endif /* AMULE_UPNP_H */
601 // File_checked_for_headers