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