X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fstream_output%2Fsap.c;h=fc84ed7961da53971473514cbc762f17ca68fb82;hb=aafa45bdc907464e0a4d6624233d8533edb51c05;hp=606fbec3afaa07daf86163677578ab1be003079e;hpb=d6a7c477213c5b927459372e89c8ddc3b67a9475;p=vlc diff --git a/src/stream_output/sap.c b/src/stream_output/sap.c index 606fbec3af..fc84ed7961 100644 --- a/src/stream_output/sap.c +++ b/src/stream_output/sap.c @@ -1,7 +1,7 @@ /***************************************************************************** * sap.c : SAP announce handler ***************************************************************************** - * Copyright (C) 2002-2005 the VideoLAN team + * Copyright (C) 2002-2007 the VideoLAN team * $Id$ * * Authors: Clément Stenac @@ -26,18 +26,24 @@ * Preamble *****************************************************************************/ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include #include /* free() */ #include /* sprintf() */ -#include /* strerror() */ +#include #include /* tolower(), isxdigit() */ +#include #include #include #include #include "stream_output.h" +#include "libvlc.h" /* SAP is always on that port */ #define SAP_PORT 9875 @@ -66,8 +72,8 @@ struct sap_address_t /* Used for flow control */ mtime_t t1; - vlc_bool_t b_enabled; - vlc_bool_t b_ready; + bool b_enabled; + bool b_ready; int i_interval; int i_buff; int i_limit; @@ -88,11 +94,8 @@ struct sap_session_t { /***************************************************************************** * Local prototypes *****************************************************************************/ -static void RunThread( vlc_object_t *p_this); -static int CalculateRate( sap_handler_t *p_sap, sap_address_t *p_address ); -static char *SDPGenerate( sap_handler_t *p_sap, - const session_descriptor_t *p_session, - const sap_address_t *p_addr, vlc_bool_t b_ssm ); +static void * RunThread( vlc_object_t *p_this); +static int ComputeRate( sap_address_t *p_address ); static int announce_SendSAPAnnounce( sap_handler_t *p_sap, sap_session_t *p_session ); @@ -104,6 +107,8 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, static int announce_SAPAnnounceDel( sap_handler_t *p_sap, session_descriptor_t *p_session ); +static void announce_SAPHandlerDestructor( vlc_object_t *p_this ); + /** * Create the SAP handler @@ -115,15 +120,12 @@ sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce ) { sap_handler_t *p_sap; - p_sap = vlc_object_create( p_announce, sizeof( sap_handler_t ) ); - + p_sap = vlc_custom_create( VLC_OBJECT(p_announce), sizeof( sap_handler_t ), + VLC_OBJECT_ANNOUNCE, "announce" ); if( !p_sap ) - { - msg_Err( p_announce, "out of memory" ); return NULL; - } - vlc_mutex_init( p_sap, &p_sap->object_lock ); + p_sap->psz_object_name = strdup( "sap announcer" ); p_sap->pf_add = announce_SAPAnnounceAdd; p_sap->pf_del = announce_SAPAnnounceDel; @@ -135,27 +137,25 @@ sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce ) p_sap->b_control = config_GetInt( p_sap, "sap-flow-control"); if( vlc_thread_create( p_sap, "sap handler", RunThread, - VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) + VLC_THREAD_PRIORITY_LOW, false ) ) { msg_Dbg( p_announce, "unable to spawn SAP handler thread"); - free( p_sap ); + vlc_object_release( p_sap ); return NULL; - }; + } + + vlc_object_set_destructor( p_sap, announce_SAPHandlerDestructor ); + msg_Dbg( p_announce, "thread created, %i sessions", p_sap->i_sessions); + return p_sap; } -/** - * Destroy the SAP handler - * \param p_this the SAP Handler to destroy - * \return nothing - */ -void announce_SAPHandlerDestroy( sap_handler_t *p_sap ) +static void announce_SAPHandlerDestructor( vlc_object_t * p_this ) { + sap_handler_t *p_sap = (sap_handler_t *)p_this; int i; - vlc_mutex_destroy( &p_sap->object_lock ); - /* Free the remaining sessions */ for( i = 0 ; i< p_sap->i_sessions ; i++) { @@ -181,9 +181,6 @@ void announce_SAPHandlerDestroy( sap_handler_t *p_sap ) REMOVE_ELEM( p_sap->pp_addresses, p_sap->i_addresses, i ); FREENULL( p_address ); } - - /* Free the structure */ - vlc_object_destroy( p_sap ); } /** @@ -191,7 +188,7 @@ void announce_SAPHandlerDestroy( sap_handler_t *p_sap ) * \param p_this the SAP Handler object * \return nothing */ -static void RunThread( vlc_object_t *p_this) +static void * RunThread( vlc_object_t *p_this) { sap_handler_t *p_sap = (sap_handler_t*)p_this; sap_session_t *p_session; @@ -201,19 +198,19 @@ static void RunThread( vlc_object_t *p_this) int i; /* If needed, get the rate info */ - if( p_sap->b_control == VLC_TRUE ) + if( p_sap->b_control == true ) { for( i = 0 ; i< p_sap->i_addresses ; i++) { - if( p_sap->pp_addresses[i]->b_enabled == VLC_TRUE ) + if( p_sap->pp_addresses[i]->b_enabled == true ) { - CalculateRate( p_sap, p_sap->pp_addresses[i] ); + ComputeRate( p_sap->pp_addresses[i] ); } } } /* Find the session to announce */ - vlc_mutex_lock( &p_sap->object_lock ); + vlc_object_lock( p_sap ); if( p_sap->i_sessions > p_sap->i_current_session + 1) { p_sap->i_current_session++; @@ -224,22 +221,23 @@ static void RunThread( vlc_object_t *p_this) } else { - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); msleep( SAP_IDLE ); continue; } p_session = p_sap->pp_sessions[p_sap->i_current_session]; - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); /* And announce it */ - if( p_session->p_address->b_enabled == VLC_TRUE && - p_session->p_address->b_ready == VLC_TRUE ) + if( p_session->p_address->b_enabled == true && + p_session->p_address->b_ready == true ) { announce_SendSAPAnnounce( p_sap, p_session ); } msleep( SAP_IDLE ); } + return NULL; } /* Add a SAP announce */ @@ -248,17 +246,17 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, { int i; char psz_addr[NI_MAXNUMERICHOST]; - vlc_bool_t b_ipv6 = VLC_FALSE, b_ssm = VLC_FALSE; + bool b_ipv6 = false, b_ssm = false; sap_session_t *p_sap_session; mtime_t i_hash; struct sockaddr_storage addr; socklen_t addrlen; - vlc_mutex_lock( &p_sap->object_lock ); + vlc_object_lock( p_sap ); addrlen = p_session->addrlen; if ((addrlen == 0) || (addrlen > sizeof (addr))) { - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); msg_Err( p_sap, "No/invalid address specified for SAP announce" ); return VLC_EGENERIC; } @@ -288,7 +286,7 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, /* Unicast IPv6 - assume global scope */ memcpy( a6->s6_addr, "\xff\x0e", 2 ); - b_ipv6 = VLC_TRUE; + b_ipv6 = true; break; } #endif @@ -325,7 +323,7 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, { msg_Err( p_sap, "Out-of-scope multicast address " "not supported by SAP" ); - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); return VLC_EGENERIC; } @@ -334,7 +332,7 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, } default: - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); msg_Err( p_sap, "Address family %d not supported by SAP", addr.ss_family ); return VLC_EGENERIC; @@ -345,7 +343,7 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, if( i ) { - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); msg_Err( p_sap, "%s", vlc_gai_strerror( i ) ); return VLC_EGENERIC; } @@ -373,34 +371,34 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, malloc( sizeof(sap_address_t) ); if( !p_address ) { - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); return VLC_ENOMEM; } p_address->psz_address = strdup( psz_addr ); p_address->i_wfd = net_ConnectUDP( VLC_OBJECT(p_sap), psz_addr, SAP_PORT, 255 ); if( p_address->i_wfd != -1 ) { - net_StopRecv( p_address->i_wfd ); + shutdown( p_address->i_wfd, SHUT_RD ); p_address->origlen = sizeof (p_address->orig); getsockname (p_address->i_wfd, (struct sockaddr *)&p_address->orig, &p_address->origlen); } - if( p_sap->b_control == VLC_TRUE ) + if( p_sap->b_control == true ) { p_address->i_rfd = net_ListenUDP1( (vlc_object_t*)p_sap, psz_addr, SAP_PORT ); if( p_address->i_rfd != -1 ) - net_StopSend( p_address->i_rfd ); + shutdown( p_address->i_rfd, SHUT_WR ); p_address->i_buff = 0; - p_address->b_enabled = VLC_TRUE; - p_address->b_ready = VLC_FALSE; + p_address->b_enabled = true; + p_address->b_ready = false; p_address->i_limit = 10000; /* 10000 bps */ p_address->t1 = 0; } else { - p_address->b_enabled = VLC_TRUE; - p_address->b_ready = VLC_TRUE; + p_address->b_enabled = true; + p_address->b_ready = true; p_address->i_interval = config_GetInt( p_sap,"sap-interval"); p_address->i_rfd = -1; } @@ -409,7 +407,7 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, && p_sap->b_control ) ) { msg_Warn( p_sap, "disabling address" ); - p_address->b_enabled = VLC_FALSE; + p_address->b_enabled = false; } INSERT_ELEM( p_sap->pp_addresses, @@ -419,9 +417,8 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, p_sap_session->p_address = p_address; } - if (p_session->origlen == 0) - memcpy (&p_session->orig, &p_sap_session->p_address->orig, - p_session->origlen = p_sap_session->p_address->origlen); + memcpy (&p_session->orig, &p_sap_session->p_address->orig, + p_session->origlen = p_sap_session->p_address->origlen); size_t headsize = 20; switch (p_session->orig.ss_family) @@ -437,21 +434,12 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, default: msg_Err( p_sap, "Address family %d not supported by SAP", addr.ss_family ); - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); return VLC_EGENERIC; } /* If needed, build the SDP */ - if( p_session->psz_sdp == NULL ) - { - p_session->psz_sdp = SDPGenerate( p_sap, p_session, - p_sap_session->p_address, b_ssm ); - if( p_session->psz_sdp == NULL ) - { - vlc_mutex_unlock( &p_sap->object_lock ); - return VLC_ENOMEM; - } - } + assert( p_session->psz_sdp != NULL ); p_sap_session->i_last = 0; p_sap_session->i_length = headsize + strlen (p_session->psz_sdp); @@ -459,7 +447,7 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, if (p_sap_session->psz_data == NULL) { free (p_session->psz_sdp); - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); return VLC_ENOMEM; } @@ -513,7 +501,7 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, msg_Dbg( p_sap,"%i addresses, %i sessions", p_sap->i_addresses,p_sap->i_sessions); - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); return VLC_SUCCESS; } @@ -523,7 +511,7 @@ static int announce_SAPAnnounceDel( sap_handler_t *p_sap, session_descriptor_t *p_session ) { int i; - vlc_mutex_lock( &p_sap->object_lock ); + vlc_object_lock( p_sap ); msg_Dbg( p_sap, "removing session %p from SAP", p_session); @@ -532,6 +520,7 @@ static int announce_SAPAnnounceDel( sap_handler_t *p_sap, { if( p_session == p_sap->pp_sessions[i]->p_sd ) { + free( p_session->psz_sdp ); sap_session_t *p_mysession = p_sap->pp_sessions[i]; REMOVE_ELEM( p_sap->pp_sessions, p_sap->i_sessions, @@ -549,7 +538,7 @@ static int announce_SAPAnnounceDel( sap_handler_t *p_sap, msg_Dbg( p_sap,"%i announcements remaining", p_sap->i_sessions ); - vlc_mutex_unlock( &p_sap->object_lock ); + vlc_object_unlock( p_sap ); return VLC_SUCCESS; } @@ -585,62 +574,13 @@ static int announce_SendSAPAnnounce( sap_handler_t *p_sap, p_session->i_next = p_session->i_last + p_session->p_address->i_interval*1000000; } - else - { - return VLC_SUCCESS; - } return VLC_SUCCESS; } -static char *SDPGenerate( sap_handler_t *p_sap, - const session_descriptor_t *p_session, - const sap_address_t *p_addr, vlc_bool_t b_ssm ) -{ - char *psz_group, *psz_name, *psz_sdp; - - char *head = StartSDP (p_session->psz_name, p_session->description, - p_session->url, p_session->email, p_session->phone, b_ssm, - (const struct sockaddr *)&p_session->orig, p_session->origlen, - (const struct sockaddr *)&p_session->addr, p_session->addrlen); - if (head == NULL) - return NULL; - - psz_group = p_session->psz_group; - psz_name = p_session->psz_name; - - char *plgroup; - if ((psz_group == NULL) - || (asprintf (&plgroup, "a=x-plgroup:%s\r\n", psz_group) == -1)) - plgroup = NULL; - - const char *comedia = NULL; - if (!strncasecmp (p_session->sdpformat, "DCCP", 4) - || !strncasecmp (p_session->sdpformat, "TCP", 3)) - comedia = "a=setup:passive\r\n" - "a=connection:new\r\n"; - - int res = asprintf (&psz_sdp, "%s" "%s" "%s" - "m=video %d %s\r\n", - head, - plgroup ?: "", - comedia ?: "", - ntohs (net_GetPort ((const struct sockaddr *)&p_session->addr)), - p_session->sdpformat); - free (plgroup); - - if (res == -1) - return NULL; - - msg_Dbg( p_sap, "Generated SDP (%i bytes):\n%s", strlen(psz_sdp), - psz_sdp ); - return psz_sdp; -} - -static int CalculateRate( sap_handler_t *p_sap, sap_address_t *p_address ) +static int ComputeRate( sap_address_t *p_address ) { - int i_read; uint8_t buffer[SAP_MAX_BUFFER]; - int i_tot = 0; + ssize_t i_tot = 0; mtime_t i_temp; int i_rate; @@ -649,13 +589,14 @@ static int CalculateRate( sap_handler_t *p_sap, sap_address_t *p_address ) p_address->t1 = mdate(); return VLC_SUCCESS; } - do + for (;;) { /* Might be too slow if we have huge data */ - i_read = net_ReadNonBlock( p_sap, p_address->i_rfd, NULL, buffer, - SAP_MAX_BUFFER, 0 ); + ssize_t i_read = recv( p_address->i_rfd, buffer, SAP_MAX_BUFFER, 0 ); + if (i_read == -1) + break; i_tot += i_read; - } while( i_read > 0 ); + } i_temp = mdate(); @@ -684,7 +625,7 @@ static int CalculateRate( sap_handler_t *p_sap, sap_address_t *p_address ) p_address->psz_address,SAP_PORT, i_rate, p_address->i_interval ); #endif - p_address->b_ready = VLC_TRUE; + p_address->b_ready = true; p_address->t1 = i_temp; p_address->i_buff = 0;