[vlc-devel] [PATCH] Advertise the HTTP interface using Avahi

Rafaël Carré rafael.carre at gmail.com
Fri Sep 16 00:22:01 CEST 2011


Hi,

Le Thu, 15 Sep 2011 21:52:54 +0530,
akash mehrotra <mehrotra.akash at gmail.com> a écrit :

> From 3146e6ba7331a34eed8414d9b41b0b3b37ef0b44 Mon Sep 17 00:00:00 2001
> From: Akash Mehrotra <mehrotra.akash at gmail.com>
> Date: Fri, 26 Aug 2011 17:43:05 +0530
> Subject: [PATCH] Advertise the HTTP interface over Bonjour
> 
> ---
>  configure.ac               |    2 +
>  modules/lua/bonjour_advt.h |  263 ++++++++++++++++++++++++++++++++++++++++++++
>  modules/lua/intf.c         |    2 +
>  3 files changed, 267 insertions(+), 0 deletions(-)
>  create mode 100644 modules/lua/bonjour_advt.h
> 
> diff --git a/configure.ac b/configure.ac
> index adbbddd..f540e92 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1608,9 +1608,11 @@ then
>          )
>        ])
>      ])
> +  PKG_CHECK_MODULES(LUA2,avahi-client,VLC_ADD_LIBS([lua],[$LUA2_LIBS]))

I think it would be more clear if you use AVAHI_CLIENT instead of LUA2

>    if test "x${have_lua}" = "xyes" ;  then
>       VLC_ADD_LIBS([lua],[$LUA_LIBS])
>       VLC_ADD_CFLAGS([lua],[$LUA_CFLAGS])
> +     VLC_ADD_CFLAGS([lua],[-D_REENTRANT])
>    else
>        AC_MSG_ERROR([Could not find lua. Lua is needed for some interfaces (rc, telnet, http) as well as many other custom scripts. Use --disable-lua to ignore this error.])
>    fi
> diff --git a/modules/lua/bonjour_advt.h b/modules/lua/bonjour_advt.h
> new file mode 100644
> index 0000000..a7b7734
> --- /dev/null
> +++ b/modules/lua/bonjour_advt.h
> @@ -0,0 +1,263 @@
> +#ifndef  _GNU_SOURCE
> +#   define  _GNU_SOURCE
> +#endif

Why do you need this define?

