Example #1
0
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;
}
Example #2
0
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 );
}