3 * @brief Linux DVB API version 5
5 /*****************************************************************************
6 * Copyright © 2011 Rémi Denis-Courmont
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 ****************************************************************************/
27 #include <vlc_common.h>
34 #include <sys/ioctl.h>
35 #include <linux/dvb/version.h>
36 #include <linux/dvb/frontend.h>
37 #include <linux/dvb/dmx.h>
42 # define O_SEARCH O_RDONLY
45 #define DVBv5(minor) \
46 (DVB_API_VERSION > 5 \
47 || (DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= (minor)))
49 # error Linux DVB kernel headers version 2.6.28 or later required.
52 /** Opens the device directory for the specified DVB adapter */
53 static int dvb_open_adapter (uint8_t adapter)
57 snprintf (dir, sizeof (dir), "/dev/dvb/adapter%"PRIu8, adapter);
58 return open (dir, O_SEARCH|O_DIRECTORY|O_CLOEXEC);
61 /** Opens the DVB device node of the specified type */
62 static int dvb_open_node (int dirfd, uint8_t dev, const char *type, int flags)
65 char path[strlen (type) + 4];
67 snprintf (path, sizeof (path), "%s%"PRIu8, type, dev);
68 fd = openat (dirfd, path, flags|O_CLOEXEC);
70 fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK);
80 static int icmp (const void *a, const void *b)
82 int key = (intptr_t)a;
83 const dvb_int_map_t *entry = b;
84 return key - entry->vlc;
87 /** Maps a VLC config integer to a Linux DVB enum value */
88 static int dvb_parse_int (int i, const dvb_int_map_t *map, size_t n, int def)
90 const void *k = (const void *)(intptr_t)i;
91 const dvb_int_map_t *p = bsearch (k, map, n, sizeof (*map), icmp);
92 return (p != NULL) ? p->linux_ : def;
101 static int scmp (const void *a, const void *b)
104 dvb_str_map_t *entry = b;
105 return strcmp (key, entry->vlc);
108 /** Maps a VLC config string to a Linux DVB enum value */
109 static int dvb_parse_str (const char *str, const dvb_str_map_t *map, size_t n,
114 const dvb_str_map_t *p = bsearch (str, map, n, sizeof (*map), scmp);
121 /*** Modulations ***/
122 static int dvb_parse_modulation (const char *str, int def)
124 static const dvb_str_map_t mods[] =
126 { "128QAM", QAM_128 },
127 { "16APSK", APSK_16 },
130 { "256QAM", QAM_256 },
131 { "32APSK", APSK_32 },
140 return dvb_parse_str (str, mods, sizeof (mods) / sizeof (*mods), def);
143 static int dvb_parse_fec (uint32_t fec)
145 static const dvb_int_map_t rates[] =
148 { VLC_FEC(1,2), FEC_1_2 },
151 { VLC_FEC(2,3), FEC_2_3 },
152 { VLC_FEC(3,4), FEC_3_4 },
153 { VLC_FEC(3,5), FEC_3_5 },
154 { VLC_FEC(4,5), FEC_4_5 },
155 { VLC_FEC(5,6), FEC_5_6 },
156 { VLC_FEC(6,7), FEC_6_7 },
157 { VLC_FEC(7,8), FEC_7_8 },
158 { VLC_FEC(8,9), FEC_8_9 },
159 { VLC_FEC(9,10), FEC_9_10 },
160 { VLC_FEC_AUTO, FEC_AUTO },
162 return dvb_parse_int (fec, rates, sizeof (rates) / sizeof (*rates),
173 # define MAX_PIDS 256
183 struct dvb_frontend_info info;
185 //size_t buffer_size;
189 * Opens the DVB tuner
191 dvb_device_t *dvb_open (vlc_object_t *obj, bool tune)
193 uint8_t adapter = var_InheritInteger (obj, "dvb-adapter");
194 uint8_t device = var_InheritInteger (obj, "dvb-device");
196 int dirfd = dvb_open_adapter (adapter);
199 msg_Err (obj, "cannot access adapter %"PRIu8": %m", adapter);
203 dvb_device_t *d = malloc (sizeof (*d));
204 if (unlikely(d == NULL))
213 d->budget = var_InheritBool (obj, "dvb-budget-mode");
219 d->demux = dvb_open_node (dirfd, device, "demux", O_RDONLY);
222 msg_Err (obj, "cannot access demultiplexer: %m");
228 if (ioctl (d->demux, DMX_SET_BUFFER_SIZE, 1 << 20) < 0)
229 msg_Warn (obj, "cannot expand demultiplexing buffer: %m");
231 /* We need to filter at least one PID. The tap for TS demultiplexing
232 * cannot be configured otherwise. So add the PAT. */
233 struct dmx_pes_filter_params param;
235 param.pid = d->budget ? 0x2000 : 0x000;
236 param.input = DMX_IN_FRONTEND;
237 param.output = DMX_OUT_TSDEMUX_TAP;
238 param.pes_type = DMX_PES_OTHER;
239 param.flags = DMX_IMMEDIATE_START;
240 if (ioctl (d->demux, DMX_SET_PES_FILTER, ¶m) < 0)
242 msg_Err (obj, "cannot setup TS demultiplexer: %m");
249 d->dir = fcntl (dirfd, F_DUPFD_CLOEXEC);
252 for (size_t i = 0; i < MAX_PIDS; i++)
253 d->pids[i].pid = d->pids[i].fd = -1;
254 d->demux = dvb_open_node (d->dir, device, "dvr", O_RDONLY);
257 msg_Err (obj, "cannot access DVR: %m");
267 d->frontend = dvb_open_node (dirfd, device, "frontend", O_RDWR);
268 if (d->frontend == -1)
270 msg_Err (obj, "cannot access frontend %"PRIu8
271 " of adapter %"PRIu8": %m", device, adapter);
275 if (ioctl (d->frontend, FE_GET_INFO, &d->info) < 0)
277 msg_Err (obj, "cannot get frontend info: %m");
281 msg_Dbg (obj, "using frontend: %s", d->info.name);
282 msg_Dbg (obj, " type %u, capabilities 0x%08X", d->info.type,
285 d->ca = dvb_open_node (dirfd, device, "ca", O_RDWR);
287 msg_Dbg (obj, "conditional access module not available (%m)");
299 void dvb_close (dvb_device_t *d)
305 for (size_t i = 0; i < MAX_PIDS; i++)
306 if (d->pids[i].fd != -1)
307 close (d->pids[i].fd);
312 if (d->frontend != -1)
319 * Reads TS data from the tuner.
320 * @return number of bytes read, 0 on EOF, -1 if no data (yet).
322 ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len)
324 struct pollfd ufd[2];
327 ufd[0].fd = d->demux;
328 ufd[0].events = POLLIN;
329 if (d->frontend != -1)
331 ufd[1].fd = d->frontend;
332 ufd[1].events = POLLIN;
338 if (poll (ufd, n, 500 /* FIXME */) < 0)
341 if (d->frontend != -1 && ufd[1].revents)
343 struct dvb_frontend_event ev;
345 if (ioctl (d->frontend, FE_GET_EVENT, &ev) < 0)
347 if (errno == EOVERFLOW)
349 msg_Err (d->obj, "cannot dequeue events fast enough!");
352 msg_Err (d->obj, "cannot dequeue frontend event: %m");
356 msg_Dbg (d->obj, "frontend status: 0x%02X", (unsigned)ev.status);
361 ssize_t val = read (d->demux, buf, len);
362 if (val == -1 && (errno != EAGAIN && errno != EINTR))
364 if (errno == EOVERFLOW)
366 msg_Err (d->obj, "cannot demux data fast enough!");
369 msg_Err (d->obj, "cannot demux: %m");
378 int dvb_add_pid (dvb_device_t *d, uint16_t pid)
383 if (pid == 0 || ioctl (d->demux, DMX_ADD_PID, &pid) >= 0)
386 for (size_t i = 0; i < MAX_PIDS; i++)
388 if (d->pids[i].pid == pid)
390 if (d->pids[i].fd != -1)
393 int fd = dvb_open_node (d->dir, d->dev_id, "demux", O_RDONLY);
397 /* We need to filter at least one PID. The tap for TS demultiplexing
398 * cannot be configured otherwise. So add the PAT. */
399 struct dmx_pes_filter_params param;
402 param.input = DMX_IN_FRONTEND;
403 param.output = DMX_OUT_TS_TAP;
404 param.pes_type = DMX_PES_OTHER;
405 param.flags = DMX_IMMEDIATE_START;
406 if (ioctl (fd, DMX_SET_PES_FILTER, ¶m) < 0)
412 d->pids[i].pid = pid;
418 msg_Err (d->obj, "cannot add PID 0x%04"PRIu16": %m", pid);
422 void dvb_remove_pid (dvb_device_t *d, uint16_t pid)
428 ioctl (d->demux, DMX_REMOVE_PID, &pid);
430 for (size_t i = 0; i < MAX_PIDS; i++)
432 if (d->pids[i].pid == pid)
434 close (d->pids[i].fd);
435 d->pids[i].pid = d->pids[i].fd = -1;
442 const delsys_t *dvb_guess_system (dvb_device_t *d)
444 assert (d->frontend != -1);
446 //bool v2 = d->info.caps & FE_CAN_2G_MODULATION;
448 switch (d->info.type)
450 case FE_QPSK: return /*v2 ? &dvbs2 :*/ &dvbs;
451 case FE_QAM: return &dvbc;
452 case FE_OFDM: return &dvbt;
453 case FE_ATSC: return &atsc;
458 float dvb_get_signal_strength (dvb_device_t *d)
462 if (ioctl (d->frontend, FE_READ_SIGNAL_STRENGTH, &strength) < 0)
464 return strength / 65535.;
467 float dvb_get_snr (dvb_device_t *d)
471 if (ioctl (d->frontend, FE_READ_SNR, &snr) < 0)
476 static int dvb_vset_props (dvb_device_t *d, size_t n, va_list ap)
478 struct dtv_property buf[n], *prop = buf;
479 struct dtv_properties props = { .num = n, .props = buf };
481 memset (prop, 0, sizeof (prop));
485 prop->cmd = va_arg (ap, uint32_t);
486 prop->u.data = va_arg (ap, uint32_t);
487 msg_Dbg (d->obj, "setting property %"PRIu32" to %"PRIu32,
488 prop->cmd, prop->u.data);
493 if (ioctl (d->frontend, FE_SET_PROPERTY, &props) < 0)
495 msg_Err (d->obj, "cannot set frontend tuning parameters: %m");
501 static int dvb_set_props (dvb_device_t *d, size_t n, ...)
507 ret = dvb_vset_props (d, n, ap);
512 static int dvb_set_prop (dvb_device_t *d, uint32_t prop, uint32_t val)
514 return dvb_set_props (d, 1, prop, val);
517 int dvb_set_inversion (dvb_device_t *d, int v)
521 case 0: v = INVERSION_OFF; break;
522 case 1: v = INVERSION_ON; break;
523 default: v = INVERSION_AUTO; break;
525 return dvb_set_prop (d, DTV_INVERSION, v);
528 int dvb_tune (dvb_device_t *d)
530 return dvb_set_prop (d, DTV_TUNE, 0 /* dummy */);
535 int dvb_set_dvbc (dvb_device_t *d, uint32_t freq, const char *modstr,
536 uint32_t srate, uint32_t fec)
538 unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
539 fec = dvb_parse_fec (fec);
541 return dvb_set_props (d, 6, DTV_CLEAR, 0,
542 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_AC,
543 DTV_FREQUENCY, freq * 1000, DTV_MODULATION, mod,
544 DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec);
549 static unsigned dvb_parse_polarization (char pol)
551 static const dvb_int_map_t tab[5] = {
552 { 0, SEC_VOLTAGE_OFF },
553 { 'H', SEC_VOLTAGE_18 },
554 { 'L', SEC_VOLTAGE_18 },
555 { 'R', SEC_VOLTAGE_13 },
556 { 'V', SEC_VOLTAGE_13 },
558 return dvb_parse_int (pol, tab, 5, SEC_VOLTAGE_OFF);
561 int dvb_set_sec (dvb_device_t *d, uint32_t freq, char pol,
562 uint32_t lowf, uint32_t highf, uint32_t switchf)
564 /* Always try to configure high voltage, but only warn on enable failure */
565 int val = var_InheritBool (d->obj, "dvb-high-voltage");
566 if (ioctl (d->frontend, FE_ENABLE_HIGH_LNB_VOLTAGE, &val) < 0 && val)
567 msg_Err (d->obj, "cannot enable high LNB voltage: %m");
569 /* Windows BDA exposes a higher-level API covering LNB oscillators.
570 * So lets pretend this is platform-specific stuff and do it here. */
572 { /* Default oscillator frequencies */
575 uint16_t min, max, low, high;
577 { /* min max low high */
578 { 10700, 13250, 9750, 10600 }, /* Ku band */
579 { 4500, 4800, 5950, 0 }, /* C band (high) */
580 { 3400, 4200, 5150, 0 }, /* C band (low) */
581 { 2500, 2700, 3650, 0 }, /* S band */
582 { 950, 2150, 0, 0 }, /* adjusted IF (L band) */
584 uint_fast16_t mhz = freq / 1000;
586 for (size_t i = 0; i < sizeof (tab) / sizeof (tab[0]); i++)
587 if (mhz >= tab[i].min && mhz <= tab[i].max)
589 lowf = tab[i].low * 1000;
590 highf = tab[i].high * 1000;
594 msg_Err (d->obj, "no known band for frequency %u kHz", freq);
596 msg_Dbg (d->obj, "selected LNB low: %u kHz, LNB high: %u kHz",
600 /* Use high oscillator frequency? */
601 bool high = highf != 0 && freq > switchf;
603 freq -= high ? highf : lowf;
604 if ((int32_t)freq < 0)
606 assert (freq < 0x7fffffff);
609 switch (var_InheritInteger (d->obj, "dvb-tone"))
611 case 0: tone = SEC_TONE_OFF; break;
612 case 1: tone = SEC_TONE_ON; break;
613 default: tone = high ? SEC_TONE_ON : SEC_TONE_OFF;
616 /*** LNB selection / DiSEqC ***/
617 unsigned voltage = dvb_parse_polarization (pol);
618 if (dvb_set_props (d, 2, DTV_TONE, SEC_TONE_OFF, DTV_VOLTAGE, voltage))
621 unsigned satno = var_InheritInteger (d->obj, "dvb-satno");
625 #undef msleep /* we know what we are doing! */
626 struct dvb_diseqc_master_cmd cmd;
628 satno = (satno - 1) & 3;
629 cmd.msg[0] = 0xE0; /* framing: master, no reply, 1st TX */
630 cmd.msg[1] = 0x10; /* address: all LNB/switch */
631 cmd.msg[2] = 0x38; /* command: Write Port Group 0 */
632 cmd.msg[3] = 0xF0 /* data[0]: clear all bits */
633 | (satno << 2) /* LNB (A, B, C or D) */
634 | ((voltage == SEC_VOLTAGE_18) << 1) /* polarization */
635 | (tone == SEC_TONE_ON); /* option */
636 cmd.msg[4] = cmd.msg[5] = 0; /* unused */
637 msleep (15000); /* wait 15 ms before DiSEqC command */
638 if (ioctl (d->frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) < 0)
640 msg_Err (d->obj, "cannot send DiSEqC command: %m");
643 msleep (54000 + 15000);
647 if (ioctl (d->frontend, FE_DISEQC_SEND_BURST,
648 satno ? SEC_MINI_B : SEC_MINI_A) < 0)
650 msg_Err (d->obj, "cannot send Mini-DiSEqC tone burst: %m");
656 /* Continuous tone (to select high oscillator frequency) */
657 return dvb_set_props (d, 2, DTV_FREQUENCY, freq, DTV_TONE, tone);
660 int dvb_set_dvbs (dvb_device_t *d, uint32_t freq, uint32_t srate, uint32_t fec)
662 fec = dvb_parse_fec (fec);
664 return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS,
665 DTV_FREQUENCY, freq, DTV_SYMBOL_RATE, srate,
669 int dvb_set_dvbs2 (dvb_device_t *d, uint32_t freq, const char *modstr,
670 uint32_t srate, uint32_t fec, int pilot, int rolloff)
672 unsigned mod = dvb_parse_modulation (modstr, QPSK);
673 fec = dvb_parse_fec (fec);
677 case 0: pilot = PILOT_OFF; break;
678 case 1: pilot = PILOT_ON; break;
679 default: pilot = PILOT_AUTO; break;
684 case 20: rolloff = ROLLOFF_20; break;
685 case 25: rolloff = ROLLOFF_25; break;
686 case 35: rolloff = ROLLOFF_35; break;
687 default: rolloff = PILOT_AUTO; break;
690 return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS2,
691 DTV_FREQUENCY, freq, DTV_MODULATION, mod,
692 DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec,
693 DTV_PILOT, pilot, DTV_ROLLOFF, rolloff);
698 static int dvb_parse_transmit_mode (int i)
700 static const dvb_int_map_t tab[] = {
701 { -1, TRANSMISSION_MODE_AUTO },
702 { 2, TRANSMISSION_MODE_2K },
704 { 4, TRANSMISSION_MODE_4K },
706 { 8, TRANSMISSION_MODE_8K },
708 { 16, TRANSMISSION_MODE_16K },
709 { 32, TRANSMISSION_MODE_32K },
712 return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
713 TRANSMISSION_MODE_AUTO);
716 static int dvb_parse_guard (uint32_t guard)
718 static const dvb_int_map_t tab[] = {
719 /*{ VLC_GUARD(1,128), GUARD_INTERVAL_1_128 },*/
720 { VLC_GUARD(1,16), GUARD_INTERVAL_1_16 },
721 { VLC_GUARD(1,32), GUARD_INTERVAL_1_32 },
722 { VLC_GUARD(1,4), GUARD_INTERVAL_1_4 },
723 { VLC_GUARD(1,8), GUARD_INTERVAL_1_8 },
724 /*{ VLC_GUARD(19,128), GUARD_INTERVAL_19_128 },*/
725 /*{ VLC_GUARD(9,256), GUARD_INTERVAL_9_256 },*/
726 { VLC_GUARD_AUTO, GUARD_INTERVAL_AUTO },
728 return dvb_parse_int (guard, tab, sizeof (tab) / sizeof (*tab),
729 GUARD_INTERVAL_AUTO);
732 static int dvb_parse_hierarchy (int i)
734 static const dvb_int_map_t tab[] = {
735 { HIERARCHY_AUTO, -1 },
736 { HIERARCHY_NONE, 0 },
741 return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
745 int dvb_set_dvbt (dvb_device_t *d, uint32_t freq, const char *modstr,
746 uint32_t fec_hp, uint32_t fec_lp, uint32_t bandwidth,
747 int transmit_mode, uint32_t guard, int hierarchy)
749 uint32_t mod = dvb_parse_modulation (modstr, QAM_AUTO);
750 fec_hp = dvb_parse_fec (fec_hp);
751 fec_lp = dvb_parse_fec (fec_lp);
752 bandwidth *= 1000000;
753 transmit_mode = dvb_parse_transmit_mode (transmit_mode);
754 guard = dvb_parse_guard (guard);
755 hierarchy = dvb_parse_hierarchy (hierarchy);
757 return dvb_set_props (d, 10, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT,
758 DTV_FREQUENCY, freq * 1000, DTV_MODULATION, mod,
759 DTV_CODE_RATE_HP, fec_hp, DTV_CODE_RATE_LP, fec_lp,
760 DTV_BANDWIDTH_HZ, bandwidth,
761 DTV_TRANSMISSION_MODE, transmit_mode,
762 DTV_GUARD_INTERVAL, guard,
763 DTV_HIERARCHY, hierarchy);
768 int dvb_set_atsc (dvb_device_t *d, uint32_t freq, const char *modstr)
770 unsigned mod = dvb_parse_modulation (modstr, VSB_8);
772 return dvb_set_props (d, 4, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ATSC,
773 DTV_FREQUENCY, freq * 1000, DTV_MODULATION, mod);
776 int dvb_set_cqam (dvb_device_t *d, uint32_t freq, const char *modstr)
778 unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
780 return dvb_set_props (d, 4, DTV_CLEAR, 0,
781 DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_B,
782 DTV_FREQUENCY, freq * 1000, DTV_MODULATION, mod);