]> git.sesse.net Git - vlc/blobdiff - modules/access/tcp.c
Include the BlackMagic SDK stuff with <>.
[vlc] / modules / access / tcp.c
index 0c1e6d015ba8aa3776a43144217b6c4236d365ad..7b111f0ca055c7d77c1d4450cf569626e1e91365 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * tcp.c: TCP access plug-in
+ * tcp.c: TCP input module
  *****************************************************************************
- * Copyright (C) 2003 VideoLAN
- * $Id: tcp.c,v 1.2 2003/12/04 16:49:43 sam Exp $
+ * Copyright (C) 2003-2004 the VideoLAN team
+ * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include <stdlib.h>
 
-#include <vlc/vlc.h>
-#include <vlc/input.h>
-
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef HAVE_SYS_TIME_H
-#    include <sys/time.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
 #endif
 
-#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
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_access.h>
 
-#include "network.h"
+#include <vlc_network.h>
 
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-#define CACHING_TEXT N_("caching value in ms")
+#define CACHING_TEXT N_("Caching value in ms")
 #define CACHING_LONGTEXT N_( \
-    "Allows you to modify the default caching value for udp streams. This " \
-    "value should be set in miliseconds units." )
+    "Caching value for TCP streams. This " \
+    "value should be set in milliseconds." )
 
 static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
 
-vlc_module_begin();
-    set_description( _("TCP input") );
-    add_category_hint( N_("TCP"), NULL , VLC_TRUE );
-    add_integer( "tcp-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
-    set_capability( "access", 0 );
-    add_shortcut( "tcp" );
-    add_shortcut( "tcp4" );
-    add_shortcut( "tcp6" );
-    set_callbacks( Open, Close );
-vlc_module_end();
+vlc_module_begin ()
+    set_shortname( N_("TCP") )
+    set_description( N_("TCP input") )
+    set_category( CAT_INPUT )
+    set_subcategory( SUBCAT_INPUT_ACCESS )
 
+    add_integer( "tcp-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT,
+                 CACHING_LONGTEXT, true )
+        change_safe()
+
+    set_capability( "access", 0 )
+    add_shortcut( "tcp" )
+    set_callbacks( Open, Close )
+vlc_module_end ()
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
 struct access_sys_t
 {
-    int fd;
+    int        fd;
 };
 
-static ssize_t  Read ( input_thread_t *, byte_t *, size_t );
+
+static ssize_t Read( access_t *, uint8_t *, size_t );
+static int Control( access_t *, int, va_list );
 
 /*****************************************************************************
  * Open: open the socket
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
-    input_thread_t *p_input = (input_thread_t *)p_this;
-    access_sys_t   *p_sys;
-
-    char           *psz_network;
-    char           *psz_dup = strdup(p_input->psz_name);
-    char           *psz_parser = psz_dup;
+    access_t     *p_access = (access_t *)p_this;
+    access_sys_t *p_sys;
 
-    network_socket_t sock;
-    module_t         *p_network;
-
-    vlc_value_t     val;
-
-    /* Select ip version */
-    psz_network = "";
-    if( config_GetInt( p_input, "ipv4" ) )
-    {
-        psz_network = "ipv4";
-    }
-    if( config_GetInt( p_input, "ipv6" ) )
-    {
-        psz_network = "ipv6";
-    }
-    if( *p_input->psz_access )
-    {
-        /* Find out which shortcut was used */
-        if( !strncmp( p_input->psz_access, "tcp6", 5 ) )
-        {
-            psz_network = "ipv6";
-        }
-        else if( !strncmp( p_input->psz_access, "tcp4", 5 ) )
-        {
-            psz_network = "ipv4";
-        }
-    }
+    char         *psz_dup = strdup(p_access->psz_location);
+    char         *psz_parser = psz_dup;
 
     /* Parse server:port */
-    while( *psz_parser && *psz_parser != ':' )
+    if( *psz_parser == '[' )
     {
-        if( *psz_parser == '[' )
-        {
-            /* IPV6 */
-            while( *psz_parser && *psz_parser  != ']' )
-            {
-                psz_parser++;
-            }
-        }
-        psz_parser++;
+        psz_parser = strchr( psz_parser, ']' );
+        if( psz_parser == NULL )
+            psz_parser = psz_dup;
     }
+    psz_parser = strchr( psz_parser, ':' );
 
-    if( *psz_parser != ':' || psz_parser == psz_dup )
+    if( psz_parser == NULL )
     {
-        msg_Err( p_input, "you have to provide server:port addresse" );
+        msg_Err( p_access, "missing port number : %s", psz_dup );
         free( psz_dup );
         return VLC_EGENERIC;
     }
 
     *psz_parser++ = '\0';
 
-    /* Prepare the network_socket_t structure */
-    sock.i_type = NETWORK_TCP;
-    sock.psz_bind_addr = "";
-    sock.i_bind_port = 0;
-    sock.psz_server_addr = psz_dup;
-    sock.i_server_port = atoi( psz_parser );
-    sock.i_ttl           = 0;
-
-    if( sock.i_server_port <= 0 )
+    /* Init p_access */
+    access_InitFields( p_access );
+    ACCESS_SET_CALLBACKS( Read, NULL, Control, NULL );
+    p_sys = p_access->p_sys = calloc( 1, sizeof( access_sys_t ) );
+    if( !p_sys )
     {
-        msg_Err( p_input, "invalid port number (%d)", sock.i_server_port );
         free( psz_dup );
-        return VLC_EGENERIC;
+        return VLC_ENOMEM;
     }
 
-    /* connecting */
-    msg_Dbg( p_input, "opening server=%s:%d",
-             sock.psz_server_addr, sock.i_server_port );
-    p_input->p_private = (void*)&sock;
-    p_network = module_Need( p_input, "network", psz_network );
+    p_sys->fd = net_ConnectTCP( p_access, psz_dup, atoi( psz_parser ) );
     free( psz_dup );
-    if( p_network == NULL )
+
+    if( p_sys->fd < 0 )
     {
+        free( p_sys );
         return VLC_EGENERIC;
     }
-    module_Unneed( p_input, p_network );
-
-    p_input->p_access_data = p_sys = malloc( sizeof( access_sys_t ) );
-    p_sys->fd = sock.i_handle;
-
-    p_input->pf_read = Read;
-    p_input->pf_set_program = input_SetProgram;
-    p_input->pf_set_area = NULL;
-    p_input->pf_seek = NULL;
-
-    vlc_mutex_lock( &p_input->stream.stream_lock );
-    p_input->stream.b_pace_control = VLC_TRUE;  /* FIXME ? */
-    p_input->stream.b_seekable = 0;
-    p_input->stream.p_selected_area->i_tell = 0;
-    p_input->stream.i_method = INPUT_METHOD_NETWORK;
-    p_input->i_mtu = 0;
-    vlc_mutex_unlock( &p_input->stream.stream_lock );
 
     /* Update default_pts to a suitable value for udp access */
-    var_Create( p_input, "tcp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
-    var_Get( p_input, "tcp-caching", &val );
-    p_input->i_pts_delay = val.i_int * 1000;
+    var_Create( p_access, "tcp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
 
     return VLC_SUCCESS;
 }
@@ -205,64 +132,80 @@ static int Open( vlc_object_t *p_this )
  *****************************************************************************/
 static void Close( vlc_object_t *p_this )
 {
-    input_thread_t *p_input = (input_thread_t *)p_this;
-    access_sys_t   *p_sys = p_input->p_access_data;
+    access_t     *p_access = (access_t *)p_this;
+    access_sys_t *p_sys = p_access->p_sys;
 
-    msg_Info( p_input, "closing TCP target `%s'", p_input->psz_source );
+    net_Close( p_sys->fd );
+    free( p_sys );
+}
 
-#ifdef UNDER_CE
-    CloseHandle( (HANDLE)p_sys->fd );
-#elif defined( WIN32 )
-    closesocket( p_sys->fd );
-#else
-    close( p_sys->fd );
-#endif
+/*****************************************************************************
+ * Read: read on a file descriptor
+ *****************************************************************************/
+static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
+{
+    access_sys_t *p_sys = p_access->p_sys;
+    int i_read;
 
-    free( p_sys );
+    if( p_access->info.b_eof )
+        return 0;
+
+    i_read = net_Read( p_access, p_sys->fd, NULL, p_buffer, i_len,
+                       false );
+    if( i_read == 0 )
+        p_access->info.b_eof = true;
+    else if( i_read > 0 )
+        p_access->info.i_pos += i_read;
+
+    return i_read;
 }
 
 /*****************************************************************************
- * Read: read on a file descriptor, checking b_die periodically
+ * Control:
  *****************************************************************************/
-static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
+static int Control( access_t *p_access, int i_query, va_list args )
 {
-#ifdef UNDER_CE
-    return -1;
-#else
-    access_sys_t   *p_sys = p_input->p_access_data;
-    struct timeval  timeout;
-    fd_set          fds;
-    ssize_t         i_recv;
-    int             i_ret;
-
-    do
-    {
-        if( p_input->b_die || p_input->b_error )
-        {
-            return 0;
-        }
-
-        /* Initialize file descriptor set */
-        FD_ZERO( &fds );
-        FD_SET( p_sys->fd, &fds );
-
-        /* We'll wait 0.5 second if nothing happens */
-        timeout.tv_sec = 0;
-        timeout.tv_usec = 500000;
-    } while( ( i_ret = select( p_sys->fd + 1, &fds, NULL, NULL, &timeout )) == 0 ||
-             ( i_ret < 0 && errno == EINTR ) );
-
-    if( i_ret < 0 )
-    {
-        msg_Err( p_input, "network select error (%s)", strerror(errno) );
-        return -1;
-    }
+    bool    *pb_bool;
+    int64_t *pi_64;
 
-    if( ( i_recv = recv( p_sys->fd, p_buffer, i_len, 0 ) ) < 0 )
+    switch( i_query )
     {
-        msg_Err( p_input, "recv failed (%s)", strerror(errno) );
+        /* */
+        case ACCESS_CAN_SEEK:
+        case ACCESS_CAN_FASTSEEK:
+            pb_bool = (bool*)va_arg( args, bool* );
+            *pb_bool = false;
+            break;
+        case ACCESS_CAN_PAUSE:
+            pb_bool = (bool*)va_arg( args, bool* );
+            *pb_bool = true;    /* FIXME */
+            break;
+        case ACCESS_CAN_CONTROL_PACE:
+            pb_bool = (bool*)va_arg( args, bool* );
+            *pb_bool = true;    /* FIXME */
+            break;
+
+        case ACCESS_GET_PTS_DELAY:
+            pi_64 = (int64_t*)va_arg( args, int64_t * );
+            *pi_64 = var_GetInteger( p_access, "tcp-caching" ) * INT64_C(1000);
+            break;
+
+        /* */
+        case ACCESS_SET_PAUSE_STATE:
+            /* Nothing to do */
+            break;
+
+        case ACCESS_GET_TITLE_INFO:
+        case ACCESS_SET_TITLE:
+        case ACCESS_SET_SEEKPOINT:
+        case ACCESS_SET_PRIVATE_ID_STATE:
+        case ACCESS_GET_CONTENT_TYPE:
+            return VLC_EGENERIC;
+
+        default:
+            msg_Warn( p_access, "unimplemented query in control" );
+            return VLC_EGENERIC;
+
     }
-    return i_recv;
-#endif
+    return VLC_SUCCESS;
 }
-