Commit 5deafc16 authored by Laurent Aimar's avatar Laurent Aimar
Browse files

* all: use net_*.

parent 83c6d1f7
......@@ -2,7 +2,7 @@
* mms.c: MMS over tcp, udp and http access plug-in
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mms.c,v 1.34 2003/05/15 22:27:36 massiot Exp $
* $Id: mms.c,v 1.35 2004/01/21 16:56:16 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -69,11 +69,6 @@ vlc_module_begin();
add_bool( "mms-all", 0, NULL,
"force selection of all streams",
"force selection of all streams", VLC_TRUE );
#if 0
add_string( "mms-stream", NULL, NULL,
"streams selection",
"force this stream selection", VLC_TRUE );
#endif
add_integer( "mms-maxbitrate", 0, NULL,
"max bitrate",
"set max bitrate for auto streams selections", VLC_FALSE );
......@@ -89,9 +84,14 @@ static int Open( vlc_object_t *p_this )
{
input_thread_t *p_input = (input_thread_t*)p_this;
int i_err;
/* First set ipv4/ipv6 */
var_Create( p_input, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
/* mms-caching */
var_Create( p_input, "mms-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
/* use specified method */
if( *p_input->psz_access )
{
if( !strncmp( p_input->psz_access, "mmsu", 4 ) )
......@@ -108,15 +108,12 @@ static int Open( vlc_object_t *p_this )
}
}
i_err = E_( MMSTUOpen )( p_input );
if( i_err )
if( E_( MMSTUOpen )( p_input ) )
{
i_err = E_( MMSHOpen )( p_input );
/* try mmsh if mmstu failed */
return E_( MMSHOpen )( p_input );
}
return i_err;
return VLC_SUCCESS;
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* mmsh.c:
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mmsh.c,v 1.6 2003/08/26 00:51:19 fenrir Exp $
* $Id: mmsh.c,v 1.7 2004/01/21 16:56:16 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -35,32 +35,6 @@
#include <vlc/vlc.h>
#include <vlc/input.h>
#ifdef HAVE_ERRNO_H
# include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#if defined( UNDER_CE )
# include <winsock.h>
#elif defined( 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 "network.h"
#include "asf.h"
#include "buffer.h"
......@@ -71,20 +45,22 @@
/*****************************************************************************
* Local prototypes
*****************************************************************************/
int E_( MMSHOpen ) ( input_thread_t * );
void E_( MMSHClose ) ( input_thread_t * );
int E_(MMSHOpen) ( input_thread_t * );
void E_(MMSHClose) ( input_thread_t * );
static ssize_t Read( input_thread_t *, byte_t *, size_t );
static void Seek( input_thread_t *, off_t );
static ssize_t Read ( input_thread_t * p_input, byte_t * p_buffer,
size_t i_len );
static void Seek ( input_thread_t *, off_t );
static ssize_t NetFill( input_thread_t *, access_sys_t *, int );
/****************************************************************************
****************************************************************************
******************* *******************
******************* Main functions *******************
******************* *******************
****************************************************************************
****************************************************************************/
static int mmsh_start ( input_thread_t *, off_t );
static void mmsh_stop ( input_thread_t * );
static int mmsh_get_packet( input_thread_t *, chunk_t * );
static http_answer_t *http_answer_parse( uint8_t *, int );
static void http_answer_free ( http_answer_t * );
static http_field_t *http_field_find ( http_field_t *, char * );
static int chunk_parse( chunk_t *, uint8_t *, int );
/****************************************************************************
* Open: connect to ftp server and ask for file
......@@ -98,11 +74,13 @@ int E_( MMSHOpen ) ( input_thread_t *p_input )
http_field_t *p_field;
chunk_t ck;
vlc_value_t val;
/* init p_sys */
p_input->p_access_data = p_sys = malloc( sizeof( access_sys_t ) );
p_sys->i_proto = MMS_PROTO_HTTP;
p_sys->p_socket = NULL;
p_sys->fd = -1;
p_sys->i_request_context = 1;
p_sys->i_buffer = 0;
p_sys->i_buffer_pos = 0;
......@@ -128,7 +106,8 @@ int E_( MMSHOpen ) ( input_thread_t *p_input )
p_sys->p_url->i_port = 80;
}
if( ( p_sys->p_socket = NetOpenTCP( p_input, p_sys->p_url ) ) == NULL )
if( ( p_sys->fd = net_OpenTCP( p_input, p_sys->p_url->psz_host,
p_sys->p_url->i_port ) ) < 0 )
{
msg_Err( p_input, "cannot connect" );
goto exit_error;
......@@ -146,16 +125,15 @@ int E_( MMSHOpen ) ( input_thread_t *p_input )
p += sprintf( p, "Pragma: xClientGUID={"GUID_FMT"}\r\n",
GUID_PRINT( p_sys->guid ) );
p += sprintf( p, "Connection: Close\r\n\r\n" );
NetWrite( p_input, p_sys->p_socket, p_sys->buffer, p - p_sys->buffer );
net_Write( p_input, p_sys->fd, p_sys->buffer, p - p_sys->buffer );
if( NetFill ( p_input, p_sys, BUFFER_SIZE ) <= 0 )
{
msg_Err( p_input, "cannot read answer" );
goto exit_error;
}
NetClose( p_input, p_sys->p_socket );
p_sys->p_socket = NULL;
net_Close( p_sys->fd ); p_sys->fd = -1;
p_ans = http_answer_parse( p_sys->buffer, p_sys->i_buffer );
if( !p_ans )
......@@ -300,21 +278,21 @@ int E_( MMSHOpen ) ( input_thread_t *p_input )
p_input->stream.i_method = INPUT_METHOD_NETWORK;
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* Update default_pts to a suitable value for ftp access */
p_input->i_pts_delay = config_GetInt( p_input, "mms-caching" ) * 1000;
/* Update default_pts to a suitable value for mms access */
var_Get( p_input, "mms-caching", &val );
p_input->i_pts_delay = val.i_int * 1000;
return( VLC_SUCCESS );
return VLC_SUCCESS;
exit_error:
E_( url_free )( p_sys->p_url );
if( p_sys->p_socket )
if( p_sys->fd > 0 )
{
NetClose( p_input, p_sys->p_socket );
net_Close( p_sys->fd );
}
free( p_sys );
return( VLC_EGENERIC );
return VLC_EGENERIC;
}
/*****************************************************************************
......@@ -331,74 +309,6 @@ void E_( MMSHClose ) ( input_thread_t *p_input )
free( p_sys );
}
static int mmsh_get_packet( input_thread_t * p_input,
chunk_t *p_ck )
{
access_sys_t *p_sys = p_input->p_access_data;
int i_mov = p_sys->i_buffer - p_sys->i_buffer_pos;
if( p_sys->i_buffer_pos > BUFFER_SIZE / 2 )
{
if( i_mov > 0 )
{
memmove( &p_sys->buffer[0],
&p_sys->buffer[p_sys->i_buffer_pos],
i_mov );
}
p_sys->i_buffer = i_mov;
p_sys->i_buffer_pos = 0;
}
if( NetFill( p_input, p_sys, 12 ) < 12 )
{
msg_Warn( p_input, "cannot fill buffer" );
return VLC_EGENERIC;
}
chunk_parse( p_ck, &p_sys->buffer[p_sys->i_buffer_pos],
p_sys->i_buffer - p_sys->i_buffer_pos );
if( p_ck->i_type == 0x4524 ) // Transfer complete
{
msg_Warn( p_input, "EOF" );
return VLC_EGENERIC;
}
else if( p_ck->i_type != 0x4824 && p_ck->i_type != 0x4424 )
{
msg_Err( p_input, "invalid chunk FATAL" );
return VLC_EGENERIC;
}
if( p_ck->i_data < p_ck->i_size2 - 8 )
{
if( NetFill( p_input, p_sys, p_ck->i_size2 - 8 - p_ck->i_data ) <= 0 )
{
msg_Warn( p_input, "cannot fill buffer" );
return VLC_EGENERIC;
}
chunk_parse( p_ck, &p_sys->buffer[p_sys->i_buffer_pos],
p_sys->i_buffer - p_sys->i_buffer_pos );
}
if( p_sys->i_packet_sequence != 0 &&
p_ck->i_sequence != p_sys->i_packet_sequence )
{
msg_Warn( p_input, "packet lost ?" );
}
p_sys->i_packet_sequence = p_ck->i_sequence + 1;
p_sys->i_packet_used = 0;
p_sys->i_packet_length = p_ck->i_data;
p_sys->p_packet = p_ck->p_data;
p_sys->i_buffer_pos += 12 + p_ck->i_data;
return VLC_SUCCESS;
}
/*****************************************************************************
* Seek: try to go at the right place
*****************************************************************************/
......@@ -437,10 +347,8 @@ static void Seek( input_thread_t * p_input, off_t i_pos )
p_sys->i_pos = i_pos;
p_sys->i_packet_used += i_offset;
p_input->stream.p_selected_area->i_tell = i_pos;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
/*****************************************************************************
......@@ -498,15 +406,60 @@ static ssize_t Read ( input_thread_t * p_input, byte_t * p_buffer,
return( i_data );
}
/*****************************************************************************
* NetFill:
*****************************************************************************/
static ssize_t NetFill( input_thread_t *p_input, access_sys_t *p_sys, int i_size )
{
int i_try = 0;
int i_total = 0;
i_size = __MIN( i_size, BUFFER_SIZE - p_sys->i_buffer );
if( i_size <= 0 )
{
return 0;
}
for( ;; )
{
int i_read;
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
i_read = net_Read( p_input, p_sys->fd,
&p_sys->buffer[p_sys->i_buffer], i_size, VLC_FALSE );
static int mmsh_start( input_thread_t *p_input,
off_t i_pos )
if( i_read == 0 )
{
if( i_try++ > 2 )
{
break;
}
msg_Dbg( p_input, "another try %d/2", i_try );
continue;
}
if( i_read < 0 || p_input->b_die || p_input->b_error )
{
break;
}
i_total += i_read;
p_sys->i_buffer += i_read;
if( i_total >= i_size )
{
break;
}
}
p_sys->buffer[p_sys->i_buffer] = '\0';
return i_total;
}
/*****************************************************************************
*
*****************************************************************************/
static int mmsh_start( input_thread_t *p_input, off_t i_pos )
{
access_sys_t *p_sys = p_input->p_access_data;
uint8_t *p;
......@@ -516,7 +469,8 @@ static int mmsh_start( input_thread_t *p_input,
msg_Dbg( p_input, "starting stream" );
if( ( p_sys->p_socket = NetOpenTCP( p_input, p_sys->p_url ) ) == NULL )
if( ( p_sys->fd = net_OpenTCP( p_input, p_sys->p_url->psz_host,
p_sys->p_url->i_port ) ) < 0 )
{
/* should not occur */
msg_Err( p_input, "cannot connect to the server" );
......@@ -574,8 +528,7 @@ static int mmsh_start( input_thread_t *p_input,
p += sprintf( p, "\r\n" );
p += sprintf( p, "Connection: Close\r\n\r\n" );
NetWrite( p_input, p_sys->p_socket, p_sys->buffer, p - p_sys->buffer );
net_Write( p_input, p_sys->fd, p_sys->buffer, p - p_sys->buffer );
msg_Dbg( p_input, "filling buffer" );
/* we read until we found a \r\n\r\n or \n\n */
......@@ -588,10 +541,7 @@ static int mmsh_start( input_thread_t *p_input,
uint8_t *p;
p = &p_sys->buffer[p_sys->i_buffer];
i_read =
NetRead( p_input, p_sys->p_socket,
&p_sys->buffer[p_sys->i_buffer],
1024 );
i_read = net_Read( p_input, p_sys->fd, &p_sys->buffer[p_sys->i_buffer], 1024, VLC_FALSE );
if( i_read == 0 )
{
......@@ -651,229 +601,89 @@ static int mmsh_start( input_thread_t *p_input,
return VLC_SUCCESS;
}
/*****************************************************************************
*
*****************************************************************************/
static void mmsh_stop( input_thread_t *p_input )
{
access_sys_t *p_sys = p_input->p_access_data;
msg_Dbg( p_input, "closing stream" );
NetClose( p_input, p_sys->p_socket );
p_sys->p_socket = NULL;
net_Close( p_sys->fd ); p_sys->fd = -1;
}
static ssize_t NetFill( input_thread_t *p_input,
access_sys_t *p_sys, int i_size )
/*****************************************************************************
*
*****************************************************************************/
static int mmsh_get_packet( input_thread_t * p_input, chunk_t *p_ck )
{
int i_try = 0;
int i_total = 0;
access_sys_t *p_sys = p_input->p_access_data;
i_size = __MIN( i_size, BUFFER_SIZE - p_sys->i_buffer );
if( i_size <= 0 )
{
return 0;
}
int i_mov = p_sys->i_buffer - p_sys->i_buffer_pos;
for( ;; )
if( p_sys->i_buffer_pos > BUFFER_SIZE / 2 )
{
int i_read;
i_read = NetRead( p_input, p_sys->p_socket,
&p_sys->buffer[p_sys->i_buffer], i_size );
if( i_read == 0 )
{
if( i_try++ > 2 )
{
break;
}
msg_Dbg( p_input, "another try %d/2", i_try );
continue;
}
if( i_read < 0 || p_input->b_die || p_input->b_error )
{
break;
}
i_total += i_read;
p_sys->i_buffer += i_read;
if( i_total >= i_size )
if( i_mov > 0 )
{
break;
memmove( &p_sys->buffer[0],
&p_sys->buffer[p_sys->i_buffer_pos],
i_mov );
}
}
p_sys->buffer[p_sys->i_buffer] = '\0';
return i_total;
}
/****************************************************************************
* NetOpenTCP:
****************************************************************************/
static input_socket_t * NetOpenTCP( input_thread_t *p_input, url_t *p_url )
{
input_socket_t *p_socket;
char *psz_network;
module_t *p_network;
network_socket_t socket_desc;
p_socket = malloc( sizeof( input_socket_t ) );
memset( p_socket, 0, sizeof( input_socket_t ) );
psz_network = "";
if( config_GetInt( p_input, "ipv4" ) )
{
psz_network = "ipv4";
}
else if( config_GetInt( p_input, "ipv6" ) )
{
psz_network = "ipv6";
p_sys->i_buffer = i_mov;
p_sys->i_buffer_pos = 0;
}
msg_Dbg( p_input, "waiting for connection..." );
socket_desc.i_type = NETWORK_TCP;
socket_desc.psz_server_addr = p_url->psz_host;
socket_desc.i_server_port = p_url->i_port;
socket_desc.psz_bind_addr = "";
socket_desc.i_bind_port = 0;
socket_desc.i_ttl = 0;
p_input->p_private = (void*)&socket_desc;
if( !( p_network = module_Need( p_input, "network", psz_network ) ) )
if( NetFill( p_input, p_sys, 12 ) < 12 )
{
msg_Err( p_input, "failed to connect with server" );
return NULL;
msg_Warn( p_input, "cannot fill buffer" );
return VLC_EGENERIC;
}
module_Unneed( p_input, p_network );
p_socket->i_handle = socket_desc.i_handle;
p_input->i_mtu = socket_desc.i_mtu;
msg_Dbg( p_input,
"connection with \"%s:%d\" successful",
p_url->psz_host,
p_url->i_port );
return p_socket;
}
/*****************************************************************************
* Read: read on a file descriptor, checking b_die periodically
*****************************************************************************/
static ssize_t NetRead( input_thread_t *p_input,
input_socket_t *p_socket,
byte_t *p_buffer, size_t i_len )
{
struct timeval timeout;
fd_set fds;
ssize_t i_recv;
int i_ret;
/* Initialize file descriptor set */
FD_ZERO( &fds );
FD_SET( p_socket->i_handle, &fds );
/* We'll wait 1 second if nothing happens */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* Find if some data is available */
while( ( i_ret = select( p_socket->i_handle + 1, &fds,
NULL, NULL, &timeout )) == 0 ||
#ifdef HAVE_ERRNO_H
( i_ret < 0 && errno == EINTR )
#endif
)
{
FD_ZERO( &fds );
FD_SET( p_socket->i_handle, &fds );
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if( p_input->b_die || p_input->b_error )
{
return 0;
}
}
chunk_parse( p_ck, &p_sys->buffer[p_sys->i_buffer_pos],
p_sys->i_buffer - p_sys->i_buffer_pos );
if( i_ret < 0 )
if( p_ck->i_type == 0x4524 ) // Transfer complete
{
msg_Err( p_input, "network select error (%s)", strerror(errno) );
return -1;
msg_Warn( p_input, "EOF" );
return VLC_EGENERIC;
}
i_recv = recv( p_socket->i_handle, p_buffer, i_len, 0 );
if( i_recv < 0 )
else if( p_ck->i_type != 0x4824 && p_ck->i_type != 0x4424 )
{
msg_Err( p_input, "recv failed (%s)", strerror(errno) );
msg_Err( p_input, "invalid chunk FATAL" );
return VLC_EGENERIC;
}
return i_recv;
}
static ssize_t NetWrite( input_thread_t *p_input,
input_socket_t *p_socket,
byte_t *p_buffer, size_t i_len )
{
struct timeval timeout;
fd_set fds;
ssize_t i_send;
int i_ret;
/* Initialize file descriptor set */
FD_ZERO( &fds );
FD_SET( p_socket->i_handle, &fds );
/* We'll wait 1 second if nothing happens */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* Find if some data is available */
while( ( i_ret = select( p_socket->i_handle + 1, NULL, &fds, NULL, &timeout ) ) == 0 ||
#ifdef HAVE_ERRNO_H
( i_ret < 0 && errno == EINTR )
#endif
)
if( p_ck->i_data < p_ck->i_size2 - 8 )
{
FD_ZERO( &fds );
FD_SET( p_socket->i_handle, &fds );
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if( p_input->b_die || p_input->b_error )
if( NetFill( p_input, p_sys, p_ck->i_size2 - 8 - p_ck->i_data ) <= 0 )
{
return 0;
msg_Warn( p_input, "cannot fill buffer" );
return VLC_EGENERIC;
}
chunk_parse( p_ck, &p_sys->buffer[p_sys->i_buffer_pos],
p_sys->i_buffer - p_sys->i_buffer_pos );
}
if( i_ret < 0 )
{</