static int result(const struct test *test) { char *absurl = NULL; int ret = 0; ret = UpnpResolveURL2(test->base, test->rel, &absurl); if (ret == test->error && (test->expect == NULL || strcmp(test->expect, absurl) == 0)) { ret = 0; } else { printf("%s:%d: '%s' | '%s' -> '%s' != '%s' (%d)\n", __FILE__, test->line, test->base, test->rel, absurl, test->expect, ret); ret = 1; } free(absurl); return ret; }
void MediaServerList::parseNewServer( IXML_Document *doc, const std::string &location ) { if ( !doc ) { msg_Err( m_sd, "Null IXML_Document" ); return; } if ( location.empty() ) { msg_Err( m_sd, "Empty location" ); return; } const char* psz_base_url = location.c_str(); /* Try to extract baseURL */ IXML_NodeList* p_url_list = ixmlDocument_getElementsByTagName( doc, "URLBase" ); if ( p_url_list ) { if ( IXML_Node* p_url_node = ixmlNodeList_item( p_url_list, 0 ) ) { IXML_Node* p_text_node = ixmlNode_getFirstChild( p_url_node ); if ( p_text_node ) psz_base_url = ixmlNode_getNodeValue( p_text_node ); } ixmlNodeList_free( p_url_list ); } /* Get devices */ IXML_NodeList* p_device_list = ixmlDocument_getElementsByTagName( doc, "device" ); if ( !p_device_list ) return; for ( unsigned int i = 0; i < ixmlNodeList_length( p_device_list ); i++ ) { IXML_Element* p_device_element = ( IXML_Element* ) ixmlNodeList_item( p_device_list, i ); if( !p_device_element ) continue; const char* psz_device_type = xml_getChildElementValue( p_device_element, "deviceType" ); if ( !psz_device_type ) { msg_Warn( m_sd, "No deviceType found!" ); continue; } if ( strncmp( MEDIA_SERVER_DEVICE_TYPE, psz_device_type, strlen( MEDIA_SERVER_DEVICE_TYPE ) - 1 ) && strncmp( SATIP_SERVER_DEVICE_TYPE, psz_device_type, strlen( SATIP_SERVER_DEVICE_TYPE ) - 1 ) ) continue; const char* psz_udn = xml_getChildElementValue( p_device_element, "UDN" ); if ( !psz_udn ) { msg_Warn( m_sd, "No UDN!" ); continue; } /* Check if server is already added */ if ( getServer( psz_udn ) ) { msg_Warn( m_sd, "Server with uuid '%s' already exists.", psz_udn ); continue; } const char* psz_friendly_name = xml_getChildElementValue( p_device_element, "friendlyName" ); if ( !psz_friendly_name ) { msg_Dbg( m_sd, "No friendlyName!" ); continue; } std::string iconUrl = getIconURL( p_device_element, psz_base_url ); // We now have basic info, we need to get the content browsing url // so the access module can browse without fetching the manifest again if ( !strncmp( SATIP_SERVER_DEVICE_TYPE, psz_device_type, strlen( SATIP_SERVER_DEVICE_TYPE ) - 1 ) ) { SD::MediaServerDesc* p_server = NULL; vlc_url_t url; vlc_UrlParse( &url, psz_base_url ); char *psz_satip_channellist = config_GetPsz(m_sd, "satip-channelist"); if( !psz_satip_channellist ) { break; } /* a user may have provided a custom playlist url */ if (strncmp(psz_satip_channellist, "CustomList", 10) == 0) { char *psz_satip_playlist_url = config_GetPsz( m_sd, "satip-channellist-url" ); if ( psz_satip_playlist_url ) { p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_satip_playlist_url, iconUrl ); if( likely( p_server ) ) { p_server->satIpHost = url.psz_host; p_server->isSatIp = true; if( !addServer( p_server ) ) { delete p_server; } } /* to comply with the SAT>IP specification, we don't fall back on another channel list if this path failed */ free( psz_satip_playlist_url ); vlc_UrlClean( &url ); continue; } } /* If requested by the user, check for a SAT>IP m3u list, which may be provided by some rare devices */ if (strncmp(psz_satip_channellist, "ServerList", 10) == 0) { const char* psz_m3u_url = xml_getChildElementValue( p_device_element, "satip:X_SATIPM3U" ); if ( psz_m3u_url ) { if ( strncmp( "http", psz_m3u_url, 4) ) { char* psz_url = NULL; if ( UpnpResolveURL2( psz_base_url, psz_m3u_url, &psz_url ) == UPNP_E_SUCCESS ) { p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_url, iconUrl ); free(psz_url); } } else { p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_m3u_url, iconUrl ); } if ( unlikely( !p_server ) ) break; p_server->satIpHost = url.psz_host; p_server->isSatIp = true; if ( !addServer( p_server ) ) delete p_server; free(psz_satip_channellist); } else { msg_Warn( m_sd, "SAT>IP server '%s' did not provide a playlist", url.psz_host); } /* to comply with the SAT>IP specifications, we don't fallback on another channel list if this path failed */ vlc_UrlClean( &url ); continue; } /* Normally, fetch a playlist from the web, * which will be processed by a lua script a bit later */ char *psz_url; if (asprintf( &psz_url, "http://www.satip.info/Playlists/%s.m3u", psz_satip_channellist ) < 0 ) { vlc_UrlClean( &url ); free( psz_satip_channellist ); continue; } p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_url, iconUrl ); if( likely( p_server ) ) { p_server->satIpHost = url.psz_host; p_server->isSatIp = true; if( !addServer( p_server ) ) { delete p_server; } } free( psz_url ); free( psz_satip_channellist ); vlc_UrlClean( &url ); continue; } /* Check for ContentDirectory service. */ IXML_NodeList* p_service_list = ixmlElement_getElementsByTagName( p_device_element, "service" ); if ( !p_service_list ) continue; for ( unsigned int j = 0; j < ixmlNodeList_length( p_service_list ); j++ ) { IXML_Element* p_service_element = (IXML_Element*)ixmlNodeList_item( p_service_list, j ); const char* psz_service_type = xml_getChildElementValue( p_service_element, "serviceType" ); if ( !psz_service_type ) { msg_Warn( m_sd, "No service type found." ); continue; } int k = strlen( CONTENT_DIRECTORY_SERVICE_TYPE ) - 1; if ( strncmp( CONTENT_DIRECTORY_SERVICE_TYPE, psz_service_type, k ) ) continue; const char* psz_control_url = xml_getChildElementValue( p_service_element, "controlURL" ); if ( !psz_control_url ) { msg_Warn( m_sd, "No control url found." ); continue; } /* Try to browse content directory. */ char* psz_url = ( char* ) malloc( strlen( psz_base_url ) + strlen( psz_control_url ) + 1 ); if ( psz_url ) { if ( UpnpResolveURL( psz_base_url, psz_control_url, psz_url ) == UPNP_E_SUCCESS ) { SD::MediaServerDesc* p_server = new(std::nothrow) SD::MediaServerDesc( psz_udn, psz_friendly_name, psz_url, iconUrl ); free( psz_url ); if ( unlikely( !p_server ) ) break; if ( !addServer( p_server ) ) { delete p_server; continue; } } else free( psz_url ); } } ixmlNodeList_free( p_service_list ); } ixmlNodeList_free( p_device_list ); }