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"
41 std::string stdEmptyString
;
43 extern std::string stdEmptyString
;
48 * Case insensitive std::string comparison
50 bool stdStringIsEqualCI(
51 const std::string
&s1
,
52 const std::string
&s2
);
55 class CUPnPPortMapping
59 std::string m_protocol
;
60 std::string m_enabled
;
61 std::string m_description
;
67 const std::string
&protocol
= stdEmptyString
,
69 const std::string
&description
= stdEmptyString
);
70 ~CUPnPPortMapping() {}
72 const std::string
&getPort() const
74 const std::string
&getProtocol() const
75 { return m_protocol
; }
76 const std::string
&getEnabled() const
78 const std::string
&getDescription() const
79 { return m_description
; }
80 const std::string
&getKey() const
85 class CUPnPControlPoint
;
91 static const std::string
&UPNP_ROOT_DEVICE
;
92 static const std::string
&UPNP_DEVICE_IGW
;
93 static const std::string
&UPNP_DEVICE_WAN
;
94 static const std::string
&UPNP_DEVICE_WAN_CONNECTION
;
95 static const std::string
&UPNP_DEVICE_LAN
;
96 static const std::string
&UPNP_SERVICE_LAYER3_FORWARDING
;
97 static const std::string
&UPNP_SERVICE_WAN_COMMON_INTERFACE_CONFIG
;
98 static const std::string
&UPNP_SERVICE_WAN_IP_CONNECTION
;
99 static const std::string
&UPNP_SERVICE_WAN_PPP_CONNECTION
;
100 CUPnPControlPoint
&m_ctrlPoint
;
103 CUPnPLib(CUPnPControlPoint
&ctrlPoint
);
106 // Convenience function so we don't have to write explicit calls
107 // to char2unicode every time
108 std::string
GetUPnPErrorMessage(int code
) const;
110 // Convenience function to avoid repetitive processing of error
112 std::string
processUPnPErrorMessage(
113 const std::string
&messsage
,
115 const DOMString errorString
,
116 IXML_Document
*doc
) const;
118 // Processing response to actions
119 void ProcessActionResponse(
120 IXML_Document
*RespDoc
,
121 const std::string
&actionName
) const;
124 IXML_Element
*Element_GetRootElement(
125 IXML_Document
*doc
) const;
126 IXML_Element
*Element_GetFirstChild(
127 IXML_Element
*parent
) const;
128 IXML_Element
*Element_GetNextSibling(
129 IXML_Element
*child
) const;
130 const DOMString
Element_GetTag(
131 IXML_Element
*element
) const;
132 const std::string
Element_GetTextValue(
133 IXML_Element
*element
) const;
134 const std::string
Element_GetChildValueByTag(
135 IXML_Element
*element
,
136 const DOMString tag
) const;
137 IXML_Element
*Element_GetFirstChildByTag(
138 IXML_Element
*element
,
139 const DOMString tag
) const;
140 IXML_Element
*Element_GetNextSiblingByTag(
141 IXML_Element
*element
,
142 const DOMString tag
) const;
143 const std::string
Element_GetAttributeByTag(
144 IXML_Element
*element
,
145 const DOMString tag
) const;
149 class CUPnPControlPoint
;
152 * Even though we can retrieve the upnpLib handler from the upnpControlPoint,
153 * we must pass it separetly at this point, because the class CUPnPControlPoint
154 * must be declared after.
156 * CUPnPLib can only be removed from the constructor once we agree to link to
157 * UPnPLib explicitly, making this dlopen() stuff unnecessary.
159 template <typename T
, char const *XML_ELEMENT_NAME
, char const *XML_LIST_NAME
>
160 class CXML_List
: public std::map
<const std::string
, T
*>
164 const CUPnPControlPoint
&upnpControlPoint
,
166 IXML_Element
*parent
,
167 const std::string
&url
);
172 template <typename T
, char const *XML_ELEMENT_NAME
, char const *XML_LIST_NAME
>
173 CXML_List
<T
, XML_ELEMENT_NAME
, XML_LIST_NAME
>::CXML_List(
174 const CUPnPControlPoint
&upnpControlPoint
,
176 IXML_Element
*parent
,
177 const std::string
&url
)
179 IXML_Element
*elementList
=
180 upnpLib
.Element_GetFirstChildByTag(parent
, XML_LIST_NAME
);
182 for ( IXML_Element
*element
= upnpLib
.Element_GetFirstChildByTag(elementList
, XML_ELEMENT_NAME
);
184 element
= upnpLib
.Element_GetNextSiblingByTag(element
, XML_ELEMENT_NAME
)) {
185 // Add a new element to the element list
186 T
*upnpElement
= new T(upnpControlPoint
, upnpLib
, element
, url
);
187 (*this)[upnpElement
->GetKey()] = upnpElement
;
190 std::ostringstream msg
;
191 msg
<< "\n " << XML_LIST_NAME
<< ": " <<
192 i
<< " " << XML_ELEMENT_NAME
<< "s.";
193 AddDebugLogLineN(logUPnP
, msg
);
197 template <typename T
, char const *XML_ELEMENT_NAME
, char const *XML_LIST_NAME
>
198 CXML_List
<T
, XML_ELEMENT_NAME
, XML_LIST_NAME
>::~CXML_List()
200 typename CXML_List
<T
, XML_ELEMENT_NAME
, XML_LIST_NAME
>::iterator it
;
201 for(it
= this->begin(); it
!= this->end(); ++it
) {
206 extern const char s_argument
[];
207 extern const char s_argumentList
[];
208 extern const char s_action
[];
209 extern const char s_actionList
[];
210 extern const char s_allowedValue
[];
211 extern const char s_allowedValueList
[];
212 extern const char s_stateVariable
[];
213 extern const char s_serviceStateTable
[];
214 extern const char s_service
[];
215 extern const char s_serviceList
[];
216 extern const char s_device
[];
217 extern const char s_deviceList
[];
220 const char s_argument
[] = "argument";
221 const char s_argumentList
[] = "argumentList";
222 const char s_action
[] = "action";
223 const char s_actionList
[] = "actionList";
224 const char s_allowedValue
[] = "allowedValue";
225 const char s_allowedValueList
[] = "allowedValueList";
226 const char s_stateVariable
[] = "stateVariable";
227 const char s_serviceStateTable
[] = "serviceStateTable";
228 const char s_service
[] = "service";
229 const char s_serviceList
[] = "serviceList";
230 const char s_device
[] = "device";
231 const char s_deviceList
[] = "deviceList";
236 typedef CXML_List
<CUPnPArgument
, s_argument
, s_argumentList
> ArgumentList
;
238 typedef CXML_List
<CUPnPAction
, s_action
, s_actionList
> ActionList
;
239 class CUPnPStateVariable
;
240 typedef CXML_List
<CUPnPStateVariable
, s_stateVariable
, s_serviceStateTable
> ServiceStateTable
;
241 class CUPnPAllowedValue
;
242 typedef CXML_List
<CUPnPAllowedValue
, s_allowedValue
, s_allowedValueList
> AllowedValueList
;
244 typedef CXML_List
<CUPnPService
, s_service
, s_serviceList
> ServiceList
;
246 typedef CXML_List
<CUPnPDevice
, s_device
, s_deviceList
> DeviceList
;
252 IXML_Element
*m_root
;
253 const std::string m_ErrorCode
;
254 const std::string m_ErrorDescription
;
257 const CUPnPLib
&upnpLib
,
258 IXML_Document
*errorDoc
);
260 const std::string
&getErrorCode() const
261 { return m_ErrorCode
; }
262 const std::string
&getErrorDescription() const
263 { return m_ErrorDescription
; }
270 const CUPnPControlPoint
&m_UPnPControlPoint
;
271 const std::string m_name
;
272 const std::string m_direction
;
274 const std::string m_relatedStateVariable
;
278 const CUPnPControlPoint
&upnpControlPoint
,
280 IXML_Element
*argument
,
281 const std::string
&SCPDURL
);
283 const std::string
&GetName() const
285 const std::string
&GetDirection() const
286 { return m_direction
; }
287 bool GetRetVal() const
289 const std::string
&GetRelatedStateVariable() const
290 { return m_relatedStateVariable
; }
291 const std::string
&GetKey() const
300 const CUPnPControlPoint
&m_UPnPControlPoint
;
301 ArgumentList m_ArgumentList
;
302 const std::string m_name
;
306 const CUPnPControlPoint
&upnpControlPoint
,
308 IXML_Element
*action
,
309 const std::string
&SCPDURL
);
311 const std::string
&GetName() const
313 const std::string
&GetKey() const
315 const ArgumentList
&GetArgumentList() const
316 { return m_ArgumentList
; }
320 class CUPnPAllowedValue
323 const CUPnPControlPoint
&m_UPnPControlPoint
;
324 const std::string m_allowedValue
;
328 const CUPnPControlPoint
&upnpControlPoint
,
330 IXML_Element
*allowedValue
,
331 const std::string
&SCPDURL
);
332 ~CUPnPAllowedValue() {}
333 const std::string
&GetAllowedValue() const
334 { return m_allowedValue
; }
335 const std::string
&GetKey() const
336 { return m_allowedValue
; }
340 class CUPnPStateVariable
343 const CUPnPControlPoint
&m_UPnPControlPoint
;
344 AllowedValueList m_AllowedValueList
;
345 const std::string m_name
;
346 const std::string m_dataType
;
347 const std::string m_defaultValue
;
348 const std::string m_sendEvents
;
352 const CUPnPControlPoint
&upnpControlPoint
,
354 IXML_Element
*stateVariable
,
355 const std::string
&URLBase
);
356 ~CUPnPStateVariable() {}
357 const std::string
&GetNname() const
359 const std::string
&GetDataType() const
360 { return m_dataType
; }
361 const std::string
&GetDefaultValue() const
362 { return m_defaultValue
; }
363 const std::string
&GetKey() const
365 const AllowedValueList
&GetAllowedValueList() const
366 { return m_AllowedValueList
; }
373 const CUPnPControlPoint
&m_UPnPControlPoint
;
374 ActionList m_ActionList
;
375 ServiceStateTable m_ServiceStateTable
;
376 const std::string m_SCPDURL
;
380 const CUPnPControlPoint
&upnpControlPoint
,
383 const std::string
&SCPDURL
);
385 const ActionList
&GetActionList() const
386 { return m_ActionList
; }
387 const ServiceStateTable
&GetServiceStateTable() const
388 { return m_ServiceStateTable
; }
392 class CUPnPArgumentValue
395 std::string m_argument
;
399 CUPnPArgumentValue();
400 CUPnPArgumentValue(const std::string
&argument
, const std::string
&value
);
401 ~CUPnPArgumentValue() {}
403 const std::string
&GetArgument() const { return m_argument
; }
404 const std::string
&GetValue() const { return m_value
; }
405 const std::string
&SetArgument(const std::string
& argument
) { return m_argument
= argument
; }
406 const std::string
&SetValue(const std::string
&value
) { return m_value
= value
; }
413 const CUPnPControlPoint
&m_UPnPControlPoint
;
415 const std::string m_serviceType
;
416 const std::string m_serviceId
;
417 const std::string m_SCPDURL
;
418 const std::string m_controlURL
;
419 const std::string m_eventSubURL
;
420 std::string m_absSCPDURL
;
421 std::string m_absControlURL
;
422 std::string m_absEventSubURL
;
425 std::auto_ptr
<CUPnPSCPD
> m_SCPD
;
429 const CUPnPControlPoint
&upnpControlPoint
,
431 IXML_Element
*service
,
432 const std::string
&URLBase
);
435 const std::string
&GetServiceType() const
436 { return m_serviceType
; }
437 const std::string
&GetServiceId() const
438 { return m_serviceId
; }
439 const std::string
&GetSCPDURL() const
440 { return m_SCPDURL
; }
441 const std::string
&GetAbsSCPDURL() const
442 { return m_absSCPDURL
; }
443 const std::string
&GetControlURL() const
444 { return m_controlURL
; }
445 const std::string
&GetEventSubURL() const
446 { return m_eventSubURL
; }
447 const std::string
&GetAbsControlURL() const
448 { return m_absControlURL
; }
449 const std::string
&GetAbsEventSubURL() const
450 { return m_absEventSubURL
; }
451 int GetTimeout() const
452 { return m_timeout
; }
453 void SetTimeout(int t
)
455 int *GetTimeoutAddr()
456 { return &m_timeout
; }
459 void SetSID(const char *s
)
460 { memcpy(m_SID
, s
, sizeof(Upnp_SID
)); }
461 const std::string
&GetKey() const
462 { return m_serviceId
; }
463 bool IsSubscribed() const
464 { return m_SCPD
.get() != NULL
; }
465 void SetSCPD(CUPnPSCPD
*SCPD
)
466 { m_SCPD
.reset(SCPD
); }
469 const std::string
&ActionName
,
470 const std::vector
<CUPnPArgumentValue
> &ArgValue
) const;
471 const std::string
GetStateVariable(
472 const std::string
&stateVariableName
) const;
479 const CUPnPControlPoint
&m_UPnPControlPoint
;
481 // Please, lock these lists before use
482 DeviceList m_DeviceList
;
483 ServiceList m_ServiceList
;
485 const std::string m_deviceType
;
486 const std::string m_friendlyName
;
487 const std::string m_manufacturer
;
488 const std::string m_manufacturerURL
;
489 const std::string m_modelDescription
;
490 const std::string m_modelName
;
491 const std::string m_modelNumber
;
492 const std::string m_modelURL
;
493 const std::string m_serialNumber
;
494 const std::string m_UDN
;
495 const std::string m_UPC
;
496 std::string m_presentationURL
;
500 const CUPnPControlPoint
&upnpControlPoint
,
502 IXML_Element
*device
,
503 const std::string
&URLBase
);
506 const std::string
&GetUDN() const
508 const std::string
&GetDeviceType() const
509 { return m_deviceType
; }
510 const std::string
&GetFriendlyName() const
511 { return m_friendlyName
; }
512 const std::string
&GetPresentationURL() const
513 { return m_presentationURL
; }
514 const std::string
&GetKey() const
519 class CUPnPRootDevice
: public CUPnPDevice
522 const CUPnPControlPoint
&m_UPnPControlPoint
;
523 const std::string m_URLBase
;
524 const std::string m_location
;
529 const CUPnPControlPoint
&upnpControlPoint
,
531 IXML_Element
*rootDevice
,
532 const std::string
&OriginalURLBase
,
533 const std::string
&FixedURLBase
,
534 const char *location
,
536 ~CUPnPRootDevice() {}
538 const std::string
&GetURLBase() const
539 { return m_URLBase
; }
540 const std::string
&GetLocation() const
541 { return m_location
; }
542 int GetExpires() const
543 { return m_expires
; }
544 void SetExpires(int expires
)
545 { m_expires
= expires
; }
549 typedef std::map
<const std::string
, CUPnPRootDevice
*> RootDeviceMap
;
550 typedef std::map
<const std::string
, CUPnPService
*> ServiceMap
;
551 typedef std::map
<const std::string
, CUPnPPortMapping
> PortMappingMap
;
554 class CUPnPControlPoint
557 static CUPnPControlPoint
*s_CtrlPoint
;
560 UpnpClient_Handle m_UPnPClientHandle
;
561 RootDeviceMap m_RootDeviceMap
;
562 ServiceMap m_ServiceMap
;
563 PortMappingMap m_ActivePortMappingsMap
;
564 CUPnPMutex m_RootDeviceListMutex
;
565 bool m_IGWDeviceDetected
;
566 //#warning This variable is for testing purposes only and should disappear on release.
567 CUPnPService
*m_WanService
;
568 CUPnPMutex m_WaitForSearchTimeoutMutex
;
571 CUPnPControlPoint(unsigned short udpPort
);
572 ~CUPnPControlPoint();
573 void Subscribe(CUPnPService
&service
);
574 void Unsubscribe(CUPnPService
&service
);
575 bool AddPortMappings(
576 std::vector
<CUPnPPortMapping
> &upnpPortMapping
);
577 bool DeletePortMappings(
578 std::vector
<CUPnPPortMapping
> &upnpPortMapping
);
580 UpnpClient_Handle
GetUPnPClientHandle() const
581 { return m_UPnPClientHandle
; }
583 bool GetIGWDeviceDetected() const
584 { return m_IGWDeviceDetected
; }
585 void SetIGWDeviceDetected(bool b
)
586 { m_IGWDeviceDetected
= b
; }
587 bool WanServiceDetected() const
588 { return !m_ServiceMap
.empty(); }
589 void SetWanService(CUPnPService
*service
)
590 { m_WanService
= service
; }
594 Upnp_EventType EventType
,
599 void OnEventReceived(
600 const std::string
&Sid
,
602 IXML_Document
*ChangedVariables
);
604 IXML_Element
*rootDevice
,
605 const std::string
&urlBase
,
606 const char *location
,
608 void RemoveRootDevice(
610 void RefreshPortMappings();
611 bool PrivateAddPortMapping(
612 CUPnPPortMapping
&upnpPortMapping
);
613 bool PrivateDeletePortMapping(
614 CUPnPPortMapping
&upnpPortMapping
);
618 #endif /* AMULE_UPNP_H */
620 // File_checked_for_headers