Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
7cfe1ace
Commit
7cfe1ace
authored
Apr 21, 2011
by
Konstantin Pavlov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
UPNP: Document some functions and prettify existing documentation.
parent
d03d1439
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
78 additions
and
34 deletions
+78
-34
modules/services_discovery/upnp.cpp
modules/services_discovery/upnp.cpp
+78
-34
No files found.
modules/services_discovery/upnp.cpp
View file @
7cfe1ace
...
@@ -39,11 +39,15 @@
...
@@ -39,11 +39,15 @@
#include <assert.h>
#include <assert.h>
// Constants
/*
* Constants
*/
const
char
*
MEDIA_SERVER_DEVICE_TYPE
=
"urn:schemas-upnp-org:device:MediaServer:1"
;
const
char
*
MEDIA_SERVER_DEVICE_TYPE
=
"urn:schemas-upnp-org:device:MediaServer:1"
;
const
char
*
CONTENT_DIRECTORY_SERVICE_TYPE
=
"urn:schemas-upnp-org:service:ContentDirectory:1"
;
const
char
*
CONTENT_DIRECTORY_SERVICE_TYPE
=
"urn:schemas-upnp-org:service:ContentDirectory:1"
;
// VLC handle
/*
* VLC handle
*/
struct
services_discovery_sys_t
struct
services_discovery_sys_t
{
{
UpnpClient_Handle
client_handle
;
UpnpClient_Handle
client_handle
;
...
@@ -51,13 +55,16 @@ struct services_discovery_sys_t
...
@@ -51,13 +55,16 @@ struct services_discovery_sys_t
vlc_mutex_t
callback_lock
;
vlc_mutex_t
callback_lock
;
};
};
// VLC callback prototypes
/*
* VLC callback prototypes
*/
static
int
Open
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
VLC_SD_PROBE_HELPER
(
"upnp"
,
"Universal Plug'n'Play"
,
SD_CAT_LAN
)
VLC_SD_PROBE_HELPER
(
"upnp"
,
"Universal Plug'n'Play"
,
SD_CAT_LAN
)
// Module descriptor
/*
* Module descriptor
*/
vlc_module_begin
();
vlc_module_begin
();
set_shortname
(
"UPnP"
);
set_shortname
(
"UPnP"
);
set_description
(
N_
(
"Universal Plug'n'Play"
)
);
set_description
(
N_
(
"Universal Plug'n'Play"
)
);
...
@@ -69,9 +76,9 @@ vlc_module_begin();
...
@@ -69,9 +76,9 @@ vlc_module_begin();
VLC_SD_PROBE_SUBMODULE
VLC_SD_PROBE_SUBMODULE
vlc_module_end
();
vlc_module_end
();
/*
// More prototypes...
* Local prototypes
*/
static
int
Callback
(
Upnp_EventType
event_type
,
void
*
p_event
,
void
*
p_user_data
);
static
int
Callback
(
Upnp_EventType
event_type
,
void
*
p_event
,
void
*
p_user_data
);
const
char
*
xml_getChildElementValue
(
IXML_Element
*
p_parent
,
const
char
*
xml_getChildElementValue
(
IXML_Element
*
p_parent
,
...
@@ -83,9 +90,9 @@ const char* xml_getChildElementAttributeValue( IXML_Element* p_parent,
...
@@ -83,9 +90,9 @@ const char* xml_getChildElementAttributeValue( IXML_Element* p_parent,
IXML_Document
*
parseBrowseResult
(
IXML_Document
*
p_doc
);
IXML_Document
*
parseBrowseResult
(
IXML_Document
*
p_doc
);
/*
// VLC callbacks..
.
* Initializes UPNP instance
.
*/
static
int
Open
(
vlc_object_t
*
p_this
)
static
int
Open
(
vlc_object_t
*
p_this
)
{
{
int
i_res
;
int
i_res
;
...
@@ -96,6 +103,9 @@ static int Open( vlc_object_t *p_this )
...
@@ -96,6 +103,9 @@ static int Open( vlc_object_t *p_this )
if
(
!
(
p_sd
->
p_sys
=
p_sys
)
)
if
(
!
(
p_sd
->
p_sys
=
p_sys
)
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
/* Initialize on first IPv4-capable adapter and first open port
* TODO: use UpnpInit2() to utilize IPv6.
*/
i_res
=
UpnpInit
(
0
,
0
);
i_res
=
UpnpInit
(
0
,
0
);
if
(
i_res
!=
UPNP_E_SUCCESS
)
if
(
i_res
!=
UPNP_E_SUCCESS
)
{
{
...
@@ -107,6 +117,7 @@ static int Open( vlc_object_t *p_this )
...
@@ -107,6 +117,7 @@ static int Open( vlc_object_t *p_this )
p_sys
->
p_server_list
=
new
MediaServerList
(
p_sd
);
p_sys
->
p_server_list
=
new
MediaServerList
(
p_sd
);
vlc_mutex_init
(
&
p_sys
->
callback_lock
);
vlc_mutex_init
(
&
p_sys
->
callback_lock
);
/* Register a control point */
i_res
=
UpnpRegisterClient
(
Callback
,
p_sd
,
&
p_sys
->
client_handle
);
i_res
=
UpnpRegisterClient
(
Callback
,
p_sd
,
&
p_sys
->
client_handle
);
if
(
i_res
!=
UPNP_E_SUCCESS
)
if
(
i_res
!=
UPNP_E_SUCCESS
)
{
{
...
@@ -115,6 +126,7 @@ static int Open( vlc_object_t *p_this )
...
@@ -115,6 +126,7 @@ static int Open( vlc_object_t *p_this )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
/* Search for media servers */
i_res
=
UpnpSearchAsync
(
p_sys
->
client_handle
,
5
,
i_res
=
UpnpSearchAsync
(
p_sys
->
client_handle
,
5
,
MEDIA_SERVER_DEVICE_TYPE
,
p_sd
);
MEDIA_SERVER_DEVICE_TYPE
,
p_sd
);
if
(
i_res
!=
UPNP_E_SUCCESS
)
if
(
i_res
!=
UPNP_E_SUCCESS
)
...
@@ -135,6 +147,9 @@ static int Open( vlc_object_t *p_this )
...
@@ -135,6 +147,9 @@ static int Open( vlc_object_t *p_this )
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
/*
* Releases resources.
*/
static
void
Close
(
vlc_object_t
*
p_this
)
static
void
Close
(
vlc_object_t
*
p_this
)
{
{
services_discovery_t
*
p_sd
=
(
services_discovery_t
*
)
p_this
;
services_discovery_t
*
p_sd
=
(
services_discovery_t
*
)
p_this
;
...
@@ -148,9 +163,11 @@ static void Close( vlc_object_t *p_this )
...
@@ -148,9 +163,11 @@ static void Close( vlc_object_t *p_this )
free
(
p_sd
->
p_sys
);
free
(
p_sd
->
p_sys
);
}
}
/
/ XML utility functions:
/
* XML utility functions */
// Returns the value of a child element, or 0 on error
/*
* Returns the value of a child element, or NULL on error
*/
const
char
*
xml_getChildElementValue
(
IXML_Element
*
p_parent
,
const
char
*
xml_getChildElementValue
(
IXML_Element
*
p_parent
,
const
char
*
psz_tag_name_
)
const
char
*
psz_tag_name_
)
{
{
...
@@ -170,6 +187,9 @@ const char* xml_getChildElementValue( IXML_Element* p_parent,
...
@@ -170,6 +187,9 @@ const char* xml_getChildElementValue( IXML_Element* p_parent,
return
ixmlNode_getNodeValue
(
p_text_node
);
return
ixmlNode_getNodeValue
(
p_text_node
);
}
}
/*
* Returns the value of a child element's attribute, or NULL on error
*/
const
char
*
xml_getChildElementAttributeValue
(
IXML_Element
*
p_parent
,
const
char
*
xml_getChildElementAttributeValue
(
IXML_Element
*
p_parent
,
const
char
*
psz_tag_name_
,
const
char
*
psz_tag_name_
,
const
char
*
psz_attribute_
)
const
char
*
psz_attribute_
)
...
@@ -188,7 +208,9 @@ const char* xml_getChildElementAttributeValue( IXML_Element* p_parent,
...
@@ -188,7 +208,9 @@ const char* xml_getChildElementAttributeValue( IXML_Element* p_parent,
return
ixmlElement_getAttribute
(
(
IXML_Element
*
)
p_element
,
psz_attribute_
);
return
ixmlElement_getAttribute
(
(
IXML_Element
*
)
p_element
,
psz_attribute_
);
}
}
// Extracts the result document from a SOAP response
/*
* Extracts the result document from a SOAP response
*/
IXML_Document
*
parseBrowseResult
(
IXML_Document
*
p_doc
)
IXML_Document
*
parseBrowseResult
(
IXML_Document
*
p_doc
)
{
{
ixmlRelaxParser
(
1
);
ixmlRelaxParser
(
1
);
...
@@ -217,7 +239,9 @@ IXML_Document* parseBrowseResult( IXML_Document* p_doc )
...
@@ -217,7 +239,9 @@ IXML_Document* parseBrowseResult( IXML_Document* p_doc )
}
}
// Handles all UPnP events
/*
* Handles all UPnP events
*/
static
int
Callback
(
Upnp_EventType
event_type
,
void
*
p_event
,
void
*
p_user_data
)
static
int
Callback
(
Upnp_EventType
event_type
,
void
*
p_event
,
void
*
p_user_data
)
{
{
services_discovery_t
*
p_sd
=
(
services_discovery_t
*
)
p_user_data
;
services_discovery_t
*
p_sd
=
(
services_discovery_t
*
)
p_user_data
;
...
@@ -271,7 +295,7 @@ static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data
...
@@ -271,7 +295,7 @@ static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data
case
UPNP_EVENT_AUTORENEWAL_FAILED
:
case
UPNP_EVENT_AUTORENEWAL_FAILED
:
case
UPNP_EVENT_SUBSCRIPTION_EXPIRED
:
case
UPNP_EVENT_SUBSCRIPTION_EXPIRED
:
{
{
/
/ Re-subscribe...
/
* Re-subscribe. */
Upnp_Event_Subscribe
*
p_s
=
(
Upnp_Event_Subscribe
*
)
p_event
;
Upnp_Event_Subscribe
*
p_s
=
(
Upnp_Event_Subscribe
*
)
p_event
;
...
@@ -297,9 +321,13 @@ static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data
...
@@ -297,9 +321,13 @@ static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data
}
}
// Class implementations...
/*
* Local class implementations.
*/
// MediaServer...
/*
* MediaServer
*/
void
MediaServer
::
parseDeviceDescription
(
IXML_Document
*
p_doc
,
void
MediaServer
::
parseDeviceDescription
(
IXML_Document
*
p_doc
,
const
char
*
p_location
,
const
char
*
p_location
,
...
@@ -319,7 +347,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
...
@@ -319,7 +347,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
const
char
*
psz_base_url
=
p_location
;
const
char
*
psz_base_url
=
p_location
;
/
/ Try to extract baseURL
/
* Try to extract baseURL */
IXML_NodeList
*
p_url_list
=
ixmlDocument_getElementsByTagName
(
p_doc
,
"baseURL"
);
IXML_NodeList
*
p_url_list
=
ixmlDocument_getElementsByTagName
(
p_doc
,
"baseURL"
);
if
(
p_url_list
)
if
(
p_url_list
)
{
{
...
@@ -333,7 +361,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
...
@@ -333,7 +361,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
ixmlNodeList_free
(
p_url_list
);
ixmlNodeList_free
(
p_url_list
);
}
}
/
/ Get devices
/
* Get devices */
IXML_NodeList
*
p_device_list
=
IXML_NodeList
*
p_device_list
=
ixmlDocument_getElementsByTagName
(
p_doc
,
"device"
);
ixmlDocument_getElementsByTagName
(
p_doc
,
"device"
);
...
@@ -362,7 +390,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
...
@@ -362,7 +390,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
continue
;
continue
;
}
}
/
/ Check if server is already added
/
* Check if server is already added */
if
(
p_sd
->
p_sys
->
p_server_list
->
getServer
(
psz_udn
)
!=
0
)
if
(
p_sd
->
p_sys
->
p_server_list
->
getServer
(
psz_udn
)
!=
0
)
{
{
msg_Warn
(
p_sd
,
"Server with uuid '%s' already exists."
,
psz_udn
);
msg_Warn
(
p_sd
,
"Server with uuid '%s' already exists."
,
psz_udn
);
...
@@ -388,7 +416,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
...
@@ -388,7 +416,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
continue
;
continue
;
}
}
/
/ Check for ContentDirectory service...
/
* Check for ContentDirectory service. */
IXML_NodeList
*
p_service_list
=
IXML_NodeList
*
p_service_list
=
ixmlElement_getElementsByTagName
(
p_device_element
,
ixmlElement_getElementsByTagName
(
p_device_element
,
"service"
);
"service"
);
...
@@ -431,7 +459,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
...
@@ -431,7 +459,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
continue
;
continue
;
}
}
/
/ Try to subscribe to ContentDirectory service
/
* Try to subscribe to ContentDirectory service */
char
*
psz_url
=
(
char
*
)
malloc
(
strlen
(
psz_base_url
)
+
char
*
psz_url
=
(
char
*
)
malloc
(
strlen
(
psz_base_url
)
+
strlen
(
psz_event_sub_url
)
+
1
);
strlen
(
psz_event_sub_url
)
+
1
);
...
@@ -447,7 +475,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
...
@@ -447,7 +475,7 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
free
(
psz_url
);
free
(
psz_url
);
}
}
/
/ Try to browse content directory...
/
* Try to browse content directory. */
psz_url
=
(
char
*
)
malloc
(
strlen
(
psz_base_url
)
+
psz_url
=
(
char
*
)
malloc
(
strlen
(
psz_base_url
)
+
strlen
(
psz_control_url
)
+
1
);
strlen
(
psz_control_url
)
+
1
);
...
@@ -518,6 +546,10 @@ const char* MediaServer::getContentDirectoryControlURL() const
...
@@ -518,6 +546,10 @@ const char* MediaServer::getContentDirectoryControlURL() const
return
_content_directory_control_url
.
c_str
();
return
_content_directory_control_url
.
c_str
();
}
}
/**
* Subscribes current client handle to Content Directory Service.
* CDS exports the server shares to clients.
*/
void
MediaServer
::
subscribeToContentDirectory
()
void
MediaServer
::
subscribeToContentDirectory
()
{
{
const
char
*
psz_url
=
getContentDirectoryEventURL
();
const
char
*
psz_url
=
getContentDirectoryEventURL
();
...
@@ -543,7 +575,9 @@ void MediaServer::subscribeToContentDirectory()
...
@@ -543,7 +575,9 @@ void MediaServer::subscribeToContentDirectory()
getFriendlyName
(),
UpnpGetErrorMessage
(
i_res
)
);
getFriendlyName
(),
UpnpGetErrorMessage
(
i_res
)
);
}
}
}
}
/*
* Constructs UpnpAction to browse available content.
*/
IXML_Document
*
MediaServer
::
_browseAction
(
const
char
*
psz_object_id_
,
IXML_Document
*
MediaServer
::
_browseAction
(
const
char
*
psz_object_id_
,
const
char
*
psz_browser_flag_
,
const
char
*
psz_browser_flag_
,
const
char
*
psz_filter_
,
const
char
*
psz_filter_
,
...
@@ -628,7 +662,7 @@ IXML_Document* MediaServer::_browseAction( const char* psz_object_id_,
...
@@ -628,7 +662,7 @@ IXML_Document* MediaServer::_browseAction( const char* psz_object_id_,
i_res
=
UpnpSendAction
(
_p_sd
->
p_sys
->
client_handle
,
i_res
=
UpnpSendAction
(
_p_sd
->
p_sys
->
client_handle
,
psz_url
,
psz_url
,
psz_service_type
,
psz_service_type
,
0
,
/
/ ignored in SDK, must be NULL
0
,
/
* ignored in SDK, must be NULL */
p_action
,
p_action
,
&
p_response
);
&
p_response
);
...
@@ -651,7 +685,7 @@ browseActionCleanup:
...
@@ -651,7 +685,7 @@ browseActionCleanup:
void
MediaServer
::
fetchContents
()
void
MediaServer
::
fetchContents
()
{
{
/
/ Delete previous contents to prevent duplicate entries
/
* Delete previous contents to prevent duplicate entries */
if
(
_p_contents
)
if
(
_p_contents
)
{
{
delete
_p_contents
;
delete
_p_contents
;
...
@@ -669,6 +703,9 @@ void MediaServer::fetchContents()
...
@@ -669,6 +703,9 @@ void MediaServer::fetchContents()
_buildPlaylist
(
_p_contents
,
NULL
);
_buildPlaylist
(
_p_contents
,
NULL
);
}
}
/*
* Fetches and parses the UPNP response
*/
bool
MediaServer
::
_fetchContents
(
Container
*
p_parent
)
bool
MediaServer
::
_fetchContents
(
Container
*
p_parent
)
{
{
if
(
!
p_parent
)
if
(
!
p_parent
)
...
@@ -839,6 +876,10 @@ bool MediaServer::_fetchContents( Container* p_parent )
...
@@ -839,6 +876,10 @@ bool MediaServer::_fetchContents( Container* p_parent )
// do not exist in the new directory listing, then remove them from the shown listing using
// do not exist in the new directory listing, then remove them from the shown listing using
// services_discovery_RemoveItem. If new files were introduced within an already existing
// services_discovery_RemoveItem. If new files were introduced within an already existing
// container, we could simply do so with services_discovery_AddItem.
// container, we could simply do so with services_discovery_AddItem.
/*
* Builds playlist based on available input items.
*/
void
MediaServer
::
_buildPlaylist
(
Container
*
p_parent
,
input_item_node_t
*
p_input_node
)
void
MediaServer
::
_buildPlaylist
(
Container
*
p_parent
,
input_item_node_t
*
p_input_node
)
{
{
bool
b_send
=
p_input_node
==
NULL
;
bool
b_send
=
p_input_node
==
NULL
;
...
@@ -902,8 +943,9 @@ bool MediaServer::compareSID( const char* psz_sid )
...
@@ -902,8 +943,9 @@ bool MediaServer::compareSID( const char* psz_sid )
}
}
// MediaServerList...
/*
* MediaServerList class
*/
MediaServerList
::
MediaServerList
(
services_discovery_t
*
p_sd
)
MediaServerList
::
MediaServerList
(
services_discovery_t
*
p_sd
)
{
{
_p_sd
=
p_sd
;
_p_sd
=
p_sd
;
...
@@ -989,8 +1031,9 @@ void MediaServerList::removeServer( const char* psz_udn )
...
@@ -989,8 +1031,9 @@ void MediaServerList::removeServer( const char* psz_udn )
}
}
// Item...
/*
* Item class
*/
Item
::
Item
(
Container
*
p_parent
,
const
char
*
psz_object_id
,
const
char
*
psz_title
,
Item
::
Item
(
Container
*
p_parent
,
const
char
*
psz_object_id
,
const
char
*
psz_title
,
const
char
*
psz_resource
,
mtime_t
i_duration
)
const
char
*
psz_resource
,
mtime_t
i_duration
)
{
{
...
@@ -1042,8 +1085,9 @@ void Item::setInputItem( input_item_t* p_input_item )
...
@@ -1042,8 +1085,9 @@ void Item::setInputItem( input_item_t* p_input_item )
_p_input_item
=
p_input_item
;
_p_input_item
=
p_input_item
;
}
}
// Container...
/*
* Container class
*/
Container
::
Container
(
Container
*
p_parent
,
Container
::
Container
(
Container
*
p_parent
,
const
char
*
psz_object_id
,
const
char
*
psz_object_id
,
const
char
*
psz_title
)
const
char
*
psz_title
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment