Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
881768ad
Commit
881768ad
authored
Nov 25, 2002
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* all: begin to add mms over udp support. It begin to work (at least
for me) but it still needs some work.
parent
1158db5f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
577 additions
and
343 deletions
+577
-343
modules/access/mms/buffer.c
modules/access/mms/buffer.c
+7
-2
modules/access/mms/buffer.h
modules/access/mms/buffer.h
+2
-2
modules/access/mms/mms.c
modules/access/mms/mms.c
+532
-315
modules/access/mms/mms.h
modules/access/mms/mms.h
+36
-24
No files found.
modules/access/mms/buffer.c
View file @
881768ad
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* buffer.c: MMS access plug-in
* buffer.c: MMS access plug-in
*****************************************************************************
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* Copyright (C) 2001, 2002 VideoLAN
* $Id: buffer.c,v 1.
1 2002/11/22 18:35:57 sam
Exp $
* $Id: buffer.c,v 1.
2 2002/11/25 00:22:04 fenrir
Exp $
*
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
*
...
@@ -193,7 +193,7 @@ uint64_t var_buffer_get64( var_buffer_t *p_buf )
...
@@ -193,7 +193,7 @@ uint64_t var_buffer_get64( var_buffer_t *p_buf )
return
(
i_dw1
+
(
i_dw2
<<
32
)
);
return
(
i_dw1
+
(
i_dw2
<<
32
)
);
}
}
int
var_buffer_getmemory
(
var_buffer_t
*
p_buf
,
void
*
p_mem
,
int
i_mem
)
int
var_buffer_getmemory
(
var_buffer_t
*
p_buf
,
void
*
p_mem
,
int
64_t
i_mem
)
{
{
int
i_copy
;
int
i_copy
;
...
@@ -202,6 +202,11 @@ int var_buffer_getmemory ( var_buffer_t *p_buf, void *p_mem, int i_mem )
...
@@ -202,6 +202,11 @@ int var_buffer_getmemory ( var_buffer_t *p_buf, void *p_mem, int i_mem )
{
{
memcpy
(
p_mem
,
p_buf
+
p_buf
->
i_data
,
i_copy
);
memcpy
(
p_mem
,
p_buf
+
p_buf
->
i_data
,
i_copy
);
}
}
if
(
i_copy
<
0
)
{
// fprintf( stderr, "\n**************arrrrrrggggg\n" );
i_copy
=
0
;
}
p_buf
->
i_data
+=
i_copy
;
p_buf
->
i_data
+=
i_copy
;
return
(
i_copy
);
return
(
i_copy
);
}
}
...
...
modules/access/mms/buffer.h
View file @
881768ad
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* buffer.h: MMS access plug-in
* buffer.h: MMS access plug-in
*****************************************************************************
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* Copyright (C) 2001, 2002 VideoLAN
* $Id: buffer.h,v 1.
1 2002/11/22 18:35:57 sam
Exp $
* $Id: buffer.h,v 1.
2 2002/11/25 00:22:04 fenrir
Exp $
*
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
*
...
@@ -50,7 +50,7 @@ uint8_t var_buffer_get8 ( var_buffer_t *p_buf );
...
@@ -50,7 +50,7 @@ uint8_t var_buffer_get8 ( var_buffer_t *p_buf );
uint16_t
var_buffer_get16
(
var_buffer_t
*
p_buf
);
uint16_t
var_buffer_get16
(
var_buffer_t
*
p_buf
);
uint32_t
var_buffer_get32
(
var_buffer_t
*
p_buf
);
uint32_t
var_buffer_get32
(
var_buffer_t
*
p_buf
);
uint64_t
var_buffer_get64
(
var_buffer_t
*
p_buf
);
uint64_t
var_buffer_get64
(
var_buffer_t
*
p_buf
);
int
var_buffer_getmemory
(
var_buffer_t
*
p_buf
,
void
*
p_mem
,
int
i_mem
);
int
var_buffer_getmemory
(
var_buffer_t
*
p_buf
,
void
*
p_mem
,
int
64_t
i_mem
);
int
var_buffer_readempty
(
var_buffer_t
*
p_buf
);
int
var_buffer_readempty
(
var_buffer_t
*
p_buf
);
void
var_buffer_getguid
(
var_buffer_t
*
p_buf
,
guid_t
*
p_guid
);
void
var_buffer_getguid
(
var_buffer_t
*
p_buf
,
guid_t
*
p_guid
);
modules/access/mms/mms.c
View file @
881768ad
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* mms.c: MMS access plug-in
* mms.c: MMS access plug-in
*****************************************************************************
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mms.c,v 1.
6 2002/11/22 18:35:57 sam
Exp $
* $Id: mms.c,v 1.
7 2002/11/25 00:22:04 fenrir
Exp $
*
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
*
...
@@ -76,8 +76,6 @@ static void Close ( vlc_object_t * );
...
@@ -76,8 +76,6 @@ static void Close ( vlc_object_t * );
static
int
Read
(
input_thread_t
*
p_input
,
byte_t
*
p_buffer
,
static
int
Read
(
input_thread_t
*
p_input
,
byte_t
*
p_buffer
,
size_t
i_len
);
size_t
i_len
);
static
ssize_t
NetRead
(
input_thread_t
*
p_input
,
input_socket_t
*
p_socket
,
byte_t
*
p_buffer
,
size_t
i_len
);
static
void
Seek
(
input_thread_t
*
,
off_t
);
static
void
Seek
(
input_thread_t
*
,
off_t
);
static
int
SetProgram
(
input_thread_t
*
,
pgrm_descriptor_t
*
);
static
int
SetProgram
(
input_thread_t
*
,
pgrm_descriptor_t
*
);
...
@@ -85,7 +83,7 @@ static int SetProgram ( input_thread_t *, pgrm_descriptor_t * );
...
@@ -85,7 +83,7 @@ static int SetProgram ( input_thread_t *, pgrm_descriptor_t * );
static
int
MMSOpen
(
input_thread_t
*
,
url_t
*
,
int
,
char
*
);
static
int
MMSOpen
(
input_thread_t
*
,
url_t
*
,
int
,
char
*
);
static
int
MMSStart
(
input_thread_t
*
,
uint32_t
);
static
int
MMSStart
(
input_thread_t
*
,
uint32_t
);
static
int
MMSStop
(
input_thread_t
*
p_input
);
// Not used
static
int
MMSStop
(
input_thread_t
*
p_input
);
static
int
MMSClose
(
input_thread_t
*
);
static
int
MMSClose
(
input_thread_t
*
);
...
@@ -109,7 +107,9 @@ static void mms_ParseURL( url_t *p_url, char *psz_url );
...
@@ -109,7 +107,9 @@ static void mms_ParseURL( url_t *p_url, char *psz_url );
/*
/*
* Ok, ok, j'le ferai plus...
* Ok, ok, j'le ferai plus...
*/
*/
/*
* Merci :))
*/
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
...
@@ -122,8 +122,6 @@ vlc_module_begin();
...
@@ -122,8 +122,6 @@ vlc_module_begin();
"force selection of all streams"
,
"force selection of all streams"
,
"force selection of all streams"
);
"force selection of all streams"
);
// add_bool( "mms-modem", 0, NULL, "Set maxbitrate to 56Kb/s","" );
add_string
(
"mms-stream"
,
NULL
,
NULL
,
add_string
(
"mms-stream"
,
NULL
,
NULL
,
"streams selection"
,
"streams selection"
,
"force this stream selection"
);
"force this stream selection"
);
...
@@ -152,8 +150,6 @@ static int Open( vlc_object_t *p_this )
...
@@ -152,8 +150,6 @@ static int Open( vlc_object_t *p_this )
(
void
*
)
p_access
=
malloc
(
sizeof
(
access_t
)
);
(
void
*
)
p_access
=
malloc
(
sizeof
(
access_t
)
);
memset
(
p_access
,
0
,
sizeof
(
access_t
)
);
memset
(
p_access
,
0
,
sizeof
(
access_t
)
);
p_access
->
p_cmd
=
malloc
(
BUF_SIZE
);
/* *** Parse URL and get server addr/port and path *** */
/* *** Parse URL and get server addr/port and path *** */
mms_ParseURL
(
&
p_access
->
url
,
p_input
->
psz_name
);
mms_ParseURL
(
&
p_access
->
url
,
p_input
->
psz_name
);
...
@@ -161,15 +157,18 @@ static int Open( vlc_object_t *p_this )
...
@@ -161,15 +157,18 @@ static int Open( vlc_object_t *p_this )
!
(
*
p_access
->
url
.
psz_server_addr
)
)
!
(
*
p_access
->
url
.
psz_server_addr
)
)
{
{
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
p_cmd
);
msg_Err
(
p_input
,
"invalid server name"
);
msg_Err
(
p_input
,
"invalid server name"
);
return
(
-
1
);
return
(
-
1
);
}
}
if
(
p_access
->
url
.
i_server_port
==
0
)
if
(
p_access
->
url
.
i_server_port
==
0
)
{
{
p_access
->
url
.
i_server_port
=
1755
;
/
/ default port
p_access
->
url
.
i_server_port
=
1755
;
/
* default port */
}
}
if
(
p_access
->
url
.
i_bind_port
==
0
)
{
p_access
->
url
.
i_bind_port
=
7000
;
/* default port */
}
/* *** connect to this server *** */
/* *** connect to this server *** */
/* 1: look at requested protocol (udp/tcp) */
/* 1: look at requested protocol (udp/tcp) */
...
@@ -197,11 +196,11 @@ static int Open( vlc_object_t *p_this )
...
@@ -197,11 +196,11 @@ static int Open( vlc_object_t *p_this )
}
}
/* 3: connect */
/* 3: connect */
if
(
i_proto
==
MMS_PROTO_AUTO
)
if
(
i_proto
==
MMS_PROTO_AUTO
)
{
/
/ first try with TCP
{
/
* first try with TCP */
i_status
=
i_status
=
MMSOpen
(
p_input
,
&
p_access
->
url
,
MMS_PROTO_TCP
,
psz_network
);
MMSOpen
(
p_input
,
&
p_access
->
url
,
MMS_PROTO_TCP
,
psz_network
);
if
(
i_status
<
0
)
if
(
i_status
<
0
)
{
/
/ then with UDP
{
/
* then with UDP */
i_status
=
i_status
=
MMSOpen
(
p_input
,
&
p_access
->
url
,
MMS_PROTO_UDP
,
psz_network
);
MMSOpen
(
p_input
,
&
p_access
->
url
,
MMS_PROTO_UDP
,
psz_network
);
}
}
...
@@ -215,16 +214,12 @@ static int Open( vlc_object_t *p_this )
...
@@ -215,16 +214,12 @@ static int Open( vlc_object_t *p_this )
if
(
i_status
<
0
)
if
(
i_status
<
0
)
{
{
// all sockets are closed
msg_Err
(
p_input
,
"cannot connect to server"
);
msg_Err
(
p_input
,
"cannot connect to server"
);
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
p_cmd
);
return
(
-
1
);
return
(
-
1
);
}
}
msg_Dbg
(
p_input
,
"connected to %s"
,
p_access
->
url
.
psz_server_addr
);
msg_Dbg
(
p_input
,
"connected to %s"
,
p_access
->
url
.
psz_server_addr
);
// all sockets are open
/* *** set exported functions *** */
/* *** set exported functions *** */
p_input
->
pf_read
=
Read
;
p_input
->
pf_read
=
Read
;
...
@@ -232,7 +227,7 @@ static int Open( vlc_object_t *p_this )
...
@@ -232,7 +227,7 @@ static int Open( vlc_object_t *p_this )
p_input
->
pf_set_program
=
SetProgram
;
p_input
->
pf_set_program
=
SetProgram
;
p_input
->
pf_set_area
=
NULL
;
p_input
->
pf_set_area
=
NULL
;
p_input
->
p_private
=
NULL
;
// XXX ??
p_input
->
p_private
=
NULL
;
/* *** finished to set some variable *** */
/* *** finished to set some variable *** */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
...
@@ -261,7 +256,6 @@ static int Open( vlc_object_t *p_this )
...
@@ -261,7 +256,6 @@ static int Open( vlc_object_t *p_this )
msg_Err
(
p_input
,
"cannot start stream"
);
msg_Err
(
p_input
,
"cannot start stream"
);
MMSClose
(
p_input
);
MMSClose
(
p_input
);
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
p_cmd
);
return
(
-
1
);
return
(
-
1
);
}
}
...
@@ -281,7 +275,6 @@ static void Close( vlc_object_t *p_this )
...
@@ -281,7 +275,6 @@ static void Close( vlc_object_t *p_this )
/* free memory */
/* free memory */
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
url
.
psz_private
);
FREE
(
p_access
->
p_cmd
);
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -404,60 +397,6 @@ static int Read ( input_thread_t * p_input, byte_t * p_buffer,
...
@@ -404,60 +397,6 @@ static int Read ( input_thread_t * p_input, byte_t * p_buffer,
return
(
i_data
);
return
(
i_data
);
}
}
/*****************************************************************************
* NetRead: 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
)
{
#ifdef UNDER_CE
return
-
1
;
#else
struct
timeval
timeout
;
fd_set
fds
;
int
i_ret
;
/* Initialize file descriptor set */
FD_ZERO
(
&
fds
);
FD_SET
(
p_socket
->
i_handle
,
&
fds
);
/* We'll wait 0.5 second if nothing happens */
timeout
.
tv_sec
=
0
;
timeout
.
tv_usec
=
500000
;
/* Find if some data is available */
i_ret
=
select
(
p_socket
->
i_handle
+
1
,
&
fds
,
NULL
,
NULL
,
&
timeout
);
if
(
i_ret
==
-
1
&&
errno
!=
EINTR
)
{
msg_Err
(
p_input
,
"network select error (%s)"
,
strerror
(
errno
)
);
}
else
if
(
i_ret
>
0
)
{
ssize_t
i_recv
=
recv
(
p_socket
->
i_handle
,
p_buffer
,
i_len
,
0
);
if
(
i_recv
>
0
)
{
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
p_selected_area
->
i_tell
+=
i_recv
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
}
if
(
i_recv
<
0
)
{
msg_Err
(
p_input
,
"recv failed (%s)"
,
strerror
(
errno
)
);
}
return
i_recv
;
}
return
0
;
#endif
}
static
void
asf_HeaderParse
(
mms_stream_t
stream
[
128
],
static
void
asf_HeaderParse
(
mms_stream_t
stream
[
128
],
uint8_t
*
p_header
,
int
i_header
)
uint8_t
*
p_header
,
int
i_header
)
{
{
...
@@ -471,17 +410,21 @@ static void asf_HeaderParse( mms_stream_t stream[128],
...
@@ -471,17 +410,21 @@ static void asf_HeaderParse( mms_stream_t stream[128],
stream
[
i
].
i_cat
=
MMS_STREAM_UNKNOWN
;
stream
[
i
].
i_cat
=
MMS_STREAM_UNKNOWN
;
}
}
// fprintf( stderr, " ---------------------header:%d\n", i_header );
var_buffer_initread
(
&
buffer
,
p_header
,
i_header
);
var_buffer_initread
(
&
buffer
,
p_header
,
i_header
);
var_buffer_getguid
(
&
buffer
,
&
guid
);
var_buffer_getguid
(
&
buffer
,
&
guid
);
if
(
!
CmpGuid
(
&
guid
,
&
asf_object_header_guid
)
)
if
(
!
CmpGuid
(
&
guid
,
&
asf_object_header_guid
)
)
{
{
// XXX Error
// XXX Error
// fprintf( stderr, " ---------------------ERROR------\n" );
}
}
var_buffer_getmemory
(
&
buffer
,
NULL
,
30
-
16
);
var_buffer_getmemory
(
&
buffer
,
NULL
,
30
-
16
);
for
(
;;
)
for
(
;;
)
{
{
// fprintf( stderr, " ---------------------data:%d\n", buffer.i_data );
if
(
var_buffer_readempty
(
&
buffer
)
)
if
(
var_buffer_readempty
(
&
buffer
)
)
{
{
return
;
return
;
...
@@ -493,13 +436,14 @@ static void asf_HeaderParse( mms_stream_t stream[128],
...
@@ -493,13 +436,14 @@ static void asf_HeaderParse( mms_stream_t stream[128],
{
{
int
i_stream_id
;
int
i_stream_id
;
guid_t
stream_type
;
guid_t
stream_type
;
// msg_Dbg( p_input, "found stream_properties" );
// msg_Dbg( p_input, "found stream_properties" );
var_buffer_getguid
(
&
buffer
,
&
stream_type
);
var_buffer_getguid
(
&
buffer
,
&
stream_type
);
var_buffer_getmemory
(
&
buffer
,
NULL
,
32
);
var_buffer_getmemory
(
&
buffer
,
NULL
,
32
);
i_stream_id
=
var_buffer_get8
(
&
buffer
)
&
0x7f
;
i_stream_id
=
var_buffer_get8
(
&
buffer
)
&
0x7f
;
var_buffer_getmemory
(
&
buffer
,
NULL
,
i_size
-
24
-
32
-
16
-
1
);
// fprintf( stderr, " 1---------------------skip:%lld\n", i_size - 24 - 32 - 16 - 1 );
var_buffer_getmemory
(
&
buffer
,
NULL
,
i_size
-
24
-
32
-
16
-
1
);
if
(
CmpGuid
(
&
stream_type
,
&
asf_object_stream_type_video
)
)
if
(
CmpGuid
(
&
stream_type
,
&
asf_object_stream_type_video
)
)
{
{
...
@@ -531,12 +475,14 @@ static void asf_HeaderParse( mms_stream_t stream[128],
...
@@ -531,12 +475,14 @@ static void asf_HeaderParse( mms_stream_t stream[128],
i_count
--
;
i_count
--
;
i_size
-=
6
;
i_size
-=
6
;
}
}
// fprintf( stderr, " 2---------------------skip:%lld\n", i_size - 24);
var_buffer_getmemory
(
&
buffer
,
NULL
,
i_size
-
24
);
var_buffer_getmemory
(
&
buffer
,
NULL
,
i_size
-
24
);
}
}
else
else
{
{
// skip unknown guid
// skip unknown guid
var_buffer_getmemory
(
&
buffer
,
NULL
,
i_size
-
24
);
var_buffer_getmemory
(
&
buffer
,
NULL
,
i_size
-
24
);
// fprintf( stderr, " 3---------------------skip:%lld\n", i_size - 24);
}
}
}
}
}
}
...
@@ -731,40 +677,64 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -731,40 +677,64 @@ static int MMSOpen( input_thread_t *p_input,
p_input
->
p_private
=
(
void
*
)
&
socket_desc
;
p_input
->
p_private
=
(
void
*
)
&
socket_desc
;
if
(
!
(
p_network
=
module_Need
(
p_input
,
"network"
,
psz_network
)
)
)
if
(
!
(
p_network
=
module_Need
(
p_input
,
"network"
,
psz_network
)
)
)
{
{
msg_Err
(
p_input
,
"failed to open a connection"
);
msg_Err
(
p_input
,
"failed to open a connection
(tcp)
"
);
return
(
-
1
);
return
(
-
1
);
}
}
module_Unneed
(
p_input
,
p_network
);
module_Unneed
(
p_input
,
p_network
);
p_access
->
socket_
server
.
i_handle
=
socket_desc
.
i_handle
;
p_access
->
socket_
tcp
.
i_handle
=
socket_desc
.
i_handle
;
p_input
->
i_mtu
=
socket_desc
.
i_mtu
;
// FIXME
p_input
->
i_mtu
=
0
;
/*socket_desc.i_mtu;*/
msg_Dbg
(
p_input
,
msg_Dbg
(
p_input
,
"connection with
\"
%s:%d
\"
successful"
,
"connection
(tcp)
with
\"
%s:%d
\"
successful"
,
p_url
->
psz_server_addr
,
p_url
->
psz_server_addr
,
p_url
->
i_server_port
);
p_url
->
i_server_port
);
/* *** Bind port if UDP protocol is selected *** */
/* *** Bind port if UDP protocol is selected *** */
// TODO
if
(
b_udp
)
if
(
b_udp
)
{
{
msg_Err
(
p_input
,
msg_Err
(
p_input
,
"MMS/UDP not yet implemented"
);
"MMS/UDP not yet functionnal, anyway trying..."
);
// close socket
if
(
!
p_url
->
psz_bind_addr
||
!*
p_url
->
psz_bind_addr
)
{
msg_Err
(
p_input
,
"for udp you have to provide bind address (mms://<server_addr>@<bind_addr/<path> (FIXME)"
);
#if defined( UNDER_CE )
#if defined( UNDER_CE )
CloseHandle
(
(
HANDLE
)
p_access
->
socket_server
.
i_handle
);
CloseHandle
(
(
HANDLE
)
p_access
->
socket_tcp
.
i_handle
);
#elif defined( WIN32 )
#elif defined( WIN32 )
closesocket
(
p_access
->
socket_server
.
i_handle
);
closesocket
(
p_access
->
socket_tcp
.
i_handle
);
#else
#else
close
(
p_access
->
socket_server
.
i_handle
);
close
(
p_access
->
socket_tcp
.
i_handle
);
#endif
#endif
return
(
-
1
);
return
(
-
1
);
}
socket_desc
.
i_type
=
NETWORK_UDP
;
socket_desc
.
psz_server_addr
=
""
;
socket_desc
.
i_server_port
=
0
;
socket_desc
.
psz_bind_addr
=
p_url
->
psz_bind_addr
;
socket_desc
.
i_bind_port
=
p_url
->
i_bind_port
;
p_input
->
p_private
=
(
void
*
)
&
socket_desc
;
if
(
!
(
p_network
=
module_Need
(
p_input
,
"network"
,
psz_network
)
)
)
{
msg_Err
(
p_input
,
"failed to open a connection (udp)"
);
#if defined( UNDER_CE )
CloseHandle
(
(
HANDLE
)
p_access
->
socket_tcp
.
i_handle
);
#elif defined( WIN32 )
closesocket
(
p_access
->
socket_tcp
.
i_handle
);
#else
close
(
p_access
->
socket_tcp
.
i_handle
);
#endif
return
(
-
1
);
}
module_Unneed
(
p_input
,
p_network
);
p_access
->
socket_udp
.
i_handle
=
socket_desc
.
i_handle
;
p_input
->
i_mtu
=
0
;
/*socket_desc.i_mtu; FIXME */
}
}
/* *** Init context for mms prototcol *** */
/* *** Init context for mms prototcol *** */
GenerateGuid
(
&
p_access
->
guid
);
/
/ used to identify client by server
GenerateGuid
(
&
p_access
->
guid
);
/
* used to identify client by server */
msg_Dbg
(
p_input
,
msg_Dbg
(
p_input
,
"generated guid: "
GUID_FMT
,
"generated guid: "
GUID_FMT
,
GUID_PRINT
(
p_access
->
guid
)
);
GUID_PRINT
(
p_access
->
guid
)
);
p_access
->
i_command_level
=
1
;
/
/ updated after 0x1A command
p_access
->
i_command_level
=
1
;
/
* updated after 0x1A command */
p_access
->
i_seq_num
=
0
;
p_access
->
i_seq_num
=
0
;
p_access
->
i_media_packet_id_type
=
0x04
;
p_access
->
i_media_packet_id_type
=
0x04
;
p_access
->
i_header_packet_id_type
=
0x02
;
p_access
->
i_header_packet_id_type
=
0x02
;
...
@@ -777,6 +747,10 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -777,6 +747,10 @@ static int MMSOpen( input_thread_t *p_input,
p_access
->
i_media_used
=
0
;
p_access
->
i_media_used
=
0
;
p_access
->
i_pos
=
0
;
p_access
->
i_pos
=
0
;
p_access
->
i_buffer_tcp
=
0
;
p_access
->
i_buffer_udp
=
0
;
p_access
->
p_cmd
=
NULL
;
p_access
->
i_cmd
=
0
;
/* *** send command 1 : connection request *** */
/* *** send command 1 : connection request *** */
var_buffer_initwrite
(
&
buffer
,
0
);
var_buffer_initwrite
(
&
buffer
,
0
);
...
@@ -831,8 +805,17 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -831,8 +805,17 @@ static int MMSOpen( input_thread_t *p_input,
var_buffer_add32
(
&
buffer
,
0x00000000
);
var_buffer_add32
(
&
buffer
,
0x00000000
);
var_buffer_add32
(
&
buffer
,
0x000a0000
);
var_buffer_add32
(
&
buffer
,
0x000a0000
);
var_buffer_add32
(
&
buffer
,
0x00000002
);
var_buffer_add32
(
&
buffer
,
0x00000002
);
// FIXME wrong for UDP FIXME
if
(
b_udp
)
sprintf
(
tmp
,
"
\\\\
127.0.0.1
\\
%s
\\
1242"
,
b_udp
?
"UDP"
:
"TCP"
);
{
sprintf
(
tmp
,
"
\\\\
%s
\\
UDP
\\
%d"
,
p_url
->
psz_bind_addr
,
p_url
->
i_bind_port
);
}
else
{
sprintf
(
tmp
,
"
\\\\
127.0.0.1
\\
TCP
\\
1242"
);
}
var_buffer_addUTF16
(
&
buffer
,
tmp
);
var_buffer_addUTF16
(
&
buffer
,
tmp
);
var_buffer_add16
(
&
buffer
,
'0'
);
var_buffer_add16
(
&
buffer
,
'0'
);
...
@@ -844,7 +827,7 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -844,7 +827,7 @@ static int MMSOpen( input_thread_t *p_input,
buffer
.
i_data
);
buffer
.
i_data
);
/* *** response from server, should be 0x02 or 0x03 *** */
/* *** response from server, should be 0x02 or 0x03 *** */
mms_CommandRead
(
p_input
,
0x02
,
0
);
mms_CommandRead
(
p_input
,
0x02
,
0
x03
);
if
(
p_access
->
i_command
==
0x03
)
if
(
p_access
->
i_command
==
0x03
)
{
{
msg_Err
(
p_input
,
msg_Err
(
p_input
,
...
@@ -861,7 +844,6 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -861,7 +844,6 @@ static int MMSOpen( input_thread_t *p_input,
/* *** send command 5 : media file name/path requested *** */
/* *** send command 5 : media file name/path requested *** */
var_buffer_reinitwrite
(
&
buffer
,
0
);
var_buffer_reinitwrite
(
&
buffer
,
0
);
var_buffer_add64
(
&
buffer
,
0
);
var_buffer_add64
(
&
buffer
,
0
);
// var_buffer_addUTF16( &buffer, "/" );
var_buffer_addUTF16
(
&
buffer
,
p_url
->
psz_path
);
var_buffer_addUTF16
(
&
buffer
,
p_url
->
psz_path
);
mms_CommandSend
(
p_input
,
mms_CommandSend
(
p_input
,
...
@@ -878,7 +860,7 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -878,7 +860,7 @@ static int MMSOpen( input_thread_t *p_input,
if
(
p_access
->
i_command
==
0x1A
)
if
(
p_access
->
i_command
==
0x1A
)
{
{
msg_Err
(
p_input
,
"id/password requested (not yet supported)"
);
msg_Err
(
p_input
,
"id/password requested (not yet supported)"
);
/
/ FIXME
/
* FIXME */
var_buffer_free
(
&
buffer
);
var_buffer_free
(
&
buffer
);
MMSClose
(
p_input
);
MMSClose
(
p_input
);
return
(
-
1
);
return
(
-
1
);
...
@@ -893,7 +875,7 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -893,7 +875,7 @@ static int MMSOpen( input_thread_t *p_input,
return
(
-
1
);
return
(
-
1
);
}
}
/
/ 1 for file ok, 2 for authen ok
/
* 1 for file ok, 2 for authen ok */
switch
(
GetDWLE
(
p_access
->
p_cmd
+
MMS_CMD_HEADERSIZE
)
)
switch
(
GetDWLE
(
p_access
->
p_cmd
+
MMS_CMD_HEADERSIZE
)
)
{
{
case
0x0001
:
case
0x0001
:
...
@@ -933,6 +915,9 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -933,6 +915,9 @@ static int MMSOpen( input_thread_t *p_input,
p_access
->
i_max_bit_rate
,
p_access
->
i_max_bit_rate
,
p_access
->
i_header_size
);
p_access
->
i_header_size
);
/* XXX XXX dirty hack XXX XXX */
p_input
->
i_mtu
=
3
*
p_access
->
i_packet_length
;
/* *** send command 15 *** */
/* *** send command 15 *** */
var_buffer_reinitwrite
(
&
buffer
,
0
);
var_buffer_reinitwrite
(
&
buffer
,
0
);
...
@@ -968,15 +953,15 @@ static int MMSOpen( input_thread_t *p_input,
...
@@ -968,15 +953,15 @@ static int MMSOpen( input_thread_t *p_input,
return
(
-
1
);
return
(
-
1
);
}
}
/* *** parse header and get stream and their id *** */
/* *** parse header and get stream and their id *** */
/
/ get all streams properties,
/
* get all streams properties,
//
*
//
TODO : stream bitrates properties(optional)
*
TODO : stream bitrates properties(optional)
// and bitrate mutual exclusion(optional)
* and bitrate mutual exclusion(optional) */
asf_HeaderParse
(
p_access
->
stream
,
asf_HeaderParse
(
p_access
->
stream
,
p_access
->
p_header
,
p_access
->
i_header
);
p_access
->
p_header
,
p_access
->
i_header
);
mms_StreamSelect
(
p_input
,
p_access
->
stream
);
mms_StreamSelect
(
p_input
,
p_access
->
stream
);
/* *** now select stream we want to receive *** */
/* *** now select stream we want to receive *** */
/
/ TODO take care of stream bitrate TODO
/
* TODO take care of stream bitrate TODO */
i_streams
=
0
;
i_streams
=
0
;
i_first
=
-
1
;
i_first
=
-
1
;
var_buffer_reinitwrite
(
&
buffer
,
0
);
var_buffer_reinitwrite
(
&
buffer
,
0
);
...
@@ -1061,9 +1046,8 @@ static int MMSStart ( input_thread_t *p_input, uint32_t i_packet )
...
@@ -1061,9 +1046,8 @@ static int MMSStart ( input_thread_t *p_input, uint32_t i_packet )
/* *** start stream from packet 0 *** */
/* *** start stream from packet 0 *** */
var_buffer_initwrite
(
&
buffer
,
0
);
var_buffer_initwrite
(
&
buffer
,
0
);
var_buffer_add64
(
&
buffer
,
0
);
/
/ seek point in second
var_buffer_add64
(
&
buffer
,
0
);
/
* seek point in second */
var_buffer_add32
(
&
buffer
,
0xffffffff
);
var_buffer_add32
(
&
buffer
,
0xffffffff
);
// var_buffer_add32( &buffer, 0xffffffff ); // begin from start
var_buffer_add32
(
&
buffer
,
i_packet
);
// begin from start
var_buffer_add32
(
&
buffer
,
i_packet
);
// begin from start
var_buffer_add8
(
&
buffer
,
0xff
);
// stream time limit
var_buffer_add8
(
&
buffer
,
0xff
);
// stream time limit
var_buffer_add8
(
&
buffer
,
0xff
);
// on 3bytes ...
var_buffer_add8
(
&
buffer
,
0xff
);
// on 3bytes ...
...
@@ -1127,24 +1111,25 @@ static int MMSClose ( input_thread_t *p_input )
...
@@ -1127,24 +1111,25 @@ static int MMSClose ( input_thread_t *p_input )
NULL
,
0
);
NULL
,
0
);
/* *** close sockets *** */
/* *** close sockets *** */
#if defined( UNDER_CE )
#if defined( UNDER_CE )
CloseHandle
(
(
HANDLE
)
p_access
->
socket_
server
.
i_handle
);
CloseHandle
(
(
HANDLE
)
p_access
->
socket_
tcp
.
i_handle
);
#elif defined( WIN32 )
#elif defined( WIN32 )
closesocket
(
p_access
->
socket_
server
.
i_handle
);
closesocket
(
p_access
->
socket_
tcp
.
i_handle
);
#else
#else
close
(
p_access
->
socket_
server
.
i_handle
);
close
(
p_access
->
socket_
tcp
.
i_handle
);
#endif
#endif
if
(
p_access
->
i_proto
==
MMS_PROTO_UDP
)
if
(
p_access
->
i_proto
==
MMS_PROTO_UDP
)
{
{
#if defined( UNDER_CE )
#if defined( UNDER_CE )
CloseHandle
(
(
HANDLE
)
p_access
->
socket_
data
.
i_handle
);
CloseHandle
(
(
HANDLE
)
p_access
->
socket_
udp
.
i_handle
);
#elif defined( WIN32 )
#elif defined( WIN32 )
closesocket
(
p_access
->
socket_
data
.
i_handle
);
closesocket
(
p_access
->
socket_
udp
.
i_handle
);
#else
#else
close
(
p_access
->
socket_
data
.
i_handle
);
close
(
p_access
->
socket_
udp
.
i_handle
);
#endif
#endif
}
}
FREE
(
p_access
->
p_cmd
);
FREE
(
p_access
->
p_media
);
FREE
(
p_access
->
p_media
);
FREE
(
p_access
->
p_header
);
FREE
(
p_access
->
p_header
);
...
@@ -1174,7 +1159,8 @@ static void mms_ParseURL( url_t *p_url, char *psz_url )
...
@@ -1174,7 +1159,8 @@ static void mms_ParseURL( url_t *p_url, char *psz_url )
}
}
p_url
->
psz_server_addr
=
psz_parser
;
p_url
->
psz_server_addr
=
psz_parser
;
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
&&
*
psz_parser
!=
'/'
)
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
&&
*
psz_parser
!=
'/'
&&
*
psz_parser
!=
'@'
)
{
{
psz_parser
++
;
psz_parser
++
;
}
}
...
@@ -1194,6 +1180,51 @@ static void mms_ParseURL( url_t *p_url, char *psz_url )
...
@@ -1194,6 +1180,51 @@ static void mms_ParseURL( url_t *p_url, char *psz_url )
{
{
psz_server_port
=
""
;
psz_server_port
=
""
;
}
}
if
(
*
psz_parser
==
'@'
)
{
char
*
psz_bind_port
;
*
psz_parser
=
'\0'
;
psz_parser
++
;
p_url
->
psz_bind_addr
=
psz_parser
;
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
&&
*
psz_parser
!=
'/'
)
{
psz_parser
++
;
}
if
(
*
psz_parser
==
':'
)
{
*
psz_parser
=
'\0'
;
psz_parser
++
;
psz_bind_port
=
psz_parser
;
while
(
*
psz_parser
&&
*
psz_parser
!=
'/'
)
{
psz_parser
++
;
}
}
else
{
psz_bind_port
=
""
;
}
if
(
*
psz_bind_port
)
{
p_url
->
i_bind_port
=
strtol
(
psz_bind_port
,
&
psz_parser
,
10
);
}
else
{
p_url
->
i_bind_port
=
0
;
}
}
else
{
p_url
->
psz_bind_addr
=
""
;
p_url
->
i_bind_port
=
0
;
}
if
(
*
psz_parser
==
'/'
)
if
(
*
psz_parser
==
'/'
)
{
{
*
psz_parser
=
'\0'
;
*
psz_parser
=
'\0'
;
...
@@ -1211,29 +1242,6 @@ static void mms_ParseURL( url_t *p_url, char *psz_url )
...
@@ -1211,29 +1242,6 @@ static void mms_ParseURL( url_t *p_url, char *psz_url )
}
}
}
}
static
int
mms_ReadData
(
input_thread_t
*
p_input
,
uint8_t
*
p_data
,
int
i_data
)
{
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
int
i_read
;
while
(
i_data
>
0
)
{
i_read
=
NetRead
(
p_input
,
&
p_access
->
socket_server
,
p_data
,
i_data
);
if
(
i_read
<
0
)
{
msg_Err
(
p_input
,
"failed to read data"
);
return
(
-
1
);
}
i_data
-=
i_read
;
p_data
+=
i_read
;
}
return
(
0
);
}
/****************************************************************************
/****************************************************************************
*
*
* MMS specific functions
* MMS specific functions
...
@@ -1255,11 +1263,11 @@ static int mms_CommandSend( input_thread_t *p_input,
...
@@ -1255,11 +1263,11 @@ static int mms_CommandSend( input_thread_t *p_input,
/* first init uffer */
/* first init uffer */
var_buffer_initwrite
(
&
buffer
,
0
);
var_buffer_initwrite
(
&
buffer
,
0
);
var_buffer_add32
(
&
buffer
,
0x00000001
);
/
/ start sequence
var_buffer_add32
(
&
buffer
,
0x00000001
);
/
* start sequence */
var_buffer_add32
(
&
buffer
,
0xB00BFACE
);
// ...
var_buffer_add32
(
&
buffer
,
0xB00BFACE
);
/
/ size after protocol type
/
* size after protocol type */
var_buffer_add32
(
&
buffer
,
i_data
+
MMS_CMD_HEADERSIZE
-
16
);
var_buffer_add32
(
&
buffer
,
i_data
+
MMS_CMD_HEADERSIZE
-
16
);
var_buffer_add32
(
&
buffer
,
0x20534d4d
);
/
/ protocol "MMS "
var_buffer_add32
(
&
buffer
,
0x20534d4d
);
/
* protocol "MMS " */
var_buffer_add32
(
&
buffer
,
i_data_by8
+
4
);
var_buffer_add32
(
&
buffer
,
i_data_by8
+
4
);
var_buffer_add32
(
&
buffer
,
p_access
->
i_seq_num
);
p_access
->
i_seq_num
++
;
var_buffer_add32
(
&
buffer
,
p_access
->
i_seq_num
);
p_access
->
i_seq_num
++
;
var_buffer_add64
(
&
buffer
,
0
);
var_buffer_add64
(
&
buffer
,
0
);
...
@@ -1275,7 +1283,7 @@ static int mms_CommandSend( input_thread_t *p_input,
...
@@ -1275,7 +1283,7 @@ static int mms_CommandSend( input_thread_t *p_input,
}
}
/* send it */
/* send it */
if
(
send
(
p_access
->
socket_
server
.
i_handle
,
if
(
send
(
p_access
->
socket_
tcp
.
i_handle
,
buffer
.
p_data
,
buffer
.
p_data
,
buffer
.
i_data
,
buffer
.
i_data
,
0
)
==
-
1
)
0
)
==
-
1
)
...
@@ -1288,62 +1296,413 @@ static int mms_CommandSend( input_thread_t *p_input,
...
@@ -1288,62 +1296,413 @@ static int mms_CommandSend( input_thread_t *p_input,
return
(
0
);
return
(
0
);
}
}
static
int
mms_ReceiveCommand
(
input_thread_t
*
p_input
)
static
int
NetFillBuffer
(
input_thread_t
*
p_input
)
{
#ifdef UNDER_CE
return
-
1
;
#else
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
struct
timeval
timeout
;
fd_set
fds
;
int
i_ret
;
/* FIXME when using udp */
ssize_t
i_tcp
,
i_udp
;
ssize_t
i_tcp_read
,
i_udp_read
;
int
i_handle_max
;
/* Initialize file descriptor set */
FD_ZERO
(
&
fds
);
i_tcp
=
MMS_BUFFER_SIZE
/
2
-
p_access
->
i_buffer_tcp
;
if
(
p_access
->
i_proto
==
MMS_PROTO_UDP
)
{
i_udp
=
MMS_BUFFER_SIZE
/
2
-
p_access
->
i_buffer_udp
;
}
else
{
i_udp
=
0
;
/* there isn't udp socket */
}
i_handle_max
=
0
;
if
(
i_tcp
>
0
)
{
FD_SET
(
p_access
->
socket_tcp
.
i_handle
,
&
fds
);
i_handle_max
=
__MAX
(
i_handle_max
,
p_access
->
socket_tcp
.
i_handle
);
}
if
(
i_udp
>
0
)
{
FD_SET
(
p_access
->
socket_udp
.
i_handle
,
&
fds
);
i_handle_max
=
__MAX
(
i_handle_max
,
p_access
->
socket_udp
.
i_handle
);
}
if
(
i_handle_max
==
0
)
{
msg_Warn
(
p_input
,
"nothing to read %d:%d"
,
i_tcp
,
i_udp
);
return
(
0
);
}
else
{
msg_Warn
(
p_input
,
"ask for tcp:%d udp:%d"
,
i_tcp
,
i_udp
);
}
/* We'll wait 0.5 second if nothing happens */
timeout
.
tv_sec
=
0
;
timeout
.
tv_usec
=
500000
;
/* Find if some data is available */
i_ret
=
select
(
i_handle_max
+
1
,
&
fds
,
NULL
,
NULL
,
&
timeout
);
if
(
i_ret
==
-
1
&&
errno
!=
EINTR
)
{
msg_Err
(
p_input
,
"network select error (%s)"
,
strerror
(
errno
)
);
return
-
1
;
}
if
(
i_tcp
>
0
&&
FD_ISSET
(
p_access
->
socket_tcp
.
i_handle
,
&
fds
)
)
{
i_tcp_read
=
recv
(
p_access
->
socket_tcp
.
i_handle
,
p_access
->
buffer_tcp
+
p_access
->
i_buffer_tcp
,
i_tcp
+
MMS_BUFFER_SIZE
/
2
,
0
);
}
else
{
i_tcp_read
=
0
;
}
if
(
i_udp
>
0
&&
FD_ISSET
(
p_access
->
socket_udp
.
i_handle
,
&
fds
)
)
{
i_udp_read
=
recv
(
p_access
->
socket_udp
.
i_handle
,
p_access
->
buffer_udp
+
p_access
->
i_buffer_udp
,
i_udp
+
MMS_BUFFER_SIZE
/
2
,
0
);
}
else
{
i_udp_read
=
0
;
}
p_access
->
i_buffer_tcp
+=
i_tcp_read
;
p_access
->
i_buffer_udp
+=
i_udp_read
;
msg_Dbg
(
p_input
,
"filling TCP buffer with %d bytes (buffer:%d)"
,
i_tcp_read
,
p_access
->
i_buffer_tcp
);
if
(
p_access
->
i_proto
==
MMS_PROTO_UDP
)
{
msg_Dbg
(
p_input
,
"filling UDP buffer with %d bytes (buffer:%d)"
,
i_udp_read
,
p_access
->
i_buffer_udp
);
}
return
(
i_tcp_read
+
i_udp_read
);
#endif
}
static
int
mms_ParseCommand
(
input_thread_t
*
p_input
,
uint8_t
*
p_data
,
int
i_data
,
int
*
pi_used
)
{
{
#define GET32( i_pos ) \
#define GET32( i_pos ) \
( p_access->p_cmd[i_pos] + ( p_access->p_cmd[i_pos +1] << 8 ) + \
( p_access->p_cmd[i_pos] + ( p_access->p_cmd[i_pos +1] << 8 ) + \
( p_access->p_cmd[i_pos + 2] << 16 ) + \
( p_access->p_cmd[i_pos + 2] << 16 ) + \
( p_access->p_cmd[i_pos + 3] << 24 ) )
( p_access->p_cmd[i_pos + 3] << 24 ) )
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
int
i_length
;
uint32_t
i_id
;
if
(
p_access
->
p_cmd
)
{
free
(
p_access
->
p_cmd
);
}
p_access
->
i_cmd
=
i_data
;
p_access
->
p_cmd
=
malloc
(
i_data
);
memcpy
(
p_access
->
p_cmd
,
p_data
,
i_data
);
*
pi_used
=
i_data
;
/* by default */
if
(
i_data
<
MMS_CMD_HEADERSIZE
)
{
msg_Warn
(
p_input
,
"truncated command (header incomplete)"
);
p_access
->
i_command
=
0
;
return
(
-
1
);
}
i_id
=
GetDWLE
(
p_data
+
4
);
i_length
=
GetDWLE
(
p_data
+
8
)
+
16
;
if
(
i_id
!=
0xb00bface
)
{
msg_Err
(
p_input
,
"incorrect command header (0x%x)"
,
i_id
);
p_access
->
i_command
=
0
;
return
(
-
1
);
}
if
(
i_length
>
p_access
->
i_cmd
)
{
msg_Warn
(
p_input
,
"truncated command (missing %d bytes)"
,
i_length
-
i_data
);
p_access
->
i_command
=
0
;
return
(
-
1
);
}
else
if
(
i_length
<
p_access
->
i_cmd
)
{
p_access
->
i_cmd
=
i_length
;
*
pi_used
=
i_length
;
}
msg_Dbg
(
p_input
,
"recv command start_sequence:0x%8.8x command_id:0x%8.8x length:%d len8:%d sequence 0x%8.8x len8_II:%d dir_comm:0x%8.8x"
,
GET32
(
0
),
GET32
(
4
),
GET32
(
8
),
GET32
(
16
),
GET32
(
20
),
GET32
(
32
),
GET32
(
36
),
GET32
(
40
)
);
p_access
->
i_command
=
GET32
(
36
)
&
0xffff
;
return
(
MMS_PACKET_CMD
);
}
static
int
mms_ParsePacket
(
input_thread_t
*
p_input
,
uint8_t
*
p_data
,
int
i_data
,
int
*
pi_used
)
{
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
int
i_packet_seq_num
;
int
i_packet_length
;
int
i_packet_id
;
uint8_t
*
p_packet
;
*
pi_used
=
i_data
;
/* default */
if
(
i_data
<=
8
)
{
msg_Warn
(
p_input
,
"truncated packet (header incomplete)"
);
return
(
-
1
);
}
i_packet_id
=
p_data
[
4
];
i_packet_seq_num
=
GetDWLE
(
p_data
);
i_packet_length
=
GetWLE
(
p_data
+
6
);
if
(
i_packet_length
>
i_data
||
i_packet_length
<=
8
)
{
msg_Warn
(
p_input
,
"truncated packet (missing %d bytes)"
,
i_packet_length
-
i_data
);
return
(
-
1
);
}
else
if
(
i_packet_length
<
i_data
)
{
*
pi_used
=
i_packet_length
;
}
if
(
i_packet_id
==
0xff
)
{
msg_Warn
(
p_input
,
"receive MMS UDP pair timing"
);
return
(
MMS_PACKET_UDP_TIMING
);
}
if
(
i_packet_id
!=
p_access
->
i_header_packet_id_type
&&
i_packet_id
!=
p_access
->
i_media_packet_id_type
)
{
msg_Warn
(
p_input
,
"incorrect Packet Id Type (0x%x)"
,
i_packet_id
);
return
(
-
1
);
}
/* we now have a media or a header packet */
p_packet
=
malloc
(
i_packet_length
-
8
);
// don't bother with preheader
memcpy
(
p_packet
,
p_data
+
8
,
i_packet_length
-
8
);
if
(
i_packet_seq_num
!=
p_access
->
i_packet_seq_num
)
{
/* FIXME for udp could be just wrong order ? */
msg_Warn
(
p_input
,
"detected packet lost (%d != %d)"
,
i_packet_seq_num
,
p_access
->
i_packet_seq_num
);
p_access
->
i_packet_seq_num
=
i_packet_seq_num
;
}
p_access
->
i_packet_seq_num
++
;
if
(
i_packet_id
==
p_access
->
i_header_packet_id_type
)
{
FREE
(
p_access
->
p_header
);
p_access
->
p_header
=
p_packet
;
p_access
->
i_header
=
i_packet_length
-
8
;
msg_Dbg
(
p_input
,
"receive header packet (%d bytes)"
,
i_packet_length
-
8
);
do
return
(
MMS_PACKET_HEADER
);
}
else
{
{
int
i_length
;
FREE
(
p_access
->
p_media
);
// see for UDP mode
p_access
->
p_media
=
p_packet
;
p_access
->
i_media
=
i_packet_length
-
8
;
p_access
->
i_media_used
=
0
;
msg_Dbg
(
p_input
,
"receive media packet (%d bytes)"
,
i_packet_length
-
8
);
return
(
MMS_PACKET_MEDIA
);
}
}
static
int
mms_ReceivePacket
(
input_thread_t
*
p_input
)
{
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
int
i_packet_tcp_type
;
int
i_packet_udp_type
;
/* *** Read complete command *** */
for
(
;;
)
p_access
->
i_cmd
=
NetRead
(
p_input
,
&
p_access
->
socket_server
,
{
p_access
->
p_cmd
,
BUF_SIZE
);
if
(
NetFillBuffer
(
p_input
)
<
0
)
if
(
p_access
->
i_cmd
<
12
)
{
{
msg_Warn
(
p_input
,
"failed to receive command"
);
msg_Warn
(
p_input
,
"cannot fill buffer"
);
p_access
->
i_command
=
0
;
continue
;
return
(
-
1
);
}
}
i_length
=
GetDWLE
(
p_access
->
p_cmd
+
8
)
+
16
;
/* TODO udp */
if
(
i_length
>
p_access
->
i_cmd
)
i_packet_tcp_type
=
-
1
;
i_packet_udp_type
=
-
1
;
if
(
p_access
->
i_buffer_tcp
>
0
)
{
{
if
(
mms_ReadData
(
p_input
,
int
i_used
;
p_access
->
p_cmd
+
p_access
->
i_cmd
,
i_length
-
p_access
->
i_cmd
)
<
0
)
if
(
GetDWLE
(
p_access
->
buffer_tcp
+
4
)
==
0xb00bface
)
{
i_packet_tcp_type
=
mms_ParseCommand
(
p_input
,
p_access
->
buffer_tcp
,
p_access
->
i_buffer_tcp
,
&
i_used
);
}
else
{
i_packet_tcp_type
=
mms_ParsePacket
(
p_input
,
p_access
->
buffer_tcp
,
p_access
->
i_buffer_tcp
,
&
i_used
);
}
if
(
i_used
<
MMS_BUFFER_SIZE
)
{
{
m
sg_Warn
(
p_input
,
"failed to receive command"
);
m
emmove
(
p_access
->
buffer_tcp
,
p_access
->
i_command
=
0
;
p_access
->
buffer_tcp
+
i_used
,
return
(
-
1
);
MMS_BUFFER_SIZE
-
i_used
);
}
}
p_access
->
i_buffer_tcp
-=
i_used
;
}
}
else
if
(
p_access
->
i_buffer_udp
>
0
)
{
int
i_used
;
#if 0
if( GetDWLE( p_access->buffer_tcp + 4 ) == 0xb00bface )
{
i_packet_tcp_type =
mms_ParseCommand( p_input,
p_access->buffer_tcp,
p_access->i_buffer_tcp,
&i_used );
msg_Dbg
(
p_input
,
"received %d bytes"
,
p_access
->
i_cmd
);
}
else
#endif
{
i_packet_tcp_type
=
mms_ParsePacket
(
p_input
,
p_access
->
buffer_udp
,
p_access
->
i_buffer_udp
,
&
i_used
);
}
if
(
i_used
<
MMS_BUFFER_SIZE
)
{
memmove
(
p_access
->
buffer_udp
,
p_access
->
buffer_udp
+
i_used
,
MMS_BUFFER_SIZE
-
i_used
);
}
p_access
->
i_buffer_udp
-=
i_used
;
}
else
{
i_packet_udp_type
=
-
1
;
}
p_access
->
i_command
=
GET32
(
36
)
&
0xffff
;
if
(
i_packet_tcp_type
==
MMS_PACKET_CMD
&&
msg_Dbg
(
p_input
,
p_access
->
i_command
==
0x1b
)
"recv command start_sequence:0x%8.8x command_id:0x%8.8x length:%d len8:%d sequence 0x%8.8x len8_II:%d dir_comm:0x%8.8x"
,
{
GET32
(
0
),
mms_CommandSend
(
p_input
,
0x1b
,
0
,
0
,
NULL
,
0
);
GET32
(
4
),
i_packet_tcp_type
=
-
1
;
GET32
(
8
),
}
GET32
(
16
),
GET32
(
20
),
if
(
i_packet_tcp_type
!=
-
1
)
GET32
(
32
),
{
GET32
(
36
),
return
(
i_packet_tcp_type
);
GET32
(
40
)
);
}
else
if
(
i_packet_udp_type
!=
-
1
)
{
return
(
i_packet_udp_type
);
}
}
}
static
int
mms_ReceiveCommand
(
input_thread_t
*
p_input
)
{
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
for
(
;;
)
{
int
i_used
;
int
i_status
;
NetFillBuffer
(
p_input
);
i_status
=
mms_ParseCommand
(
p_input
,
p_access
->
buffer_tcp
,
p_access
->
i_buffer_tcp
,
&
i_used
);
if
(
i_used
<
MMS_BUFFER_SIZE
)
{
memmove
(
p_access
->
buffer_tcp
,
p_access
->
buffer_tcp
+
i_used
,
MMS_BUFFER_SIZE
-
i_used
);
}
p_access
->
i_buffer_tcp
-=
i_used
;
if
(
i_status
<
0
)
{
return
(
-
1
);
}
if
(
p_access
->
i_command
==
0x1b
)
if
(
p_access
->
i_command
==
0x1b
)
{
{
mms_CommandSend
(
p_input
,
0x1b
,
0
,
0
,
NULL
,
0
);
mms_CommandSend
(
p_input
,
0x1b
,
0
,
0
,
NULL
,
0
);
}
}
else
}
while
(
p_access
->
i_command
==
0x1b
);
{
break
;
}
}
return
(
0
);
return
(
0
);
}
}
...
@@ -1395,145 +1754,6 @@ static int mms_CommandRead( input_thread_t *p_input, int i_command1, int i_comma
...
@@ -1395,145 +1754,6 @@ static int mms_CommandRead( input_thread_t *p_input, int i_command1, int i_comma
}
}
static
int
mms_ReceivePacket
(
input_thread_t
*
p_input
)
{
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
uint8_t
preheader
[
8
];
int
i_read
;
if
(
p_access
->
i_proto
==
MMS_PROTO_UDP
)
{
return
(
-
1
);
}
else
{
for
(
;;
)
{
i_read
=
NetRead
(
p_input
,
&
p_access
->
socket_server
,
preheader
,
8
);
if
(
i_read
<
8
)
{
msg_Warn
(
p_input
,
"cannot read preheader"
);
return
(
-
1
);
}
/* preheader format :
* u32 i_sequence_number
* u8 i_packet_id
* u8 i_udp_sequence/i_tcp_flags
* u16 i_length
*/
if
(
preheader
[
4
]
==
p_access
->
i_header_packet_id_type
||
preheader
[
4
]
==
p_access
->
i_media_packet_id_type
||
preheader
[
4
]
==
0xff
)
// udp timing pair
{
int
i_packet_seq_num
;
int
i_packet_length
;
int
i_packet_id
;
uint8_t
*
p_packet
;
i_packet_seq_num
=
GetDWLE
(
preheader
);
i_packet_length
=
GetWLE
(
preheader
+
6
);
i_packet_id
=
preheader
[
4
];
/* *** read complete packet *** */
if
(
i_packet_length
<=
8
)
{
msg_Err
(
p_input
,
"empty or broken packet"
);
return
(
-
1
);
}
p_packet
=
malloc
(
i_packet_length
-
8
);
if
(
mms_ReadData
(
p_input
,
p_packet
,
i_packet_length
-
8
)
<
0
)
{
msg_Err
(
p_input
,
"cannot read data"
);
}
if
(
i_packet_id
==
0xff
)
{
msg_Warn
(
p_input
,
"receive MMS UDP pair timing"
);
free
(
p_packet
);
return
(
MMS_PACKET_UDP_TIMING
);
}
else
{
if
(
i_packet_seq_num
!=
p_access
->
i_packet_seq_num
)
{
// FIXME for udp could be just wrong order ?
msg_Warn
(
p_input
,
"detected packet lost (%d != %d)"
,
i_packet_seq_num
,
p_access
->
i_packet_seq_num
);
p_access
->
i_packet_seq_num
=
i_packet_seq_num
;
}
p_access
->
i_packet_seq_num
++
;
if
(
i_packet_id
==
p_access
->
i_header_packet_id_type
)
{
FREE
(
p_access
->
p_header
);
p_access
->
p_header
=
p_packet
;
p_access
->
i_header
=
i_packet_length
-
8
;
return
(
MMS_PACKET_HEADER
);
}
else
{
FREE
(
p_access
->
p_media
);
p_access
->
p_media
=
p_packet
;
p_access
->
i_media
=
i_packet_length
-
8
;
p_access
->
i_media_used
=
0
;
return
(
MMS_PACKET_MEDIA
);
}
}
}
else
{
int
i_packet_length
;
// command ?
if
(
GetDWLE
(
preheader
+
4
)
!=
0xb00bface
)
{
msg_Err
(
p_input
,
"incorrect command header (0x%x)"
,
GetDWLE
(
preheader
+
4
)
);
}
memcpy
(
p_access
->
p_cmd
,
preheader
,
8
);
if
(
mms_ReadData
(
p_input
,
p_access
->
p_cmd
+
8
,
8
)
<
0
)
{
msg_Err
(
p_input
,
"cannot read data"
);
}
p_access
->
i_cmd
=
16
;
i_packet_length
=
GetDWLE
(
p_access
->
p_cmd
+
8
);
if
(
mms_ReadData
(
p_input
,
p_access
->
p_cmd
+
16
,
i_packet_length
)
<
0
)
{
msg_Err
(
p_input
,
"cannot read data"
);
}
p_access
->
i_cmd
+=
i_packet_length
;
p_access
->
i_command
=
GetDWLE
(
p_access
->
p_cmd
+
36
)
&
0xffff
;
if
(
p_access
->
i_command
==
0x1b
)
{
mms_CommandSend
(
p_input
,
0x1b
,
0
,
0
,
NULL
,
0
);
}
else
{
return
(
MMS_PACKET_CMD
);
}
}
}
}
}
static
int
mms_HeaderMediaRead
(
input_thread_t
*
p_input
,
int
i_type
)
static
int
mms_HeaderMediaRead
(
input_thread_t
*
p_input
,
int
i_type
)
{
{
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
access_t
*
p_access
=
(
access_t
*
)
p_input
->
p_access_data
;
...
@@ -1551,7 +1771,7 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type )
...
@@ -1551,7 +1771,7 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type )
"cannot receive header (%d/%d)"
,
i_count
,
MMS_RETRY_MAX
);
"cannot receive header (%d/%d)"
,
i_count
,
MMS_RETRY_MAX
);
msleep
(
MMS_RETRY_SLEEP
);
msleep
(
MMS_RETRY_SLEEP
);
}
}
else
if
(
i_status
==
i_type
)
else
if
(
i_status
==
i_type
||
i_type
==
MMS_PACKET_ANY
)
{
{
return
(
0
);
return
(
0
);
}
}
...
@@ -1583,6 +1803,3 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type )
...
@@ -1583,6 +1803,3 @@ static int mms_HeaderMediaRead( input_thread_t *p_input, int i_type )
return
(
-
1
);
return
(
-
1
);
}
}
modules/access/mms/mms.h
View file @
881768ad
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* mms.h: MMS access plug-in
* mms.h: MMS access plug-in
*****************************************************************************
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mms.h,v 1.
3 2002/11/13 20:28:13
fenrir Exp $
* $Id: mms.h,v 1.
4 2002/11/25 00:22:04
fenrir Exp $
*
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
*
...
@@ -26,9 +26,13 @@ typedef struct url_s
...
@@ -26,9 +26,13 @@ typedef struct url_s
{
{
char
*
psz_server_addr
;
char
*
psz_server_addr
;
int
i_server_port
;
int
i_server_port
;
char
*
psz_bind_addr
;
int
i_bind_port
;
char
*
psz_path
;
char
*
psz_path
;
/
/ private
/
* private */
char
*
psz_private
;
char
*
psz_private
;
}
url_t
;
}
url_t
;
...
@@ -39,10 +43,11 @@ typedef struct url_s
...
@@ -39,10 +43,11 @@ typedef struct url_s
#define MMS_PROTO_TCP 1
#define MMS_PROTO_TCP 1
#define MMS_PROTO_UDP 2
#define MMS_PROTO_UDP 2
#define MMS_PACKET_CMD 0
#define MMS_PACKET_ANY 0
#define MMS_PACKET_HEADER 1
#define MMS_PACKET_CMD 1
#define MMS_PACKET_MEDIA 2
#define MMS_PACKET_HEADER 2
#define MMS_PACKET_UDP_TIMING 3
#define MMS_PACKET_MEDIA 3
#define MMS_PACKET_UDP_TIMING 4
#define MMS_STREAM_VIDEO 0x0001
#define MMS_STREAM_VIDEO 0x0001
...
@@ -54,27 +59,34 @@ typedef struct url_s
...
@@ -54,27 +59,34 @@ typedef struct url_s
typedef
struct
mms_stream_s
typedef
struct
mms_stream_s
{
{
int
i_id
;
/
/ 1 -> 127
int
i_id
;
/
* 1 -> 127 */
int
i_cat
;
/
/ MMS_STREAM_VIDEO, MMS_STREAM_AUDIO
int
i_cat
;
/
* MMS_STREAM_VIDEO, MMS_STREAM_AUDIO */
int
i_bitrate
;
/
/ -1 if unknown
int
i_bitrate
;
/
* -1 if unknown */
int
i_selected
;
int
i_selected
;
}
mms_stream_t
;
}
mms_stream_t
;
#define MMS_BUFFER_SIZE 100000
typedef
struct
access_s
typedef
struct
access_s
{
{
int
i_proto
;
/
/ MMS_PROTO_TCP, MMS_PROTO_UDP
int
i_proto
;
/
* MMS_PROTO_TCP, MMS_PROTO_UDP */
input_socket_t
socket_
server
;
// TCP socket for communication with server
input_socket_t
socket_
tcp
;
/* TCP socket for communication with server */
input_socket_t
socket_
data
;
// Optional UDP socket for data(media/header packet)
input_socket_t
socket_
udp
;
/* Optional UDP socket for data(media/header packet) */
/
/ send by server
/
* send by server */
url_t
url
;
/
/ connect to this server
url_t
url
;
/
* connect to this server */
mms_stream_t
stream
[
128
];
/
/in asf never more than 1->127 streams
mms_stream_t
stream
[
128
];
/
* in asf never more than 1->127 streams */
off_t
i_pos
;
/
/ position of next byte to be read
off_t
i_pos
;
/
* position of next byte to be read */
/* */
uint8_t
buffer_tcp
[
MMS_BUFFER_SIZE
];
int
i_buffer_tcp
;
uint8_t
buffer_udp
[
MMS_BUFFER_SIZE
];
int
i_buffer_udp
;
/* data necessary to send data to server */
/* data necessary to send data to server */
guid_t
guid
;
guid_t
guid
;
int
i_command_level
;
int
i_command_level
;
...
@@ -84,26 +96,26 @@ typedef struct access_s
...
@@ -84,26 +96,26 @@ typedef struct access_s
int
i_packet_seq_num
;
int
i_packet_seq_num
;
uint8_t
*
p_cmd
;
// latest command read
uint8_t
*
p_cmd
;
/* latest command read */
int
i_cmd
;
// allocated at the begining
int
i_cmd
;
/* allocated at the begining */
uint8_t
*
p_header
;
// allocated by mms_ReadPacket
uint8_t
*
p_header
;
/* allocated by mms_ReadPacket */
int
i_header
;
int
i_header
;
uint8_t
*
p_media
;
// allocated by mms_ReadPacket
uint8_t
*
p_media
;
/* allocated by mms_ReadPacket */
int
i_media
;
int
i_media
;
int
i_media_used
;
int
i_media_used
;
/
/ extracted informations
/
* extracted informations */
int
i_command
;
int
i_command
;
/
/ from 0x01 answer (not yet set)
/
* from 0x01 answer (not yet set) */
char
*
psz_server_version
;
char
*
psz_server_version
;
char
*
psz_tool_version
;
char
*
psz_tool_version
;
char
*
psz_update_player_url
;
char
*
psz_update_player_url
;
char
*
psz_encryption_type
;
char
*
psz_encryption_type
;
/
/ from 0x06 answer
/
* from 0x06 answer */
uint32_t
i_flags_broadcast
;
uint32_t
i_flags_broadcast
;
uint32_t
i_media_length
;
uint32_t
i_media_length
;
int
i_packet_length
;
int
i_packet_length
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment