Commit 75da755c authored by Christophe Massiot's avatar Christophe Massiot

* ALL: Move the config-specific stuff to a substructure, with dedicated...

* ALL: Move the config-specific stuff to a substructure, with dedicated functions. * dvblast.c: Factorize the IP-parsing stuff. * output.c: Add support for a configurable MTU and a variable number of TS per packet. * dvblast.c: Add new options /ifindex= /mtu= /tos= /ssrc=. * output.c: Use biTStream instead of custom RTP functions. * udp.c: Implement IPv6 support and add options /mtu= /ifaddr= /ifindex=.
parent 16c7b832
# DVBlast Makefile
# Customise the path of your kernel
VERSION = 1.2.0
VERSION = 2.0.0
TOPDIR = `basename ${PWD}`
CFLAGS += -Wall -O3 -fomit-frame-pointer
......
......@@ -7,6 +7,8 @@ Changes between 1.2 and 2.0:
* Smooth packet output with an extra buffer
* libdvbpsi runtime is no longer needed; biTStream development library
is used instead
* Add the ability to bind to a specific network interface
* Add a configurable MTU
* Add support for NIT in DVB compliance mode
* Syslog support with -l option
* Override FEC Inner with -F option
......
......@@ -80,13 +80,26 @@ instance a multi-program transport stream. The address is specified with
such a stream for instance to cross network boundaries between the
receivers and the target network.
The syntax of the -D option is:
[<src host>[:<src port>]@]<src mcast>[:<port>][/<opts>]*
where <src mcast> is the multicast address carrying the stream, and <src
host> is optionally the address of the source, for source-specific multicast.
Options include:
/udp (for streams without an RTP header)
/mtu=XXXX (sets the maximum UDP packet size)
/ifindex=X (binds to a specific network interface, by link number)
/ifaddr=XXX.XXX.XXX.XXX (binds to a specific network interface, by address)
For example:
-D 239.255.0.2:1234/udp/ifindex=1
Configuring outputs
===================
DVBlast reads a configuration file containing one or several lines in the
format :
<IP>[:<port>][/<option>]* <always on> <SID> [<PID>,]*
<IP>[:<port>][@<IP>[:<port>]][/<option>]* <always on> <SID> [<PID>,]*
For instance :
239.255.0.1:1234 1 10750 1234,1235,1236
......@@ -105,6 +118,15 @@ For example :
[ff12::1%eth0]:1234 1 10750
[ff15::abcd]:1234 1 10750
An optional bind address can be specified after an '@' sign. The typical
usage of this is to allow binding to a specific interface in a system which
has several. For instance:
239.255.0.1:1234@192.168.42.1 1 10750
For IPv6 the bind address is not relevant; binding to an interface is achieved
via the option "/ifindex=X" where X is the number of the link, as given by
the command `ip link`.
The "always on" flag tells DVBlast whether the channel is expected to
be on at all times or if it may break. If set to "1", then DVBlast will
regularly reset the CAM module if it fails to descramble the service,
......@@ -117,12 +139,16 @@ Available options include :
/dvb (turns on -C for a specific output)
/epg (turns on -C -e for a specific output)
/tsid=XXX (sets the transport stream ID)
/ssrc=XXX.XXX.XXX.XXX (sets the RTP synchronization source IPv4)
/retention=XXX (see -E)
/latency=XXX (see -L)
/ttl=XX (see -t)
/tos=XX (sets the IPv4 Type Of Service option)
/mtu=XXXX (sets the maximum UDP packet size)
Several options can be appended, for instance:
239.255.0.1:1234/udp/epg/tsid=42
239.255.0.1:1234/udp/epg/tsid=42/ssrc=192.168.0.1
The optional "/udp" parameter can be used to force DVBlast to output
raw UDP stream. This functionality is provided for backwards compatibility
......
This diff is collapsed.
This diff is collapsed.
......@@ -30,10 +30,8 @@
#define DEFAULT_PORT 3001
#define TS_SIZE 188
#define NB_BLOCKS 7
#define NB_BLOCKS_IPV6 6 // assume MTU of 1280 bytes for IPv6
#define RTP_SIZE 12
#define EMPTY_PID 8192
#define DEFAULT_IPV4_MTU 1500
#define DEFAULT_IPV6_MTU 1280
#define PADDING_PID 8191
#define WATCHDOG_WAIT 10000000LL
#define MAX_ERRORS 1000
......@@ -74,14 +72,35 @@ typedef struct block_t
typedef struct packet_t packet_t;
typedef struct output_t
typedef struct output_config_t
{
/* address information, protocol agnostic */
struct sockaddr_storage *p_addr;
socklen_t i_addrlen;
/* identity */
int i_family;
struct sockaddr_storage connect_addr;
struct sockaddr_storage bind_addr;
int i_if_index_v6;
/* display string */
/* common config */
char *psz_displayname;
uint64_t i_config;
/* output config */
uint8_t pi_ssrc[4];
mtime_t i_output_latency, i_max_retention;
int i_ttl;
uint8_t i_tos;
int i_mtu;
/* demux config */
int i_tsid;
uint16_t i_sid; /* 0 if raw mode */
uint16_t *pi_pids;
int i_nb_pids;
} output_config_t;
typedef struct output_t
{
output_config_t config;
/* output */
int i_handle;
......@@ -103,17 +122,7 @@ typedef struct output_t
uint8_t i_sdt_version, i_sdt_cc;
block_t *p_eit_ts_buffer;
uint8_t i_eit_ts_buffer_offset, i_eit_cc;
/* configuration */
uint16_t i_sid; /* 0 if raw mode */
uint16_t *pi_pids;
int i_nb_pids;
int i_ttl;
in_addr_t i_ssrc;
uint16_t i_tsid;
bool b_fixed_tsid;
mtime_t i_output_latency, i_max_retention;
uint8_t i_config;
} output_t;
extern int i_syslog;
......@@ -122,7 +131,6 @@ extern output_t **pp_outputs;
extern int i_nb_outputs;
extern output_t output_dup;
extern char *psz_srv_socket;
extern in_addr_t i_ssrc;
extern int i_adapter;
extern int i_fenum;
extern int i_frequency;
......@@ -142,9 +150,7 @@ extern size_t i_network_name_size;
extern mtime_t i_wallclock;
extern volatile int b_hup_received;
extern int i_comm_fd;
extern uint16_t i_src_port;
extern in_addr_t i_src_addr;
extern int b_src_rawudp;
extern char *psz_udp_src;
extern int i_asi_adapter;
extern const char *psz_native_charset;
extern const char *psz_dvb_charset;
......@@ -158,6 +164,10 @@ extern void (*pf_UnsetFilter)( int i_fd, uint16_t i_pid );
* Prototypes
*****************************************************************************/
void config_Init( output_config_t *p_config );
void config_Free( output_config_t *p_config );
bool config_ParseHost( output_config_t *p_config, char *psz_string );
/* Connect/Disconnect from syslogd */
void msg_Connect( const char *ident );
void msg_Disconnect( void );
......@@ -173,6 +183,8 @@ void msg_Raw( void *_unused, const char *psz_format, ... );
mtime_t mdate( void );
void msleep( mtime_t delay );
void hexDump( uint8_t *p_data, uint32_t i_len );
struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end,
uint16_t i_default_port );
void dvb_Open( void );
void dvb_Reset( void );
......@@ -193,21 +205,20 @@ void asi_UnsetFilter( int i_fd, uint16_t i_pid );
void demux_Open( void );
void demux_Run( block_t *p_ts );
void demux_Change( output_t *p_output, int i_tsid, uint16_t i_sid,
uint16_t *pi_pids, int i_nb_pids );
void demux_Change( output_t *p_output, const output_config_t *p_config );
void demux_ResendCAPMTs( void );
bool demux_PIDIsSelected( uint16_t i_pid );
char *demux_Iconv(void *_unused, const char *psz_encoding,
char *p_string, size_t i_length);
output_t *output_Create( const char *psz_displayname, struct addrinfo *p_ai );
int output_Init( output_t *p_output, const char *psz_displayname,
struct addrinfo *p_ai );
output_t *output_Create( const output_config_t *p_config );
int output_Init( output_t *p_output, const output_config_t *p_config );
void output_Close( output_t *p_output );
void output_Put( output_t *p_output, block_t *p_block );
mtime_t output_Send( void );
void output_SetTTL( output_t *p_output, int i_ttl );
output_t *output_Find( const output_config_t *p_config );
void output_Change( output_t *p_output, const output_config_t *p_config );
void comm_Open( void );
void comm_Read( void );
......
This diff is collapsed.
This diff is collapsed.
......@@ -29,7 +29,9 @@
#include <stdarg.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
......@@ -250,3 +252,80 @@ void hexDump( uint8_t *p_data, uint32_t i_len )
free( p_outline );
}
/*****************************************************************************
* ParseNodeService: parse a host:port string
*****************************************************************************/
struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end,
uint16_t i_default_port )
{
int i_family = AF_INET;
char psz_port_buffer[6];
char *psz_string = strdup( _psz_string );
char *psz_node, *psz_port = NULL, *psz_end;
struct addrinfo *p_res;
struct addrinfo hint;
int i_ret;
if ( psz_string[0] == '[' )
{
i_family = AF_INET6;
psz_node = psz_string + 1;
psz_end = strchr( psz_node, ']' );
if ( psz_end == NULL )
{
msg_Warn( NULL, "invalid IPv6 address %s", _psz_string );
free( psz_string );
return NULL;
}
*psz_end++ = '\0';
}
else
{
psz_node = psz_string;
psz_end = strpbrk( psz_string, "@:,/" );
}
if ( psz_end != NULL && psz_end[0] == ':' )
{
*psz_end++ = '\0';
psz_port = psz_end;
psz_end = strpbrk( psz_port, "@:,/" );
}
if ( psz_end != NULL )
{
*psz_end = '\0';
if ( ppsz_end != NULL )
*ppsz_end = _psz_string + (psz_end - psz_string);
}
else if ( ppsz_end != NULL )
*ppsz_end = _psz_string + strlen(_psz_string);
if ( i_default_port != 0 && (psz_port == NULL || !*psz_port) )
{
sprintf( psz_port_buffer, "%u", i_default_port );
psz_port = psz_port_buffer;
}
if ( psz_node[0] == '\0' )
{
free( psz_string );
return NULL;
}
memset( &hint, 0, sizeof(hint) );
hint.ai_family = i_family;
hint.ai_socktype = SOCK_DGRAM;
hint.ai_protocol = 0;
hint.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG;
if ( (i_ret = getaddrinfo( psz_node, psz_port, NULL, &p_res )) != 0 )
{
msg_Warn( NULL, "getaddrinfo error: %s", gai_strerror(i_ret) );
free( psz_string );
return NULL;
}
free( psz_string );
return p_res;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment