* all: as announce calls non-standard functions (SLP), remove it from
authorClément Stenac <zorglub@videolan.org>
Thu, 14 Aug 2003 20:02:55 +0000 (20:02 +0000)
committerClément Stenac <zorglub@videolan.org>
Thu, 14 Aug 2003 20:02:55 +0000 (20:02 +0000)
src, and build it in the stream_out_standard module to avoid a link

Makefile.am
configure.ac
include/announce.h [deleted file]
include/vlc_common.h
modules/stream_out/Modules.am
modules/stream_out/announce.c [new file with mode: 0644]
modules/stream_out/announce.h [new file with mode: 0644]
modules/stream_out/standard.c
src/misc/modules.c
src/stream_output/announce.c [deleted file]

index 5542a15..d40d2fd 100644 (file)
@@ -87,7 +87,6 @@ HEADERS_include = \
        include/os_specific.h \
        include/stream_control.h \
        include/stream_output.h \
-       include/announce.h \
        include/variables.h \
        include/video_output.h \
        include/vlc_common.h \
@@ -315,7 +314,6 @@ SOURCES_libvlc_common = \
        src/audio_output/output.c \
        src/audio_output/intf.c \
        src/stream_output/stream_output.c \
-       src/stream_output/announce.c \
        src/misc/mtime.c \
        src/misc/modules.c \
        src/misc/threads.c \
index 7a2b41e..c9dcd83 100644 (file)
@@ -1,5 +1,5 @@
 dnl Autoconf settings for vlc
-dnl $Id: configure.ac,v 1.58 2003/08/13 23:26:55 gbazin Exp $
+dnl $Id: configure.ac,v 1.59 2003/08/14 20:02:55 zorglub Exp $
 
 AC_INIT(vlc,0.6.3-cvs)
 
@@ -2836,7 +2836,7 @@ then
     then
       AX_ADD_PLUGINS([slp])
       AX_ADD_LDFLAGS([slp],[-lslp])
-      AX_ADD_LDFLAGS([vlc],[-lslp])
+      AX_ADD_LDFLAGS([stream_out_standard],[-lslp])
     fi
   else
     AC_MSG_CHECKING(for slp headers in ${with_slp})
@@ -2846,7 +2846,7 @@ then
       AC_MSG_RESULT(yes)
       AX_ADD_PLUGINS([slp])
       AX_ADD_LDFLAGS([slp],[-L${with_slp} -lslp])
-      AX_ADD_LDFLAGS([vlc],[-L${with_slp} -lslp])
+      AX_ADD_LDFLAGS([stream_out_standard],[-L${with_slp} -lslp])
       AX_ADD_CPPFLAGS([slp],[-I${with_slp}])
       AC_DEFINE(HAVE_SLP_H)
     else
diff --git a/include/announce.h b/include/announce.h
deleted file mode 100644 (file)
index 0856d0c..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*****************************************************************************
- * announce.h : Session announcement
- *****************************************************************************
- * Copyright (C) 2002 VideoLAN
- * $Id: announce.h,v 1.9 2003/08/13 19:38:27 gbazin Exp $
- *
- * Authors: Clément Stenac <zorglub@via.ecp.fr>
- *
- * 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.
- *****************************************************************************/
-
-/*****************************************************************************
- * sap_session_t: SAP Session descriptor
- *****************************************************************************/
-
-#if defined( UNDER_CE )
-#   include <winsock.h>
-#elif defined( WIN32 )
-#   include <winsock2.h>
-#   include <ws2tcpip.h>
-#   define close closesocket
-#else
-#   include <netdb.h>                                         /* hostent ... */
-#   include <sys/socket.h>
-#   include <netinet/in.h>
-#   ifdef HAVE_ARPA_INET_H
-#       include <arpa/inet.h>                    /* inet_ntoa(), inet_aton() */
-#   endif
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#   include <sys/types.h>
-#endif
-
-
-struct sap_session_t
-{
-        char psz_url[256];
-        char psz_name[1024];
-        char psz_port[8];
-        module_t p_network;
-        unsigned int i_socket;
-        unsigned int i_calls;
-        int i_ip_version;
-};
-
-
-struct slp_session_t
-{
-        char *psz_url;
-        char *psz_name;
-};
-
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-VLC_EXPORT( sap_session_t *, sout_SAPNew, ( sout_instance_t *,char * , char * , int , char *) );
-VLC_EXPORT( void, sout_SAPSend, ( sout_instance_t *,sap_session_t *) );
-VLC_EXPORT( void, sout_SAPDelete, ( sout_instance_t *,sap_session_t * ) );
-
-VLC_EXPORT( int, sout_SLPReg, (sout_instance_t*,char*,char*) );
-VLC_EXPORT( int, sout_SLPDereg, (sout_instance_t*,char*,char*) );
index c94640b..9e9ce14 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.72 2003/08/14 11:47:32 gbazin Exp $
+ * $Id: vlc_common.h,v 1.73 2003/08/14 20:02:55 zorglub Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -263,8 +263,8 @@ typedef struct sout_mux_t sout_mux_t;
 typedef struct sout_stream_t    sout_stream_t;
 typedef struct sout_cfg_t       sout_cfg_t;
 typedef struct sout_format_t    sout_format_t;
-typedef struct sap_session_t    sap_session_t;
-typedef struct slp_session_t    slp_session_t;
+/*typedef struct sap_session_t    sap_session_t;
+typedef struct slp_session_t    slp_session_t;*/
 
 /* Decoders */
 typedef struct decoder_fifo_t decoder_fifo_t;
index 4494407..eb58d74 100644 (file)
@@ -1,5 +1,6 @@
 SOURCES_stream_out_dummy = dummy.c
-SOURCES_stream_out_standard = standard.c
+SOURCES_stream_out_standard = standard.c \
+                             announce.c
 SOURCES_stream_out_transcode = transcode.c
 SOURCES_stream_out_duplicate = duplicate.c
 SOURCES_stream_out_es = es.c
diff --git a/modules/stream_out/announce.c b/modules/stream_out/announce.c
new file mode 100644 (file)
index 0000000..0f44db0
--- /dev/null
@@ -0,0 +1,513 @@
+/*****************************************************************************
+ * announce.c : Session announcement
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ *
+ * Authors: Clément Stenac <zorglub@via.ecp.fr>
+ *          Damien Lucas <nitrox@via.ecp.fr>
+ *
+ * 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 <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <stdio.h>                                              /* sprintf() */
+#include <string.h>                                            /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/sout.h>
+
+#ifdef HAVE_UNISTD_H
+#   include <unistd.h>
+#endif
+
+#ifdef WIN32
+#   include <winsock2.h>
+#   include <ws2tcpip.h>
+#   ifndef IN_MULTICAST
+#       define IN_MULTICAST(a) IN_CLASSD(a)
+#   endif
+#else
+#   include <sys/socket.h>
+#endif
+
+#ifdef HAVE_SLP_H
+# include <slp.h>
+#endif
+
+#include "announce.h"
+#include "network.h"
+
+#define SAP_IPV4_ADDR "224.2.127.254" /* Standard port and address for SAP */
+#define SAP_PORT 9875
+
+#define SAP_IPV6_ADDR_1 "FF0"
+#define SAP_IPV6_ADDR_2 "::2:7FFE"
+
+#define DEFAULT_PORT "1234"
+
+/****************************************************************************
+ *  Split : split a string into two parts: the one which is before the delim
+ *               and the one which is after.
+ *               NULL is returned if delim is not found
+ ****************************************************************************/
+static char * split( char *psz_in, char *psz_out1, char *psz_out2, char delim)
+{
+    unsigned int i_count = 0; /* pos in input string */
+    unsigned int i_pos1  = 0; /* pos in out2 string */
+    unsigned int i_pos2  = 0;
+    char *psz_cur; /* store the pos of the first delim found */
+
+    /* Skip spaces at the beginning */
+    while( psz_in[i_count] == ' ' )
+    {
+        i_count++;
+    }
+
+    if( psz_in[i_count] == '\0' )
+    {
+        return NULL;
+    }
+
+    /* Look for delim */
+    while( psz_in[i_count] && psz_in[i_count] != delim )
+    {
+        psz_out1[i_pos1] = psz_in[i_count];
+        i_count++;
+        i_pos1++;
+    }
+    /* Mark the end of out1 */
+    psz_out1[i_pos1] = '\0';
+
+    if( psz_in[i_count] == '\0' )
+    {
+        return NULL;
+    }
+
+    /* store pos of the first delim */
+    psz_cur = psz_in + i_count;
+
+    /* skip all delim and all spaces */
+    while( psz_in[i_count] == ' ' || psz_in[i_count] == delim )
+    {
+        i_count++;
+    }
+
+    if( psz_in[i_count] == '\0' )
+    {
+        return psz_cur;
+    }
+
+    /* Store the second string */
+    while( psz_in[i_count] )
+    {
+        psz_out2[i_pos2] = psz_in[i_count];
+        i_pos2++;
+        i_count++;
+    }
+    psz_out2[i_pos2] = '\0';
+
+    return psz_cur;
+}
+
+/*****************************************************************************
+ * sout_SAPNew: Creates a SAP Session
+ *****************************************************************************/
+sap_session_t * sout_SAPNew ( sout_instance_t *p_sout,
+                                     char * psz_url_arg,
+                                     char * psz_name_arg,
+                                     int ip_version,
+                                     char * psz_v6_scope )
+{
+    sap_session_t       *p_sap; /* The SAP structure */
+    module_t            *p_network; /* Network module */
+    network_socket_t    socket_desc; /* Socket descriptor */
+    char                *sap_ipv6_addr = NULL; /* IPv6 built address */
+    char                *psz_eol; /* Used to parse IPv6 URIs */
+    int                 i_port; /* Port in numerical format */
+
+    /* Allocate the SAP structure */
+    p_sap = (sap_session_t *) malloc( sizeof ( sap_session_t ) ) ;
+    if ( !p_sap )
+    {
+        msg_Err( p_sout, "out of memory" );
+        return NULL;
+    }
+
+    /* Fill the information in the structure */
+    if( strstr( psz_url_arg, "[" ) )
+    {
+        /* We have an IPv6 address. Do not use ':' as the port separator */
+        psz_eol = strchr( psz_url_arg, ']' );
+        if( !psz_eol )
+        {
+            msg_Warn( p_sout, "no matching ], unable to parse URI");
+            return NULL;
+        }
+
+        if( !psz_eol++ )
+        {
+            sprintf( p_sap->psz_url, "%s", psz_url_arg );
+            sprintf( p_sap->psz_port, "%s", DEFAULT_PORT );
+        }
+        else
+        {
+            *psz_eol = '\0';
+            sprintf( p_sap->psz_url, "%s", psz_url_arg );
+            psz_eol++;
+            if( psz_eol )
+            {
+                sprintf( p_sap->psz_port, "%s", psz_eol );
+            }
+        }
+    }
+    else
+    {
+        split( psz_url_arg, p_sap->psz_url, p_sap->psz_port, ':' );
+    }
+
+    /* Check if we have a port */
+    if( !strlen( p_sap->psz_port ) )
+    {
+        sprintf( p_sap->psz_port, "%s", DEFAULT_PORT );
+    }
+
+    /* Make sure our port is valid and atoi it */
+    i_port = atoi( p_sap->psz_port );
+
+    if( !i_port )
+    {
+        sprintf( p_sap->psz_port, "%s", DEFAULT_PORT );
+    }
+    else
+    {
+        sprintf( p_sap->psz_port, "%i", i_port );
+    }
+
+    /* The name that we send */
+    sprintf( p_sap->psz_name, "%s", psz_name_arg );
+
+    p_sap->i_ip_version = ip_version;
+
+    /* Only "6" triggers IPv6. IPv4 is default */
+    if( ip_version != 6 )
+    {
+        msg_Dbg( p_sout, "creating IPv4 SAP socket" );
+
+        /* Fill the socket descriptor */
+        socket_desc.i_type            = NETWORK_UDP;
+        socket_desc.psz_bind_addr     = "";
+        socket_desc.i_bind_port       = 0;
+        socket_desc.psz_server_addr   = SAP_IPV4_ADDR;
+        socket_desc.i_server_port     = SAP_PORT;
+        socket_desc.i_handle          = 0;
+        socket_desc.i_ttl             = 0;
+
+        /* Call the network module */
+        p_sout->p_private = (void*) &socket_desc;
+        if( !( p_network = module_Need( p_sout, "network", "ipv4" ) ) )
+        {
+             msg_Warn( p_sout, "failed to open a connection (udp)" );
+             return NULL;
+        }
+        module_Unneed( p_sout, p_network );
+
+        p_sap->i_socket = socket_desc.i_handle;
+        if( p_sap->i_socket < 0 )
+        {
+            msg_Warn( p_sout, "unable to initialize SAP" );
+            return NULL;
+        }
+    }
+    else
+    {
+        msg_Dbg( p_sout, "creating IPv6 SAP socket with scope %s",
+                         psz_v6_scope );
+
+        /* Initialize and build the IPv6 address to broadcast to */
+        sap_ipv6_addr = (char *) malloc( 28 * sizeof(char) );
+        if ( !sap_ipv6_addr )
+        {
+            msg_Err( p_sout, "out of memory" );
+            return NULL;
+        }
+        sprintf( sap_ipv6_addr, "%s%c%s",
+                 SAP_IPV6_ADDR_1, psz_v6_scope[0], SAP_IPV6_ADDR_2 );
+
+        /* Fill the socket descriptor */
+        socket_desc.i_type          = NETWORK_UDP;
+        socket_desc.psz_bind_addr   = "";
+        socket_desc.i_bind_port     = 0;
+        socket_desc.psz_server_addr = sap_ipv6_addr;
+        socket_desc.i_server_port   = SAP_PORT;
+        socket_desc.i_handle        = 0;
+        socket_desc.i_ttl           = 0;
+
+        /* Call the network module */
+        p_sout->p_private = (void *) &socket_desc;
+        if( !( p_network = module_Need( p_sout, "network", "ipv6" ) ) )
+        {
+            msg_Warn( p_sout, "failed to open a connection (udp)" );
+            return NULL;
+        }
+        module_Unneed( p_sout, p_network );
+
+        p_sap->i_socket = socket_desc.i_handle;
+        if( p_sap->i_socket <= 0 )
+        {
+            msg_Warn( p_sout, "unable to initialize SAP" );
+            return NULL;
+        }
+
+        /* Free what we allocated */
+        if( sap_ipv6_addr )
+        {
+            free( sap_ipv6_addr );
+        }
+    }
+
+    msg_Dbg( p_sout, "SAP initialization complete" );
+
+    return p_sap;
+}
+
+/*****************************************************************************
+ * sout_SAPDelete: Deletes a SAP Session
+ *****************************************************************************/
+void sout_SAPDelete( sout_instance_t *p_sout, sap_session_t * p_sap )
+{
+    int i_ret;
+
+#if defined( UNDER_CE )
+    i_ret = CloseHandle( (HANDLE)p_sap->i_socket );
+#elif defined( WIN32 )
+    i_ret = closesocket( p_sap->i_socket );
+#else
+    i_ret = close( p_sap->i_socket );
+#endif
+
+    if( i_ret )
+    {
+        msg_Err( p_sout, "unable to close SAP socket" );
+    }
+
+    free( p_sap );
+}
+
+/*****************************************************************************
+ * sout_SAPSend: Sends a SAP packet
+ *****************************************************************************/
+void sout_SAPSend( sout_instance_t *p_sout, sap_session_t * p_sap )
+{
+    char psz_msg[1000];                     /* SDP content */
+    char *psz_head;                         /* SAP header */
+    char *psz_send;                         /* What we send */
+    char *psz_type = "application/sdp";
+    int i_header_size;                      /* SAP header size */
+    int i_msg_size;                         /* SDP content size */
+    int i_size;                             /* Total size */
+    int i_ret = 0;
+
+    /* We send a packet every 24 calls to the function */
+    if( p_sap->i_calls++ < 24 )
+    {
+        return;
+    }
+
+    i_header_size = 8 + strlen( psz_type ) + 1;
+    psz_head = (char *) malloc( i_header_size * sizeof( char ) );
+
+    if( ! psz_head )
+    {
+        msg_Err( p_sout, "out of memory" );
+        return;
+    }
+
+    /* Create the SAP headers */
+    psz_head[0] = 0x20; /* Means IPv4, not encrypted, not compressed */
+    psz_head[1] = 0x00; /* No authentification */
+    psz_head[2] = 0x42; /* Version */
+    psz_head[3] = 0x12; /* Version */
+
+    psz_head[4] = 0x01; /* Source IP  FIXME: we should get the real address */
+    psz_head[5] = 0x02; /* idem */
+    psz_head[6] = 0x03; /* idem */
+    psz_head[7] = 0x04; /* idem */
+
+    strncpy( psz_head + 8, psz_type, 15 );
+    psz_head[ i_header_size-1 ] = '\0';
+
+    /* Create the SDP content */
+    /* Do not add spaces at beginning of the lines ! */
+    sprintf( psz_msg, "v=0\n"
+                      "o=VideoLAN 3247692199 3247895918 IN IP4 VideoLAN\n"
+                      "s=%s\n"
+                      "u=VideoLAN\n"
+                      "t=0 0\n"
+                      "m=audio %s udp 14\n"
+                      "c=IN IP4 %s/15\n"
+                      "a=type:test\n",
+             p_sap->psz_name, p_sap->psz_port, p_sap->psz_url );
+
+    i_msg_size = strlen( psz_msg );
+    i_size = i_msg_size + i_header_size;
+
+    /* Create the message */
+    psz_send = (char *) malloc( i_size*sizeof(char) );
+    if( !psz_send )
+    {
+        msg_Err( p_sout, "out of memory" );
+        return;
+    }
+
+    memcpy( psz_send, psz_head, i_header_size );
+    memcpy( psz_send + i_header_size, psz_msg, i_msg_size );
+
+    if( i_size < 1024 ) /* We mustn't send packets larger than 1024B */
+    {
+        i_ret = send( p_sap->i_socket, psz_send, i_size, 0 );
+    }
+
+    if( i_ret <= 0 )
+    {
+        msg_Warn( p_sout, "SAP send failed on socket %i (%s)",
+                          p_sap->i_socket, strerror(errno) );
+    }
+
+    p_sap->i_calls = 0;
+
+    /* Free what we allocated */
+    free( psz_send );
+    free( psz_head );
+}
+
+
+   
+/*****************************************************************************
+ * sout_SLPBuildName: Builds a service name according to SLP standard
+ *****************************************************************************/
+static char * sout_SLPBuildName(char *psz_url,char *psz_name)
+{
+    char *psz_service;
+    unsigned int i_size;
+
+    /* name to build is: service:$(name).videolan://$(url) */
+
+    i_size =  8 + strlen(psz_name) + 12 + strlen(psz_url) + 1;
+
+    psz_service=(char *)malloc(i_size * sizeof(char));
+
+    snprintf( psz_service , i_size, 
+              "service:%s.videolan://%s",
+              psz_name,psz_url);
+    psz_service[i_size]='\0'; /* Just to make sure */    
+
+    return psz_service;
+    
+}
+
+/*****************************************************************************
+ * sout_SLPReport: Reporting function. Unused at the moment but needed
+ *****************************************************************************/
+#ifdef HAVE_SLP_H
+static void sout_SLPReport(SLPHandle slp_handle,SLPError slp_error,void* cookie)
+{
+}  
+#endif
+
+/*****************************************************************************
+ * sout_SLPReg: Registers the program with SLP
+ *****************************************************************************/
+int sout_SLPReg( sout_instance_t *p_sout, char * psz_url,
+                               char * psz_name)
+{
+#ifdef HAVE_SLP_H
+    SLPHandle   slp_handle; 
+    SLPError    slp_res;
+    char *psz_service= sout_SLPBuildName(psz_url,psz_name);
+        
+    if( SLPOpen( NULL, SLP_FALSE, &slp_handle ) != SLP_OK)
+    {
+        msg_Warn(p_sout,"Unable to initialize SLP");
+        return -1;
+    } 
+
+    msg_Info(p_sout , "Registering %s (name: %s) in SLP",
+                      psz_service , psz_name);
+    
+    slp_res = SLPReg ( slp_handle,
+            psz_service,
+            SLP_LIFETIME_MAXIMUM,
+            NULL,
+            psz_name,
+            SLP_TRUE,
+            sout_SLPReport,
+            NULL );
+    
+    if( slp_res != SLP_OK )
+    {
+        msg_Warn(p_sout,"Error while registering service: %i", slp_res );
+        return -1;
+    }
+
+    return 0;
+
+#else /* This function should never be called if this is false */
+    return -1;
+#endif
+}
+
+
+/*****************************************************************************
+ * sout_SLDePReg: Unregisters the program from SLP
+ *****************************************************************************/
+int sout_SLPDereg( sout_instance_t *p_sout, char * psz_url,
+                               char * psz_name)
+{
+#ifdef HAVE_SLP_H
+
+    SLPHandle   slp_handle; 
+    SLPError    slp_res;
+    char *psz_service= sout_SLPBuildName(psz_url,psz_name);
+        
+    if( SLPOpen( NULL, SLP_FALSE, &slp_handle ) != SLP_OK)
+    {
+        msg_Warn(p_sout,"Unable to initialize SLP");
+        return -1;
+    } 
+
+    msg_Info(p_sout , "Unregistering %s from SLP",
+                      psz_service);
+    
+    slp_res = SLPDereg ( slp_handle,
+            psz_service,
+            sout_SLPReport,
+            NULL );
+    
+    if( slp_res != SLP_OK )
+    {
+        msg_Warn(p_sout,"Error while registering service: %i", slp_res );
+        return -1;
+    }
+
+    return 0;
+
+#else /* This function should never be called if this is false */
+    return -1; 
+#endif
+}
diff --git a/modules/stream_out/announce.h b/modules/stream_out/announce.h
new file mode 100644 (file)
index 0000000..896795f
--- /dev/null
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * announce.h : Session announcement
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ * $Id: announce.h,v 1.1 2003/08/14 20:02:55 zorglub Exp $
+ *
+ * Authors: Clément Stenac <zorglub@via.ecp.fr>
+ *
+ * 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
+ *****************************************************************************/
+
+#if defined( UNDER_CE )
+#   include <winsock.h>
+#elif defined( WIN32 )
+#   include <winsock2.h>
+#   include <ws2tcpip.h>
+#   define close closesocket
+#else
+#   include <netdb.h>                                         /* hostent ... */
+#   include <sys/socket.h>
+#   include <netinet/in.h>
+#   ifdef HAVE_ARPA_INET_H
+#       include <arpa/inet.h>                    /* inet_ntoa(), inet_aton() */
+#   endif
+#endif
+
+#ifdef HAVE_SLP_H
+#   include <slp.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#   include <sys/types.h>
+#endif
+
+/*****************************************************************************
+ * sap_session_t: SAP Session descriptor
+ *****************************************************************************/
+struct sap_session_t
+{
+        char psz_url[256];
+        char psz_name[1024];
+        char psz_port[8];
+        module_t p_network;
+        unsigned int i_socket;
+        unsigned int i_calls;
+        int i_ip_version;
+};
+
+typedef struct sap_session_t sap_session_t;
+/*****************************************************************************
+ * slp_session_t: SLP Session descriptor
+ *****************************************************************************/
+struct slp_session_t
+{
+        char *psz_url;
+        char *psz_name;
+};
+
+typedef struct slp_session_t slp_session_t;
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+sap_session_t *  sout_SAPNew        (sout_instance_t *,
+                                     char *, char* , int, char *);
+void             sout_SAPDelete     (sout_instance_t *,sap_session_t*);
+void             sout_SAPSend       (sout_instance_t *,sap_session_t *);
+int              sout_SLPReg        (sout_instance_t *,char *,char *);
+int              sout_SLPDereg      (sout_instance_t *,char *,char *);
+
+
+/*
+VLC_EXPORT( sap_session_t *, sout_SAPNew, ( sout_instance_t *,char * , char * , int , char *) );
+VLC_EXPORT( void, sout_SAPSend, ( sout_instance_t *,sap_session_t *) );
+VLC_EXPORT( void, sout_SAPDelete, ( sout_instance_t *,sap_session_t * ) );
+
+VLC_EXPORT( int, sout_SLPReg, (sout_instance_t*,char*,char*) );
+VLC_EXPORT( int, sout_SLPDereg, (sout_instance_t*,char*,char*) );*/
index fd73fa9..d4ef592 100644 (file)
@@ -2,7 +2,7 @@
  * standard.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: standard.c,v 1.11 2003/08/13 21:15:42 gbazin Exp $
+ * $Id: standard.c,v 1.12 2003/08/14 20:02:55 zorglub Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -30,7 +30,7 @@
 
 #include <vlc/vlc.h>
 #include <vlc/sout.h>
-#include <announce.h>
+#include "announce.h"
 
 #define DEFAULT_IPV6_SCOPE "8"
 
index c0fb70c..d8c3aae 100644 (file)
@@ -2,7 +2,7 @@
  * modules.c : Builtin and plugin modules management functions
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: modules.c,v 1.127 2003/08/01 00:00:50 fenrir Exp $
+ * $Id: modules.c,v 1.128 2003/08/14 20:02:55 zorglub Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Ethan C. Baldridge <BaldridgeE@cadmus.com>
@@ -87,7 +87,7 @@
 #include "aout_internal.h"
 
 #include "stream_output.h"
-#include "announce.h"
+/*#include "announce.h"*/
 #include "osd.h"
 
 #include "iso_lang.h"
diff --git a/src/stream_output/announce.c b/src/stream_output/announce.c
deleted file mode 100644 (file)
index 3708e98..0000000
+++ /dev/null
@@ -1,512 +0,0 @@
-/*****************************************************************************
- * announce.c : Session announcement
- *****************************************************************************
- * Copyright (C) 2002 VideoLAN
- *
- * Authors: Clément Stenac <zorglub@via.ecp.fr>
- *          Damien Lucas <nitrox@via.ecp.fr>
- *
- * 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 <errno.h>                                                 /* ENOMEM */
-#include <stdlib.h>                                                /* free() */
-#include <stdio.h>                                              /* sprintf() */
-#include <string.h>                                            /* strerror() */
-
-#include <vlc/vlc.h>
-#include <vlc/sout.h>
-
-#ifdef HAVE_UNISTD_H
-#   include <unistd.h>
-#endif
-
-#ifdef WIN32
-#   include <winsock2.h>
-#   include <ws2tcpip.h>
-#   ifndef IN_MULTICAST
-#       define IN_MULTICAST(a) IN_CLASSD(a)
-#   endif
-#else
-#   include <sys/socket.h>
-#endif
-
-#ifdef HAVE_SLP_H
-# include <slp.h>
-#endif
-
-#include "announce.h"
-#include "network.h"
-
-#define SAP_IPV4_ADDR "224.2.127.254" /* Standard port and address for SAP */
-#define SAP_PORT 9875
-
-#define SAP_IPV6_ADDR_1 "FF0"
-#define SAP_IPV6_ADDR_2 "::2:7FFE"
-
-#define DEFAULT_PORT "1234"
-
-/****************************************************************************
- *  Split : split a string into two parts: the one which is before the delim
- *               and the one which is after.
- *               NULL is returned if delim is not found
- ****************************************************************************/
-
-static char * split( char *psz_in, char *psz_out1, char *psz_out2, char delim)
-{
-    unsigned int i_count = 0; /* pos in input string */
-    unsigned int i_pos1  = 0; /* pos in out2 string */
-    unsigned int i_pos2  = 0;
-    char *psz_cur; /* store the pos of the first delim found */
-
-    /* Skip spaces at the beginning */
-    while( psz_in[i_count] == ' ' )
-    {
-        i_count++;
-    }
-
-    if( psz_in[i_count] == '\0' )
-    {
-        return NULL;
-    }
-
-    /* Look for delim */
-    while( psz_in[i_count] && psz_in[i_count] != delim )
-    {
-        psz_out1[i_pos1] = psz_in[i_count];
-        i_count++;
-        i_pos1++;
-    }
-    /* Mark the end of out1 */
-    psz_out1[i_pos1] = '\0';
-
-    if( psz_in[i_count] == '\0' )
-    {
-        return NULL;
-    }
-
-    /* store pos of the first delim */
-    psz_cur = psz_in + i_count;
-
-    /* skip all delim and all spaces */
-    while( psz_in[i_count] == ' ' || psz_in[i_count] == delim )
-    {
-        i_count++;
-    }
-
-    if( psz_in[i_count] == '\0' )
-    {
-        return psz_cur;
-    }
-
-    /* Store the second string */
-    while( psz_in[i_count] )
-    {
-        psz_out2[i_pos2] = psz_in[i_count];
-        i_pos2++;
-        i_count++;
-    }
-    psz_out2[i_pos2] = '\0';
-
-    return psz_cur;
-}
-
-/*****************************************************************************
- * sout_SAPNew: Creates a SAP Session
- *****************************************************************************/
-sap_session_t * sout_SAPNew ( sout_instance_t *p_sout, char * psz_url_arg,
-                              char * psz_name_arg, int ip_version,
-                              char * psz_v6_scope )
-{
-    sap_session_t       *p_sap; /* The SAP structure */
-    module_t            *p_network; /* Network module */
-    network_socket_t    socket_desc; /* Socket descriptor */
-    char                *sap_ipv6_addr = NULL; /* IPv6 built address */
-    char                *psz_eol; /* Used to parse IPv6 URIs */
-    int                 i_port; /* Port in numerical format */
-
-    /* Allocate the SAP structure */
-    p_sap = (sap_session_t *) malloc( sizeof ( sap_session_t ) ) ;
-    if ( !p_sap )
-    {
-        msg_Err( p_sout, "out of memory" );
-        return NULL;
-    }
-
-    /* Fill the information in the structure */
-    if( strstr( psz_url_arg, "[" ) )
-    {
-        /* We have an IPv6 address. Do not use ':' as the port separator */
-        psz_eol = strchr( psz_url_arg, ']' );
-        if( !psz_eol )
-        {
-            msg_Warn( p_sout, "no matching ], unable to parse URI");
-            return NULL;
-        }
-
-        if( !psz_eol++ )
-        {
-            sprintf( p_sap->psz_url, "%s", psz_url_arg );
-            sprintf( p_sap->psz_port, "%s", DEFAULT_PORT );
-        }
-        else
-        {
-            *psz_eol = '\0';
-            sprintf( p_sap->psz_url, "%s", psz_url_arg );
-            psz_eol++;
-            if( psz_eol )
-            {
-                sprintf( p_sap->psz_port, "%s", psz_eol );
-            }
-        }
-    }
-    else
-    {
-        split( psz_url_arg, p_sap->psz_url, p_sap->psz_port, ':' );
-    }
-
-    /* Check if we have a port */
-    if( !strlen( p_sap->psz_port ) )
-    {
-        sprintf( p_sap->psz_port, "%s", DEFAULT_PORT );
-    }
-
-    /* Make sure our port is valid and atoi it */
-    i_port = atoi( p_sap->psz_port );
-
-    if( !i_port )
-    {
-        sprintf( p_sap->psz_port, "%s", DEFAULT_PORT );
-    }
-    else
-    {
-        sprintf( p_sap->psz_port, "%i", i_port );
-    }
-
-    /* The name that we send */
-    sprintf( p_sap->psz_name, "%s", psz_name_arg );
-
-    p_sap->i_ip_version = ip_version;
-
-    /* Only "6" triggers IPv6. IPv4 is default */
-    if( ip_version != 6 )
-    {
-        msg_Dbg( p_sout, "creating IPv4 SAP socket" );
-
-        /* Fill the socket descriptor */
-        socket_desc.i_type            = NETWORK_UDP;
-        socket_desc.psz_bind_addr     = "";
-        socket_desc.i_bind_port       = 0;
-        socket_desc.psz_server_addr   = SAP_IPV4_ADDR;
-        socket_desc.i_server_port     = SAP_PORT;
-        socket_desc.i_handle          = 0;
-        socket_desc.i_ttl             = 0;
-
-        /* Call the network module */
-        p_sout->p_private = (void*) &socket_desc;
-        if( !( p_network = module_Need( p_sout, "network", "ipv4" ) ) )
-        {
-             msg_Warn( p_sout, "failed to open a connection (udp)" );
-             return NULL;
-        }
-        module_Unneed( p_sout, p_network );
-
-        p_sap->i_socket = socket_desc.i_handle;
-        if( p_sap->i_socket < 0 )
-        {
-            msg_Warn( p_sout, "unable to initialize SAP" );
-            return NULL;
-        }
-    }
-    else
-    {
-        msg_Dbg( p_sout, "creating IPv6 SAP socket with scope %s",
-                         psz_v6_scope );
-
-        /* Initialize and build the IPv6 address to broadcast to */
-        sap_ipv6_addr = (char *) malloc( 28 * sizeof(char) );
-        if ( !sap_ipv6_addr )
-        {
-            msg_Err( p_sout, "out of memory" );
-            return NULL;
-        }
-        sprintf( sap_ipv6_addr, "%s%c%s",
-                 SAP_IPV6_ADDR_1, psz_v6_scope[0], SAP_IPV6_ADDR_2 );
-
-        /* Fill the socket descriptor */
-        socket_desc.i_type          = NETWORK_UDP;
-        socket_desc.psz_bind_addr   = "";
-        socket_desc.i_bind_port     = 0;
-        socket_desc.psz_server_addr = sap_ipv6_addr;
-        socket_desc.i_server_port   = SAP_PORT;
-        socket_desc.i_handle        = 0;
-        socket_desc.i_ttl           = 0;
-
-        /* Call the network module */
-        p_sout->p_private = (void *) &socket_desc;
-        if( !( p_network = module_Need( p_sout, "network", "ipv6" ) ) )
-        {
-            msg_Warn( p_sout, "failed to open a connection (udp)" );
-            return NULL;
-        }
-        module_Unneed( p_sout, p_network );
-
-        p_sap->i_socket = socket_desc.i_handle;
-        if( p_sap->i_socket <= 0 )
-        {
-            msg_Warn( p_sout, "unable to initialize SAP" );
-            return NULL;
-        }
-
-        /* Free what we allocated */
-        if( sap_ipv6_addr )
-        {
-            free( sap_ipv6_addr );
-        }
-    }
-
-    msg_Dbg( p_sout, "SAP initialization complete" );
-
-    return p_sap;
-}
-
-/*****************************************************************************
- * sout_SAPDelete: Deletes a SAP Session
- *****************************************************************************/
-void sout_SAPDelete( sout_instance_t *p_sout, sap_session_t * p_sap )
-{
-    int i_ret;
-
-#if defined( UNDER_CE )
-    i_ret = CloseHandle( (HANDLE)p_sap->i_socket );
-#elif defined( WIN32 )
-    i_ret = closesocket( p_sap->i_socket );
-#else
-    i_ret = close( p_sap->i_socket );
-#endif
-
-    if( i_ret )
-    {
-        msg_Err( p_sout, "unable to close SAP socket" );
-    }
-
-    free( p_sap );
-}
-
-/*****************************************************************************
- * sout_SAPSend: Sends a SAP packet
- *****************************************************************************/
-void sout_SAPSend( sout_instance_t *p_sout, sap_session_t * p_sap )
-{
-    char psz_msg[1000];                     /* SDP content */
-    char *psz_head;                         /* SAP header */
-    char *psz_send;                         /* What we send */
-    char *psz_type = "application/sdp";
-    int i_header_size;                      /* SAP header size */
-    int i_msg_size;                         /* SDP content size */
-    int i_size;                             /* Total size */
-    int i_ret = 0;
-
-    /* We send a packet every 24 calls to the function */
-    if( p_sap->i_calls++ < 24 )
-    {
-        return;
-    }
-
-    i_header_size = 8 + strlen( psz_type ) + 1;
-    psz_head = (char *) malloc( i_header_size * sizeof( char ) );
-
-    if( ! psz_head )
-    {
-        msg_Err( p_sout, "out of memory" );
-        return;
-    }
-
-    /* Create the SAP headers */
-    psz_head[0] = 0x20; /* Means IPv4, not encrypted, not compressed */
-    psz_head[1] = 0x00; /* No authentification */
-    psz_head[2] = 0x42; /* Version */
-    psz_head[3] = 0x12; /* Version */
-
-    psz_head[4] = 0x01; /* Source IP  FIXME: we should get the real address */
-    psz_head[5] = 0x02; /* idem */
-    psz_head[6] = 0x03; /* idem */
-    psz_head[7] = 0x04; /* idem */
-
-    strncpy( psz_head + 8, psz_type, 15 );
-    psz_head[ i_header_size-1 ] = '\0';
-
-    /* Create the SDP content */
-    /* Do not add spaces at beginning of the lines ! */
-    sprintf( psz_msg, "v=0\n"
-                      "o=VideoLAN 3247692199 3247895918 IN IP4 VideoLAN\n"
-                      "s=%s\n"
-                      "u=VideoLAN\n"
-                      "t=0 0\n"
-                      "m=audio %s udp 14\n"
-                      "c=IN IP4 %s/15\n"
-                      "a=type:test\n",
-             p_sap->psz_name, p_sap->psz_port, p_sap->psz_url );
-
-    i_msg_size = strlen( psz_msg );
-    i_size = i_msg_size + i_header_size;
-
-    /* Create the message */
-    psz_send = (char *) malloc( i_size*sizeof(char) );
-    if( !psz_send )
-    {
-        msg_Err( p_sout, "out of memory" );
-        return;
-    }
-
-    memcpy( psz_send, psz_head, i_header_size );
-    memcpy( psz_send + i_header_size, psz_msg, i_msg_size );
-
-    if( i_size < 1024 ) /* We mustn't send packets larger than 1024B */
-    {
-        i_ret = send( p_sap->i_socket, psz_send, i_size, 0 );
-    }
-
-    if( i_ret <= 0 )
-    {
-        msg_Warn( p_sout, "SAP send failed on socket %i (%s)",
-                          p_sap->i_socket, strerror(errno) );
-    }
-
-    p_sap->i_calls = 0;
-
-    /* Free what we allocated */
-    free( psz_send );
-    free( psz_head );
-}
-
-
-   
-/*****************************************************************************
- * sout_SLPBuildName: Builds a service name according to SLP standard
- *****************************************************************************/
-char * sout_SLPBuildName(char *psz_url,char *psz_name)
-{
-    char *psz_service;
-    unsigned int i_size;
-
-    /* name to build is: service:$(name).videolan://$(url) */
-
-    i_size =  8 + strlen(psz_name) + 12 + strlen(psz_url) + 1;
-
-    psz_service=(char *)malloc(i_size * sizeof(char));
-
-    snprintf( psz_service , i_size, 
-              "service:%s.videolan://%s",
-              psz_name,psz_url);
-    psz_service[i_size]='\0'; /* Just to make sure */    
-
-    return psz_service;
-    
-}
-
-/*****************************************************************************
- * sout_SLPReport: Reporting function. Unused at the moment but needed
- *****************************************************************************/
-#ifdef HAVE_SLP_H
-void sout_SLPReport(SLPHandle slp_handle,SLPError slp_error,void* cookie)
-{
-}  
-#endif
-
-/*****************************************************************************
- * sout_SLPReg: Registers the program with SLP
- *****************************************************************************/
-int sout_SLPReg( sout_instance_t *p_sout, char * psz_url,
-                               char * psz_name)
-{
-#ifdef HAVE_SLP_H
-    SLPHandle   slp_handle; 
-    SLPError    slp_res;
-    char *psz_service= sout_SLPBuildName(psz_url,psz_name);
-        
-    if( SLPOpen( NULL, SLP_FALSE, &slp_handle ) != SLP_OK)
-    {
-        msg_Warn(p_sout,"Unable to initialize SLP");
-        return -1;
-    } 
-
-    msg_Info(p_sout , "Registering %s (name: %s) in SLP",
-                      psz_service , psz_name);
-    
-    slp_res = SLPReg ( slp_handle,
-            psz_service,
-            SLP_LIFETIME_MAXIMUM,
-            NULL,
-            psz_name,
-            SLP_TRUE,
-            sout_SLPReport,
-            NULL );
-    
-    if( slp_res != SLP_OK )
-    {
-        msg_Warn(p_sout,"Error while registering service: %i", slp_res );
-        return -1;
-    }
-
-    return 0;
-
-#else /* This function should never be called if this is false */
-    return -1;
-#endif
-}
-
-
-/*****************************************************************************
- * sout_SLDePReg: Unregisters the program from SLP
- *****************************************************************************/
-int sout_SLPDereg( sout_instance_t *p_sout, char * psz_url,
-                               char * psz_name)
-{
-#ifdef HAVE_SLP_H
-
-    SLPHandle   slp_handle; 
-    SLPError    slp_res;
-    char *psz_service= sout_SLPBuildName(psz_url,psz_name);
-        
-    if( SLPOpen( NULL, SLP_FALSE, &slp_handle ) != SLP_OK)
-    {
-        msg_Warn(p_sout,"Unable to initialize SLP");
-        return -1;
-    } 
-
-    msg_Info(p_sout , "Unregistering %s from SLP",
-                      psz_service);
-    
-    slp_res = SLPDereg ( slp_handle,
-            psz_service,
-            sout_SLPReport,
-            NULL );
-    
-    if( slp_res != SLP_OK )
-    {
-        msg_Warn(p_sout,"Error while registering service: %i", slp_res );
-        return -1;
-    }
-
-    return 0;
-
-#else /* This function should never be called if this is false */
-    return -1; 
-#endif
-}