X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fservices_discovery%2Fbonjour.c;h=0110e016b0f81d5cfbed5933d4fab0e799d0d385;hb=c12acbd7d48431d7b5029d765e69e87378aca7a2;hp=a45e60bba2636fbda9ae0f5e2ccba9fee7d545b1;hpb=c6e29a7dda6734857ce5e28d03ea953b9e12fe35;p=vlc diff --git a/modules/services_discovery/bonjour.c b/modules/services_discovery/bonjour.c index a45e60bba2..0110e016b0 100644 --- a/modules/services_discovery/bonjour.c +++ b/modules/services_discovery/bonjour.c @@ -1,7 +1,7 @@ /***************************************************************************** * bonjour.c: Bonjour services discovery module ***************************************************************************** - * Copyright (C) 2005 the VideoLAN team + * Copyright (C) 2005-2009 the VideoLAN team * $Id$ * * Authors: Jon Lech Johansen @@ -24,17 +24,19 @@ /***************************************************************************** * Includes *****************************************************************************/ -#include /* malloc(), free() */ -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include #include -#ifdef HAVE_AVAHI_06 -# include -# include -#endif -#include +#include +#include +#include #include #include @@ -46,14 +48,18 @@ static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); -vlc_module_begin(); - set_shortname( "Bonjour" ); - set_description( _("Bonjour services") ); - set_category( CAT_PLAYLIST ); - set_subcategory( SUBCAT_PLAYLIST_SD ); - set_capability( "services_discovery", 0 ); - set_callbacks( Open, Close ); -vlc_module_end(); +VLC_SD_PROBE_HELPER("bonjour", "Bonjour services", SD_CAT_LAN) + +vlc_module_begin () + set_shortname( "Bonjour" ) + set_description( N_("Bonjour services") ) + set_category( CAT_PLAYLIST ) + set_subcategory( SUBCAT_PLAYLIST_SD ) + set_capability( "services_discovery", 0 ) + set_callbacks( Open, Close ) + + VLC_SD_PROBE_SUBMODULE +vlc_module_end () /***************************************************************************** * Local structures @@ -61,22 +67,16 @@ vlc_module_end(); struct services_discovery_sys_t { - /* playlist node */ - playlist_item_t *p_node_cat, *p_node_one; - playlist_t *p_playlist; - - AvahiSimplePoll *simple_poll; + AvahiThreadedPoll *poll; AvahiClient *client; AvahiServiceBrowser *sb; + vlc_dictionary_t services_name_to_input_item; }; /***************************************************************************** * Local prototypes *****************************************************************************/ -/* Main functions */ - static void Run ( services_discovery_t *p_intf ); - /***************************************************************************** * client_callback *****************************************************************************/ @@ -86,15 +86,11 @@ static void client_callback( AvahiClient *c, AvahiClientState state, services_discovery_t *p_sd = ( services_discovery_t* )userdata; services_discovery_sys_t *p_sys = p_sd->p_sys; -#ifdef HAVE_AVAHI_06 if( state == AVAHI_CLIENT_FAILURE && (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) ) -#else - if( state == AVAHI_CLIENT_DISCONNECTED ) -#endif { msg_Err( p_sd, "avahi client disconnected" ); - avahi_simple_poll_quit( p_sys->simple_poll ); + avahi_threaded_poll_quit( p_sys->poll ); } } @@ -113,19 +109,16 @@ static void resolve_callback( const AvahiAddress *address, uint16_t port, AvahiStringList *txt, -#ifdef HAVE_AVAHI_06 AvahiLookupResultFlags flags, -#endif void* userdata ) { services_discovery_t *p_sd = ( services_discovery_t* )userdata; services_discovery_sys_t *p_sys = p_sd->p_sys; + + VLC_UNUSED(interface); VLC_UNUSED(host_name); + VLC_UNUSED(flags); -#ifdef HAVE_AVAHI_06 if( event == AVAHI_RESOLVER_FAILURE ) -#else - if( event == AVAHI_RESOLVER_TIMEOUT ) -#endif { msg_Err( p_sd, "failed to resolve service '%s' of type '%s' in domain '%s'", @@ -137,14 +130,15 @@ static void resolve_callback( char *psz_uri = NULL; char *psz_addr = NULL; AvahiStringList *asl = NULL; - playlist_item_t *p_item = NULL; + input_item_t *p_input = NULL; msg_Dbg( p_sd, "service '%s' of type '%s' in domain '%s'", name, type, domain ); avahi_address_snprint(a, (sizeof(a)/sizeof(a[0]))-1, address); if( protocol == AVAHI_PROTO_INET6 ) - asprintf( &psz_addr, "[%s]", a ); + if( asprintf( &psz_addr, "[%s]", a ) == -1 ) + return; if( txt != NULL ) asl = avahi_string_list_find( txt, "path" ); @@ -156,8 +150,12 @@ static void resolve_callback( if( avahi_string_list_get_pair( asl, &key, &value, &size ) == 0 && value != NULL ) { - asprintf( &psz_uri, "http://%s:%d%s", - psz_addr != NULL ? psz_addr : a, port, value ); + if( asprintf( &psz_uri, "http://%s:%d%s", + psz_addr != NULL ? psz_addr : a, port, value ) == -1 ) + { + free( psz_addr ); + return; + } } if( key != NULL ) avahi_free( (void *)key ); @@ -166,26 +164,28 @@ static void resolve_callback( } else { - asprintf( &psz_uri, "http://%s:%d", - psz_addr != NULL ? psz_addr : a, port ); + if( asprintf( &psz_uri, "http://%s:%d", + psz_addr != NULL ? psz_addr : a, port ) == -1 ) + { + free( psz_addr ); + return; + } } - if( psz_addr != NULL ) - free( (void *)psz_addr ); + free( psz_addr ); if( psz_uri != NULL ) { - p_item = playlist_ItemNew( p_sd, psz_uri, name ); - free( (void *)psz_uri ); + p_input = input_item_New( p_sd, psz_uri, name ); + free( psz_uri ); } - if( p_item != NULL ) + if( p_input != NULL ) { - p_item->i_flags &= ~PLAYLIST_SKIP_FLAG; - - playlist_NodeAddItem( p_sys->p_playlist, p_item, - VIEW_CATEGORY, p_sys->p_node, - PLAYLIST_APPEND, PLAYLIST_END ); - } + vlc_dictionary_insert( &p_sys->services_name_to_input_item, + name, p_input ); + services_discovery_AddItem( p_sd, p_input, NULL /* no category */ ); + vlc_gc_decref( p_input ); + } } avahi_service_resolver_free( r ); @@ -202,39 +202,39 @@ static void browse_callback( const char *name, const char *type, const char *domain, -#ifdef HAVE_AVAHI_06 AvahiLookupResultFlags flags, -#endif void* userdata ) { + VLC_UNUSED(b); + VLC_UNUSED(flags); services_discovery_t *p_sd = ( services_discovery_t* )userdata; services_discovery_sys_t *p_sys = p_sd->p_sys; - if( event == AVAHI_BROWSER_NEW ) { if( avahi_service_resolver_new( p_sys->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, -#ifdef HAVE_AVAHI_06 0, -#endif resolve_callback, userdata ) == NULL ) { msg_Err( p_sd, "failed to resolve service '%s': %s", name, avahi_strerror( avahi_client_errno( p_sys->client ) ) ); } } - else + else if( name ) { - playlist_item_t *p_item; - - p_item = playlist_ChildSearchName( p_sys->p_node, name ); - if( p_item == NULL ) - { + /** \todo Store the input id and search it, rather than searching the items */ + input_item_t *p_item; + p_item = vlc_dictionary_value_for_key( + &p_sys->services_name_to_input_item, + name ); + if( !p_item ) msg_Err( p_sd, "failed to find service '%s' in playlist", name ); - } else { - playlist_Delete( p_sys->p_playlist, p_item->input.i_id ); + services_discovery_RemoveItem( p_sd, p_item ); + vlc_dictionary_remove_value_for_key( + &p_sys->services_name_to_input_item, + name, NULL, NULL ); } } } @@ -246,32 +246,23 @@ static int Open( vlc_object_t *p_this ) { services_discovery_t *p_sd = ( services_discovery_t* )p_this; services_discovery_sys_t *p_sys; - playlist_view_t *p_view; - vlc_value_t val; int err; - p_sd->p_sys = p_sys = (services_discovery_sys_t *)malloc( - sizeof( services_discovery_sys_t ) ); - if( p_sd->p_sys == NULL ) - { - msg_Err( p_sd, "out of memory" ); - return VLC_EGENERIC; - } + p_sd->p_sys = p_sys = calloc( 1, sizeof( services_discovery_sys_t ) ); + if( !p_sys ) + return VLC_ENOMEM; - memset( p_sys, 0, sizeof(*p_sys) ); + vlc_dictionary_init( &p_sys->services_name_to_input_item, 1 ); - p_sys->simple_poll = avahi_simple_poll_new(); - if( p_sys->simple_poll == NULL ) + p_sys->poll = avahi_threaded_poll_new(); + if( p_sys->poll == NULL ) { - msg_Err( p_sd, "failed to create avahi simple poll" ); + msg_Err( p_sd, "failed to create Avahi threaded poll" ); goto error; } - p_sys->client = avahi_client_new( avahi_simple_poll_get(p_sys->simple_poll), -#ifdef HAVE_AVAHI_06 - 0, -#endif - client_callback, p_sd, &err ); + p_sys->client = avahi_client_new( avahi_threaded_poll_get(p_sys->poll), + 0, client_callback, p_sd, &err ); if( p_sys->client == NULL ) { msg_Err( p_sd, "failed to create avahi client: %s", @@ -282,43 +273,25 @@ static int Open( vlc_object_t *p_this ) p_sys->sb = avahi_service_browser_new( p_sys->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_vlc-http._tcp", NULL, -#ifdef HAVE_AVAHI_06 - 0, -#endif - browse_callback, p_sd ); + 0, browse_callback, p_sd ); if( p_sys->sb == NULL ) { msg_Err( p_sd, "failed to create avahi service browser" ); goto error; } - /* Create our playlist node */ - p_sys->p_playlist = (playlist_t *)vlc_object_find( p_sd, - VLC_OBJECT_PLAYLIST, - FIND_ANYWHERE ); - if( !p_sys->p_playlist ) - { - msg_Warn( p_sd, "unable to find playlist, cancelling"); - goto error; - } - - playlist_NodesCreateForSD( p_playlist, _("Bonjour"), &p_sys->p_node_cat, - &p_sys->p_node_one ); - p_sd->pf_run = Run; - return VLC_SUCCESS; error: - if( p_sys->p_playlist != NULL ) - vlc_object_release( p_sys->p_playlist ); if( p_sys->sb != NULL ) avahi_service_browser_free( p_sys->sb ); if( p_sys->client != NULL ) avahi_client_free( p_sys->client ); - if( p_sys->simple_poll != NULL ) - avahi_simple_poll_free( p_sys->simple_poll ); + if( p_sys->poll != NULL ) + avahi_threaded_poll_free( p_sys->poll ); - free( (void *)p_sys ); + vlc_dictionary_clear( &p_sys->services_name_to_input_item, NULL, NULL ); + free( p_sys ); return VLC_EGENERIC; } @@ -333,27 +306,8 @@ static void Close( vlc_object_t *p_this ) avahi_service_browser_free( p_sys->sb ); avahi_client_free( p_sys->client ); - avahi_simple_poll_free( p_sys->simple_poll ); - - playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node, VLC_TRUE, VLC_TRUE ); - vlc_object_release( p_sys->p_playlist ); + avahi_threaded_poll_free( p_sys->poll ); + vlc_dictionary_clear( &p_sys->services_name_to_input_item, NULL, NULL ); free( p_sys ); } - -/***************************************************************************** - * Run: main thread - *****************************************************************************/ -static void Run( services_discovery_t *p_sd ) -{ - services_discovery_sys_t *p_sys = p_sd->p_sys; - - while( !p_sd->b_die ) - { - if( avahi_simple_poll_iterate( p_sys->simple_poll, 100 ) != 0 ) - { - msg_Err( p_sd, "poll iterate failed" ); - break; - } - } -}