📄 upnp_intel.cpp
字号:
if ( !serviceType ) continue; if ( strcmp( CONTENT_DIRECTORY_SERVICE_TYPE, serviceType ) != 0 ) continue; const char* eventSubURL = xml_getChildElementValue( serviceElement, "eventSubURL" ); if ( !eventSubURL ) continue; const char* controlURL = xml_getChildElementValue( serviceElement, "controlURL" ); if ( !controlURL ) continue; // Try to subscribe to ContentDirectory service char* url = ( char* )malloc( strlen( baseURL ) + strlen( eventSubURL ) + 1 ); if ( url ) { char* s1 = strdup( baseURL ); char* s2 = strdup( eventSubURL ); if ( UpnpResolveURL( s1, s2, url ) == UPNP_E_SUCCESS ) { // msg_Dbg( cookie->serviceDiscovery, "CDS EVENT URL: %s", url ); server->setContentDirectoryEventURL( url ); server->subscribeToContentDirectory(); } free( s1 ); free( s2 ); free( url ); } // Try to browse content directory... url = ( char* )malloc( strlen( baseURL ) + strlen( controlURL ) + 1 ); if ( url ) { char* s1 = strdup( baseURL ); char* s2 = strdup( controlURL ); if ( UpnpResolveURL( s1, s2, url ) == UPNP_E_SUCCESS ) { // msg_Dbg( cookie->serviceDiscovery, "CDS CTRL URL: %s", url ); server->setContentDirectoryControlURL( url ); server->fetchContents(); } free( s1 ); free( s2 ); free( url ); } } ixmlNodeList_free( serviceList ); } } ixmlNodeList_free( deviceList ); }}MediaServer::MediaServer( const char* UDN, const char* friendlyName, Cookie* cookie ){ _cookie = cookie; _UDN = UDN; _friendlyName = friendlyName; _contents = 0; _playlistNode = 0;}MediaServer::~MediaServer(){ if ( _contents ) { playlist_NodeDelete( _cookie->serviceDiscovery->p_sys->p_playlist, _playlistNode, true, true ); } delete _contents;}const char* MediaServer::getUDN() const{ const char* s = _UDN.c_str(); return s;}const char* MediaServer::getFriendlyName() const{ const char* s = _friendlyName.c_str(); return s;}void MediaServer::setContentDirectoryEventURL( const char* url ){ _contentDirectoryEventURL = url;}const char* MediaServer::getContentDirectoryEventURL() const{ const char* s = _contentDirectoryEventURL.c_str(); return s;}void MediaServer::setContentDirectoryControlURL( const char* url ){ _contentDirectoryControlURL = url;}const char* MediaServer::getContentDirectoryControlURL() const{ return _contentDirectoryControlURL.c_str();}void MediaServer::subscribeToContentDirectory(){ const char* url = getContentDirectoryEventURL(); if ( !url || strcmp( url, "" ) == 0 ) { msg_Dbg( _cookie->serviceDiscovery, "No subscription url set!" ); return; } int timeOut = 1810; Upnp_SID sid; int res = UpnpSubscribe( _cookie->clientHandle, url, &timeOut, sid ); if ( res == UPNP_E_SUCCESS ) { _subscriptionTimeOut = timeOut; memcpy( _subscriptionID, sid, sizeof( Upnp_SID ) ); } else { msg_Dbg( _cookie->serviceDiscovery, "%s:%d: WARNING: '%s': %s", __FILE__, __LINE__, getFriendlyName(), UpnpGetErrorMessage( res ) ); }}IXML_Document* MediaServer::_browseAction( const char* pObjectID, const char* pBrowseFlag, const char* pFilter, const char* pStartingIndex, const char* pRequestedCount, const char* pSortCriteria ){ IXML_Document* action = 0; IXML_Document* response = 0; const char* url = getContentDirectoryControlURL(); if ( !url || strcmp( url, "" ) == 0 ) { msg_Dbg( _cookie->serviceDiscovery, "No subscription url set!" ); return 0; } char* ObjectID = strdup( pObjectID ); char* BrowseFlag = strdup( pBrowseFlag ); char* Filter = strdup( pFilter ); char* StartingIndex = strdup( pStartingIndex ); char* RequestedCount = strdup( pRequestedCount ); char* SortCriteria = strdup( pSortCriteria ); char* serviceType = strdup( CONTENT_DIRECTORY_SERVICE_TYPE ); int res; res = UpnpAddToAction( &action, "Browse", serviceType, "ObjectID", ObjectID ); if ( res != UPNP_E_SUCCESS ) { /* msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR: %s", __FILE__, __LINE__, UpnpGetErrorMessage( res ) ); */ goto browseActionCleanup; } res = UpnpAddToAction( &action, "Browse", serviceType, "BrowseFlag", BrowseFlag ); if ( res != UPNP_E_SUCCESS ) { /* msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR: %s", __FILE__, __LINE__, UpnpGetErrorMessage( res ) ); */ goto browseActionCleanup; } res = UpnpAddToAction( &action, "Browse", serviceType, "Filter", Filter ); if ( res != UPNP_E_SUCCESS ) { /* msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR: %s", __FILE__, __LINE__, UpnpGetErrorMessage( res ) ); */ goto browseActionCleanup; } res = UpnpAddToAction( &action, "Browse", serviceType, "StartingIndex", StartingIndex ); if ( res != UPNP_E_SUCCESS ) { /* msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR: %s", __FILE__, __LINE__, UpnpGetErrorMessage( res ) ); */ goto browseActionCleanup; } res = UpnpAddToAction( &action, "Browse", serviceType, "RequestedCount", RequestedCount ); if ( res != UPNP_E_SUCCESS ) { /* msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR: %s", __FILE__, __LINE__, UpnpGetErrorMessage( res ) ); */ goto browseActionCleanup; } res = UpnpAddToAction( &action, "Browse", serviceType, "SortCriteria", SortCriteria ); if ( res != UPNP_E_SUCCESS ) { /* msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR: %s", __FILE__, __LINE__, UpnpGetErrorMessage( res ) ); */ goto browseActionCleanup; } res = UpnpSendAction( _cookie->clientHandle, url, CONTENT_DIRECTORY_SERVICE_TYPE, 0, action, &response ); if ( res != UPNP_E_SUCCESS ) { msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR: %s", __FILE__, __LINE__, UpnpGetErrorMessage( res ) ); ixmlDocument_free( response ); response = 0; } browseActionCleanup: free( ObjectID ); free( BrowseFlag ); free( Filter ); free( StartingIndex ); free( RequestedCount ); free( SortCriteria ); free( serviceType ); ixmlDocument_free( action ); return response;}void MediaServer::fetchContents(){ Container* root = new Container( 0, "0", getFriendlyName() ); _fetchContents( root ); if ( _contents ) { vlc_mutex_lock( &_cookie->serviceDiscovery->p_sys->p_playlist->object_lock ); playlist_NodeEmpty( _cookie->serviceDiscovery->p_sys->p_playlist, _playlistNode, true ); vlc_mutex_unlock( &_cookie->serviceDiscovery->p_sys->p_playlist->object_lock ); delete _contents; } _contents = root; _contents->setPlaylistNode( _playlistNode ); _buildPlaylist( _contents );}bool MediaServer::_fetchContents( Container* parent ){ if (!parent) { msg_Dbg( _cookie->serviceDiscovery, "%s:%d: parent==NULL", __FILE__, __LINE__ ); return false; } IXML_Document* response = _browseAction( parent->getObjectID(), "BrowseDirectChildren", "*", "0", "0", "" ); if ( !response ) { msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR!", __FILE__, __LINE__ ); return false; } IXML_Document* result = parseBrowseResult( response ); ixmlDocument_free( response ); if ( !result ) { msg_Dbg( _cookie->serviceDiscovery, "%s:%d: ERROR!", __FILE__, __LINE__ ); return false; } IXML_NodeList* containerNodeList = ixmlDocument_getElementsByTagName( result, "container" ); if ( containerNodeList ) { for ( unsigned int i = 0; i < ixmlNodeList_length( containerNodeList ); i++ ) { IXML_Element* containerElement = ( IXML_Element* )ixmlNodeList_item( containerNodeList, i ); const char* objectID = ixmlElement_getAttribute( containerElement, "id" ); if ( !objectID ) continue; const char* childCountStr = ixmlElement_getAttribute( containerElement, "childCount" ); if ( !childCountStr ) continue; int childCount = atoi( childCountStr ); const char* title = xml_getChildElementValue( containerElement, "dc:title" ); if ( !title ) continue; const char* resource = xml_getChildElementValue( containerElement, "res" ); if ( resource && childCount < 1 ) { Item* item = new Item( parent, objectID, title, resource ); parent->addItem( item ); } else { Container* container = new Container( parent, objectID, title ); parent->addContainer( container ); if ( childCount > 0 ) _fetchContents( container ); } } ixmlNodeList_free( containerNodeList ); } IXML_NodeList* itemNodeList = ixmlDocument_getElementsByTagName( result, "item" ); if ( itemNodeList ) { for ( unsigned int i = 0; i < ixmlNodeList_length( itemNodeList ); i++ ) { IXML_Element* itemElement = ( IXML_Element* )ixmlNodeList_item( itemNodeList, i ); const char* objectID = ixmlElement_getAttribute( itemElement, "id" ); if ( !objectID ) continue; const char* title = xml_getChildElementValue( itemElement, "dc:title" ); if ( !title ) continue; const char* resource = xml_getChildElementValue( itemElement, "res" ); if ( !resource ) continue; Item* item = new Item( parent, objectID, title, resource ); parent->addItem( item ); } ixmlNodeList_free( itemNodeList ); } ixmlDocument_free( result ); return true;}void MediaServer::_buildPlaylist( Container* parent ){ for ( unsigned int i = 0; i < parent->getNumContainers(); i++ ) { Container* container = parent->getContainer( i ); playlist_item_t* parentNode = parent->getPlaylistNode(); char* title = strdup( container->getTitle() ); playlist_item_t* node = playlist_NodeCreate( _cookie->serviceDiscovery->p_sys->p_playlist, VIEW_CATEGORY, title, parentNode ); free( title ); container->setPlaylistNode( node ); _buildPlaylist( container ); } for ( unsigned int i = 0; i < parent->getNumItems(); i++ ) { Item* item = parent->getItem( i ); playlist_item_t* parentNode = parent->getPlaylistNode(); playlist_item_t* node = playlist_ItemNew( _cookie->serviceDiscovery, item->getResource(), item->getTitle() ); playlist_NodeAddItem( _cookie->serviceDiscovery->p_sys->p_playlist, node, VIEW_CATEGORY, parentNode, PLAYLIST_APPEND, PLAYLIST_END ); item->setPlaylistNode( node ); }}void MediaServer::setPlaylistNode( playlist_item_t* playlistNode ){ _playlistNode = playlistNode;}bool MediaServer::compareSID( const char* sid ){ return ( strncmp( _subscriptionID, sid, sizeof( Upnp_SID ) ) == 0 );}// MediaServerList...MediaServerList::MediaServerList( Cookie* cookie ){ _cookie = cookie;}MediaServerList::~MediaServerList(){ for ( unsigned int i = 0; i < _list.size(); i++ ) { delete _list[i]; }}bool MediaServerList::addServer( MediaServer* s ){ if ( getServer( s->getUDN() ) != 0 ) return false; msg_Dbg( _cookie->serviceDiscovery, "Adding server '%s'", s->getFriendlyName() ); _list.push_back( s ); char* name = strdup( s->getFriendlyName() ); playlist_item_t* node = playlist_NodeCreate( _cookie->serviceDiscovery->p_sys->p_playlist, VIEW_CATEGORY, name, _cookie->serviceDiscovery->p_sys->p_node ); free( name ); s->setPlaylistNode( node ); return true;}MediaServer* MediaServerList::getServer( const char* UDN ){ MediaServer* result = 0; for ( unsigned int i = 0; i < _list.size(); i++ ) { if( strcmp( UDN, _list[i]->getUDN() ) == 0 ) { result = _list[i]; break; } } return result;}MediaServer* MediaServerList::getServerBySID( const char* sid ){ MediaServer* server = 0; for ( unsigned int i = 0; i < _list.size(); i++ ) { if ( _list[i]->compareSID( sid ) ) { server = _list[i]; break; } } return server;}void MediaServerList::removeServer( const char* UDN ){ MediaServer* server = getServer( UDN ); if ( !server ) return; msg_Dbg( _cookie->serviceDiscovery, "Removing server '%s'", server->getFriendlyName() ); std::vector<MediaServer*>::iterator it; for ( it = _list.begin(); it != _list.end(); it++ ) { if ( *it == server ) { _list.erase( it ); delete server; break; } }}// Item...Item::Item( Container* parent, const char* objectID, const char* title, const char* resource ){ _parent = parent; _objectID = objectID; _title = title; _resource = resource; _playlistNode = 0;}const char* Item::getObjectID() const{ return _objectID.c_str();}const char* Item::getTitle() const{ return _title.c_str();}const char* Item::getResource() const{ return _resource.c_str();}void Item::setPlaylistNode( playlist_item_t* node ){ _playlistNode = node;}playlist_item_t* Item::getPlaylistNode() const{ return _playlistNode;}// Container...Container::Container( Container* parent, const char* objectID, const char* title ){ _parent = parent; _objectID = objectID; _title = title; _playlistNode = 0;}Container::~Container(){ for ( unsigned int i = 0; i < _containers.size(); i++ ) { delete _containers[i]; } for ( unsigned int i = 0; i < _items.size(); i++ ) { delete _items[i]; }}void Container::addItem( Item* item ){ _items.push_back( item );}void Container::addContainer( Container* container ){ _containers.push_back( container );}const char* Container::getObjectID() const{ return _objectID.c_str();}const char* Container::getTitle() const{ return _title.c_str();}unsigned int Container::getNumItems() const{ return _items.size();}unsigned int Container::getNumContainers() const{ return _containers.size();}Item* Container::getItem( unsigned int i ) const{ if ( i < _items.size() ) return _items[i]; return 0;}Container* Container::getContainer( unsigned int i ) const{ if ( i < _containers.size() ) return _containers[i]; return 0;}void Container::setPlaylistNode( playlist_item_t* node ){ _playlistNode = node;}playlist_item_t* Container::getPlaylistNode() const{ return _playlistNode;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -