* Preamble
*****************************************************************************/
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
#include <stdlib.h> /* free() */
#include <stdio.h> /* sprintf() */
-#include <string.h> /* strerror() */
+#include <string.h>
#include <ctype.h> /* tolower(), isxdigit() */
+#include <assert.h>
#include <vlc_sout.h>
#include <vlc_network.h>
#include <vlc_charset.h>
#include "stream_output.h"
+#include "libvlc.h"
/* SAP is always on that port */
#define SAP_PORT 9875
/* 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;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static void RunThread( vlc_object_t *p_this);
+static void * RunThread( vlc_object_t *p_this);
static int ComputeRate( sap_address_t *p_address );
-static char *SDPGenerate( sap_handler_t *p_sap,
- const session_descriptor_t *p_session,
- vlc_bool_t b_ssm );
static int announce_SendSAPAnnounce( sap_handler_t *p_sap,
sap_session_t *p_session );
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
{
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;
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++)
{
REMOVE_ELEM( p_sap->pp_addresses, p_sap->i_addresses, i );
FREENULL( p_address );
}
-
- /* Free the structure */
- vlc_object_destroy( 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;
{
int i;
+ msleep( SAP_IDLE );
+
/* 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 )
{
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++;
}
else
{
- vlc_mutex_unlock( &p_sap->object_lock );
- msleep( SAP_IDLE );
+ vlc_object_unlock( p_sap );
continue;
}
p_session = p_sap->pp_sessions[p_sap->i_current_session];
- vlc_mutex_unlock( &p_sap->object_lock );
/* 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 );
+ vlc_object_unlock( p_sap );
}
+ return NULL;
}
/* Add a SAP announce */
{
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;
}
/* Unicast IPv6 - assume global scope */
memcpy( a6->s6_addr, "\xff\x0e", 2 );
- b_ipv6 = VLC_TRUE;
+ b_ipv6 = true;
break;
}
#endif
{
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;
}
}
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;
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;
}
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->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 )
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;
}
&& 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,
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)
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, 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);
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;
}
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;
}
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);
{
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,
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;
}
return VLC_SUCCESS;
}
-static char *SDPGenerate( sap_handler_t *p_sap,
- const session_descriptor_t *p_session,
- vlc_bool_t b_ssm )
-{
- char *psz_group, *psz_name, *psz_sdp;
-
- char *head = sdp_Start (p_session->psz_name, p_session->description,
- p_session->url, p_session->email, p_session->phone,
- (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 (%u bytes):\n%s",
- (unsigned)strlen(psz_sdp), psz_sdp );
- return psz_sdp;
-}
-
static int ComputeRate( sap_address_t *p_address )
{
uint8_t buffer[SAP_MAX_BUFFER];
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;