Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
a0d58179
Commit
a0d58179
authored
Sep 09, 2005
by
Jon Lech Johansen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* Bonjour services discovery module using avahi.
parent
29ff734c
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
726 additions
and
3 deletions
+726
-3
configure.ac
configure.ac
+16
-1
modules/access_output/Modules.am
modules/access_output/Modules.am
+1
-1
modules/access_output/bonjour.c
modules/access_output/bonjour.c
+302
-0
modules/access_output/bonjour.h
modules/access_output/bonjour.h
+25
-0
modules/access_output/http.c
modules/access_output/http.c
+63
-1
modules/services_discovery/Modules.am
modules/services_discovery/Modules.am
+1
-0
modules/services_discovery/bonjour.c
modules/services_discovery/bonjour.c
+318
-0
No files found.
configure.ac
View file @
a0d58179
...
@@ -1607,7 +1607,7 @@ then
...
@@ -1607,7 +1607,7 @@ then
VLC_ADD_BUILTINS([mux_ts])
VLC_ADD_BUILTINS([mux_ts])
fi
fi
VLC_ADD_CPPFLAGS([mux_ts ts dvb],[-I${real_dvbpsi_tree}/src])
VLC_ADD_CPPFLAGS([mux_ts ts dvb],[-I${real_dvbpsi_tree}/src])
VLC_ADD_LDFLAGS([mux_ts ts dvb],[
-L${real_dvbpsi_tree}/src/.libs -ldvbpsi
])
VLC_ADD_LDFLAGS([mux_ts ts dvb],[
${real_dvbpsi_tree}/src/.libs/libdvbpsi.a
])
else
else
dnl The given libdvbpsi wasn't built
dnl The given libdvbpsi wasn't built
AC_MSG_RESULT(no)
AC_MSG_RESULT(no)
...
@@ -4152,6 +4152,21 @@ then
...
@@ -4152,6 +4152,21 @@ then
[AC_MSG_WARN(DAAP library not found)])
[AC_MSG_WARN(DAAP library not found)])
fi
fi
dnl
dnl Bonjour services discovery
dnl
AC_ARG_ENABLE(bonjour,
[ --enable-bonjour Bonjour services discovery (default enabled)])
if test "${enable_bonjour}" != "no"
then
PKG_CHECK_MODULES(BONJOUR, avahi-client >= 0.3,
[AC_DEFINE(HAVE_AVAHI_CLIENT, [], [Define if you have the avahi-client library])
VLC_ADD_LDFLAGS([bonjour access_output_http],[$BONJOUR_LIBS])
VLC_ADD_CFLAGS([bonjour access_output_http],[$BONJOUR_CFLAGS])
VLC_ADD_PLUGINS([bonjour]) ],
[AC_MSG_WARN(avahi-client library not found)])
fi
dnl
dnl
dnl Lirc plugin
dnl Lirc plugin
dnl
dnl
...
...
modules/access_output/Modules.am
View file @
a0d58179
SOURCES_access_output_dummy = dummy.c
SOURCES_access_output_dummy = dummy.c
SOURCES_access_output_file = file.c
SOURCES_access_output_file = file.c
SOURCES_access_output_udp = udp.c
SOURCES_access_output_udp = udp.c
SOURCES_access_output_http = http.c
SOURCES_access_output_http = http.c
bonjour.c bonjour.h
SOURCES_access_output_shout = shout.c
SOURCES_access_output_shout = shout.c
modules/access_output/bonjour.c
0 → 100644
View file @
a0d58179
/*****************************************************************************
* bonjour.c
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon@nanocrew.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <vlc/vlc.h>
#ifdef HAVE_AVAHI_CLIENT
#include <vlc/intf.h>
#include <vlc/sout.h>
#include <avahi-client/client.h>
#include <avahi-common/alternative.h>
#include <avahi-common/simple-watch.h>
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
/*****************************************************************************
* Structures
*****************************************************************************/
typedef
struct
poll_thread_t
{
VLC_COMMON_MEMBERS
AvahiSimplePoll
*
simple_poll
;
}
poll_thread_t
;
typedef
struct
bonjour_t
{
vlc_object_t
*
p_log
;
poll_thread_t
*
poll_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
)
{
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
,
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_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
(
poll_thread_t
*
p_pt
)
{
vlc_thread_ready
(
p_pt
);
while
(
!
p_pt
->
b_die
)
if
(
avahi_simple_poll_iterate
(
p_pt
->
simple_poll
,
100
)
!=
0
)
break
;
}
/*****************************************************************************
* bonjour_start_service
*****************************************************************************/
void
*
bonjour_start_service
(
vlc_object_t
*
p_log
,
char
*
psz_stype
,
char
*
psz_name
,
int
i_port
,
char
*
psz_txt
)
{
int
err
;
bonjour_t
*
p_sys
;
p_sys
=
(
bonjour_t
*
)
malloc
(
sizeof
(
*
p_sys
)
);
if
(
p_sys
==
NULL
)
{
msg_Err
(
p_log
,
"out of memory"
);
return
NULL
;
}
memset
(
p_sys
,
0
,
sizeof
(
*
p_sys
)
);
p_sys
->
p_log
=
p_log
;
p_sys
->
i_port
=
i_port
;
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
)
{
msg_Err
(
p_sys
->
p_log
,
"out of memory"
);
goto
error
;
}
if
(
psz_txt
!=
NULL
)
{
p_sys
->
psz_txt
=
avahi_strdup
(
psz_txt
);
if
(
p_sys
->
psz_txt
==
NULL
)
{
msg_Err
(
p_sys
->
p_log
,
"out of memory"
);
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
),
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
;
}
p_sys
->
poll_thread
=
vlc_object_create
(
p_sys
->
p_log
,
sizeof
(
poll_thread_t
)
);
if
(
p_sys
->
poll_thread
==
NULL
)
{
msg_Err
(
p_sys
->
p_log
,
"out of memory"
);
goto
error
;
}
p_sys
->
poll_thread
->
simple_poll
=
p_sys
->
simple_poll
;
if
(
vlc_thread_create
(
p_sys
->
poll_thread
,
"Avahi Poll Iterate Thread"
,
poll_iterate_thread
,
VLC_THREAD_PRIORITY_HIGHEST
,
VLC_FALSE
)
)
{
msg_Err
(
p_sys
->
p_log
,
"failed to create poll iterate thread"
);
goto
error
;
}
return
(
void
*
)
p_sys
;
error:
if
(
p_sys
->
poll_thread
!=
NULL
)
vlc_object_destroy
(
p_sys
->
poll_thread
);
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
(
(
void
*
)
p_sys
);
return
NULL
;
}
/*****************************************************************************
* bonjour_stop_service
*****************************************************************************/
void
bonjour_stop_service
(
void
*
_p_sys
)
{
bonjour_t
*
p_sys
=
(
bonjour_t
*
)
_p_sys
;
if
(
p_sys
->
poll_thread
->
b_thread
)
{
p_sys
->
poll_thread
->
b_die
=
1
;
vlc_thread_join
(
p_sys
->
poll_thread
);
}
vlc_object_destroy
(
p_sys
->
poll_thread
);
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
);
}
#endif
/* HAVE_AVAHI_CLIENT */
modules/access_output/bonjour.h
0 → 100644
View file @
a0d58179
/*****************************************************************************
* bonjour.h
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon@nanocrew.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
void
*
bonjour_start_service
(
vlc_object_t
*
,
char
*
,
char
*
,
int
,
char
*
);
void
bonjour_stop_service
(
void
*
);
modules/access_output/http.c
View file @
a0d58179
/*****************************************************************************
/*****************************************************************************
* http.c
* http.c
*****************************************************************************
*****************************************************************************
* Copyright (C) 2001-200
3
the VideoLAN team
* Copyright (C) 2001-200
5
the VideoLAN team
* $Id$
* $Id$
*
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Jon Lech Johansen <jon@nanocrew.net>
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
...
@@ -29,6 +30,18 @@
...
@@ -29,6 +30,18 @@
#include <vlc/vlc.h>
#include <vlc/vlc.h>
#include <vlc/sout.h>
#include <vlc/sout.h>
#ifdef HAVE_AVAHI_CLIENT
#include <vlc/intf.h>
#include "bonjour.h"
#if defined( WIN32 )
#define DIRECTORY_SEPARATOR '\\'
#else
#define DIRECTORY_SEPARATOR '/'
#endif
#endif
#include "vlc_httpd.h"
#include "vlc_httpd.h"
#define FREE( p ) if( p ) { free( p); (p) = NULL; }
#define FREE( p ) if( p ) { free( p); (p) = NULL; }
...
@@ -120,6 +133,10 @@ struct sout_access_out_sys_t
...
@@ -120,6 +133,10 @@ struct sout_access_out_sys_t
int
i_header_size
;
int
i_header_size
;
uint8_t
*
p_header
;
uint8_t
*
p_header
;
vlc_bool_t
b_header_complete
;
vlc_bool_t
b_header_complete
;
#ifdef HAVE_AVAHI_CLIENT
void
*
p_bonjour
;
#endif
};
};
/*****************************************************************************
/*****************************************************************************
...
@@ -142,6 +159,11 @@ static int Open( vlc_object_t *p_this )
...
@@ -142,6 +159,11 @@ static int Open( vlc_object_t *p_this )
*
psz_crl
=
NULL
;
*
psz_crl
=
NULL
;
vlc_value_t
val
;
vlc_value_t
val
;
#ifdef HAVE_AVAHI_CLIENT
playlist_t
*
p_playlist
;
char
*
psz_txt
;
#endif
if
(
!
(
p_sys
=
p_access
->
p_sys
=
if
(
!
(
p_sys
=
p_access
->
p_sys
=
malloc
(
sizeof
(
sout_access_out_sys_t
)
)
)
)
malloc
(
sizeof
(
sout_access_out_sys_t
)
)
)
)
{
{
...
@@ -271,9 +293,45 @@ static int Open( vlc_object_t *p_this )
...
@@ -271,9 +293,45 @@ static int Open( vlc_object_t *p_this )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
#ifdef HAVE_AVAHI_CLIENT
asprintf
(
&
psz_txt
,
"path=%s"
,
psz_file_name
);
#endif
free
(
psz_file_name
);
free
(
psz_file_name
);
free
(
psz_name
);
free
(
psz_name
);
#ifdef HAVE_AVAHI_CLIENT
p_playlist
=
(
playlist_t
*
)
vlc_object_find
(
p_access
,
VLC_OBJECT_PLAYLIST
,
FIND_ANYWHERE
);
if
(
p_playlist
==
NULL
)
{
msg_Err
(
p_access
,
"unable to find playlist"
);
httpd_HostDelete
(
p_sys
->
p_httpd_host
);
free
(
(
void
*
)
psz_txt
);
free
(
(
void
*
)
p_sys
);
return
VLC_EGENERIC
;
}
psz_name
=
strrchr
(
p_playlist
->
status
.
p_item
->
input
.
psz_uri
,
DIRECTORY_SEPARATOR
);
if
(
psz_name
!=
NULL
)
psz_name
++
;
else
psz_name
=
p_playlist
->
status
.
p_item
->
input
.
psz_uri
;
p_sys
->
p_bonjour
=
bonjour_start_service
(
(
vlc_object_t
*
)
p_access
,
"_vlc-http._tcp"
,
psz_name
,
i_bind_port
,
psz_txt
);
free
(
(
void
*
)
psz_txt
);
if
(
p_sys
->
p_bonjour
==
NULL
)
{
vlc_object_release
(
p_playlist
);
httpd_HostDelete
(
p_sys
->
p_httpd_host
);
free
(
(
void
*
)
p_sys
);
return
VLC_EGENERIC
;
}
vlc_object_release
(
p_playlist
);
#endif
p_sys
->
i_header_allocated
=
1024
;
p_sys
->
i_header_allocated
=
1024
;
p_sys
->
i_header_size
=
0
;
p_sys
->
i_header_size
=
0
;
p_sys
->
p_header
=
malloc
(
p_sys
->
i_header_allocated
);
p_sys
->
p_header
=
malloc
(
p_sys
->
i_header_allocated
);
...
@@ -297,6 +355,10 @@ static void Close( vlc_object_t * p_this )
...
@@ -297,6 +355,10 @@ static void Close( vlc_object_t * p_this )
sout_access_out_t
*
p_access
=
(
sout_access_out_t
*
)
p_this
;
sout_access_out_t
*
p_access
=
(
sout_access_out_t
*
)
p_this
;
sout_access_out_sys_t
*
p_sys
=
p_access
->
p_sys
;
sout_access_out_sys_t
*
p_sys
=
p_access
->
p_sys
;
#ifdef HAVE_AVAHI_CLIENT
bonjour_stop_service
(
p_sys
->
p_bonjour
);
#endif
/* update p_sout->i_out_pace_nocontrol */
/* update p_sout->i_out_pace_nocontrol */
p_access
->
p_sout
->
i_out_pace_nocontrol
--
;
p_access
->
p_sout
->
i_out_pace_nocontrol
--
;
...
...
modules/services_discovery/Modules.am
View file @
a0d58179
...
@@ -3,3 +3,4 @@ SOURCES_hal = hal.c
...
@@ -3,3 +3,4 @@ SOURCES_hal = hal.c
SOURCES_daap = daap.c
SOURCES_daap = daap.c
SOURCES_shout = shout.c
SOURCES_shout = shout.c
SOURCES_upnp = upnp.cpp
SOURCES_upnp = upnp.cpp
SOURCES_bonjour = bonjour.c
modules/services_discovery/bonjour.c
0 → 100644
View file @
a0d58179
/*****************************************************************************
* bonjour.c: Bonjour services discovery module
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon@nanocrew.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Includes
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <avahi-client/client.h>
#include <avahi-common/simple-watch.h>
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
/*****************************************************************************
* Module descriptor
*****************************************************************************/
/* Callbacks */
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
();
/*****************************************************************************
* Local structures
*****************************************************************************/
struct
services_discovery_sys_t
{
/* playlist node */
playlist_item_t
*
p_node
;
playlist_t
*
p_playlist
;
AvahiSimplePoll
*
simple_poll
;
AvahiClient
*
client
;
AvahiServiceBrowser
*
sb
;
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
/* Main functions */
static
void
Run
(
services_discovery_t
*
p_intf
);
/*****************************************************************************
* client_callback
*****************************************************************************/
static
void
client_callback
(
AvahiClient
*
c
,
AvahiClientState
state
,
void
*
userdata
)
{
services_discovery_t
*
p_sd
=
(
services_discovery_t
*
)
userdata
;
services_discovery_sys_t
*
p_sys
=
p_sd
->
p_sys
;
if
(
state
==
AVAHI_CLIENT_DISCONNECTED
)
{
msg_Err
(
p_sd
,
"avahi client disconnected"
);
avahi_simple_poll_quit
(
p_sys
->
simple_poll
);
}
}
/*****************************************************************************
* resolve_callback
*****************************************************************************/
static
void
resolve_callback
(
AvahiServiceResolver
*
r
,
AvahiIfIndex
interface
,
AvahiProtocol
protocol
,
AvahiResolverEvent
event
,
const
char
*
name
,
const
char
*
type
,
const
char
*
domain
,
const
char
*
host_name
,
const
AvahiAddress
*
address
,
uint16_t
port
,
AvahiStringList
*
txt
,
void
*
userdata
)
{
services_discovery_t
*
p_sd
=
(
services_discovery_t
*
)
userdata
;
services_discovery_sys_t
*
p_sys
=
p_sd
->
p_sys
;
if
(
event
==
AVAHI_RESOLVER_TIMEOUT
)
{
msg_Err
(
p_sd
,
"failed to resolve service '%s' of type '%s' in domain '%s'"
,
name
,
type
,
domain
);
}
else
if
(
event
==
AVAHI_RESOLVER_FOUND
)
{
char
a
[
128
];
char
*
psz_uri
=
NULL
;
AvahiStringList
*
asl
;
playlist_item_t
*
p_item
=
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
);
asl
=
avahi_string_list_find
(
txt
,
"path"
);
if
(
asl
!=
NULL
)
{
size_t
size
;
char
*
key
=
NULL
;
char
*
value
=
NULL
;
if
(
avahi_string_list_get_pair
(
asl
,
&
key
,
&
value
,
&
size
)
==
0
)
asprintf
(
&
psz_uri
,
"http://%s:%d%s"
,
a
,
port
,
value
);
}
else
{
asprintf
(
&
psz_uri
,
"http://%s:%d"
,
a
,
port
);
}
if
(
psz_uri
!=
NULL
)
p_item
=
playlist_ItemNew
(
p_sd
,
psz_uri
,
name
);
if
(
p_item
!=
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
);
}
}
avahi_service_resolver_free
(
r
);
}
/*****************************************************************************
* browser_callback
*****************************************************************************/
static
void
browse_callback
(
AvahiServiceBrowser
*
b
,
AvahiIfIndex
interface
,
AvahiProtocol
protocol
,
AvahiBrowserEvent
event
,
const
char
*
name
,
const
char
*
type
,
const
char
*
domain
,
void
*
userdata
)
{
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
,
resolve_callback
,
userdata
)
==
NULL
)
{
msg_Err
(
p_sd
,
"failed to resolve service '%s': %s"
,
name
,
avahi_strerror
(
avahi_client_errno
(
p_sys
->
client
)
)
);
}
}
else
{
playlist_item_t
*
p_item
;
p_item
=
playlist_ChildSearchName
(
p_sys
->
p_node
,
name
);
if
(
p_item
==
NULL
)
{
msg_Err
(
p_sd
,
"failed to find service '%s' in playlist"
,
name
);
}
else
{
playlist_Delete
(
p_sys
->
p_playlist
,
p_item
->
input
.
i_id
);
}
}
}
/*****************************************************************************
* Open: initialize and create stuff
*****************************************************************************/
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
;
}
memset
(
p_sys
,
0
,
sizeof
(
*
p_sys
)
);
p_sys
->
simple_poll
=
avahi_simple_poll_new
();
if
(
p_sys
->
simple_poll
==
NULL
)
{
msg_Err
(
p_sd
,
"failed to create avahi simple poll"
);
goto
error
;
}
p_sys
->
client
=
avahi_client_new
(
avahi_simple_poll_get
(
p_sys
->
simple_poll
),
client_callback
,
p_sd
,
&
err
);
if
(
p_sys
->
client
==
NULL
)
{
msg_Err
(
p_sd
,
"failed to create avahi client: %s"
,
avahi_strerror
(
err
)
);
goto
error
;
}
p_sys
->
sb
=
avahi_service_browser_new
(
p_sys
->
client
,
AVAHI_IF_UNSPEC
,
AVAHI_PROTO_UNSPEC
,
"_vlc-http._tcp"
,
NULL
,
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
;
}
p_view
=
playlist_ViewFind
(
p_sys
->
p_playlist
,
VIEW_CATEGORY
);
p_sys
->
p_node
=
playlist_NodeCreate
(
p_sys
->
p_playlist
,
VIEW_CATEGORY
,
_
(
"Bonjour"
),
p_view
->
p_root
);
p_sys
->
p_node
->
i_flags
|=
PLAYLIST_RO_FLAG
;
val
.
b_bool
=
VLC_TRUE
;
var_Set
(
p_sys
->
p_playlist
,
"intf-change"
,
val
);
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
);
free
(
(
void
*
)
p_sys
);
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Close: cleanup
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
services_discovery_t
*
p_sd
=
(
services_discovery_t
*
)
p_this
;
services_discovery_sys_t
*
p_sys
=
p_sd
->
p_sys
;
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
);
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
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment