Commit 375de459 authored by Austin Burrow's avatar Austin Burrow Committed by Konstantin Pavlov

Fixed the directory duplication bug in UPnP SD Client module and cleaned code.

Signed-off-by: default avatarKonstantin Pavlov <thresh@videolan.org>
parent 1e3e7a85
...@@ -319,7 +319,6 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc, ...@@ -319,7 +319,6 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
} }
// Get devices // Get devices
IXML_NodeList* p_device_list = IXML_NodeList* p_device_list =
ixmlDocument_getElementsByTagName( p_doc, "device" ); ixmlDocument_getElementsByTagName( p_doc, "device" );
...@@ -351,8 +350,13 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc, ...@@ -351,8 +350,13 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
continue; continue;
} }
// 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_Dbg( p_sd, "%s:%d: server already exists.",
__FILE__, __LINE__ );
continue; continue;
}
const char* psz_friendly_name = const char* psz_friendly_name =
xml_getChildElementValue( p_device_element, xml_getChildElementValue( p_device_element,
...@@ -368,7 +372,6 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc, ...@@ -368,7 +372,6 @@ void MediaServer::parseDeviceDescription( IXML_Document* p_doc,
if ( !p_sd->p_sys->p_server_list->addServer( p_server ) ) if ( !p_sd->p_sys->p_server_list->addServer( p_server ) )
{ {
delete p_server; delete p_server;
p_server = 0; p_server = 0;
continue; continue;
...@@ -464,54 +467,51 @@ MediaServer::MediaServer( const char* psz_udn, ...@@ -464,54 +467,51 @@ MediaServer::MediaServer( const char* psz_udn,
_p_sd = p_sd; _p_sd = p_sd;
_UDN = psz_udn; _UDN = psz_udn;
_friendlyName = psz_friendly_name; _friendly_name = psz_friendly_name;
_contents = NULL; _p_contents = NULL;
_inputItem = NULL; _p_input_item = NULL;
} }
MediaServer::~MediaServer() MediaServer::~MediaServer()
{ {
delete _contents; delete _p_contents;
} }
const char* MediaServer::getUDN() const const char* MediaServer::getUDN() const
{ {
const char* s = _UDN.c_str(); return _UDN.c_str();
return s;
} }
const char* MediaServer::getFriendlyName() const const char* MediaServer::getFriendlyName() const
{ {
const char* s = _friendlyName.c_str(); return _friendly_name.c_str();
return s;
} }
void MediaServer::setContentDirectoryEventURL( const char* psz_url ) void MediaServer::setContentDirectoryEventURL( const char* psz_url )
{ {
_contentDirectoryEventURL = psz_url; _content_directory_event_url = psz_url;
} }
const char* MediaServer::getContentDirectoryEventURL() const const char* MediaServer::getContentDirectoryEventURL() const
{ {
const char* s = _contentDirectoryEventURL.c_str(); return _content_directory_event_url.c_str();
return s;
} }
void MediaServer::setContentDirectoryControlURL( const char* psz_url ) void MediaServer::setContentDirectoryControlURL( const char* psz_url )
{ {
_contentDirectoryControlURL = psz_url; _content_directory_control_url = psz_url;
} }
const char* MediaServer::getContentDirectoryControlURL() const const char* MediaServer::getContentDirectoryControlURL() const
{ {
return _contentDirectoryControlURL.c_str(); return _content_directory_control_url.c_str();
} }
void MediaServer::subscribeToContentDirectory() void MediaServer::subscribeToContentDirectory()
{ {
const char* psz_url = getContentDirectoryEventURL(); const char* psz_url = getContentDirectoryEventURL();
if ( !psz_url || strcmp( psz_url, "" ) == 0 ) if ( !psz_url )
{ {
msg_Dbg( _p_sd, "No subscription url set!" ); msg_Dbg( _p_sd, "No subscription url set!" );
return; return;
...@@ -524,8 +524,8 @@ void MediaServer::subscribeToContentDirectory() ...@@ -524,8 +524,8 @@ void MediaServer::subscribeToContentDirectory()
if ( i_res == UPNP_E_SUCCESS ) if ( i_res == UPNP_E_SUCCESS )
{ {
_subscriptionTimeOut = i_timeout; _i_subscription_timeout = i_timeout;
memcpy( _subscriptionID, sid, sizeof( Upnp_SID ) ); memcpy( _subscription_id, sid, sizeof( Upnp_SID ) );
} }
else else
{ {
...@@ -546,7 +546,7 @@ IXML_Document* MediaServer::_browseAction( const char* psz_object_id_, ...@@ -546,7 +546,7 @@ IXML_Document* MediaServer::_browseAction( const char* psz_object_id_,
IXML_Document* p_response = 0; IXML_Document* p_response = 0;
const char* psz_url = getContentDirectoryControlURL(); const char* psz_url = getContentDirectoryControlURL();
if ( !psz_url || strcmp( psz_url, "" ) == 0 ) if ( !psz_url )
{ {
msg_Dbg( _p_sd, "No subscription url set!" ); msg_Dbg( _p_sd, "No subscription url set!" );
return 0; return 0;
...@@ -661,13 +661,22 @@ IXML_Document* MediaServer::_browseAction( const char* psz_object_id_, ...@@ -661,13 +661,22 @@ IXML_Document* MediaServer::_browseAction( const char* psz_object_id_,
void MediaServer::fetchContents() void MediaServer::fetchContents()
{ {
// Delete previous contents to prevent duplicate entries
if ( _p_contents )
{
delete _p_contents;
services_discovery_RemoveItem( _p_sd, _p_input_item );
services_discovery_AddItem( _p_sd, _p_input_item, NULL );
}
Container* root = new Container( 0, "0", getFriendlyName() ); Container* root = new Container( 0, "0", getFriendlyName() );
_fetchContents( root ); _fetchContents( root );
_contents = root; _p_contents = root;
_contents->setInputItem( _inputItem ); _p_contents->setInputItem( _p_input_item );
_buildPlaylist( _contents, NULL ); _buildPlaylist( _p_contents, NULL );
} }
bool MediaServer::_fetchContents( Container* p_parent ) bool MediaServer::_fetchContents( Container* p_parent )
...@@ -690,19 +699,18 @@ bool MediaServer::_fetchContents( Container* p_parent ) ...@@ -690,19 +699,18 @@ bool MediaServer::_fetchContents( Container* p_parent )
return false; return false;
} }
IXML_Document* result = parseBrowseResult( p_response ); IXML_Document* p_result = parseBrowseResult( p_response );
ixmlDocument_free( p_response ); ixmlDocument_free( p_response );
if ( !result ) if ( !p_result )
{ {
msg_Dbg( _p_sd, msg_Dbg( _p_sd, "%s:%d: ERROR! browse() response parsing failed",
"%s:%d: ERROR! browse() response parsing failed",
__FILE__, __LINE__ ); __FILE__, __LINE__ );
return false; return false;
} }
IXML_NodeList* containerNodeList = IXML_NodeList* containerNodeList =
ixmlDocument_getElementsByTagName( result, "container" ); ixmlDocument_getElementsByTagName( p_result, "container" );
if ( containerNodeList ) if ( containerNodeList )
{ {
...@@ -751,7 +759,7 @@ bool MediaServer::_fetchContents( Container* p_parent ) ...@@ -751,7 +759,7 @@ bool MediaServer::_fetchContents( Container* p_parent )
ixmlNodeList_free( containerNodeList ); ixmlNodeList_free( containerNodeList );
} }
IXML_NodeList* itemNodeList = ixmlDocument_getElementsByTagName( result, IXML_NodeList* itemNodeList = ixmlDocument_getElementsByTagName( p_result,
"item" ); "item" );
if ( itemNodeList ) if ( itemNodeList )
{ {
...@@ -784,59 +792,60 @@ bool MediaServer::_fetchContents( Container* p_parent ) ...@@ -784,59 +792,60 @@ bool MediaServer::_fetchContents( Container* p_parent )
ixmlNodeList_free( itemNodeList ); ixmlNodeList_free( itemNodeList );
} }
ixmlDocument_free( result ); ixmlDocument_free( p_result );
return true; return true;
} }
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 send = p_input_node == NULL; bool b_send = p_input_node == NULL;
if( send ) if( b_send )
p_input_node = input_item_node_Create( p_parent->getInputItem() ); p_input_node = input_item_node_Create( p_parent->getInputItem() );
for ( unsigned int i = 0; i < p_parent->getNumContainers(); i++ ) for ( unsigned int i = 0; i < p_parent->getNumContainers(); i++ )
{ {
Container* container = p_parent->getContainer( i ); Container* p_container = p_parent->getContainer( i );
input_item_t* p_input_item = input_item_New( _p_sd, "vlc://nop", container->getTitle() ); input_item_t* p_input_item = input_item_New( _p_sd, "vlc://nop",
p_container->getTitle() );
input_item_node_t *p_new_node = input_item_node_t *p_new_node =
input_item_node_AppendItem( p_input_node, p_input_item ); input_item_node_AppendItem( p_input_node, p_input_item );
container->setInputItem( p_input_item ); p_container->setInputItem( p_input_item );
_buildPlaylist( container, p_new_node ); _buildPlaylist( p_container, p_new_node );
} }
for ( unsigned int i = 0; i < p_parent->getNumItems(); i++ ) for ( unsigned int i = 0; i < p_parent->getNumItems(); i++ )
{ {
Item* item = p_parent->getItem( i ); Item* p_item = p_parent->getItem( i );
input_item_t* p_input_item = input_item_New( _p_sd, input_item_t* p_input_item = input_item_New( _p_sd,
item->getResource(), p_item->getResource(),
item->getTitle() ); p_item->getTitle() );
assert( p_input_item ); assert( p_input_item );
input_item_node_AppendItem( p_input_node, p_input_item ); input_item_node_AppendItem( p_input_node, p_input_item );
item->setInputItem( p_input_item ); p_item->setInputItem( p_input_item );
} }
if( send ) if( b_send )
input_item_node_PostAndDelete( p_input_node ); input_item_node_PostAndDelete( p_input_node );
} }
void MediaServer::setInputItem( input_item_t* p_input_item ) void MediaServer::setInputItem( input_item_t* p_input_item )
{ {
if(_inputItem == p_input_item) if(_p_input_item == p_input_item)
return; return;
if(_inputItem) if(_p_input_item)
vlc_gc_decref( _inputItem ); vlc_gc_decref( _p_input_item );
vlc_gc_incref( p_input_item ); vlc_gc_incref( p_input_item );
_inputItem = p_input_item; _p_input_item = p_input_item;
} }
bool MediaServer::compareSID( const char* sid ) bool MediaServer::compareSID( const char* psz_sid )
{ {
return ( strncmp( _subscriptionID, sid, sizeof( Upnp_SID ) ) == 0 ); return ( strncmp( _subscription_id, psz_sid, sizeof( Upnp_SID ) ) == 0 );
} }
...@@ -855,49 +864,47 @@ MediaServerList::~MediaServerList() ...@@ -855,49 +864,47 @@ MediaServerList::~MediaServerList()
} }
} }
bool MediaServerList::addServer( MediaServer* s ) bool MediaServerList::addServer( MediaServer* p_server )
{ {
input_item_t* p_input_item = NULL; input_item_t* p_input_item = NULL;
if ( getServer( s->getUDN() ) != 0 ) return false; if ( getServer( p_server->getUDN() ) != 0 ) return false;
msg_Dbg( _p_sd, "Adding server '%s'",
s->getFriendlyName() );
services_discovery_t* p_sd = _p_sd; msg_Dbg( _p_sd, "Adding server '%s'", p_server->getFriendlyName() );
p_input_item = input_item_New( p_sd, "vlc://nop", s->getFriendlyName() ); p_input_item = input_item_New( _p_sd, "vlc://nop",
s->setInputItem( p_input_item ); p_server->getFriendlyName() );
p_server->setInputItem( p_input_item );
services_discovery_AddItem( p_sd, p_input_item, NULL ); services_discovery_AddItem( _p_sd, p_input_item, NULL );
_list.push_back( s ); _list.push_back( p_server );
return true; return true;
} }
MediaServer* MediaServerList::getServer( const char* psz_udn ) MediaServer* MediaServerList::getServer( const char* psz_udn )
{ {
MediaServer* result = 0; MediaServer* p_result = 0;
for ( unsigned int i = 0; i < _list.size(); i++ ) for ( unsigned int i = 0; i < _list.size(); i++ )
{ {
if( strcmp( psz_udn, _list[i]->getUDN() ) == 0 ) if( strcmp( psz_udn, _list[i]->getUDN() ) == 0 )
{ {
result = _list[i]; p_result = _list[i];
break; break;
} }
} }
return result; return p_result;
} }
MediaServer* MediaServerList::getServerBySID( const char* sid ) MediaServer* MediaServerList::getServerBySID( const char* psz_sid )
{ {
MediaServer* p_server = 0; MediaServer* p_server = 0;
for ( unsigned int i = 0; i < _list.size(); i++ ) for ( unsigned int i = 0; i < _list.size(); i++ )
{ {
if ( _list[i]->compareSID( sid ) ) if ( _list[i]->compareSID( psz_sid ) )
{ {
p_server = _list[i]; p_server = _list[i];
break; break;
...@@ -939,13 +946,13 @@ Item::Item( Container* p_parent, const char* psz_object_id, const char* psz_titl ...@@ -939,13 +946,13 @@ Item::Item( Container* p_parent, const char* psz_object_id, const char* psz_titl
_title = psz_title; _title = psz_title;
_resource = psz_resource; _resource = psz_resource;
_inputItem = NULL; _p_input_item = NULL;
} }
Item::~Item() Item::~Item()
{ {
if(_inputItem) if(_p_input_item)
vlc_gc_decref( _inputItem ); vlc_gc_decref( _p_input_item );
} }
const char* Item::getObjectID() const const char* Item::getObjectID() const
...@@ -965,19 +972,19 @@ const char* Item::getResource() const ...@@ -965,19 +972,19 @@ const char* Item::getResource() const
void Item::setInputItem( input_item_t* p_input_item ) void Item::setInputItem( input_item_t* p_input_item )
{ {
if(_inputItem == p_input_item) if(_p_input_item == p_input_item)
return; return;
if(_inputItem) if(_p_input_item)
vlc_gc_decref( _inputItem ); vlc_gc_decref( _p_input_item );
vlc_gc_incref( p_input_item ); vlc_gc_incref( p_input_item );
_inputItem = p_input_item; _p_input_item = p_input_item;
} }
input_item_t* Item::getInputItem() const input_item_t* Item::getInputItem() const
{ {
return _inputItem; return _p_input_item;
} }
...@@ -992,7 +999,7 @@ Container::Container( Container* p_parent, ...@@ -992,7 +999,7 @@ Container::Container( Container* p_parent,
_objectID = psz_object_id; _objectID = psz_object_id;
_title = psz_title; _title = psz_title;
_inputItem = NULL; _p_input_item = NULL;
} }
Container::~Container() Container::~Container()
...@@ -1007,8 +1014,8 @@ Container::~Container() ...@@ -1007,8 +1014,8 @@ Container::~Container()
delete _items[i]; delete _items[i];
} }
if(_inputItem ) if(_p_input_item )
vlc_gc_decref( _inputItem ); vlc_gc_decref( _p_input_item );
} }
void Container::addItem( Item* item ) void Container::addItem( Item* item )
...@@ -1060,17 +1067,17 @@ Container* Container::getParent() ...@@ -1060,17 +1067,17 @@ Container* Container::getParent()
void Container::setInputItem( input_item_t* p_input_item ) void Container::setInputItem( input_item_t* p_input_item )
{ {
if(_inputItem == p_input_item) if(_p_input_item == p_input_item)
return; return;
if(_inputItem) if(_p_input_item)
vlc_gc_decref( _inputItem ); vlc_gc_decref( _p_input_item );
vlc_gc_incref( p_input_item ); vlc_gc_incref( p_input_item );
_inputItem = p_input_item; _p_input_item = p_input_item;
} }
input_item_t* Container::getInputItem() const input_item_t* Container::getInputItem() const
{ {
return _inputItem; return _p_input_item;
} }
...@@ -40,12 +40,12 @@ class MediaServer ...@@ -40,12 +40,12 @@ class MediaServer
{ {
public: public:
static void parseDeviceDescription( IXML_Document* doc, static void parseDeviceDescription( IXML_Document* p_doc,
const char* location, const char* psz_location,
services_discovery_t* p_sd ); services_discovery_t* p_sd );
MediaServer( const char* UDN, MediaServer( const char* psz_udn,
const char* friendlyName, const char* psz_friendly_name,
services_discovery_t* p_sd ); services_discovery_t* p_sd );
~MediaServer(); ~MediaServer();
...@@ -53,10 +53,10 @@ public: ...@@ -53,10 +53,10 @@ public:
const char* getUDN() const; const char* getUDN() const;
const char* getFriendlyName() const; const char* getFriendlyName() const;
void setContentDirectoryEventURL( const char* url ); void setContentDirectoryEventURL( const char* psz_url );
const char* getContentDirectoryEventURL() const; const char* getContentDirectoryEventURL() const;
void setContentDirectoryControlURL( const char* url ); void setContentDirectoryControlURL( const char* psz_url );
const char* getContentDirectoryControlURL() const; const char* getContentDirectoryControlURL() const;
void subscribeToContentDirectory(); void subscribeToContentDirectory();
...@@ -64,29 +64,29 @@ public: ...@@ -64,29 +64,29 @@ public:
void setInputItem( input_item_t* p_input_item ); void setInputItem( input_item_t* p_input_item );
bool compareSID( const char* sid ); bool compareSID( const char* psz_sid );
private: private:
bool _fetchContents( Container* parent ); bool _fetchContents( Container* p_parent );
void _buildPlaylist( Container* container, input_item_node_t * ); void _buildPlaylist( Container* p_container, input_item_node_t *p_item_node );
IXML_Document* _browseAction( const char*, const char*, IXML_Document* _browseAction( const char*, const char*,
const char*, const char*, const char*, const char* ); const char*, const char*, const char*, const char* );
services_discovery_t* _p_sd; services_discovery_t* _p_sd;
Container* _contents; Container* _p_contents;
input_item_t* _inputItem; input_item_t* _p_input_item;
std::string _UDN; std::string _UDN;
std::string _friendlyName; std::string _friendly_name;
std::string _contentDirectoryEventURL; std::string _content_directory_event_url;
std::string _contentDirectoryControlURL; std::string _content_directory_control_url;
int _subscriptionTimeOut; int _i_subscription_timeout;
Upnp_SID _subscriptionID; Upnp_SID _subscription_id;
}; };
...@@ -97,11 +97,11 @@ public: ...@@ -97,11 +97,11 @@ public:
MediaServerList( services_discovery_t* p_sd ); MediaServerList( services_discovery_t* p_sd );
~MediaServerList(); ~MediaServerList();
bool addServer( MediaServer* s ); bool addServer( MediaServer* p_server );
void removeServer( const char* UDN ); void removeServer( const char* psz_udn );
MediaServer* getServer( const char* UDN ); MediaServer* getServer( const char* psz_udn );
MediaServer* getServerBySID( const char* ); MediaServer* getServerBySID( const char* psz_sid );
private: private:
...@@ -130,7 +130,7 @@ public: ...@@ -130,7 +130,7 @@ public:
private: private:
input_item_t* _inputItem; input_item_t* _p_input_item;
Container* _parent; Container* _parent;
std::string _objectID; std::string _objectID;
...@@ -164,7 +164,7 @@ public: ...@@ -164,7 +164,7 @@ public:
private: private:
input_item_t* _inputItem; input_item_t* _p_input_item;
Container* _parent; Container* _parent;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment