Commit 2eac0089 authored by Sebastian Ramacher's avatar Sebastian Ramacher

Imported Upstream version 3.0

parent 86755b39
.gitattributes export-ignore
.gitignore export-ignore
*.o
dvblast
dvblastctl
......@@ -10,6 +10,10 @@ N: Georgi Chorbadzhiyski
E: gf AT unixsol.org
D: numerous bug fixes and enhancements
N: Benjamin Cohen
E: bencoh AT notk DOT org
D: raw sockets
N: Marian Ďurkovič
E: md AT bts DOT sk
C: md
......@@ -33,3 +37,7 @@ N: Jean-Paul Saman
E: jpsaman AT videolan DOT org
C: jpsaman
D: DVB-S2 bug fixes, syslog support
N: Simon Lockhart
E: simon AT slimey DOT org
D: Deltacast ASI card support
......@@ -18,12 +18,19 @@ Compile the program with `make` and install with `make install`. Your
kernel must support DVB S2API which was merged in Linux 2.6.28 and released
on 24 Dec 2008.
DVBlast 2.X no longer requires libdvbpsi runtime and libdvbpsi-devel for
compilation. Instead you must install biTStream on your build machine (no
runtime library is needed).
DVBlast 3.X requires biTStream as a build dependancy, and libev as a runtime
dependancy.
To install biTStream, clone git repository and run `make install`.
git clone git://git.videolan.org/bitstream.git
cd bitstream
make install
To install libev, download it from the home page:
http://libev.schmorp.de
If you wish to support Deltacast ASI cards, you will first need to install
the Deltacast StreamMaster drivers and SDK, which are downloadable from the
Deltacast website (login required).
VERSION_MAJOR = 2
VERSION_MINOR = 2
VERSION_MAJOR = 3
VERSION_MINOR = 0
TOPDIR = `basename ${PWD}`
GIT_VER = $(shell git describe --tags --dirty --always 2>/dev/null)
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
deltacast_inc := $(shell sh -c 'test -f /usr/include/StreamMaster.h && echo -n Y')
CFLAGS += -Wall -Wformat-security -O3 -fomit-frame-pointer
CFLAGS += -Wall -Wformat-security -Wno-strict-aliasing -O3 -fomit-frame-pointer
CFLAGS += -g
CFLAGS += -DVERSION=\"$(VERSION_MAJOR).$(VERSION_MINOR)\"
CFLAGS += -DVERSION_MAJOR=$(VERSION_MAJOR)
......@@ -13,10 +15,22 @@ CFLAGS += -DVERSION_EXTRA=\"git-$(GIT_VER)\"
else
CFLAGS += -DVERSION_EXTRA=\"release\"
endif
ifeq ($(uname_S),Linux)
LDLIBS += -lrt
LDLIBS_DVBLAST += -lpthread
endif
ifeq ($(uname_S),Darwin)
LDLIBS += -liconv
endif
ifeq ($(deltacast_inc),Y)
CFLAGS += -DHAVE_ASI_DELTACAST_SUPPORT
LDLIBS += -lstreammaster
endif
LDLIBS_DVBLAST += -lpthread -lev
OBJ_DVBLAST = dvblast.o util.o dvb.o udp.o asi.o demux.o output.o en50221.o comm.o mrtg-cnt.o
OBJ_DVBLAST = dvblast.o util.o dvb.o udp.o asi.o demux.o output.o en50221.o comm.o mrtg-cnt.o asi-deltacast.o
OBJ_DVBLASTCTL = util.o dvblastctl.o
ifndef V
......@@ -35,17 +49,17 @@ all: dvblast dvblastctl
.PHONY: clean install uninstall dist
%.o: %.c Makefile dvblast.h en50221.h comm.h asi.h mrtg-cnt.h
%.o: %.c Makefile config.h dvblast.h en50221.h comm.h asi.h mrtg-cnt.h asi-deltacast.h
@echo "CC $<"
$(Q)$(CC) $(CFLAGS) -c $<
$(Q)$(CROSS)$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
dvblast: $(OBJ_DVBLAST)
@echo "LINK $@"
$(Q)$(CC) -o $@ $(OBJ_DVBLAST) $(LDLIBS_DVBLAST) $(LDLIBS)
$(Q)$(CROSS)$(CC) -o $@ $(OBJ_DVBLAST) $(LDLIBS_DVBLAST) $(LDLIBS)
dvblastctl: $(OBJ_DVBLASTCTL)
@echo "LINK $@"
$(Q)$(CC) -o $@ $(OBJ_DVBLASTCTL) $(LDLIBS_DVBLAST) $(LDLIBS)
$(Q)$(CROSS)$(CC) -o $@ $(OBJ_DVBLASTCTL) $(LDLIBS)
clean:
@echo "CLEAN $(CLEAN_OBJS)"
......@@ -72,7 +86,7 @@ uninstall:
done
dist: clean
@echo "ARCHIVE dvblast-$(VERSION).tar.bz2"
$(Q)git archive --format=tar --prefix=dvblast-$(VERSION)/ master | bzip2 -9 > dvblast-$(VERSION).tar.bz2
$(Q)ls -l dvblast-$(VERSION).tar.bz2
@echo "ARCHIVE dvblast-$(VERSION_MAJOR).$(VERSION_MINOR).tar.bz2"
$(Q)git archive --format=tar --prefix=dvblast-$(VERSION_MAJOR).$(VERSION_MINOR)/ master | bzip2 -9 > dvblast-$(VERSION_MAJOR).$(VERSION_MINOR).tar.bz2
$(Q)ls -l dvblast-$(VERSION_MAJOR).$(VERSION_MINOR).tar.bz2
Changes between 2.2 and 3.0:
----------------------------
* Rewrite core to use libev event loop
* Optimize allocations with a buffer pool
* Add support for building DVBlast on OS X
* Add support for uncommitted diseqc switches
* Fix ECM pid selection
* Add CA device addressing
* Add support for remapping ES pids to fixed values globally and per output
* Add support for multi-delivery system frontends
* Add support for multistream that appeared in Linux 3.6
* Add support for Deltacast ASI cards
* Add support for stream pass-through from the config file
* Add options to periodically print status of bitrate, errors and PIDs
* Add output options to set network ID and network name
* Switch default string charset to UTF-8
* Do not remove padding with ASI
Changes between 2.1 and 2.2:
----------------------------
* Fixed a regression that prevented ECM pass-through (-Y) from working.
* Fix a regression that prevented ECM pass-through (-Y) from working.
* Handle ECM pids that are described in PMT ES descriptor loop.
Changes between 2.0 and 2.1:
......
......@@ -73,6 +73,11 @@ If you own a Computer Modules DVB-ASI input card, you can have DVBlast
filter and demultiplex the inputs. You just need to specify the slot number
with -A.
If you own a Deltacast ASI input card, you can have DVBlast filter and
demultiplex the inputs. You just need to specify the input as
"-A deltacast:<x>" where <x> is 100 * the card number (0 based) + the channel
number (0 based).
DVBlast can also read from a UDP or RTP IPv4 source carrying for
instance a multi-program transport stream. The address is specified with
-D. See the 'advanced features' section for information on how to create
......@@ -146,6 +151,10 @@ Available options include :
/mtu=XXXX (sets the maximum UDP packet size)
/srvname=Some_Channel (set service name in SDT)
/srvprovider=Some_Provider (set provider name in SDT)
/pidmap=pmt_pid,audio_pid,video_pid,spu_pid
/newsid=XX (set output service ID)
/srcaddr=XXX.XXX.XXX.XXX (use RAW packets and set source IPv4)
/srcport=XX (set source port, depends on /srcaddr)
When setting text options like /srvname or /srvprovider, remember
that the underscore character (_) will be replaced by space ( ).
......@@ -191,9 +200,25 @@ DVBlast will only stream the PIDs passed. No PAT and PMT will be generated,
so if they are not included the stream won't be compliant. Also the
included PAT and PMT may contain ghost programs or ESes.
4. PID remapping
239.255.0.1:1234/udp/epg/tsid=42/ssrc=192.168.0.1/pidmap=pmt_pid,audio_pid,video_pid,spu_pid
All four PIDs are required!
Note that the CAM will not be programmed in that case (unless it has
been programmed by another line of the config file). The file is read
from the command-line :
been programmed by another line of the config file).
5. Pass-through
239.255.0.1:1234 1 *
The entire received stream will be passed through the output. Please bear in
mind that when reading from a DVB adapter, hardware PID filtering is used by
default, so not all packets will be output unless you specify the -u option.
The file is read from the command-line :
dvblast -c /tmp/dvblast.conf
......
- Test and enhance the API for DVB-C, H, and ATSC support
- Win32 support
- Improve build system (autostuff)
/*****************************************************************************
* asi-deltacast.c: support for Deltacast ASI cards
*****************************************************************************
* Copyright (C) 2004, 2009, 2015 VideoLAN
*
* Authors: Simon Lockhart <simon@slimey.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "config.h"
#ifdef HAVE_ASI_DELTACAST_SUPPORT
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <ev.h>
#include <bitstream/common.h>
#include <StreamMaster.h>
// #include <DeltacastErrors.h>
#include "asi-deltacast.h"
#include "dvblast.h"
/*****************************************************************************
* Local declarations
*****************************************************************************/
#define ASI_DELTACAST_PERIOD 1000 /* ms */
#define ASI_DELTACAST_LOCK_TIMEOUT 5000000 /* 5 s */
static HANDLE h_board, h_channel;
static struct ev_timer asi_watcher, mute_watcher;
static bool b_sync = false;
static UCHAR *p_asibuf = NULL;
static ULONG i_asibuf_len;
/*****************************************************************************
* asi_deltacast_Open
*****************************************************************************/
void asi_deltacast_Open( void )
{
ASICHANNELCONFIG RXConfig;
ULONG ApiVersion, DrvVersion, NbBoards;
ASIBOARDINFOEX BoardInfoEx;
BOOL res;
/* Get API information */
res = Asi_GetApiInfo(&ApiVersion,&DrvVersion,&NbBoards);
if (!res)
{
msg_Err( NULL, "couldn't get Deltacast API Info: 0x%08lX",
(unsigned long) Dc_GetLastError(NULL) );
exit(EXIT_FAILURE);
}
msg_Dbg( NULL, "Deltacast StreamMaster DLL v%d.%d",
(int)ApiVersion>>16,
(int)ApiVersion&0xFFFF);
msg_Dbg( NULL, "Deltacast Driver v%d.%d.%d",
(DrvVersion >> 24) & 0xFF,
(DrvVersion >> 16) & 0xFF,
(DrvVersion >> 8) & 0xFF);
msg_Dbg( NULL, "Deltacast Board Count: %d", NbBoards);
/* Get the board information */
res = Asi_GetBoardInfoEx((int)(i_asi_adapter / 100), &BoardInfoEx);
if (!res)
{
msg_Err( NULL, "couldn't get Deltacast board Info: 0x%08lX",
(unsigned long) Dc_GetLastError(NULL) );
exit(EXIT_FAILURE);
}
msg_Dbg( NULL, "Deltacast Board FPGA v%08lX",
(unsigned long)BoardInfoEx.BaseInformation.FPGAVersion);
msg_Dbg( NULL, "Deltacast Board PLD v%08lX",
(unsigned long)BoardInfoEx.BaseInformation.PLDVersion);
msg_Dbg( NULL, "Deltacast Board PLX v%08lX",
(unsigned long)BoardInfoEx.BaseInformation.PLXRevision);
msg_Dbg( NULL, "Deltacast Board Serial %08X%08X",
(ULONG)(BoardInfoEx.BaseInformation.SerialNb>>32),
(ULONG)(BoardInfoEx.BaseInformation.SerialNb&0xFFFFFFFF));
msg_Dbg( NULL, "Deltacast Board Input Count: %d", BoardInfoEx.NbRxChannels_i);
msg_Dbg( NULL, "Deltacast Board Output Count: %d", BoardInfoEx.NbTxChannels_i);
/* Open the board */
h_board = Asi_SetupBoard((int)(i_asi_adapter / 100));
if (h_board == NULL)
{
msg_Err( NULL, "couldn't setup deltacast board %d: 0x%08lX",
(int)(i_asi_adapter / 100), (unsigned long) Dc_GetLastError(NULL) );
exit(EXIT_FAILURE);
}
/* Open the channel on the board */
memset(&RXConfig,0,sizeof(ASICHANNELCONFIG));
RXConfig.DriverBufferSize = 188 * 2400; /* Use a driver buffer size of 2400 packets */
RXConfig.BoardBufferSize = 1048576; /* Use 1MB of onboard buffer */
RXConfig.TSPacketType = ASI_PKT_188; /* Use 188-bytes TS packets */
RXConfig.NbPIDFilter = 0; /* No PID filtering */
RXConfig.pPIDFilterTable = NULL; /* No PID filtering */
RXConfig.BitrateIntPeriod = ASI_INTPER_100; /* Integrate over 100 msec */
RXConfig.AllowedBRDeviation= 10000000; /* Allow 10Mbps of deviation */
RXConfig.RXTimeStamp = FALSE; /* No timestamping */
/* Try to open RX0 channel on the board 0 */
h_channel = Asi_OpenChannel(h_board, ASI_CHN_RX0 + (i_asi_adapter % 100), &RXConfig);
if (h_channel == NULL)
{
msg_Err( NULL, "couldn't setup deltacast channel %d: 0x%08lX",
(i_asi_adapter % 100), (unsigned long) Dc_GetLastError(NULL) );
exit(EXIT_FAILURE);
}
ev_timer_init(&asi_watcher, asi_deltacast_Read,
ASI_DELTACAST_PERIOD / 1000000.,
ASI_DELTACAST_PERIOD / 1000000.);
ev_timer_start(event_loop, &asi_watcher);
ev_timer_init(&mute_watcher, asi_deltacast_MuteCb,
ASI_DELTACAST_LOCK_TIMEOUT / 1000000.,
ASI_DELTACAST_LOCK_TIMEOUT / 1000000.);
}
/*****************************************************************************
* ASI deltacast events
*****************************************************************************/
static void asi_deltacast_Read(struct ev_loop *loop, struct ev_io *w, int revents)
{
BOOL res;
block_t *p_ts, **pp_current = &p_ts;
int i;
ULONG Err;
res = Asi_GetInputBuffer(h_channel, &p_asibuf, &i_asibuf_len,
ASI_DELTACAST_PERIOD);
if (!res)
{
Err = Dc_GetLastError(NULL) & ~DC_ERRORCODE_MASK;
if (Err != DCERR_TIMEOUT)
{
msg_Warn( NULL, "asi_deltacast_Read(): GetInputBuffer failed: 0x%08X!", Err);
}
return;
}
if ( !b_sync )
{
msg_Info( NULL, "frontend has acquired lock" );
switch (i_print_type) {
case PRINT_XML:
fprintf(print_fh, "<STATUS type=\"lock\" status=\"1\"/>\n");
break;
case PRINT_TEXT:
fprintf(print_fh, "lock status: 1\n");
break;
default:
break;
}
b_sync = true;
}
ev_timer_again(loop, &mute_watcher);
for (i = 0; i < i_asibuf_len / TS_SIZE; i++)
{
*pp_current = block_New();
memcpy((*pp_current)->p_ts, p_asibuf + (i * TS_SIZE), TS_SIZE);
pp_current = &(*pp_current)->p_next;
}
res = Asi_ReleaseInputBuffer(h_channel);
// msg_Warn( NULL, "asi_deltacast_Read(): returning %d blocks", i_asibuf_len / TS_SIZE );
demux_Run( p_ts );
}
static void asi_deltacast_MuteCb(struct ev_loop *loop, struct ev_timer *w, int revents)
{
msg_Warn( NULL, "frontend has lost lock" );
ev_timer_stop(loop, w);
switch (i_print_type) {
case PRINT_XML:
fprintf(print_fh, "<STATUS type=\"lock\" status=\"0\"/>\n");
break;
case PRINT_TEXT:
fprintf(print_fh, "lock status: 0\n" );
break;
default:
break;
}
}
/*****************************************************************************
* asi_deltacast_SetFilter
*****************************************************************************/
int asi_deltacast_SetFilter( uint16_t i_pid )
{
/* TODO: Support PID filtering */
msg_Warn( NULL, "asi_deltacast_SetFilter(%d) not yet implemented", i_pid );
return -1;
}
/*****************************************************************************
* asi_deltacast_UnsetFilter: normally never called
*****************************************************************************/
void asi_deltacast_UnsetFilter( int i_fd, uint16_t i_pid )
{
/* TODO: Support PID filtering */
msg_Warn( NULL, "asi_deltacast_UnsetFilter() not yet implemented" );
}
/*****************************************************************************
* asi_deltacast_Reset
*****************************************************************************/
void asi_deltacast_Reset( void )
{
/* Called when retune required, so nothing required */
msg_Warn( NULL, "asi_deltacast_Reset() do nothing" );
}
#endif
/*****************************************************************************
* asi-deltacast.h: support for Deltacast ASI cards
*****************************************************************************
* Copyright (C) 2004, 2009 VideoLAN
*
* Authors: Simon Lockhart <simon@slimey.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _ASI_DELTACAST_H
#define _ASI_DELTACAST_H
typedef enum error_source
{
DCERR_SRC_WIN32 = 0, /*! Win32 error code */
DCERR_SRC_SDI_API, /*! DELTA-sdi VIDEOMASTER error code */
DCERR_SRC_SDI_DRIVER, /*! DELTA-sdi DRIVER error code */
DCERR_SRC_STREAMMASTER, /*! DELTA-asi StreamMaster error code */
DCERR_SRC_SYSTEMSMASTER /*! DELTA-asi SystemsMaster error code */
} ERRORSOURCE;
ULONG WINAPI Dc_GetLastError (ERRORSOURCE *pErrorSource);
#define DC_ERRORCODE_MASK 0x2FFF0000 /* facility mask */
#define DCERR_TIMEOUT 0x80000201 /*! A time-out occured */
#endif
/*****************************************************************************
* asi.c: support for Computer Modules ASI cards
*****************************************************************************
* Copyright (C) 2004, 2009 VideoLAN
* Copyright (C) 2004, 2009, 2015 VideoLAN
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -19,6 +19,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "config.h"
#ifdef HAVE_ASI_SUPPORT
#include <stdlib.h>
#include <stdio.h>
......@@ -37,6 +40,8 @@
#include <arpa/inet.h>
#include <errno.h>
#include <ev.h>
#include <bitstream/common.h>
#include "asi.h"
......@@ -49,7 +54,7 @@
* (typically ~100 TS packets) to fill up. And the buffer size cannot be
* adjusted afer startup. --Meuuh
*/
#undef USE_HARDWARE_FILTERING
//#define USE_HARDWARE_FILTERING
/*****************************************************************************
* Local declarations
......@@ -60,9 +65,17 @@
#define ASI_LOCK_TIMEOUT 5000000 /* 5 s */
static int i_handle;
static struct ev_io asi_watcher;
static struct ev_timer mute_watcher;
static int i_bufsize;
static uint8_t p_pid_filter[8192 / 8];
static mtime_t i_last_packet = 0;
static bool b_sync = false;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static void asi_Read(struct ev_loop *loop, struct ev_io *w, int revents);
static void asi_MuteCb(struct ev_loop *loop, struct ev_timer *w, int revents);
/*****************************************************************************
* Local helpers
......@@ -158,7 +171,6 @@ void asi_Open( void )
memset( p_pid_filter, 0x0, sizeof(p_pid_filter) );
#else
memset( p_pid_filter, 0xff, sizeof(p_pid_filter) );
p_pid_filter[8191 / 8] &= ~(0x01 << (8191 % 8)); /* padding */
#endif
if ( ioctl( i_handle, ASI_IOC_RXSETPF, p_pid_filter ) < 0 )
{
......@@ -166,124 +178,109 @@ void asi_Open( void )
}
fsync( i_handle );
ev_io_init(&asi_watcher, asi_Read, i_handle, EV_READ);
ev_io_start(event_loop, &asi_watcher);
ev_timer_init(&mute_watcher, asi_MuteCb,
ASI_LOCK_TIMEOUT / 1000000., ASI_LOCK_TIMEOUT / 1000000.);
}
/*****************************************************************************
* asi_Read : read packets from the device
* ASI events
*****************************************************************************/
block_t *asi_Read( mtime_t i_poll_timeout )
static void asi_Read(struct ev_loop *loop, struct ev_io *w, int revents)
{
struct pollfd pfd[2];
int i_ret, i_nb_fd = 1;
unsigned int i_val;
pfd[0].fd = i_handle;
pfd[0].events = POLLIN;
if ( i_comm_fd != -1 )
if ( ioctl(i_handle, ASI_IOC_RXGETEVENTS, &i_val) == 0 )
{
pfd[1].fd = i_comm_fd;
pfd[1].events = POLLIN;
i_nb_fd++;
if ( i_val & ASI_EVENT_RX_BUFFER )
msg_Warn( NULL, "driver receive buffer queue overrun" );
if ( i_val & ASI_EVENT_RX_FIFO )
msg_Warn( NULL, "onboard receive FIFO overrun" );
if ( i_val & ASI_EVENT_RX_CARRIER )
msg_Warn( NULL, "carrier status change" );
if ( i_val & ASI_EVENT_RX_LOS )
msg_Warn( NULL, "loss of packet synchronization" );
if ( i_val & ASI_EVENT_RX_AOS )
msg_Warn( NULL, "acquisition of packet synchronization" );
if ( i_val & ASI_EVENT_RX_DATA )
msg_Warn( NULL, "receive data status change" );
}
i_ret = poll( pfd, i_nb_fd, (i_poll_timeout + 999) / 1000 );
i_wallclock = mdate();
struct iovec p_iov[i_bufsize / TS_SIZE];
block_t *p_ts, **pp_current = &p_ts;
int i, i_len;
if ( i_ret < 0 )
for ( i = 0; i < i_bufsize / TS_SIZE; i++ )
{
if( errno != EINTR )
msg_Err( NULL, "couldn't poll from device " ASI_DEVICE " (%s)",
i_asi_adapter, strerror(errno) );
return NULL;
*pp_current = block_New();
p_iov[i].iov_base = (*pp_current)->p_ts;
p_iov[i].iov_len = TS_SIZE;
pp_current = &(*pp_current)->p_next;
}
if ( (pfd[0].revents & POLLPRI) )
if ( (i_len = readv(i_handle, p_iov, i_bufsize / TS_SIZE)) < 0 )
{
unsigned int i_val;
if ( ioctl(i_handle, ASI_IOC_RXGETEVENTS, &i_val) < 0 )
msg_Err( NULL, "couldn't RXGETEVENTS (%s)", strerror(errno) );
else
{
if ( i_val & ASI_EVENT_RX_BUFFER )
msg_Warn( NULL, "driver receive buffer queue overrun" );
if ( i_val & ASI_EVENT_RX_FIFO )
msg_Warn( NULL, "onboard receive FIFO overrun" );
if ( i_val & ASI_EVENT_RX_CARRIER )
msg_Warn( NULL, "carrier status change" );
if ( i_val & ASI_EVENT_RX_LOS )
msg_Warn( NULL, "loss of packet synchronization" );
if ( i_val & ASI_EVENT_RX_AOS )
msg_Warn( NULL, "acquisition of packet synchronization" );
if ( i_val & ASI_EVENT_RX_DATA )
msg_Warn( NULL, "receive data status change" );
}
msg_Err( NULL, "couldn't read from device " ASI_DEVICE " (%s)",
i_asi_adapter, strerror(errno) );
i_len = 0;
}
i_len /= TS_SIZE;
if ( (pfd[0].revents & POLLIN) )
if ( i_len )
{
struct iovec p_iov[i_bufsize / TS_SIZE];
block_t *p_ts, **pp_current = &p_ts;
int i, i_len;
if ( !i_last_packet )
if ( !b_sync )
{
msg_Info( NULL, "frontend has acquired lock" );
switch (i_print_type) {
case PRINT_XML:
printf("<STATUS type=\"lock\" status=\"1\"/>\n");
fprintf(print_fh, "<STATUS type=\"lock\" status=\"1\"/>\n");
break;
case PRINT_TEXT:
fprintf(print_fh, "lock status: 1\n");
break;
default:
printf("frontend has acquired lock\n" );
break;
}
}
i_last_packet = i_wallclock;
for ( i = 0; i < i_bufsize / TS_SIZE; i++ )
{
*pp_current = block_New();
p_iov[i].iov_base = (*pp_current)->p_ts;
p_iov[i].iov_len = TS_SIZE;
pp_current = &(*pp_current)->p_next;
}
if ( (i_len = readv(i_handle, p_iov, i_bufsize / TS_SIZE)) < 0 )
{
msg_Err( NULL, "couldn't read from device " ASI_DEVICE " (%s)",
i_asi_adapter, strerror(errno) );
i_len = 0;
}
i_len /= TS_SIZE;
pp_current = &p_ts;
while ( i_len && *pp_current )
{
pp_current = &(*pp_current)->p_next;
i_len--;
b_sync = true;
}
if ( *pp_current )
msg_Dbg( NULL, "partial buffer received" );
block_DeleteChain( *pp_current );
*pp_current = NULL;
return p_ts;
ev_timer_again(loop, &mute_watcher);
}
else if ( i_last_packet && i_last_packet + ASI_LOCK_TIMEOUT < i_wallclock )
pp_current = &p_ts;
while ( i_len && *pp_current )
{
switch (i_print_type) {
case PRINT_XML:
printf("<STATUS type=\"lock\" status=\"0\"/>\n");
break;
default:
printf("frontend has lost lock\n" );
}
i_last_packet = 0;
pp_current = &(*pp_current)->p_next;
i_len--;
}
if ( i_comm_fd != -1 && pfd[1].revents )
comm_Read();
if ( *pp_current )
msg_Dbg( NULL, "partial buffer received" );
block_DeleteChain( *pp_current );
*pp_current = NULL;
demux_Run( p_ts );
}
return NULL;
static void asi_MuteCb(struct ev_loop *loop, struct ev_timer *w, int revents)
{
msg_Warn( NULL, "frontend has lost lock" );
ev_timer_stop(loop, w);
switch (i_print_type) {
case PRINT_XML:
fprintf(print_fh, "<STATUS type=\"lock\" status=\"0\"/>\n");
break;
case PRINT_TEXT:
</