- set_callbacks( Open, Close );
-
- VLC_SD_PROBE_SUBMODULE
-vlc_module_end();
-
-/*
- * Local prototypes
- */
-static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data );
-
-const char* xml_getChildElementValue( IXML_Element* p_parent,
- const char* psz_tag_name );
-
-const char* xml_getChildElementValue( IXML_Document* p_doc,
- const char* psz_tag_name );
-
-const char* xml_getChildElementAttributeValue( IXML_Element* p_parent,
- const char* psz_tag_name,
- const char* psz_attribute );
-
-int xml_getNumber( IXML_Document* p_doc,
- const char* psz_tag_name );
-
-IXML_Document* parseBrowseResult( IXML_Document* p_doc );
-
-/*
- * Initializes UPNP instance.
- */
-static int Open( vlc_object_t *p_this )
-{
- int i_res;
- services_discovery_t *p_sd = ( services_discovery_t* )p_this;
- services_discovery_sys_t *p_sys = ( services_discovery_sys_t * )
- calloc( 1, sizeof( services_discovery_sys_t ) );
-
- if( !( p_sd->p_sys = p_sys ) )
- return VLC_ENOMEM;
-
-#ifdef UPNP_ENABLE_IPV6
- char* psz_miface;
- psz_miface = var_InheritString( p_sd, "miface" );
- msg_Info( p_sd, "Initializing libupnp on '%s' interface", psz_miface );
- i_res = UpnpInit2( psz_miface, 0 );
- free( psz_miface );
-#else
- /* If UpnpInit2 isnt available, initialize on first IPv4-capable interface */
- i_res = UpnpInit( 0, 0 );
-#endif
- if( i_res != UPNP_E_SUCCESS )
- {
- msg_Err( p_sd, "Initialization failed: %s", UpnpGetErrorMessage( i_res ) );
- free( p_sys );
- return VLC_EGENERIC;
- }
-
- ixmlRelaxParser( 1 );
-
- p_sys->p_server_list = new MediaServerList( p_sd );
- vlc_mutex_init( &p_sys->callback_lock );
-
- /* Register a control point */
- i_res = UpnpRegisterClient( Callback, p_sd, &p_sys->client_handle );
- if( i_res != UPNP_E_SUCCESS )
- {
- msg_Err( p_sd, "Client registration failed: %s", UpnpGetErrorMessage( i_res ) );
- Close( (vlc_object_t*) p_sd );
- return VLC_EGENERIC;
- }
-
- /* Search for media servers */
- i_res = UpnpSearchAsync( p_sys->client_handle, 5,
- MEDIA_SERVER_DEVICE_TYPE, p_sd );
- if( i_res != UPNP_E_SUCCESS )
- {
- msg_Err( p_sd, "Error sending search request: %s", UpnpGetErrorMessage( i_res ) );
- Close( (vlc_object_t*) p_sd );
- return VLC_EGENERIC;
- }
-
- /* libupnp does not treat a maximum content length of 0 as unlimited
- * until 64dedf (~ pupnp v1.6.7) and provides no sane way to discriminate
- * between versions */
- if( (i_res = UpnpSetMaxContentLength( INT_MAX )) != UPNP_E_SUCCESS )
- {
- msg_Err( p_sd, "Failed to set maximum content length: %s",
- UpnpGetErrorMessage( i_res ));
-
- Close( (vlc_object_t*) p_sd );
- return VLC_EGENERIC;
- }
-
- return VLC_SUCCESS;
-}
-
-/*
- * Releases resources.
- */
-static void Close( vlc_object_t *p_this )
-{
- services_discovery_t *p_sd = ( services_discovery_t* )p_this;
-
- UpnpUnRegisterClient( p_sd->p_sys->client_handle );
- UpnpFinish();