#include <argp.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
 
#ifdef ENABLE_NLS
# define _(string) gettext(string)
# include "gettext.h"
# include <locale.h>
# include <langinfo.h>
# include <iconv.h>
#else
# define _(string) string
#endif
 
# define N_(string) string
 
#define PROGRAM_NAME    "dvb-fe-tool"
 
const char *argp_program_version = PROGRAM_NAME " version " V4L_UTILS_VERSION;
const char *argp_program_bug_address = "Mauro Carvalho Chehab <mchehab@kernel.org>";
 
static const char doc[] = N_(
        "\nA DVB frontend tool using API version 5\n"
        "\nOn the options below, the arguments are:\n"
        "  ADAPTER      - the dvb adapter to control\n"
        "  FRONTEND     - the dvb frontend to control\n"
        "  SERVER       - server address which is running the dvb5-daemon\n"
        "  PORT         - server port used by the dvb5-daemon\n");
 
static const struct argp_option options[] = {
        {"verbose",     'v',    0,              0,      N_("enables debug messages"), 0},
        {"adapter",     'a',    N_("ADAPTER"),  0,      N_("dvb adapter"), 0},
        {"frontend",    'f',    N_("FRONTEND"), 0,      N_("dvb frontend"), 0},
        {"set-delsys",  'd',    N_("PARAMS"),   0,      N_("set delivery system"), 0},
        {"femon",       'm',    0,              0,      N_("monitors frontend stats on an streaming frontend"), 0},
        {"acoustical",  'A',    0,              0,      N_("beeps if signal quality is good. Also enables femon mode. Please notice that console beep should be enabled on your wm."), 0},
#if 0 
        {"set",         's',    N_("PARAMS"),   0,      N_("set frontend"), 0},
#endif
        {"get",         'g',    0,              0,      N_("get frontend"), 0},
        {"server",      'H',    N_("SERVER"),   0,      N_("dvbv5-daemon host IP address"), 0},
        {"tcp-port",    'T',    N_("PORT"),     0,      N_("dvbv5-daemon host tcp port"), 0},
        {"device-mon",  'D',    0,              0,      N_("monitors device insert/removal"), 0},
        {"count",       'c',    N_("COUNT"),    0,      N_("samples to take (default 0 = infinite)"), 0},
        {"help",        '?',    0,              0,      N_("Give this help list"), -1},
        {"usage",       -3,     0,              0,      N_("Give a short usage message")},
        {"version",     'V',    0,              0,      N_("Print program version"), -1},
        { 0, 0, 0, 0, 0, 0 }
};
 
static int adapter = 0;
static int frontend = 0;
static unsigned get = 0;
static char *set_params = NULL;
static char *server = NULL;
static unsigned port = 0;
static int verbose = 0;
static int delsys = 0;
static int femon = 0;
static int acoustical = 0;
static int timeout_flag = 0;
static int device_mon = 0;
static int count = 0;
 
static void do_timeout(int x)
{
        (void)x;
 
        if (timeout_flag == 0) {
                timeout_flag = 1;
                alarm(2);
                signal(SIGALRM, do_timeout);
        } else {
                
                exit(1);
        }
}
 
#define ERROR(x...)                                                     \
        do {                                                            \
                fprintf(stderr, _("ERROR: "));                             \
                fprintf(stderr, x);                                     \
                fprintf(stderr, "\n");                                 \
        } while (0)
 
 
static error_t parse_opt(int k, char *arg, struct argp_state *state)
{
        switch (k) {
        case 'a':
                adapter = atoi(arg);
                break;
        case 'f':
                frontend = atoi(arg);
                break;
        case 'd':
                if (delsys < 0)
                        return ARGP_ERR_UNKNOWN;
                break;
        case 'm':
                femon++;
                break;
        case 'A':
                femon++;
                acoustical++;
                break;
#if 0
        case 's':
                set_params = arg;
                break;
#endif
        case 'g':
                get++;
                break;
        case 'D':
                device_mon++;
                break;
        case 'H':
                server = arg;
                break;
        case 'T':
                port = atoi(arg);
                break;
        case 'v':
                verbose ++;
                break;
        case 'c':
                count = atoi(arg);
                break;
        case '?':
                argp_state_help(state, state->out_stream,
                                ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG
                                | ARGP_HELP_DOC);
                fprintf(state->out_stream, _("\nReport bugs to %s.\n"), argp_program_bug_address);
                exit(0);
        case 'V':
                fprintf (state->out_stream, "%s\n", argp_program_version);
                exit(0);
        case -3:
                argp_state_help(state, state->out_stream, ARGP_HELP_USAGE);
                exit(0);
        default:
                return ARGP_ERR_UNKNOWN;
        }
        return 0;
}
 
static struct argp argp = {
        .options = options,
        .parser = parse_opt,
        .doc = doc,
};
 
