]> git.sesse.net Git - vlc/blob - modules/access/dtv/linux.c
Linux DVB: drop support for API version 5.0
[vlc] / modules / access / dtv / linux.c
1 /**
2  * @file linux.c
3  * @brief Linux DVB API version 5
4  */
5 /*****************************************************************************
6  * Copyright © 2011 Rémi Denis-Courmont
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program 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 Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <vlc_common.h>
28 #include <vlc_fs.h>
29
30 #include <errno.h>
31 #include <assert.h>
32 #include <fcntl.h>
33 #include <poll.h>
34 #include <unistd.h>
35 #include <sys/ioctl.h>
36 #include <linux/dvb/version.h>
37 #include <linux/dvb/frontend.h>
38 #include <linux/dvb/dmx.h>
39
40 #include "dtv/dtv.h"
41 #ifdef HAVE_DVBPSI
42 # include "dtv/en50221.h"
43 #endif
44
45 #ifndef O_SEARCH
46 # define O_SEARCH O_RDONLY
47 #endif
48
49 #define DVBv5(minor) \
50         (DVB_API_VERSION > 5 \
51      || (DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= (minor)))
52
53 /** Opens the device directory for the specified DVB adapter */
54 static int dvb_open_adapter (uint8_t adapter)
55 {
56     char dir[20];
57
58     snprintf (dir, sizeof (dir), "/dev/dvb/adapter%"PRIu8, adapter);
59     return vlc_open (dir, O_SEARCH|O_DIRECTORY);
60 }
61
62 /** Opens the DVB device node of the specified type */
63 static int dvb_open_node (int dir, const char *type, unsigned dev, int flags)
64 {
65     int fd;
66     char path[strlen (type) + 4];
67
68     snprintf (path, sizeof (path), "%s%u", type, dev);
69     fd = vlc_openat (dir, path, flags);
70     if (fd != -1)
71         fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK);
72     return fd;
73 }
74
75 typedef struct
76 {
77     int vlc;
78     int linux_;
79 } dvb_int_map_t;
80
81 static int icmp (const void *a, const void *b)
82 {
83     int key = (intptr_t)a;
84     const dvb_int_map_t *entry = b;
85     return key - entry->vlc;
86 }
87
88 /** Maps a VLC config integer to a Linux DVB enum value */
89 static int dvb_parse_int (int i, const dvb_int_map_t *map, size_t n, int def)
90 {
91     const void *k = (const void *)(intptr_t)i;
92     const dvb_int_map_t *p = bsearch (k, map, n, sizeof (*map), icmp);
93     return (p != NULL) ? p->linux_ : def;
94 }
95
96 typedef const struct
97 {
98     char vlc[8];
99     int linux_;
100 } dvb_str_map_t;
101
102 static int scmp (const void *a, const void *b)
103 {
104     const char *key = a;
105     dvb_str_map_t *entry = b;
106     return strcmp (key, entry->vlc);
107 }
108
109 /** Maps a VLC config string to a Linux DVB enum value */
110 static int dvb_parse_str (const char *str, const dvb_str_map_t *map, size_t n,
111                           int def)
112 {
113     if (str != NULL)
114     {
115         const dvb_str_map_t *p = bsearch (str, map, n, sizeof (*map), scmp);
116         if (p != NULL)
117             def = p->linux_;
118     }
119     return def;
120 }
121
122 /*** Modulations ***/
123 static int dvb_parse_modulation (const char *str, int def)
124 {
125     static const dvb_str_map_t mods[] =
126     {
127         { "128QAM",  QAM_128  },
128         { "16APSK", APSK_16   },
129         { "16QAM",   QAM_16   },
130         { "16VSB",   VSB_16   },
131         { "256QAM",  QAM_256  },
132         { "32APSK", APSK_32   },
133         { "32QAM",   QAM_32   },
134         { "64QAM",   QAM_64   },
135         { "8PSK",    PSK_8    }, 
136         { "8VSB",    VSB_8    },
137         { "DQPSK", DQPSK      },
138         { "QAM",     QAM_AUTO },
139         { "QPSK",   QPSK      },
140     };
141     return dvb_parse_str (str, mods, sizeof (mods) / sizeof (*mods), def);
142 }
143
144 static int dvb_parse_fec (uint32_t fec)
145 {
146     static const dvb_int_map_t rates[] =
147     {
148         { 0,             FEC_NONE },
149         { VLC_FEC(1,2),  FEC_1_2  },
150         // TODO: 1/3
151         // TODO: 1/4
152         { VLC_FEC(2,3),  FEC_2_3  },
153         { VLC_FEC(3,4),  FEC_3_4  },
154         { VLC_FEC(3,5),  FEC_3_5  },
155         { VLC_FEC(4,5),  FEC_4_5  },
156         { VLC_FEC(5,6),  FEC_5_6  },
157         { VLC_FEC(6,7),  FEC_6_7  },
158         { VLC_FEC(7,8),  FEC_7_8  },
159         { VLC_FEC(8,9),  FEC_8_9  },
160         { VLC_FEC(9,10), FEC_9_10 },
161         { VLC_FEC_AUTO,  FEC_AUTO },
162     };
163     return dvb_parse_int (fec, rates, sizeof (rates) / sizeof (*rates),
164                           FEC_AUTO);
165 }
166
167
168 struct dvb_device
169 {
170     vlc_object_t *obj;
171     int dir;
172     int demux;
173     int frontend;
174 #ifndef USE_DMX
175 # define MAX_PIDS 256
176     struct
177     {
178         int fd;
179         uint16_t pid;
180     } pids[MAX_PIDS];
181 #endif
182 #ifdef HAVE_DVBPSI
183     cam_t *cam;
184 #endif
185     unsigned systems;
186     bool budget;
187     //size_t buffer_size;
188 };
189
190 /**
191  * Opens the DVB tuner
192  */
193 dvb_device_t *dvb_open (vlc_object_t *obj)
194 {
195     dvb_device_t *d = malloc (sizeof (*d));
196     if (unlikely(d == NULL))
197         return NULL;
198
199     d->obj = obj;
200
201     uint8_t adapter = var_InheritInteger (obj, "dvb-adapter");
202
203     d->dir = dvb_open_adapter (adapter);
204     if (d->dir == -1)
205     {
206         msg_Err (obj, "cannot access adapter %"PRIu8": %m", adapter);
207         free (d);
208         return NULL;
209     }
210     d->frontend = -1;
211 #ifdef HAVE_DVBPSI
212     d->cam = NULL;
213 #endif
214     d->budget = var_InheritBool (obj, "dvb-budget-mode");
215
216 #ifndef USE_DMX
217     if (d->budget)
218 #endif
219     {
220        d->demux = dvb_open_node (d->dir, "demux", 0, O_RDONLY);
221        if (d->demux == -1)
222        {
223            msg_Err (obj, "cannot access demultiplexer: %m");
224            close (d->dir);
225            free (d);
226            return NULL;
227        }
228
229        if (ioctl (d->demux, DMX_SET_BUFFER_SIZE, 1 << 20) < 0)
230            msg_Warn (obj, "cannot expand demultiplexing buffer: %m");
231
232        /* We need to filter at least one PID. The tap for TS demultiplexing
233         * cannot be configured otherwise. So add the PAT. */
234         struct dmx_pes_filter_params param;
235
236         param.pid = d->budget ? 0x2000 : 0x000;
237         param.input = DMX_IN_FRONTEND;
238         param.output = DMX_OUT_TSDEMUX_TAP;
239         param.pes_type = DMX_PES_OTHER;
240         param.flags = DMX_IMMEDIATE_START;
241         if (ioctl (d->demux, DMX_SET_PES_FILTER, &param) < 0)
242         {
243             msg_Err (obj, "cannot setup TS demultiplexer: %m");
244             goto error;
245         }
246 #ifndef USE_DMX
247     }
248     else
249     {
250         for (size_t i = 0; i < MAX_PIDS; i++)
251             d->pids[i].pid = d->pids[i].fd = -1;
252         d->demux = dvb_open_node (d->dir, "dvr", 0, O_RDONLY);
253         if (d->demux == -1)
254         {
255             msg_Err (obj, "cannot access DVR: %m");
256             close (d->dir);
257             free (d);
258             return NULL;
259         }
260 #endif
261     }
262
263 #ifdef HAVE_DVBPSI
264     int ca = dvb_open_node (d->dir, "ca", 0, O_RDWR);
265     if (ca != -1)
266     {
267         d->cam = en50221_Init (obj, ca);
268         if (d->cam == NULL)
269             close (ca);
270     }
271     else
272         msg_Dbg (obj, "conditional access module not available (%m)");
273 #endif
274     return d;
275
276 error:
277     dvb_close (d);
278     return NULL;
279 }
280
281 void dvb_close (dvb_device_t *d)
282 {
283 #ifndef USE_DMX
284     if (!d->budget)
285     {
286         for (size_t i = 0; i < MAX_PIDS; i++)
287             if (d->pids[i].fd != -1)
288                 close (d->pids[i].fd);
289     }
290 #endif
291 #ifdef HAVE_DVBPSI
292     if (d->cam != NULL)
293         en50221_End (d->cam);
294 #endif
295     if (d->frontend != -1)
296         close (d->frontend);
297     close (d->demux);
298     close (d->dir);
299     free (d);
300 }
301
302 /**
303  * Reads TS data from the tuner.
304  * @return number of bytes read, 0 on EOF, -1 if no data (yet).
305  */
306 ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len)
307 {
308     struct pollfd ufd[2];
309     int n;
310
311 #ifdef HAVE_DVBPSI
312     if (d->cam != NULL)
313         en50221_Poll (d->cam);
314 #endif
315
316     ufd[0].fd = d->demux;
317     ufd[0].events = POLLIN;
318     if (d->frontend != -1)
319     {
320         ufd[1].fd = d->frontend;
321         ufd[1].events = POLLIN;
322         n = 2;
323     }
324     else
325         n = 1;
326
327     if (poll (ufd, n, 500 /* FIXME */) < 0)
328         return -1;
329
330     if (d->frontend != -1 && ufd[1].revents)
331     {
332         struct dvb_frontend_event ev;
333
334         if (ioctl (d->frontend, FE_GET_EVENT, &ev) < 0)
335         {
336             if (errno == EOVERFLOW)
337             {
338                 msg_Err (d->obj, "cannot dequeue events fast enough!");
339                 return -1;
340             }
341             msg_Err (d->obj, "cannot dequeue frontend event: %m");
342             return 0;
343         }
344
345         msg_Dbg (d->obj, "frontend status: 0x%02X", (unsigned)ev.status);
346     }
347
348     if (ufd[0].revents)
349     {
350         ssize_t val = read (d->demux, buf, len);
351         if (val == -1 && (errno != EAGAIN && errno != EINTR))
352         {
353             if (errno == EOVERFLOW)
354             {
355                 msg_Err (d->obj, "cannot demux data fast enough!");
356                 return -1;
357             }
358             msg_Err (d->obj, "cannot demux: %m");
359             return 0;
360         }
361         return val;
362     }
363
364     return -1;
365 }
366
367 int dvb_add_pid (dvb_device_t *d, uint16_t pid)
368 {
369     if (d->budget)
370         return 0;
371 #ifdef USE_DMX
372     if (pid == 0 || ioctl (d->demux, DMX_ADD_PID, &pid) >= 0)
373         return 0;
374 #else
375     for (size_t i = 0; i < MAX_PIDS; i++)
376     {
377         if (d->pids[i].pid == pid)
378             return 0;
379         if (d->pids[i].fd != -1)
380             continue;
381
382         int fd = dvb_open_node (d->dir, "demux", 0, O_RDONLY);
383         if (fd == -1)
384             goto error;
385
386        /* We need to filter at least one PID. The tap for TS demultiplexing
387         * cannot be configured otherwise. So add the PAT. */
388         struct dmx_pes_filter_params param;
389
390         param.pid = pid;
391         param.input = DMX_IN_FRONTEND;
392         param.output = DMX_OUT_TS_TAP;
393         param.pes_type = DMX_PES_OTHER;
394         param.flags = DMX_IMMEDIATE_START;
395         if (ioctl (fd, DMX_SET_PES_FILTER, &param) < 0)
396         {
397             close (fd);
398             goto error;
399         }
400         d->pids[i].fd = fd;
401         d->pids[i].pid = pid;
402         return 0;
403     }
404     errno = EMFILE;
405 error:
406 #endif
407     msg_Err (d->obj, "cannot add PID 0x%04"PRIu16": %m", pid);
408     return -1;
409 }
410
411 void dvb_remove_pid (dvb_device_t *d, uint16_t pid)
412 {
413     if (d->budget)
414         return;
415 #ifdef USE_DMX
416     if (pid != 0)
417         ioctl (d->demux, DMX_REMOVE_PID, &pid);
418 #else
419     for (size_t i = 0; i < MAX_PIDS; i++)
420     {
421         if (d->pids[i].pid == pid)
422         {
423             close (d->pids[i].fd);
424             d->pids[i].pid = d->pids[i].fd = -1;
425             return;
426         }
427     }
428 #endif
429 }
430
431 /** Enumerates the systems supported by one frontend */
432 static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
433 {
434 #if DVBv5(5)
435     struct dtv_property prop[2] = {
436         { .cmd = DTV_API_VERSION },
437         { .cmd = DTV_ENUM_DELSYS },
438     };
439     struct dtv_properties props = {
440         .num = 2,
441         .props = prop
442     };
443
444     if (ioctl (fd, FE_GET_PROPERTY, &props) < 0)
445     {
446          msg_Err (d->obj, "cannot enumerate frontend systems: %m");
447          goto legacy;
448     }
449
450     static const unsigned systab[] = {
451         [SYS_UNDEFINED]    = 0,
452         [SYS_DVBC_ANNEX_A] = DVB_C,
453         [SYS_DVBC_ANNEX_B] = CQAM,
454         [SYS_DVBT]         = DVB_T,
455         //[SYS_DSS]
456         [SYS_DVBS]         = DVB_S,
457         [SYS_DVBS2]        = DVB_S2,
458         //[SYS_DVBH]
459         [SYS_ISDBT]        = ISDB_T,
460         [SYS_ISDBS]        = ISDB_S,
461         [SYS_ISDBC]        = ISDB_C, // no drivers exist (as of 3.3-rc6)
462         [SYS_ATSC]         = ATSC,
463         //[SYS_ATSCMH]
464         //[SYS_DMBTH]
465         //[SYS_CMMB]
466         //[SYS_DAB]
467         [SYS_DVBT2]        = DVB_T2,
468         //[SYS_TURBO]
469         [SYS_DVBC_ANNEX_C] = ISDB_C, // another name for ISDB-C?
470     };
471     unsigned systems = 0;
472
473     msg_Dbg (d->obj, "probing frontend (kernel API v%u.%u, user API v%u.%u)",
474              prop[0].u.data >> 8, prop[0].u.data & 0xFF,
475              DVB_API_VERSION, DVB_API_VERSION_MINOR);
476
477     for (size_t i = 0; i < prop[1].u.buffer.len; i++)
478     {
479         unsigned sys = prop[1].u.buffer.data[i];
480
481         if (sys >= (sizeof (systab) / sizeof (systab[0])) || !systab[sys])
482         {
483             msg_Warn (d->obj, "unknown delivery system %u", sys);
484             continue;
485         }
486         msg_Dbg (d->obj, " system %u", sys);
487         systems |= systab[sys];
488     }
489
490     return systems;
491 legacy:
492     props.num = 1;
493 #else
494     struct dtv_property prop[1] = {
495         { .cmd = DTV_API_VERSION },
496     };
497     struct dtv_properties props = {
498         .num = 1,
499         .props = prop
500     };
501     unsigned systems = 0;
502 #endif
503     if (ioctl (fd, FE_GET_PROPERTY, &props) < 0)
504     {
505         msg_Err (d->obj, "unsupported kernel DVB version 3 or older (%m)");
506         return 0;
507     }
508
509     msg_Dbg (d->obj, "probing frontend (kernel API v%u.%u, user API v%u.%u)",
510              prop[0].u.data >> 8, prop[0].u.data & 0xFF,
511              DVB_API_VERSION, DVB_API_VERSION_MINOR);
512 #if !DVBv5(5)
513     /* Some delivery systems cannot be detected without the DVB API v5.5.
514      * To run correctly on recent kernels (Linux >= 3.3),
515      * VLC needs to be compiled with up-to-date kernel headers. */
516     if ((prop[0].u.data >> 8) > 5
517      || ((prop[0].u.data >> 8) == 5 && (prop[0].u.data & 0xFF) >= 5))
518         msg_Err (d->obj, "obsolete user API version running on a new kernel");
519         msg_Info (d->obj, "please recompile "PACKAGE_NAME" "PACKAGE_VERSION);
520 #endif
521     struct dvb_frontend_info info;
522     if (ioctl (fd, FE_GET_INFO, &info) < 0)
523     {
524         msg_Err (d->obj, "cannot get frontend info: %m");
525         return 0;
526     }
527     msg_Dbg (d->obj, " name %s", info.name);
528     msg_Dbg (d->obj, " type %u, capabilities 0x%08X", info.type, info.caps);
529     msg_Dbg (d->obj, " frequencies %10"PRIu32" to %10"PRIu32,
530              info.frequency_min, info.frequency_max);
531     msg_Dbg (d->obj, " (%"PRIu32" tolerance, %"PRIu32" per step)",
532              info.frequency_tolerance, info.frequency_stepsize);
533     msg_Dbg (d->obj, " bauds rates %10"PRIu32" to %10"PRIu32,
534              info.symbol_rate_min, info.symbol_rate_max);
535     msg_Dbg (d->obj, " (%"PRIu32" tolerance)", info.symbol_rate_tolerance);
536
537     /* DVB first generation and ATSC */
538     switch (info.type)
539     {
540         case FE_QPSK: systems = DVB_S; break;
541         case FE_QAM:  systems = DVB_C; break;
542         case FE_OFDM: systems = DVB_T; break;
543         case FE_ATSC: systems = ATSC | CQAM; break;
544         default:
545             msg_Err (d->obj, "unknown frontend type %u", info.type);
546     }
547
548     /* DVB 2nd generation */
549     switch (info.type)
550     {
551         case FE_QPSK:
552         case FE_QAM:
553         case FE_OFDM:
554             if (info.caps & FE_CAN_2G_MODULATION)
555                 systems |= systems << 1; /* DVB_foo -> DVB_foo|DVB_foo2 */
556         default:
557             break;
558     }
559
560     /* ISDB (only terrestrial before DVBv5.5)  */
561     if (info.type == FE_OFDM)
562         systems |= ISDB_T;
563
564     return systems;
565 }
566
567 /** Finds a frontend of the correct type */
568 static int dvb_find_frontend (dvb_device_t *d, unsigned system)
569 {
570     if (d->frontend != -1)
571     {
572         if (d->systems & system)
573             return 0; /* already got an adequate frontend */
574
575         close (d->frontend);
576         d->frontend = -1;
577     }
578
579     for (unsigned n = 0; n < 256; n++)
580     {
581         int fd = dvb_open_node (d->dir, "frontend", n, O_RDWR);
582         if (fd == -1)
583         {
584             if (errno == ENOENT)
585                 break; /* all frontends already enumerated */
586             msg_Err (d->obj, "cannot access frontend %u: %m", n);
587             continue;
588         }
589
590         d->systems = dvb_probe_frontend (d, fd);
591         if (d->systems & system)
592         {
593             msg_Dbg (d->obj, "selected frontend %u", n);
594             d->frontend = fd;
595             return 0;
596         }
597
598         msg_Dbg (d->obj, "skipping frontend %u: wrong type", n);
599         close (fd);
600     }
601
602     msg_Err (d->obj, "no suitable frontend found");
603     return -1;
604 }
605
606 /**
607  * Detects supported delivery systems.
608  * @return a bit mask of supported systems (zero on failure)
609  */
610 unsigned dvb_enum_systems (dvb_device_t *d)
611 {
612     unsigned systems = 0;
613
614     for (unsigned n = 0; n < 256; n++)
615     {
616         int fd = dvb_open_node (d->dir, "frontend", n, O_RDWR);
617         if (fd == -1)
618         {
619             if (errno == ENOENT)
620                 break; /* all frontends already enumerated */
621             msg_Err (d->obj, "cannot access frontend %u; %m", n);
622             continue;
623         }
624
625         systems |= dvb_probe_frontend (d, fd);
626         close (fd);
627     }
628     return systems;
629 }
630
631 float dvb_get_signal_strength (dvb_device_t *d)
632 {
633     uint16_t strength;
634
635     if (ioctl (d->frontend, FE_READ_SIGNAL_STRENGTH, &strength) < 0)
636         return 0.;
637     return strength / 65535.;
638 }
639
640 float dvb_get_snr (dvb_device_t *d)
641 {
642     uint16_t snr;
643
644     if (ioctl (d->frontend, FE_READ_SNR, &snr) < 0)
645         return 0.;
646     return snr / 65535.;
647 }
648
649 #ifdef HAVE_DVBPSI
650 void dvb_set_ca_pmt (dvb_device_t *d, struct dvbpsi_pmt_s *pmt)
651 {
652     if (d->cam != NULL)
653         en50221_SetCAPMT (d->cam, pmt);
654 }
655 #endif
656
657 static int dvb_vset_props (dvb_device_t *d, size_t n, va_list ap)
658 {
659     assert (n <= DTV_IOCTL_MAX_MSGS);
660
661     struct dtv_property buf[n], *prop = buf;
662     struct dtv_properties props = { .num = n, .props = buf };
663
664     memset (prop, 0, sizeof (prop));
665
666     while (n > 0)
667     {
668         prop->cmd = va_arg (ap, uint32_t);
669         prop->u.data = va_arg (ap, uint32_t);
670         msg_Dbg (d->obj, "setting property %2"PRIu32" to %"PRIu32,
671                  prop->cmd, prop->u.data);
672         prop++;
673         n--;
674     }
675
676     if (ioctl (d->frontend, FE_SET_PROPERTY, &props) < 0)
677     {
678         msg_Err (d->obj, "cannot set frontend tuning parameters: %m");
679         return -1;
680     }
681     return 0;
682 }
683
684 static int dvb_set_props (dvb_device_t *d, size_t n, ...)
685 {
686     va_list ap;
687     int ret;
688
689     va_start (ap, n);
690     ret = dvb_vset_props (d, n, ap);
691     va_end (ap);
692     return ret;
693 }
694
695 static int dvb_set_prop (dvb_device_t *d, uint32_t prop, uint32_t val)
696 {
697     return dvb_set_props (d, 1, prop, val);
698 }
699
700 int dvb_set_inversion (dvb_device_t *d, int v)
701 {
702     switch (v)
703     {
704         case 0:  v = INVERSION_OFF;  break;
705         case 1:  v = INVERSION_ON;   break;
706         default: v = INVERSION_AUTO; break;
707     }
708     return dvb_set_prop (d, DTV_INVERSION, v);
709 }
710
711 int dvb_tune (dvb_device_t *d)
712 {
713     return dvb_set_prop (d, DTV_TUNE, 0 /* dummy */);
714 }
715
716
717 /*** DVB-C ***/
718 int dvb_set_dvbc (dvb_device_t *d, uint32_t freq, const char *modstr,
719                   uint32_t srate, uint32_t fec)
720 {
721     unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
722     fec = dvb_parse_fec (fec);
723
724     if (dvb_find_frontend (d, DVB_C))
725         return -1;
726     return dvb_set_props (d, 6, DTV_CLEAR, 0,
727 #if DVBv5(5)
728                           DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_A,
729 #else
730                           DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_AC,
731 #endif
732                           DTV_FREQUENCY, freq, DTV_MODULATION, mod,
733                           DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec);
734 }
735
736
737 /*** DVB-S ***/
738 static unsigned dvb_parse_polarization (char pol)
739 {
740     static const dvb_int_map_t tab[5] = {
741         { 0,   SEC_VOLTAGE_OFF },
742         { 'H', SEC_VOLTAGE_18  },
743         { 'L', SEC_VOLTAGE_18  },
744         { 'R', SEC_VOLTAGE_13  },
745         { 'V', SEC_VOLTAGE_13  },
746     };
747     return dvb_parse_int (pol, tab, 5, SEC_VOLTAGE_OFF);
748 }
749
750 int dvb_set_sec (dvb_device_t *d, uint64_t freq_Hz, char pol,
751                  uint32_t lowf, uint32_t highf, uint32_t switchf)
752 {
753     uint32_t freq = freq_Hz / 1000;
754
755     /* Always try to configure high voltage, but only warn on enable failure */
756     int val = var_InheritBool (d->obj, "dvb-high-voltage");
757     if (ioctl (d->frontend, FE_ENABLE_HIGH_LNB_VOLTAGE, &val) < 0 && val)
758         msg_Err (d->obj, "cannot enable high LNB voltage: %m");
759
760     /* Windows BDA exposes a higher-level API covering LNB oscillators.
761      * So lets pretend this is platform-specific stuff and do it here. */
762     if (!lowf)
763     {   /* Default oscillator frequencies */
764         static const struct
765         {
766              uint16_t min, max, low, high;
767         } tab[] =
768         {    /*  min    max    low   high */
769              { 10700, 13250,  9750, 10600 }, /* Ku band */
770              {  4500,  4800,  5950,     0 }, /* C band (high) */
771              {  3400,  4200,  5150,     0 }, /* C band (low) */
772              {  2500,  2700,  3650,     0 }, /* S band */
773              {   950,  2150,     0,     0 }, /* adjusted IF (L band) */
774         };
775         uint_fast16_t mHz = freq / 1000;
776
777         for (size_t i = 0; i < sizeof (tab) / sizeof (tab[0]); i++)
778              if (mHz >= tab[i].min && mHz <= tab[i].max)
779              {
780                  lowf = tab[i].low * 1000;
781                  highf = tab[i].high * 1000;
782                  goto known;
783              }
784
785         msg_Err (d->obj, "no known band for frequency %u kHz", freq);
786 known:
787         msg_Dbg (d->obj, "selected LNB low: %u kHz, LNB high: %u kHz",
788                  lowf, highf);
789     }
790
791     /* Use high oscillator frequency? */
792     bool high = highf != 0 && freq > switchf;
793
794     freq -= high ? highf : lowf;
795     if ((int32_t)freq < 0)
796         freq *= -1;
797     assert (freq < 0x7fffffff);
798
799     int tone;
800     switch (var_InheritInteger (d->obj, "dvb-tone"))
801     {
802         case 0:  tone = SEC_TONE_OFF; break;
803         case 1:  tone = SEC_TONE_ON;  break;
804         default: tone = high ? SEC_TONE_ON : SEC_TONE_OFF;
805     }
806
807     /*** LNB selection / DiSEqC ***/
808     unsigned voltage = dvb_parse_polarization (pol);
809     if (dvb_set_props (d, 2, DTV_TONE, SEC_TONE_OFF, DTV_VOLTAGE, voltage))
810         return -1;
811
812     unsigned satno = var_InheritInteger (d->obj, "dvb-satno");
813     if (satno > 0)
814     {
815         /* DiSEqC 1.0 */
816 #undef msleep /* we know what we are doing! */
817         struct dvb_diseqc_master_cmd cmd;
818
819         satno = (satno - 1) & 3;
820         cmd.msg[0] = 0xE0; /* framing: master, no reply, 1st TX */
821         cmd.msg[1] = 0x10; /* address: all LNB/switch */
822         cmd.msg[2] = 0x38; /* command: Write Port Group 0 */
823         cmd.msg[3] = 0xF0  /* data[0]: clear all bits */
824                    | (satno << 2) /* LNB (A, B, C or D) */
825                    | ((voltage == SEC_VOLTAGE_18) << 1) /* polarization */
826                    | (tone == SEC_TONE_ON); /* option */
827         cmd.msg[4] = cmd.msg[5] = 0; /* unused */
828         msleep (15000); /* wait 15 ms before DiSEqC command */
829         if (ioctl (d->frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) < 0)
830         {
831             msg_Err (d->obj, "cannot send DiSEqC command: %m");
832             return -1;
833         }
834         msleep (54000 + 15000);
835
836         /* Mini-DiSEqC */
837         satno &= 1;
838         if (ioctl (d->frontend, FE_DISEQC_SEND_BURST,
839                    satno ? SEC_MINI_B : SEC_MINI_A) < 0)
840         {
841             msg_Err (d->obj, "cannot send Mini-DiSEqC tone burst: %m");
842             return -1;
843         }
844         msleep (15000);
845     }
846
847     /* Continuous tone (to select high oscillator frequency) */
848     return dvb_set_props (d, 2, DTV_FREQUENCY, freq, DTV_TONE, tone);
849 }
850
851 int dvb_set_dvbs (dvb_device_t *d, uint64_t freq_Hz,
852                   uint32_t srate, uint32_t fec)
853 {
854     uint32_t freq = freq_Hz / 1000;
855     fec = dvb_parse_fec (fec);
856
857     if (dvb_find_frontend (d, DVB_S))
858         return -1;
859     return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS,
860                           DTV_FREQUENCY, freq, DTV_SYMBOL_RATE, srate,
861                           DTV_INNER_FEC, fec);
862 }
863
864 int dvb_set_dvbs2 (dvb_device_t *d, uint64_t freq_Hz, const char *modstr,
865                    uint32_t srate, uint32_t fec, int pilot, int rolloff)
866 {
867     uint32_t freq = freq_Hz / 1000;
868     unsigned mod = dvb_parse_modulation (modstr, QPSK);
869     fec = dvb_parse_fec (fec);
870
871     switch (pilot)
872     {
873         case 0:  pilot = PILOT_OFF;  break;
874         case 1:  pilot = PILOT_ON;   break;
875         default: pilot = PILOT_AUTO; break;
876     }
877
878     switch (rolloff)
879     {
880         case 20: rolloff = ROLLOFF_20;  break;
881         case 25: rolloff = ROLLOFF_25;  break;
882         case 35: rolloff = ROLLOFF_35;  break;
883         default: rolloff = PILOT_AUTO; break;
884     }
885
886     if (dvb_find_frontend (d, DVB_S2))
887         return -1;
888     return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS2,
889                           DTV_FREQUENCY, freq, DTV_MODULATION, mod,
890                           DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec,
891                           DTV_PILOT, pilot, DTV_ROLLOFF, rolloff);
892 }
893
894
895 /*** DVB-T ***/
896 static uint32_t dvb_parse_bandwidth (uint32_t i)
897 {
898     switch (i)
899     {
900       //case  0: return 0;
901         case  2: return 1712000;
902         default: return i * 1000000;
903     }
904 }
905
906 static int dvb_parse_transmit_mode (int i)
907 {
908     static const dvb_int_map_t tab[] = {
909         { -1, TRANSMISSION_MODE_AUTO },
910 #if DVBv5(3)
911         {  1, TRANSMISSION_MODE_1K   },
912 #endif
913         {  2, TRANSMISSION_MODE_2K   },
914         {  4, TRANSMISSION_MODE_4K   },
915         {  8, TRANSMISSION_MODE_8K   },
916 #if DVBv5(3)
917         { 16, TRANSMISSION_MODE_16K  },
918         { 32, TRANSMISSION_MODE_32K  },
919 #endif
920     };
921     return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
922                           TRANSMISSION_MODE_AUTO);
923 }
924
925 static int dvb_parse_guard (uint32_t guard)
926 {
927     static const dvb_int_map_t tab[] = {
928         { VLC_GUARD(1,4),    GUARD_INTERVAL_1_4 },
929         { VLC_GUARD(1,8),    GUARD_INTERVAL_1_8 },
930         { VLC_GUARD(1,16),   GUARD_INTERVAL_1_16 },
931         { VLC_GUARD(1,32),   GUARD_INTERVAL_1_32 },
932 #if DVBv5(3)
933         { VLC_GUARD(1,128),  GUARD_INTERVAL_1_128 },
934         { VLC_GUARD(19,128), GUARD_INTERVAL_19_128 },
935         { VLC_GUARD(19,256), GUARD_INTERVAL_19_256 },
936 #endif
937         { VLC_GUARD_AUTO,    GUARD_INTERVAL_AUTO },
938     };
939     return dvb_parse_int (guard, tab, sizeof (tab) / sizeof (*tab),
940                           GUARD_INTERVAL_AUTO);
941 }
942
943 static int dvb_parse_hierarchy (int i)
944 {
945     static const dvb_int_map_t tab[] = {
946         { HIERARCHY_AUTO, -1 },
947         { HIERARCHY_NONE,  0 },
948         { HIERARCHY_1,     1 },
949         { HIERARCHY_2,     2 },
950         { HIERARCHY_4,     4 },
951     };
952     return dvb_parse_int (i, tab, sizeof (tab) / sizeof (*tab),
953                           HIERARCHY_AUTO);
954 }
955
956 int dvb_set_dvbt (dvb_device_t *d, uint32_t freq, const char *modstr,
957                   uint32_t fec_hp, uint32_t fec_lp, uint32_t bandwidth,
958                   int transmit_mode, uint32_t guard, int hierarchy)
959 {
960     uint32_t mod = dvb_parse_modulation (modstr, QAM_AUTO);
961     fec_hp = dvb_parse_fec (fec_hp);
962     fec_lp = dvb_parse_fec (fec_lp);
963     bandwidth = dvb_parse_bandwidth (bandwidth);
964     transmit_mode = dvb_parse_transmit_mode (transmit_mode);
965     guard = dvb_parse_guard (guard);
966     hierarchy = dvb_parse_hierarchy (hierarchy);
967
968     if (dvb_find_frontend (d, DVB_T))
969         return -1;
970     return dvb_set_props (d, 10, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT,
971                           DTV_FREQUENCY, freq, DTV_MODULATION, mod,
972                           DTV_CODE_RATE_HP, fec_hp, DTV_CODE_RATE_LP, fec_lp,
973                           DTV_BANDWIDTH_HZ, bandwidth,
974                           DTV_TRANSMISSION_MODE, transmit_mode,
975                           DTV_GUARD_INTERVAL, guard,
976                           DTV_HIERARCHY, hierarchy);
977 }
978
979 int dvb_set_dvbt2 (dvb_device_t *d, uint32_t freq, const char *modstr,
980                    uint32_t fec, uint32_t bandwidth,
981                    int transmit_mode, uint32_t guard)
982 {
983 #if DVBv5(3)
984     uint32_t mod = dvb_parse_modulation (modstr, QAM_AUTO);
985     fec = dvb_parse_fec (fec);
986     bandwidth = dvb_parse_bandwidth (bandwidth);
987     transmit_mode = dvb_parse_transmit_mode (transmit_mode);
988     guard = dvb_parse_guard (guard);
989
990     if (dvb_find_frontend (d, DVB_T2))
991         return -1;
992     return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT2,
993                           DTV_FREQUENCY, freq, DTV_MODULATION, mod,
994                           DTV_INNER_FEC, fec, DTV_BANDWIDTH_HZ, bandwidth,
995                           DTV_TRANSMISSION_MODE, transmit_mode,
996                           DTV_GUARD_INTERVAL, guard);
997 #else
998 # warning DVB-T2 needs Linux DVB version 5.3 or later.
999     msg_Err (d->obj, "DVB-T2 support not compiled-in");
1000     (void) freq; (void) modstr; (void) fec; (void) bandwidth;
1001     (void) transmit_mode; (void) guard;
1002     return -1;
1003 #endif
1004 }
1005
1006
1007 /*** ISDB-C ***/
1008 int dvb_set_isdbc (dvb_device_t *d, uint32_t freq, const char *modstr,
1009                    uint32_t srate, uint32_t fec)
1010 {
1011     unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
1012     fec = dvb_parse_fec (fec);
1013
1014     if (dvb_find_frontend (d, ISDB_C))
1015         return -1;
1016     return dvb_set_props (d, 6, DTV_CLEAR, 0,
1017 #if DVBv5(5)
1018                           DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_C,
1019 #else
1020 # warning ISDB-C might need Linux DVB version 5.5 or later.
1021                           DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_AC,
1022 #endif
1023                           DTV_FREQUENCY, freq, DTV_MODULATION, mod,
1024                           DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec);
1025 }
1026
1027
1028 /*** ISDB-S ***/
1029 int dvb_set_isdbs (dvb_device_t *d, uint64_t freq_Hz, uint16_t ts_id)
1030 {
1031     uint32_t freq = freq_Hz / 1000;
1032
1033     if (dvb_find_frontend (d, ISDB_S))
1034         return -1;
1035     return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBS,
1036                           DTV_FREQUENCY, freq,
1037                           DTV_ISDBS_TS_ID, (uint32_t)ts_id);
1038 }
1039
1040
1041 /*** ISDB-T ***/
1042 static int dvb_set_isdbt_layer (dvb_device_t *d, unsigned num,
1043                                 const isdbt_layer_t *l)
1044 {
1045     uint32_t mod = dvb_parse_modulation (l->modulation, QAM_AUTO);
1046     uint32_t fec = dvb_parse_fec (l->code_rate);
1047     uint32_t count = l->segment_count;
1048     uint32_t ti = l->time_interleaving;
1049
1050     num *= DTV_ISDBT_LAYERB_FEC - DTV_ISDBT_LAYERA_FEC;
1051
1052     return dvb_set_props (d, 5, DTV_DELIVERY_SYSTEM, SYS_ISDBT,
1053                           DTV_ISDBT_LAYERA_FEC + num, fec,
1054                           DTV_ISDBT_LAYERA_MODULATION + num, mod,
1055                           DTV_ISDBT_LAYERA_SEGMENT_COUNT + num, count,
1056                           DTV_ISDBT_LAYERA_TIME_INTERLEAVING + num, ti);
1057 }
1058
1059 int dvb_set_isdbt (dvb_device_t *d, uint32_t freq, uint32_t bandwidth,
1060                    int transmit_mode, uint32_t guard,
1061                    const isdbt_layer_t layers[3])
1062 {
1063     bandwidth = dvb_parse_bandwidth (bandwidth);
1064     transmit_mode = dvb_parse_transmit_mode (transmit_mode);
1065     guard = dvb_parse_guard (guard);
1066
1067     if (dvb_find_frontend (d, ISDB_T))
1068         return -1;
1069     if (dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBT,
1070                        DTV_FREQUENCY, freq, DTV_BANDWIDTH_HZ, bandwidth,
1071                        DTV_GUARD_INTERVAL, guard))
1072         return -1;
1073     for (unsigned i = 0; i < 3; i++)
1074         if (dvb_set_isdbt_layer (d, i, layers + i))
1075             return -1;
1076     return 0;
1077 }
1078
1079
1080 /*** ATSC ***/
1081 int dvb_set_atsc (dvb_device_t *d, uint32_t freq, const char *modstr)
1082 {
1083     unsigned mod = dvb_parse_modulation (modstr, VSB_8);
1084
1085     if (dvb_find_frontend (d, ATSC))
1086         return -1;
1087     return dvb_set_props (d, 4, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ATSC,
1088                           DTV_FREQUENCY, freq, DTV_MODULATION, mod);
1089 }
1090
1091 int dvb_set_cqam (dvb_device_t *d, uint32_t freq, const char *modstr)
1092 {
1093     unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
1094
1095     if (dvb_find_frontend (d, CQAM))
1096         return -1;
1097     return dvb_set_props (d, 4, DTV_CLEAR, 0,
1098                           DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_B,
1099                           DTV_FREQUENCY, freq, DTV_MODULATION, mod);
1100 }