add_savefile: remove callback parameter
[vlc/asuraparaju-public.git] / modules / access_output / bonjour.c
blob3dfb9b888a136860df1342217a7629f9e7dfca92
1 /*****************************************************************************
2 * bonjour.c
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
5 * $Id$
7 * Authors: Jon Lech Johansen <jon@nanocrew.net>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include "bonjour.h"
35 #ifdef HAVE_AVAHI_CLIENT
36 #include <vlc_sout.h>
38 #include <avahi-client/client.h>
39 #include <avahi-client/publish.h>
40 #include <avahi-client/lookup.h>
41 #include <avahi-common/alternative.h>
42 #include <avahi-common/simple-watch.h>
43 #include <avahi-common/malloc.h>
44 #include <avahi-common/error.h>
46 /*****************************************************************************
47 * Structures
48 *****************************************************************************/
49 typedef struct poll_thread_t
51 VLC_COMMON_MEMBERS
53 AvahiSimplePoll *simple_poll;
54 } poll_thread_t;
56 typedef struct bonjour_t
58 vlc_object_t *p_log;
60 poll_thread_t *poll_thread;
61 AvahiSimplePoll *simple_poll;
62 AvahiEntryGroup *group;
63 AvahiClient *client;
64 char *psz_stype;
65 char *psz_name;
66 int i_port;
67 char *psz_txt;
68 } bonjour_t;
70 /*****************************************************************************
71 * Prototypes
72 *****************************************************************************/
73 static int create_service( bonjour_t * );
75 /*****************************************************************************
76 * entry_group_callback
77 *****************************************************************************/
78 static void entry_group_callback( AvahiEntryGroup *g,
79 AvahiEntryGroupState state,
80 void *userdata )
82 (void)g;
83 bonjour_t *p_sys = (bonjour_t *)userdata;
85 if( state == AVAHI_ENTRY_GROUP_ESTABLISHED )
87 msg_Dbg( p_sys->p_log, "service '%s' successfully established",
88 p_sys->psz_name );
90 else if( state == AVAHI_ENTRY_GROUP_COLLISION )
92 char *n;
94 n = avahi_alternative_service_name( p_sys->psz_name );
95 avahi_free( p_sys->psz_name );
96 p_sys->psz_name = n;
98 create_service( p_sys );
102 /*****************************************************************************
103 * create_service
104 *****************************************************************************/
105 static int create_service( bonjour_t *p_sys )
107 int error;
109 if( p_sys->group == NULL )
111 p_sys->group = avahi_entry_group_new( p_sys->client,
112 entry_group_callback,
113 p_sys );
114 if( p_sys->group == NULL )
116 msg_Err( p_sys->p_log, "failed to create avahi entry group: %s",
117 avahi_strerror( avahi_client_errno( p_sys->client ) ) );
118 return VLC_EGENERIC;
122 error = avahi_entry_group_add_service( p_sys->group, AVAHI_IF_UNSPEC,
123 AVAHI_PROTO_UNSPEC, 0, p_sys->psz_name,
124 p_sys->psz_stype, NULL, NULL,
125 p_sys->i_port,
126 p_sys->psz_txt, NULL );
127 if( error < 0 )
129 msg_Err( p_sys->p_log, "failed to add %s service: %s",
130 p_sys->psz_stype, avahi_strerror( error ) );
131 return VLC_EGENERIC;
134 error = avahi_entry_group_commit( p_sys->group );
135 if( error < 0 )
137 msg_Err( p_sys->p_log, "failed to commit entry group: %s",
138 avahi_strerror( error ) );
139 return VLC_EGENERIC;
142 return VLC_SUCCESS;
145 /*****************************************************************************
146 * client_callback
147 *****************************************************************************/
148 static void client_callback( AvahiClient *c,
149 AvahiClientState state,
150 void * userdata )
152 bonjour_t *p_sys = (bonjour_t *)userdata;
154 if( state == AVAHI_CLIENT_S_RUNNING )
156 p_sys->client = c;
157 create_service( p_sys );
159 else if( state == AVAHI_CLIENT_S_COLLISION )
161 if( p_sys->group != NULL )
162 avahi_entry_group_reset( p_sys->group );
164 else if( state == AVAHI_CLIENT_FAILURE &&
165 (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) )
167 msg_Err( p_sys->p_log, "avahi client disconnected" );
168 avahi_simple_poll_quit( p_sys->simple_poll );
172 /*****************************************************************************
173 * poll_iterate_thread
174 *****************************************************************************/
175 static void* poll_iterate_thread( vlc_object_t *p_this )
177 poll_thread_t *p_pt = (poll_thread_t*)p_this;
178 int canc = vlc_savecancel ();
180 while( vlc_object_alive (p_pt) )
181 if( avahi_simple_poll_iterate( p_pt->simple_poll, 100 ) != 0 )
182 break;
184 vlc_restorecancel (canc);
185 return NULL;
188 /*****************************************************************************
189 * bonjour_start_service
190 *****************************************************************************/
191 void *bonjour_start_service( vlc_object_t *p_log, const char *psz_stype,
192 const char *psz_name, int i_port, char *psz_txt )
194 int err;
196 bonjour_t* p_sys = calloc( 1, sizeof(*p_sys) );
197 if( p_sys == NULL )
198 return NULL;
200 p_sys->p_log = p_log;
201 p_sys->i_port = i_port;
202 p_sys->psz_name = avahi_strdup( psz_name );
203 p_sys->psz_stype = avahi_strdup( psz_stype );
204 if( p_sys->psz_name == NULL || p_sys->psz_stype == NULL )
205 goto error;
207 if( psz_txt != NULL )
209 p_sys->psz_txt = avahi_strdup( psz_txt );
210 if( p_sys->psz_txt == NULL )
211 goto error;
214 p_sys->simple_poll = avahi_simple_poll_new();
215 if( p_sys->simple_poll == NULL )
217 msg_Err( p_sys->p_log, "failed to create avahi simple pool" );
218 goto error;
221 p_sys->client = avahi_client_new( avahi_simple_poll_get(p_sys->simple_poll),
223 client_callback, p_sys, &err );
224 if( p_sys->client == NULL )
226 msg_Err( p_sys->p_log, "failed to create avahi client: %s",
227 avahi_strerror( err ) );
228 goto error;
231 p_sys->poll_thread = vlc_object_create( p_sys->p_log,
232 sizeof(poll_thread_t) );
233 if( p_sys->poll_thread == NULL )
234 goto error;
235 p_sys->poll_thread->simple_poll = p_sys->simple_poll;
237 if( vlc_thread_create( p_sys->poll_thread, "Avahi Poll Iterate Thread",
238 poll_iterate_thread,
239 VLC_THREAD_PRIORITY_HIGHEST ) )
241 msg_Err( p_sys->p_log, "failed to create poll iterate thread" );
242 goto error;
245 return (void *)p_sys;
247 error:
248 if( p_sys->poll_thread != NULL )
249 vlc_object_release( p_sys->poll_thread );
250 if( p_sys->client != NULL )
251 avahi_client_free( p_sys->client );
252 if( p_sys->simple_poll != NULL )
253 avahi_simple_poll_free( p_sys->simple_poll );
254 if( p_sys->psz_stype != NULL )
255 avahi_free( p_sys->psz_stype );
256 if( p_sys->psz_name != NULL )
257 avahi_free( p_sys->psz_name );
258 if( p_sys->psz_txt != NULL )
259 avahi_free( p_sys->psz_txt );
261 free( p_sys );
263 return NULL;
266 /*****************************************************************************
267 * bonjour_stop_service
268 *****************************************************************************/
269 void bonjour_stop_service( void *_p_sys )
271 bonjour_t *p_sys = (bonjour_t *)_p_sys;
273 vlc_object_kill( p_sys->poll_thread );
274 vlc_thread_join( p_sys->poll_thread );
275 vlc_object_release( p_sys->poll_thread );
277 if( p_sys->group != NULL )
278 avahi_entry_group_free( p_sys->group );
280 avahi_client_free( p_sys->client );
281 avahi_simple_poll_free( p_sys->simple_poll );
283 if( p_sys->psz_name != NULL )
284 avahi_free( p_sys->psz_name );
286 if( p_sys->psz_txt != NULL )
287 avahi_free( p_sys->psz_txt );
289 avahi_free( p_sys->psz_stype );
291 free( _p_sys );
294 #endif /* HAVE_AVAHI_CLIENT */