static int print_frontend_stats(FILE *fd,
{
        char buf[512], *p;
        int rc, i, len, show, n_status_lines = 0;
 
        if (rc) {
                ERROR(_("dvb_fe_get_stats failed"));
                return -1;
        }
 
        p = buf;
        len = sizeof(buf);
 
        for (i = 0; i < MAX_DTV_STATS; i++) {
                show = 1;
 
                                     i, &p, &len, &show);
 
                                     i, &p, &len, &show);
 
                                     i, &p, &len, &show);
 
                                     i,  &p, &len, &show);
 
                                     i,  &p, &len, &show);
 
                                     i,  &p, &len, &show);
 
                                     i,  &p, &len, &show);
                if (p != buf) {
                        if (isatty(fileno(fd))) {
                                int color;
 
 
                                switch (qual) {
                                        color = 31;
                                        break;
                                        color = 36;
                                        break;
                                        color = 32;
                                        break;
                                default:
                                        color = 0;
                                        break;
                                }
                                fprintf(fd, "\033[%dm", color);
                                
                                if (acoustical) {
                                                fprintf(fd, "\a");
                                }
                        }
 
                        if (n_status_lines)
                                fprintf(fd, "\t%s\n", buf);
                        else
                                fprintf(fd, "%s\n", buf);
 
                        n_status_lines++;
 
                        p = buf;
                        len = sizeof(buf);
                }
        }
 
        fflush(fd);
 
        return 0;
}
 
{
        int rc;
 
        signal(SIGTERM, do_timeout);
        signal(SIGINT, do_timeout);
 
        do {
                if (!rc)
                        print_frontend_stats(stderr, parms);
                if (count > 0 && !--count)
                        break;
                if (!timeout_flag)
                        usleep(1000000);
        } while (!timeout_flag);
}
 
static const char * const event_type[] = {
};
 
static int dev_change_monitor(char *sysname,
{
                printf("unknown event on device %s\n", sysname);
        else
                printf("device %s was %s\n", sysname, event_type[type]);
        free(sysname);
 
        return 0;
}
 
int main(int argc, char *argv[])
{
        int ret, fe_flags = O_RDWR;
 
#ifdef ENABLE_NLS
        setlocale (LC_ALL, "");
        bindtextdomain (PACKAGE, LOCALEDIR);
        textdomain (PACKAGE);
#endif
 
        if (argp_parse(&argp, argc, argv, ARGP_NO_HELP | ARGP_NO_EXIT, 0, 0)) {
                argp_help(&argp, stderr, ARGP_HELP_SHORT_USAGE, PROGRAM_NAME);
                return -1;
        }
 
        
        if (!get && !delsys && !set_params && !femon)
 
        if (!delsys && !set_params)
                fe_flags = O_RDONLY;
 
        if (!dvb)
                return -1;
 
        if (server && port) {
                printf(_("Connecting to %s:%d\n"), server, port);
                if (ret < 0)
                        return -1;
        }
 
        if (device_mon) {
                while (1) {
                        usleep(1000000);
                }
        }
 
        if (!dvb_dev)
                return -1;
 
                return -1;
 
        if (delsys) {
                printf(_("Changing delivery system to: %s\n"),
                        delivery_system_name[delsys]);
                goto ret;
        }
 
#if 0
        if (set_params)
                do_something();
#endif
        if (get) {
        }
 
        if (femon)
                get_show_stats(parms);
 
ret:
 
        return 0;
}
Provides interfaces to handle Digital TV devices.
static int dvb_dev_remote_init(struct dvb_device *d, char *server, int port)
dvb_dev_change_type
Describes the type of change to be notifier_delay.
struct dvb_dev_list * dvb_dev_seek_by_adapter(struct dvb_device *dvb, unsigned int adapter, unsigned int num, enum dvb_dev_type type)
Find a device that matches the search criteria given by this functions's parameters.
Provides interfaces to deal with DVB channel and program files.
#define ARRAY_SIZE(x)
Calculates the number of elements of an array.
void dvb_dev_free(struct dvb_device *dvb)
free a struct dvb_device
struct dvb_open_descriptor * dvb_dev_open(struct dvb_device *dvb, const char *sysname, int flags)
Opens a dvb device.
int dvb_dev_find(struct dvb_device *dvb, dvb_dev_change_t handler, void *user_priv)
finds all DVB devices on the local machine
void dvb_dev_set_log(struct dvb_device *dvb, unsigned verbose, dvb_logfunc logfunc)
Sets the DVB verbosity and log function.
struct dvb_device * dvb_dev_alloc(void)
Allocate a struct dvb_device.
int dvb_parse_delsys(const char *name)
Ancillary function that seeks for a delivery system.
#define DTV_BER
Bit Error Rate.
int dvb_fe_snprintf_stat(struct dvb_v5_fe_parms *parms, uint32_t cmd, char *display_name, int layer, char **buf, int *len, int *show_layer_name)
Ancillary function to sprintf on ENG format.
int dvb_fe_get_parms(struct dvb_v5_fe_parms *parms)
Prints all the properties at the cache.
#define DTV_STATUS
Lock status of a DTV frontend.
dvb_quality
Provides an estimation about the user's experience while watching to a given MPEG stream.
enum dvb_quality dvb_fe_retrieve_quality(struct dvb_v5_fe_parms *parms, unsigned layer)
Retrieve the quality stats from cache.
#define DTV_QUALITY
A quality indicator that represents if a locked channel provides a good, OK or poor signal.
int dvb_set_sys(struct dvb_v5_fe_parms *parms, fe_delivery_system_t sys)
Sets the delivery system.
#define DTV_PER
Packet Error Rate.
void dvb_fe_prt_parms(const struct dvb_v5_fe_parms *parms)
Prints all the properties at the cache.
#define DTV_PRE_BER
Bit Error Rate before Viterbi.
int dvb_fe_get_stats(struct dvb_v5_fe_parms *parms)
Retrieve the stats from the Kernel.
Digital TV device node properties.
Digital TV list of devices.
struct dvb_v5_fe_parms * fe_parms
Keeps data needed to handle the DVB frontend.