From 60584e13787af008063469fba29334090d56d8d4 Mon Sep 17 00:00:00 2001 From: Jonathan McCrohan Date: Tue, 17 Sep 2013 00:36:05 +0100 Subject: Imported Upstream version 1.1.1+rev1500 --- util/szap/azap.c | 18 ++--- util/szap/czap.c | 24 +++--- util/szap/szap.c | 20 ++--- util/szap/tzap.c | 24 +++--- util/szap/util.c | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/szap/util.h | 4 + 6 files changed, 262 insertions(+), 52 deletions(-) (limited to 'util/szap') diff --git a/util/szap/azap.c b/util/szap/azap.c index 230a7b9..d024b46 100644 --- a/util/szap/azap.c +++ b/util/szap/azap.c @@ -216,18 +216,14 @@ int parse(const char *fname, const char *channel, static int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) { - struct dvb_frontend_info fe_info; + uint32_t mstd; - if (ioctl(fe_fd, FE_GET_INFO, &fe_info) < 0) { - PERROR("ioctl FE_GET_INFO failed"); - return -1; - } - - if (fe_info.type != FE_ATSC) { - ERROR ("frontend device is not an ATSC (VSB/QAM) device"); + if (check_frontend(fe_fd, FE_ATSC, &mstd) < 0) { + close(fe_fd); return -1; } + /* TODO! Some frontends need to be explicit delivery system */ printf ("tuning to %i Hz\n", frontend->frequency); if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) { @@ -240,7 +236,7 @@ int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) static -int check_frontend (int fe_fd) +int monitor_frontend (int fe_fd) { fe_status_t status; uint16_t snr, signal; @@ -344,7 +340,7 @@ int main(int argc, char **argv) if (parse (confname, channel, &frontend_param, &vpid, &apid, &sid)) return -1; - if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { + if ((frontend_fd = open(FRONTEND_DEV, O_RDWR | O_NONBLOCK)) < 0) { PERROR ("failed opening '%s'", FRONTEND_DEV); return -1; } @@ -392,7 +388,7 @@ int main(int argc, char **argv) if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0) return -1; - check_frontend (frontend_fd); + monitor_frontend (frontend_fd); close (pat_fd); close (pmt_fd); diff --git a/util/szap/czap.c b/util/szap/czap.c index 8a97d98..f49c524 100644 --- a/util/szap/czap.c +++ b/util/szap/czap.c @@ -180,32 +180,30 @@ int parse(const char *fname, int list_channels, int chan_no, const char *channel } -static -int setup_frontend(int fe_fd, struct dvb_frontend_parameters *frontend) +static int setup_frontend(int fe_fd, struct dvb_frontend_parameters *frontend) { - struct dvb_frontend_info fe_info; + int ret; + uint32_t mstd; - if (ioctl(fe_fd, FE_GET_INFO, &fe_info) < 0) { - PERROR ("ioctl FE_GET_INFO failed"); + if (check_frontend(fe_fd, FE_QAM, &mstd) < 0) { + close(fe_fd); return -1; } - - if (fe_info.type != FE_QAM) { - ERROR ("frontend device is not a QAM (DVB-C) device"); + ret = dvbfe_set_delsys(fe_fd, SYS_DVBC_ANNEX_A); + if (ret) { + PERROR("SET Delsys failed"); return -1; } - if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) { PERROR ("ioctl FE_SET_FRONTEND failed"); return -1; } - return 0; } static -int check_frontend (int fe_fd, int human_readable) +int monitor_frontend (int fe_fd, int human_readable) { fe_status_t status; uint16_t snr, signal; @@ -347,7 +345,7 @@ int main(int argc, char **argv) if (list_channels) return 0; - if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { + if ((frontend_fd = open(FRONTEND_DEV, O_RDWR | O_NONBLOCK)) < 0) { PERROR("failed opening '%s'", FRONTEND_DEV); return -1; } @@ -393,7 +391,7 @@ int main(int argc, char **argv) if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0) return -1; - check_frontend (frontend_fd, human_readable); + monitor_frontend (frontend_fd, human_readable); close (pat_fd); close (pmt_fd); diff --git a/util/szap/szap.c b/util/szap/szap.c index 9de752e..90bdbfb 100644 --- a/util/szap/szap.c +++ b/util/szap/szap.c @@ -166,7 +166,7 @@ static int do_tune(int fefd, unsigned int ifreq, unsigned int sr) } -static int check_frontend (int fe_fd, int dvr, int human_readable) +static int monitor_frontend (int fe_fd, int dvr, int human_readable) { (void)dvr; fe_status_t status; @@ -220,9 +220,8 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux, char fedev[128], dmxdev[128], auddev[128]; static int fefd, dmxfda, dmxfdv, audiofd = -1, patfd, pmtfd; int pmtpid; - uint32_t ifreq; + uint32_t ifreq, mstd; int hiband, result; - static struct dvb_frontend_info fe_info; if (!fefd) { snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend); @@ -234,20 +233,11 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux, perror("opening frontend failed"); return FALSE; } - - result = ioctl(fefd, FE_GET_INFO, &fe_info); - if (result < 0) { - perror("ioctl FE_GET_INFO failed"); - close(fefd); - return FALSE; - } - - if (fe_info.type != FE_QPSK) { - fprintf(stderr, "frontend device is not a QPSK (DVB-S) device!\n"); + if (check_frontend(fefd, FE_QPSK, &mstd) < 0) { close(fefd); return FALSE; } - + /* TODO! Some frontends need to be explicit delivery system */ if ((dmxfdv = open(dmxdev, O_RDWR)) < 0) { perror("opening video demux failed"); close(fefd); @@ -322,7 +312,7 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux, } } - check_frontend (fefd, dvr, human_readable); + monitor_frontend (fefd, dvr, human_readable); if (!interactive) { close(patfd); close(pmtfd); diff --git a/util/szap/tzap.c b/util/szap/tzap.c index ce63832..5f84cb0 100644 --- a/util/szap/tzap.c +++ b/util/szap/tzap.c @@ -351,21 +351,20 @@ int parse(const char *fname, const char *channel, } -static -int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) +static int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) { - struct dvb_frontend_info fe_info; + int ret; + uint32_t mstd; - if (ioctl(fe_fd, FE_GET_INFO, &fe_info) < 0) { - PERROR("ioctl FE_GET_INFO failed"); + if (check_frontend(fe_fd, FE_OFDM, &mstd) < 0) { + close(fe_fd); return -1; } - - if (fe_info.type != FE_OFDM) { - ERROR ("frontend device is not a OFDM (DVB-T) device"); + ret = dvbfe_set_delsys(fe_fd, SYS_DVBT); + if (ret) { + PERROR("SET Delsys failed"); return -1; } - if (silent < 2) fprintf (stderr,"tuning to %i Hz\n", frontend->frequency); @@ -373,7 +372,6 @@ int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) PERROR("ioctl FE_SET_FRONTEND failed"); return -1; } - return 0; } @@ -417,7 +415,7 @@ static void print_frontend_stats(int fe_fd, int human_readable) } static -int check_frontend (int fe_fd, int human_readable) +int monitor_frontend (int fe_fd, int human_readable) { fe_status_t status; do { @@ -593,7 +591,7 @@ int main(int argc, char **argv) if (parse (confname, channel, &frontend_param, &vpid, &apid, &sid)) return -1; - if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { + if ((frontend_fd = open(FRONTEND_DEV, O_RDWR | O_NONBLOCK)) < 0) { PERROR ("failed opening '%s'", FRONTEND_DEV); return -1; } @@ -678,7 +676,7 @@ int main(int argc, char **argv) print_frontend_stats(frontend_fd, human_readable); } else { just_the_frontend_dude: - check_frontend(frontend_fd, human_readable); + monitor_frontend(frontend_fd, human_readable); } close(pat_fd); diff --git a/util/szap/util.c b/util/szap/util.c index 99d303a..60de8f8 100644 --- a/util/szap/util.c +++ b/util/szap/util.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -121,3 +122,226 @@ int get_pmt_pid(char *dmxdev, int sid) close(patfd); return pmt_pid; } + +char *type_str[] = { + "QPSK", + "QAM", + "OFDM", + "ATSC", +}; + +/* to be used with v3 drivers */ +int check_frontend_v3(int fd, enum fe_type type) +{ + struct dvb_frontend_info info; + int ret; + + ret = ioctl(fd, FE_GET_INFO, &info); + if (ret < 0) { + perror("ioctl FE_GET_INFO failed"); + close(fd); + ret = -1; + goto exit; + } + if (info.type != type) { + fprintf(stderr, "Not a valid %s device!\n", type_str[type]); + close(fd); + ret = -EINVAL; + goto exit; + } +exit: + return ret; +} + +char *del_str[] = { + "UNDEFINED", + "DVB-C (A)", + "DVB-C (B)", + "DVB-T", + "DSS", + "DVB-S", + "DVB-S2", + "DVB-H", + "ISDB-T", + "ISDB-S", + "ISDB-C", + "ATSC", + "ATSC-M/H", + "DTMB", + "CMMB", + "DAB", + "DVB-T2", + "TURBO", + "QAM (C)", +}; + +static int map_delivery_mode(fe_type_t *type, enum fe_delivery_system delsys) +{ + switch (delsys) { + case SYS_DSS: + case SYS_DVBS: + case SYS_DVBS2: + case SYS_TURBO: + *type = FE_QPSK; + break; + case SYS_DVBT: + case SYS_DVBT2: + case SYS_DVBH: + case SYS_ISDBT: + *type = FE_OFDM; + break; + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: + *type = FE_QAM; + break; + case SYS_ATSC: + case SYS_DVBC_ANNEX_B: + *type = FE_ATSC; + break; + default: + fprintf(stderr, "Delivery system unsupported, please report to linux-media ML\n"); + return -1; + } + return 0; +} + +int get_property(int fd, uint32_t pcmd, uint32_t *len, uint8_t *data) +{ + struct dtv_property p, *b; + struct dtv_properties cmd; + int ret; + + p.cmd = pcmd; + cmd.num = 1; + cmd.props = &p; + b = &p; + + ret = ioctl(fd, FE_GET_PROPERTY, &cmd); + if (ret < 0) { + fprintf(stderr, "FE_SET_PROPERTY returned %d\n", ret); + return -1; + } + memcpy(len, &b->u.buffer.len, sizeof (uint32_t)); + memcpy(data, b->u.buffer.data, *len); + return 0; +} + +int set_property(int fd, uint32_t cmd, uint32_t data) +{ + struct dtv_property p, *b; + struct dtv_properties c; + int ret; + + p.cmd = cmd; + c.num = 1; + c.props = &p; + b = &p; + b->u.data = data; + ret = ioctl(fd, FE_SET_PROPERTY, &c); + if (ret < 0) { + fprintf(stderr, "FE_SET_PROPERTY returned %d\n", ret); + return -1; + } + return 0; +} + +int dvbfe_get_delsys(int fd, fe_delivery_system_t *delsys) +{ + uint32_t len; + /* Buggy API design */ + return get_property(fd, DTV_DELIVERY_SYSTEM, &len, (uint8_t *)delsys); +} + +int dvbfe_set_delsys(int fd, enum fe_delivery_system delsys) +{ + return set_property(fd, DTV_DELIVERY_SYSTEM, delsys); +} + +int dvbfe_enum_delsys(int fd, uint32_t *len, uint8_t *data) +{ + return get_property(fd, DTV_ENUM_DELSYS, len, data); +} + +int dvbfe_get_version(int fd, int *major, int *minor) +{ + struct dtv_property p, *b; + struct dtv_properties cmd; + int ret; + + p.cmd = DTV_API_VERSION; + cmd.num = 1; + cmd.props = &p; + b = &p; + + ret = ioctl(fd, FE_GET_PROPERTY, &cmd); + if (ret < 0) { + fprintf(stderr, "FE_GET_PROPERTY failed, ret=%d\n", ret); + return -1; + } + *major = (b->u.data >> 8) & 0xff; + *minor = b->u.data & 0xff; + return 0; +} + +int check_frontend_multi(int fd, enum fe_type type, uint32_t *mstd) +{ + int ret; + + enum fe_type delmode; + unsigned int i, valid_delsys = 0; + uint32_t len; + uint8_t data[32]; + + ret = dvbfe_enum_delsys(fd, &len, data); + if (ret) { + fprintf(stderr, "enum_delsys failed, ret=%d\n", ret); + ret = -EIO; + goto exit; + } + fprintf(stderr, "\t FE_CAN { "); + for (i = 0; i < len; i++) { + if (i < len - 1) + fprintf(stderr, "%s + ", del_str[data[i]]); + else + fprintf(stderr, "%s", del_str[data[i]]); + } + fprintf(stderr, " }\n"); + /* check whether frontend can support our delivery */ + for (i = 0; i < len; i++) { + map_delivery_mode(&delmode, data[i]); + if (type == delmode) { + valid_delsys = 1; + ret = 0; + break; + } + } + if (!valid_delsys) { + fprintf(stderr, "Not a valid %s device!\n", type_str[type]); + ret = -EINVAL; + goto exit; + } + *mstd = len; /* mstd has supported delsys count */ +exit: + return ret; +} + +int check_frontend(int fd, enum fe_type type, uint32_t *mstd) +{ + int major, minor, ret; + + ret = dvbfe_get_version(fd, &major, &minor); + if (ret) + goto exit; + fprintf(stderr, "Version: %d.%d ", major, minor); + if ((major == 5) && (minor > 8)) { + ret = check_frontend_multi(fd, type, mstd); + if (ret) + goto exit; + } else { + ret = check_frontend_v3(fd, type); + if (ret) + goto exit; + } +exit: + return ret; +} diff --git a/util/szap/util.h b/util/szap/util.h index f4b7f12..b82fdc5 100644 --- a/util/szap/util.h +++ b/util/szap/util.h @@ -22,3 +22,7 @@ int set_pesfilter(int dmxfd, int pid, int pes_type, int dvr); int get_pmt_pid(char *dmxdev, int sid); + +int check_frontend(int fd, enum fe_type type, uint32_t *mstd); + +int dvbfe_set_delsys(int fd, enum fe_delivery_system delsys); -- cgit v1.2.3