> +
> +#ifdef HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include <vlc_common.h>
> +#include <vlc_interface.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <assert.h>
> +
> +#include <lua.h>        /* Low level lua C API */
> +#include <lauxlib.h>    /* Higher level C API */
> +#include <lualib.h>     /* Lua libs */
> +
> +#include "vlc.h"
> +#include "libs.h"
> +
> +
> +#include <vlc_common.h>
> +
> +#include <vlc_sout.h>
> +
> +#include <avahi-client/client.h>
> +#include <avahi-client/publish.h>
> +#include <avahi-client/lookup.h>
> +#include <avahi-common/alternative.h>
> +#include <avahi-common/simple-watch.h>
> +#include <avahi-common/malloc.h>
> +#include <avahi-common/error.h>
> +
> +
> +typedef struct bonjour_t
> +{
> +    vlc_object_t        *p_log;
> +
> +    vlc_thread_t        thread;
> +    AvahiSimplePoll     *simple_poll;
> +    AvahiEntryGroup     *group;
> +    AvahiClient         *client;
> +    char                *psz_stype;
> +    char                *psz_name;
> +    int                 i_port;
> +    char                *psz_txt;
> +} bonjour_t;
> +
> +/*****************************************************************************
> + * Prototypes
> + *****************************************************************************/
> +static int create_service( bonjour_t * );
> +
> +/*****************************************************************************
> + * entry_group_callback
> + *****************************************************************************/
> +static void entry_group_callback( AvahiEntryGroup *g,
> +                                  AvahiEntryGroupState state,
> +                                  void *userdata )
> +{
> +    (void)g;
> +    bonjour_t *p_sys = (bonjour_t *)userdata;
> +
> +    if( state == AVAHI_ENTRY_GROUP_ESTABLISHED )
> +    {
> +        msg_Dbg( p_sys->p_log, "service '%s' successfully established",
> +                 p_sys->psz_name );
> +    }
> +    else if( state == AVAHI_ENTRY_GROUP_COLLISION )
> +    {
> +        char *n;
> +
> +        n = avahi_alternative_service_name( p_sys->psz_name );
> +        avahi_free( p_sys->psz_name );
> +        p_sys->psz_name = n;
> +
> +        create_service( p_sys );
> +    }
> +}
> +
> +/*****************************************************************************
> + * create_service
> + *****************************************************************************/
> +static int create_service( bonjour_t *p_sys )
> +{
> +    int error;
> +
> +    if( p_sys->group == NULL )
> +    {
> +        p_sys->group = avahi_entry_group_new( p_sys->client,
> +                                              entry_group_callback,
> +                                              p_sys );
> +        if( p_sys->group == NULL )
> +        {
> +            msg_Err( p_sys->p_log, "failed to create avahi entry group: %s",
> +                     avahi_strerror( avahi_client_errno( p_sys->client ) ) );
> +            return VLC_EGENERIC;
> +        }
> +    }
> +
> +    error = avahi_entry_group_add_service( p_sys->group, AVAHI_IF_UNSPEC,
> +                                           AVAHI_PROTO_UNSPEC, 0, p_sys->psz_name,
> +                                           p_sys->psz_stype, NULL, NULL,
> +                                           p_sys->i_port,
> +                                           p_sys->psz_txt, NULL );
> +    if( error < 0 )
> +    {
> +        msg_Err( p_sys->p_log, "failed to add %s service: %s",
> +                 p_sys->psz_stype, avahi_strerror( error ) );
> +        return VLC_EGENERIC;
> +    }
> +
> +    error = avahi_entry_group_commit( p_sys->group );
> +    if( error < 0 )
> +    {
> +        msg_Err( p_sys->p_log, "failed to commit entry group: %s",
> +                 avahi_strerror( error ) );
> +        return VLC_EGENERIC;
> +    }
> +
> +    return VLC_SUCCESS;
> +}
> +
> +/*****************************************************************************
> + * client_callback
> + *****************************************************************************/
> +static void client_callback( AvahiClient *c,
> +                             AvahiClientState state,
> +                             void * userdata )
> +{
> +    bonjour_t *p_sys = (bonjour_t *)userdata;
> +
> +    if( state == AVAHI_CLIENT_S_RUNNING )
> +    {
> +        p_sys->client = c;
> +        create_service( p_sys );
> +    }
> +    else if( state == AVAHI_CLIENT_S_COLLISION )
> +    {
> +        if( p_sys->group != NULL )
> +            avahi_entry_group_reset( p_sys->group );
> +    }
> +    else if( state == AVAHI_CLIENT_FAILURE &&
> +              (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) )
> +    {
> +        msg_Err( p_sys->p_log, "avahi client disconnected" );
> +        avahi_simple_poll_quit( p_sys->simple_poll );
> +    }
> +}
> +
> +/*****************************************************************************
> + * poll_iterate_thread
> + *****************************************************************************/
> +static void *poll_iterate_thread( void *data )
> +{
> +    AvahiSimplePoll *simple_poll = data;
> +
> +    for( ;; )
> +    {
> +        vlc_testcancel();
> +        int canc = vlc_savecancel();
> +        int ret = avahi_simple_poll_iterate( simple_poll, 100 );
> +        vlc_restorecancel( canc );
> +        if (ret)
> +            break;
> +    }
> +    return NULL;
> +}
> +
> +/*****************************************************************************
> + * bonjour_stop_service
> + *****************************************************************************/
> +void bonjour_stop_service( void *_p_sys )
                                    ^
Please remove the leading underscore

