aboutsummaryrefslogtreecommitdiffstats
path: root/util/szap
diff options
context:
space:
mode:
Diffstat (limited to 'util/szap')
-rw-r--r--util/szap/azap.c18
-rw-r--r--util/szap/czap.c24
-rw-r--r--util/szap/szap.c20
-rw-r--r--util/szap/tzap.c24
-rw-r--r--util/szap/util.c224
-rw-r--r--util/szap/util.h4
6 files changed, 262 insertions, 52 deletions
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 <unistd.h>
#include <stdio.h>
#include <errno.h>
+#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/types.h>
@@ -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);