> +{
> +    bonjour_t *p_sys = (bonjour_t *)_p_sys;
> +
> +    vlc_cancel( p_sys->thread );
> +    vlc_join( p_sys->thread, NULL );
> +
> +    if( p_sys->group != NULL )
> +        avahi_entry_group_free( p_sys->group );
> +
> +    avahi_client_free( p_sys->client );
> +    avahi_simple_poll_free( p_sys->simple_poll );
> +
> +    if( p_sys->psz_name != NULL )
> +        avahi_free( p_sys->psz_name );
> +
> +    if( p_sys->psz_txt != NULL )
> +        avahi_free( p_sys->psz_txt );
> +
> +    avahi_free( p_sys->psz_stype );
> +
> +    free( _p_sys );
> +}
> +
> +void start ( vlc_object_t *p_log )

The function name should be more explicit about what it does if it is
used outside the file.

startBonjourAdvertising() ?

> +{
> +    int err;
> +    bonjour_t* p_sys = calloc( 1, sizeof(*p_sys) );
> +    if( p_sys == NULL )
> +        return ;
> +    int i_port=8080;
> +    p_sys->p_log = p_log;
> +    p_sys->i_port = i_port;

> +    char *psz_name = "VLC HTTP Interface";
> +    char *psz_stype = "_http._tcp";
> +    char *psz_txt = "VLC HTTP Interface";

All these strings are static so no need to duplicate them and pass them around
through structures.
Just use them directly when calling avahi_entry_group_add_service(), this will make
your code much simpler.

> +    p_sys->psz_name = avahi_strdup( psz_name );
> +    p_sys->psz_stype = avahi_strdup( psz_stype );
> +    if( p_sys->psz_name == NULL || p_sys->psz_stype == NULL )
> +        goto error;
> +
> +    if( psz_txt != NULL )
> +    {
> +        p_sys->psz_txt = avahi_strdup( psz_txt );
> +        if( p_sys->psz_txt == NULL )
> +            goto error;
> +    }
> +
> +    p_sys->simple_poll = avahi_simple_poll_new();
> +    if( p_sys->simple_poll == NULL )
> +    {
> +        msg_Err( p_sys->p_log, "failed to create avahi simple pool" );
> +        goto error;
> +    }
> +
> +    p_sys->client = avahi_client_new( avahi_simple_poll_get(p_sys->simple_poll),
> +                                      0,
> +                                      client_callback, p_sys, &err );
> +    if( p_sys->client == NULL )
> +    {
> +        msg_Err( p_sys->p_log, "failed to create avahi client: %s",
> +                 avahi_strerror( err ) );
> +        goto error;
> +    }
> +
> +    if( vlc_clone( &p_sys->thread,
> +                   poll_iterate_thread, p_sys->simple_poll,
> +                   VLC_THREAD_PRIORITY_HIGHEST ) )
> +    {
> +        msg_Err( p_sys->p_log, "failed to create poll iterate thread" );
> +        goto error;
> +    }
> +
> +    return;
> +
> +error:
> +    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->psz_stype != NULL )
> +        avahi_free( p_sys->psz_stype );
> +    if( p_sys->psz_name != NULL )
> +        avahi_free( p_sys->psz_name );
> +    if( p_sys->psz_txt != NULL )
> +        avahi_free( p_sys->psz_txt );
> +
> +    free( p_sys );
> +
> +}
> diff --git a/modules/lua/intf.c b/modules/lua/intf.c
> index 22b974a..f09b368 100644
> --- a/modules/lua/intf.c
> +++ b/modules/lua/intf.c
> @@ -44,6 +44,7 @@
>  
>  #include "vlc.h"
>  #include "libs.h"
> +#include "bonjour_advt.h"
>  
>  /*****************************************************************************
>   * Prototypes
> @@ -424,6 +425,7 @@ int Open_LuaIntf( vlc_object_t *p_this )
>  
>  int Open_LuaHTTP( vlc_object_t *p_this )
>  {
> +    start (p_this);
>      return Start_LuaIntf( p_this, "http" );
>  }
>  

-- 
Rafaël Carré



More information about the vlc-devel mailing list