1 /*
2  *  Tvheadend - Linux DVB frontend
3  *
4  *  Copyright (C) 2013 Adam Sutton
5  *
6  *  This program is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "tvheadend.h"
21 #include "linuxdvb_private.h"
22 #include "notify.h"
23 #include "atomic.h"
24 #include "tvhpoll.h"
25 #include "streaming.h"
26 
27 #include <sys/ioctl.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <assert.h>
33 #include <linux/dvb/dmx.h>
34 #include <linux/dvb/frontend.h>
35 
36 #define NOSIGNAL(x) (((x) & FE_HAS_SIGNAL) == 0)
37 
38 static void
39 linuxdvb_frontend_monitor ( void *aux );
40 static void *
41 linuxdvb_frontend_input_thread ( void *aux );
42 
43 /* **************************************************************************
44  * Class definition
45  * *************************************************************************/
46 
47 static void
linuxdvb_frontend_class_changed(idnode_t * in)48 linuxdvb_frontend_class_changed ( idnode_t *in )
49 {
50   linuxdvb_adapter_t *la = ((linuxdvb_frontend_t*)in)->lfe_adapter;
51   linuxdvb_adapter_changed(la);
52 }
53 
54 const void *
linuxdvb_frontend_class_active_get(void * obj)55 linuxdvb_frontend_class_active_get ( void *obj )
56 {
57   int *active;
58   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)obj;
59   active = (int *)mpegts_input_class_active_get(obj);
60   if (!(*active) && lfe->lfe_adapter->la_exclusive)
61     *active = lfe->lfe_adapter->la_is_enabled(lfe->lfe_adapter);
62   return active;
63 }
64 
65 CLASS_DOC(linuxdvb_frontend)
66 CLASS_DOC(linuxdvb_frontend_dvbs)
67 CLASS_DOC(linuxdvb_frontend_dvbt)
68 CLASS_DOC(linuxdvb_frontend_dvbc)
69 
70 const idclass_t linuxdvb_frontend_class =
71 {
72   .ic_super      = &mpegts_input_class,
73   .ic_class      = "linuxdvb_frontend",
74   .ic_caption    = N_("Linux DVB frontend"),
75   .ic_doc        = tvh_doc_linuxdvb_frontend_class,
76   .ic_changed    = linuxdvb_frontend_class_changed,
77   .ic_properties = (const property_t[]) {
78     {
79       .type     = PT_BOOL,
80       .id       = "active",
81       .name     = N_("Active"),
82       .opts     = PO_RDONLY | PO_NOSAVE | PO_NOUI,
83       .get      = linuxdvb_frontend_class_active_get,
84     },
85     {
86       .type     = PT_STR,
87       .id       = "fe_path",
88       .name     = N_("Frontend path"),
89       .desc     = N_("Path to the frontend used by the device."),
90       .opts     = PO_RDONLY | PO_NOSAVE,
91       .off      = offsetof(linuxdvb_frontend_t, lfe_fe_path),
92     },
93     {
94       .type     = PT_STR,
95       .id       = "dvr_path",
96       .name     = N_("Input path"),
97       .desc     = N_("The input path used by the device."),
98       .opts     = PO_RDONLY | PO_NOSAVE,
99       .off      = offsetof(linuxdvb_frontend_t, lfe_dvr_path),
100     },
101     {
102       .type     = PT_STR,
103       .id       = "dmx_path",
104       .name     = N_("Demux path"),
105       .desc     = N_("The demux path used by the device."),
106       .opts     = PO_RDONLY | PO_NOSAVE,
107       .off      = offsetof(linuxdvb_frontend_t, lfe_dmx_path),
108     },
109     {
110       .type     = PT_INT,
111       .id       = "fe_number",
112       .name     = N_("Frontend number"),
113       .desc     = N_("The frontend number given to the device."),
114       .opts     = PO_RDONLY | PO_NOSAVE,
115       .off      = offsetof(linuxdvb_frontend_t, lfe_number),
116     },
117     {
118       .type     = PT_STR,
119       .id       = "sysfs_device",
120       .name     = N_("Device path in sysfs"),
121       .desc     = N_("The device path in sysfs filesystem (/sys)."),
122       .opts     = PO_RDONLY | PO_NOSAVE | PO_MULTILINE,
123       .off      = offsetof(linuxdvb_frontend_t, lfe_sysfs),
124     },
125     {
126       .type     = PT_INT,
127       .id       = "pids_max",
128       .name     = N_("Maximum PIDs"),
129       .desc     = N_("The limit for the PID filter (driver or hardware)."),
130       .off      = offsetof(linuxdvb_frontend_t, lfe_pids_max),
131       .opts     = PO_ADVANCED,
132       .def.i    = 32
133     },
134     {
135       .type     = PT_BOOL,
136       .id       = "pids_use_all",
137       .name     = N_("Allow all PIDs"),
138       .desc     = N_("Allow all PIDs (no filter) when the 'Maximum PIDs' limit is reached."),
139       .off      = offsetof(linuxdvb_frontend_t, lfe_pids_use_all),
140       .opts     = PO_ADVANCED,
141       .def.i    = 1
142     },
143     {
144       .type     = PT_BOOL,
145       .id       = "powersave",
146       .name     = N_("Power save"),
147       .desc     = N_("Enable/disable power save mode (if supported by "
148                      "the device)."),
149       .off      = offsetof(linuxdvb_frontend_t, lfe_powersave),
150     },
151     {
152       .type     = PT_U32,
153       .id       = "tune_repeats",
154       .name     = N_("# tune repeats"),
155       .desc     = N_("Number of repeats for the tune requests (default is "
156                      "zero - no repeats). Note: this represents the "
157                      "number of repeats, not the number of requests - "
158                      "so 0 means 'send once: don't repeat', 1 means "
159                      "'send twice: send once, then send one repeat',"
160                      " etc."),
161       .opts     = PO_ADVANCED,
162       .off      = offsetof(linuxdvb_frontend_t, lfe_tune_repeats),
163     },
164     {
165       .type     = PT_U32,
166       .id       = "skip_bytes",
167       .name     = N_("Skip initial bytes"),
168       .desc     = N_("If set, the first bytes from the MPEG-TS stream "
169                      "are discarded. It may be required for some "
170                      "drivers or hardware which do not flush the MPEG-TS "
171                       "buffers completely after a frequency/parameter change."),
172       .opts     = PO_ADVANCED,
173       .off      = offsetof(linuxdvb_frontend_t, lfe_skip_bytes),
174     },
175     {
176       .type     = PT_U32,
177       .id       = "ibuf_size",
178       .name     = N_("Input buffer (bytes)"),
179       .desc     = N_("The number of bytes to buffer. By default, "
180                      "linuxdvb's input buffer is 18800 bytes long. The "
181                      "accepted range is 18800-1880000 bytes."),
182       .opts     = PO_ADVANCED,
183       .off      = offsetof(linuxdvb_frontend_t, lfe_ibuf_size),
184     },
185     {
186       .type     = PT_U32,
187       .id       = "status_period",
188       .name     = N_("Status period (ms)"),
189       .desc     = N_("By default, linuxdvb's status read period is "
190                      "1000ms (one second). The accepted range is 250ms "
191                      "to 8000ms. Note that for some hardware or drivers "
192                      "(like USB), the status operations take too much "
193                      "time and CPU. In this case, increase the default "
194                      "value. For fast hardware, this value might be "
195                      "decreased to make the decision of the re-tune "
196                      "algorithm based on the signal status faster."),
197       .opts     = PO_ADVANCED,
198       .off      = offsetof(linuxdvb_frontend_t, lfe_status_period),
199     },
200     {
201       .type     = PT_BOOL,
202       .id       = "old_status",
203       .name     = N_("Force old status"),
204       .desc     = N_("Always use the old ioctls to read the linuxdvb "
205                      "status (signal strength, SNR, error counters). "
206                      "Some drivers are not mature enough to provide the "
207                      "correct values using the new v5 linuxdvb API."),
208       .opts     = PO_ADVANCED,
209       .off      = offsetof(linuxdvb_frontend_t, lfe_old_status),
210     },
211     {}
212   }
213 };
214 
215 const idclass_t linuxdvb_frontend_dvbt_class =
216 {
217   .ic_super      = &linuxdvb_frontend_class,
218   .ic_class      = "linuxdvb_frontend_dvbt",
219   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbt_class,
220   .ic_caption    = N_("TV Adapters - Linux DVB-T Frontend"),
221   .ic_properties = (const property_t[]){
222     {
223       .type     = PT_BOOL,
224       .id       = "lna",
225       .name     = N_("LNA (low noise amplifier)"),
226       .desc     = N_("Enable/disable LNA."),
227       .off      = offsetof(linuxdvb_frontend_t, lfe_lna),
228     },
229     {}
230   }
231 };
232 
233 static idnode_set_t *
linuxdvb_frontend_dvbs_class_get_childs(idnode_t * self)234 linuxdvb_frontend_dvbs_class_get_childs ( idnode_t *self )
235 {
236   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)self;
237   idnode_set_t        *is  = idnode_set_create(0);
238   idnode_set_add(is, &lfe->lfe_satconf->ls_id, NULL, NULL);
239   return is;
240 }
241 
242 static int
linuxdvb_frontend_dvbs_class_satconf_set(void * self,const void * str)243 linuxdvb_frontend_dvbs_class_satconf_set ( void *self, const void *str )
244 {
245   linuxdvb_frontend_t *lfe = self;
246   htsmsg_t *conf;
247   str = str ?: "";
248   if (lfe->lfe_satconf) {
249     if (!strcmp(str, lfe->lfe_satconf->ls_type))
250       return 0;
251     linuxdvb_satconf_delete(lfe->lfe_satconf, 1);
252   }
253   conf = htsmsg_create_map();
254   htsmsg_add_str(conf, "type", str);
255   lfe->lfe_satconf = linuxdvb_satconf_create(lfe, conf);
256   htsmsg_destroy(conf);
257   return 1;
258 }
259 
260 static const void *
linuxdvb_frontend_dvbs_class_satconf_get(void * self)261 linuxdvb_frontend_dvbs_class_satconf_get ( void *self )
262 {
263   linuxdvb_frontend_t *lfe = self;
264   if (lfe->lfe_satconf)
265     prop_ptr = lfe->lfe_satconf->ls_type;
266   else
267     prop_ptr = NULL;
268   return &prop_ptr;
269 }
270 
271 static htsmsg_t *
linuxdvb_frontend_dvbs_class_master_enum(void * self,const char * lang)272 linuxdvb_frontend_dvbs_class_master_enum( void * self, const char *lang )
273 {
274   linuxdvb_frontend_t *lfe = self, *lfe2;
275   linuxdvb_adapter_t *la;
276   tvh_hardware_t *th;
277   char ubuf[UUID_HEX_SIZE];
278   htsmsg_t *m = htsmsg_create_list();
279   if (self == NULL) return m;
280   htsmsg_t *e = htsmsg_create_key_val("", N_("This tuner"));
281   htsmsg_add_msg(m, NULL, e);
282   LIST_FOREACH(th, &tvh_hardware, th_link) {
283     if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) continue;
284     la = (linuxdvb_adapter_t*)th;
285     LIST_FOREACH(lfe2, &la->la_frontends, lfe_link) {
286       if (lfe2 != lfe && lfe2->lfe_type == lfe->lfe_type) {
287         e = htsmsg_create_key_val(idnode_uuid_as_str(&lfe2->ti_id, ubuf), lfe2->mi_name);
288         htsmsg_add_msg(m, NULL, e);
289       }
290     }
291   }
292   return m;
293 }
294 
295 const idclass_t linuxdvb_frontend_dvbs_class =
296 {
297   .ic_super      = &linuxdvb_frontend_class,
298   .ic_class      = "linuxdvb_frontend_dvbs",
299   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbs_class,
300   .ic_caption    = N_("TV Adapters - Linux DVB-S Frontend (Master)"),
301   .ic_get_childs = linuxdvb_frontend_dvbs_class_get_childs,
302   .ic_properties = (const property_t[]){
303     {
304       .type     = PT_STR,
305       .id       = "satconf",
306       .name     = N_("Satellite config"),
307       .desc     = N_("The satellite configuration to use."),
308       .opts     = PO_NOSAVE,
309       .set      = linuxdvb_frontend_dvbs_class_satconf_set,
310       .get      = linuxdvb_frontend_dvbs_class_satconf_get,
311       .list     = linuxdvb_satconf_type_list,
312       .def.s    = "simple"
313     },
314     {
315       .type     = PT_STR,
316       .id       = "fe_master",
317       .name     = N_("Master tuner"),
318       .desc     = N_("The signal from the standard universal LNB can be "
319                      "split using a simple coaxial splitter "
320                      "(no multiswitch) to several outputs. In this "
321                      "case, the position, the polarization and low-high "
322                      "band settings must be equal. If you set another "
323                      "tuner as master, then this tuner will act as "
324                      "a slave and Tvheadend will assure that this tuner "
325                      "will not use incompatible parameters (position, "
326                      "polarization, lo-hi)."),
327       .list     = linuxdvb_frontend_dvbs_class_master_enum,
328       .off      = offsetof(linuxdvb_frontend_t, lfe_master),
329     },
330     {
331       .id       = "networks",
332       .type     = PT_NONE,
333     },
334     {}
335   }
336 };
337 
338 const idclass_t linuxdvb_frontend_dvbs_slave_class =
339 {
340   .ic_super      = &linuxdvb_frontend_class,
341   .ic_class      = "linuxdvb_frontend_dvbs_slave",
342   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbs_class,
343   .ic_caption    = N_("TV Adapters - Linux DVB-S Slave Frontend"),
344   .ic_properties = (const property_t[]){
345     {
346       .type     = PT_STR,
347       .id       = "fe_master",
348       .name     = N_("Master tuner"),
349       .desc     = N_("The signal from the standard universal LNB can be "
350                      "split using a simple coaxial splitter "
351                      "(no multiswitch) to several outputs. In this "
352                      "case, the position, the polarization and low-high "
353                      "band settings must be equal. If you set another "
354                      "tuner as master, then this tuner will act as "
355                      "a slave and tvheadend will assure that this tuner "
356                      "will not use incompatible parameters (position, "
357                      "polarization, lo-hi)."),
358       .list     = linuxdvb_frontend_dvbs_class_master_enum,
359       .off      = offsetof(linuxdvb_frontend_t, lfe_master),
360     },
361     {
362       .id       = "networks",
363       .type     = PT_NONE,
364     },
365     {}
366   }
367 };
368 
369 const idclass_t linuxdvb_frontend_dvbc_class =
370 {
371   .ic_super      = &linuxdvb_frontend_class,
372   .ic_class      = "linuxdvb_frontend_dvbc",
373   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbc_class,
374   .ic_caption    = N_("TV Adapters - Linux DVB-C Frontend"),
375   .ic_properties = (const property_t[]){
376     {}
377   }
378 };
379 
380 const idclass_t linuxdvb_frontend_atsc_t_class =
381 {
382   .ic_super      = &linuxdvb_frontend_class,
383   .ic_class      = "linuxdvb_frontend_atsc_t",
384   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbt_class,
385   .ic_caption    = N_("TV Adapters - Linux ATSC-T Frontend"),
386   .ic_properties = (const property_t[]){
387     {}
388   }
389 };
390 
391 const idclass_t linuxdvb_frontend_atsc_c_class =
392 {
393   .ic_super      = &linuxdvb_frontend_class,
394   .ic_class      = "linuxdvb_frontend_atsc_c",
395   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbc_class,
396   .ic_caption    = N_("TV Adapters - Linux ATSC-C Frontend"),
397   .ic_properties = (const property_t[]){
398     {}
399   }
400 };
401 
402 const idclass_t linuxdvb_frontend_isdb_t_class =
403 {
404   .ic_super      = &linuxdvb_frontend_class,
405   .ic_class      = "linuxdvb_frontend_isdb_t",
406   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbt_class,
407   .ic_caption    = N_("TV Adapters - Linux ISDB-T Frontend"),
408   .ic_properties = (const property_t[]){
409     {}
410   }
411 };
412 
413 const idclass_t linuxdvb_frontend_isdb_c_class =
414 {
415   .ic_super      = &linuxdvb_frontend_class,
416   .ic_class      = "linuxdvb_frontend_isdb_c",
417   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbc_class,
418   .ic_caption    = N_("TV Adapters - Linux ISDB-C Frontend"),
419   .ic_properties = (const property_t[]){
420     {}
421   }
422 };
423 
424 const idclass_t linuxdvb_frontend_isdb_s_class =
425 {
426   .ic_super      = &linuxdvb_frontend_class,
427   .ic_class      = "linuxdvb_frontend_isdb_s",
428   .ic_doc        = tvh_doc_linuxdvb_frontend_dvbs_class,
429   .ic_caption    = N_("TV Adapters - Linux ISDB-S Frontend (Master)"),
430   .ic_properties = (const property_t[]){
431     {}
432   }
433 };
434 
435 const idclass_t linuxdvb_frontend_dab_class =
436 {
437   .ic_super      = &linuxdvb_frontend_class,
438   .ic_class      = "linuxdvb_frontend_dab",
439   .ic_caption    = N_("TV Adapters - Linux DAB Frontend"),
440   .ic_properties = (const property_t[]){
441     {}
442   }
443 };
444 
445 /* **************************************************************************
446  * Class methods
447  * *************************************************************************/
448 
449 static void
linuxdvb_frontend_close_fd(linuxdvb_frontend_t * lfe,const char * name)450 linuxdvb_frontend_close_fd ( linuxdvb_frontend_t *lfe, const char *name )
451 {
452   char buf[256];
453 
454   if (lfe->lfe_fe_fd <= 0)
455     return;
456 
457   if (name == NULL) {
458     lfe->mi_display_name((mpegts_input_t *)lfe, buf, sizeof(buf));
459     name = buf;
460   }
461 
462   tvhtrace(LS_LINUXDVB, "%s - closing FE %s (%d)",
463            name, lfe->lfe_fe_path, lfe->lfe_fe_fd);
464   close(lfe->lfe_fe_fd);
465   lfe->lfe_fe_fd = -1;
466   if (lfe->lfe_satconf)
467     linuxdvb_satconf_reset(lfe->lfe_satconf);
468 }
469 
470 static int
linuxdvb_frontend_open_fd(linuxdvb_frontend_t * lfe,const char * name)471 linuxdvb_frontend_open_fd ( linuxdvb_frontend_t *lfe, const char *name )
472 {
473   linuxdvb_frontend_t *lfe2;
474   const char *extra = "";
475 
476   if (lfe->lfe_fe_fd > 0)
477     return 0;
478 
479   /* Share FD across frontends */
480   if (lfe->lfe_adapter->la_exclusive) {
481     LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
482       if (lfe2->lfe_fe_fd > 0) {
483         lfe->lfe_fe_fd = dup(lfe2->lfe_fe_fd);
484         extra = " (shared)";
485         break;
486       }
487     }
488   }
489 
490   if (lfe->lfe_fe_fd <= 0) {
491     lfe->lfe_fe_fd = tvh_open(lfe->lfe_fe_path, O_RDWR | O_NONBLOCK, 0);
492     extra = "";
493   }
494 
495   tvhtrace(LS_LINUXDVB, "%s - opening FE %s (%d)%s",
496            name, lfe->lfe_fe_path, lfe->lfe_fe_fd, extra);
497 
498   return lfe->lfe_fe_fd <= 0;
499 }
500 
501 static void
linuxdvb_frontend_enabled_updated(mpegts_input_t * mi)502 linuxdvb_frontend_enabled_updated ( mpegts_input_t *mi )
503 {
504   char buf[512];
505   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
506 
507   mi->mi_display_name(mi, buf, sizeof(buf));
508 
509   /* Ensure disabled */
510   if (!mi->mi_enabled) {
511     tvhtrace(LS_LINUXDVB, "%s - disabling tuner", buf);
512     linuxdvb_frontend_close_fd(lfe, buf);
513     mtimer_disarm(&lfe->lfe_monitor_timer);
514 
515   /* Ensure FE opened (if not powersave) */
516   } else if (!lfe->lfe_powersave && lfe->lfe_fe_fd <= 0 && lfe->lfe_fe_path) {
517 
518     linuxdvb_frontend_open_fd(lfe, buf);
519 
520   }
521 }
522 
523 static int
linuxdvb_frontend_get_weight(mpegts_input_t * mi,mpegts_mux_t * mm,int flags,int weight)524 linuxdvb_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight )
525 {
526   int w = 0;
527   linuxdvb_adapter_t *la = ((linuxdvb_frontend_t*)mi)->lfe_adapter;
528   linuxdvb_frontend_t *lfe;
529   if (la->la_exclusive) {
530     LIST_FOREACH(lfe, &la->la_frontends, lfe_link)
531       w = MAX(w, mpegts_input_get_weight((mpegts_input_t*)lfe, mm, flags, weight));
532   } else {
533     w = mpegts_input_get_weight(mi, mm, flags, weight);
534   }
535   return w;
536 }
537 
538 static int
linuxdvb_frontend_get_priority(mpegts_input_t * mi,mpegts_mux_t * mm,int flags)539 linuxdvb_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags )
540 {
541   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
542   int r = mpegts_input_get_priority(mi, mm, flags);
543   if (lfe->lfe_satconf)
544     r += linuxdvb_satconf_get_priority(lfe->lfe_satconf, mm);
545   return r;
546 }
547 
548 static int
linuxdvb_frontend_get_grace(mpegts_input_t * mi,mpegts_mux_t * mm)549 linuxdvb_frontend_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm )
550 {
551   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
552   int r = 5;
553   if (lfe->lfe_satconf)
554     r = linuxdvb_satconf_get_grace(lfe->lfe_satconf, mm);
555   return r;
556 }
557 
558 static int
linuxdvb_frontend_is_enabled(mpegts_input_t * mi,mpegts_mux_t * mm,int flags,int weight)559 linuxdvb_frontend_is_enabled
560   ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight )
561 {
562   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2;
563   linuxdvb_adapter_t *la;
564   tvh_hardware_t *th;
565   char ubuf[UUID_HEX_SIZE];
566   int w;
567 
568   if (lfe->lfe_fe_path == NULL)
569     return MI_IS_ENABLED_NEVER;
570   w = mpegts_input_is_enabled(mi, mm, flags, weight);
571   if (w != MI_IS_ENABLED_OK)
572     return w;
573   if (access(lfe->lfe_fe_path, R_OK | W_OK))
574     return MI_IS_ENABLED_NEVER;
575   if (mm == NULL)
576     return MI_IS_ENABLED_OK;
577   if (lfe->lfe_in_setup)
578     return MI_IS_ENABLED_RETRY;
579   if (lfe->lfe_type != DVB_TYPE_S)
580     goto ok;
581 
582   /* check if any "blocking" tuner is running */
583   LIST_FOREACH(th, &tvh_hardware, th_link) {
584     if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) continue;
585     la = (linuxdvb_adapter_t*)th;
586     LIST_FOREACH(lfe2, &la->la_frontends, lfe_link) {
587       if (lfe2 == lfe) continue;
588       if (lfe2->lfe_type != DVB_TYPE_S) continue;
589       if (lfe->lfe_master && !strcmp(lfe->lfe_master, idnode_uuid_as_str(&lfe2->ti_id, ubuf))) {
590         if (lfe2->lfe_satconf == NULL)
591           return MI_IS_ENABLED_NEVER; /* invalid master */
592         if (lfe2->lfe_refcount <= 0)
593           return MI_IS_ENABLED_RETRY; /* prefer master */
594         if (linuxdvb_satconf_match_mux(lfe2->lfe_satconf, mm))
595           goto ok;
596         return MI_IS_ENABLED_RETRY;
597       }
598       if (lfe2->lfe_master &&
599           !strcmp(lfe2->lfe_master, idnode_uuid_as_str(&lfe->ti_id, ubuf)) &&
600           lfe2->lfe_refcount > 0) {
601         if (lfe->lfe_satconf == NULL)
602           return MI_IS_ENABLED_NEVER;
603         if (linuxdvb_satconf_match_mux(lfe->lfe_satconf, mm))
604           goto ok;
605         return MI_IS_ENABLED_RETRY;
606       }
607     }
608   }
609 
610 
611 ok:
612   if (lfe->lfe_adapter->la_exclusive) {
613     w = -1;
614     LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
615       if (lfe2 == lfe) continue;
616       w = MAX(w, mpegts_input_get_weight((mpegts_input_t *)lfe2, mm, flags, weight));
617     }
618     if (w >= weight)
619       return MI_IS_ENABLED_RETRY;
620   }
621 
622   return MI_IS_ENABLED_OK;
623 }
624 
625 static void
linuxdvb_frontend_stop_mux(mpegts_input_t * mi,mpegts_mux_instance_t * mmi)626 linuxdvb_frontend_stop_mux
627   ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
628 {
629   char buf1[256], buf2[256];
630   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2;
631 
632   if (lfe->lfe_master)
633     assert(lfe->lfe_type == DVB_TYPE_S);
634 
635   mi->mi_display_name(mi, buf1, sizeof(buf1));
636   mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2));
637   tvhdebug(LS_LINUXDVB, "%s - stopping %s", buf1, buf2);
638 
639   /* Stop thread */
640   if (lfe->lfe_dvr_pipe.wr > 0) {
641     tvh_write(lfe->lfe_dvr_pipe.wr, "", 1);
642     tvhtrace(LS_LINUXDVB, "%s - waiting for dvr thread", buf1);
643     pthread_join(lfe->lfe_dvr_thread, NULL);
644     tvh_pipe_close(&lfe->lfe_dvr_pipe);
645     tvhdebug(LS_LINUXDVB, "%s - stopped dvr thread", buf1);
646   }
647 
648   /* Not locked */
649   lfe->lfe_ready   = 0;
650   lfe->lfe_locked  = 0;
651   lfe->lfe_status  = 0;
652   lfe->lfe_status2 = 0;
653 
654   /* Ensure it won't happen immediately */
655   mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, sec2mono(2));
656 
657   if (lfe->lfe_satconf && lfe->lfe_refcount == 1)
658     linuxdvb_satconf_post_stop_mux(lfe->lfe_satconf);
659 
660   if (lfe->lfe_master) {
661     lfe2 = (linuxdvb_frontend_t *)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL);
662     if (lfe2->lfe_type != lfe->lfe_type)
663       lfe2 = NULL;
664     if (lfe2) { /* master tuner shutdown procedure */
665       assert(lfe2->lfe_refcount >= 0);
666       if (--lfe2->lfe_refcount == 0) {
667         lfe2->lfe_ready   = 0;
668         lfe2->lfe_locked  = 0;
669         lfe2->lfe_status  = 0;
670         lfe2->lfe_status2 = 0;
671         /* Ensure it won't happen immediately */
672         mtimer_arm_rel(&lfe2->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, sec2mono(2));
673         if (lfe2->lfe_satconf)
674           linuxdvb_satconf_post_stop_mux(lfe2->lfe_satconf);
675         lfe2->lfe_in_setup = 0;
676         lfe2->lfe_freq = 0;
677       }
678     }
679   }
680 
681   lfe->lfe_refcount--;
682   lfe->lfe_in_setup = 0;
683   lfe->lfe_freq = 0;
684   mpegts_pid_done(&lfe->lfe_pids);
685 }
686 
687 static int
linuxdvb_frontend_warm_mux(mpegts_input_t * mi,mpegts_mux_instance_t * mmi)688 linuxdvb_frontend_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
689 {
690   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2 = NULL;
691   mpegts_mux_instance_t *lmmi = NULL;
692   int r;
693 
694   r = mpegts_input_warm_mux(mi, mmi);
695   if (r)
696     return r;
697 
698   if (!lfe->lfe_adapter->la_exclusive)
699     return 0;
700 
701   /* Stop other active frontend (should be only one) */
702   LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) {
703     if (lfe2 == lfe) continue;
704     pthread_mutex_lock(&lfe2->mi_output_lock);
705     lmmi = LIST_FIRST(&lfe2->mi_mux_active);
706     pthread_mutex_unlock(&lfe2->mi_output_lock);
707     if (lmmi) {
708       /* Stop */
709       lmmi->mmi_mux->mm_stop(lmmi->mmi_mux, 1, SM_CODE_ABORTED);
710     }
711     linuxdvb_frontend_close_fd(lfe2, NULL);
712     mtimer_disarm(&lfe2->lfe_monitor_timer);
713   }
714   return 0;
715 }
716 
717 static int
linuxdvb_frontend_start_mux(mpegts_input_t * mi,mpegts_mux_instance_t * mmi,int weight)718 linuxdvb_frontend_start_mux
719   ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight )
720 {
721   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2;
722   int res, f;
723 
724   assert(lfe->lfe_in_setup == 0);
725 
726   lfe->lfe_refcount++;
727   lfe->lfe_in_setup = 1;
728   lfe->lfe_ioctls   = 0;
729 
730   if (lfe->lfe_master) {
731     assert(lfe->lfe_type == DVB_TYPE_S);
732     lfe2 = (linuxdvb_frontend_t *)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL);
733     if (lfe2 && lfe2->lfe_type != lfe->lfe_type)
734       lfe2 = NULL;
735     res = SM_CODE_TUNING_FAILED;
736     if (lfe2) {
737       f = linuxdvb_satconf_lnb_freq(lfe2->lfe_satconf, mmi);
738       if (f <= 0)
739         goto end;
740       if (lfe2->lfe_refcount++ == 0) {
741         lfe2->lfe_in_setup = 1;
742         lfe2->lfe_ioctls   = 0;
743         res = linuxdvb_satconf_start_mux(lfe2->lfe_satconf, mmi, 0);
744         if (res)
745           goto end;
746       }
747       res = linuxdvb_frontend_tune1((linuxdvb_frontend_t*)mi, mmi, f);
748     }
749     goto end;
750   }
751 
752   if (lfe->lfe_satconf)
753     res = linuxdvb_satconf_start_mux(lfe->lfe_satconf, mmi, lfe->lfe_refcount > 1);
754   else
755     res = linuxdvb_frontend_tune1((linuxdvb_frontend_t*)mi, mmi, -1);
756 
757 end:
758   if (res) {
759     lfe->lfe_in_setup = 0;
760     lfe->lfe_refcount--;
761   }
762   return res;
763 }
764 
765 static void
linuxdvb_frontend_update_pids(mpegts_input_t * mi,mpegts_mux_t * mm)766 linuxdvb_frontend_update_pids
767   ( mpegts_input_t *mi, mpegts_mux_t *mm )
768 {
769   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
770   mpegts_pid_t *mp;
771   mpegts_pid_sub_t *mps;
772 
773   pthread_mutex_lock(&lfe->lfe_dvr_lock);
774   mpegts_pid_done(&lfe->lfe_pids);
775   RB_FOREACH(mp, &mm->mm_pids, mp_link) {
776     if (mp->mp_pid == MPEGTS_FULLMUX_PID)
777       lfe->lfe_pids.all = 1;
778     else if (mp->mp_pid < MPEGTS_FULLMUX_PID) {
779       RB_FOREACH(mps, &mp->mp_subs, mps_link)
780         mpegts_pid_add(&lfe->lfe_pids, mp->mp_pid, mps->mps_weight);
781     }
782   }
783   pthread_mutex_unlock(&lfe->lfe_dvr_lock);
784 
785   if (lfe->lfe_dvr_pipe.wr > 0)
786     tvh_write(lfe->lfe_dvr_pipe.wr, "c", 1);
787 }
788 
789 static idnode_set_t *
linuxdvb_frontend_network_list(mpegts_input_t * mi)790 linuxdvb_frontend_network_list ( mpegts_input_t *mi )
791 {
792   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
793 
794   tvhtrace(LS_LINUXDVB, "%s: network list for %s",
795            mi->mi_name ?: "", dvb_type2str(lfe->lfe_type));
796 
797   return dvb_network_list_by_fe_type(lfe->lfe_type);
798 }
799 
800 /* **************************************************************************
801  * Data processing
802  * *************************************************************************/
803 
804 static inline int
ioctl_check(linuxdvb_frontend_t * lfe,int bit)805 ioctl_check( linuxdvb_frontend_t *lfe, int bit )
806 {
807   return !(lfe->lfe_ioctls & (1 << bit));
808 }
809 
810 static inline void
ioctl_bad(linuxdvb_frontend_t * lfe,int bit)811 ioctl_bad( linuxdvb_frontend_t *lfe, int bit )
812 {
813   lfe->lfe_ioctls |= 1 << bit;
814 }
815 
816 static void
linuxdvb_frontend_monitor(void * aux)817 linuxdvb_frontend_monitor ( void *aux )
818 {
819   uint16_t u16;
820   uint32_t u32;
821   char buf[256];
822   linuxdvb_frontend_t *lfe = aux;
823   mpegts_mux_instance_t *mmi = LIST_FIRST(&lfe->mi_mux_active);
824   mpegts_mux_t *mm;
825   fe_status_t fe_status;
826   signal_state_t status;
827   signal_status_t sigstat;
828   streaming_message_t sm;
829   service_t *s;
830   int logit = 0, retune, e;
831   uint32_t period = MINMAX(lfe->lfe_status_period, 250, 8000);
832 #if DVB_VER_ATLEAST(5,10)
833   struct dtv_property fe_properties[6];
834   struct dtv_properties dtv_prop;
835   int gotprop;
836 #endif
837 
838   lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf));
839   tvhtrace(LS_LINUXDVB, "%s - checking FE status%s", buf, lfe->lfe_ready ? " (ready)" : "");
840 
841   /* Disabled */
842   if (!lfe->mi_enabled && mmi)
843     mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1, SM_CODE_ABORTED);
844 
845   /* Close FE */
846   if (lfe->lfe_fe_fd > 0 && !lfe->lfe_refcount && lfe->lfe_powersave) {
847     linuxdvb_frontend_close_fd(lfe, buf);
848     return;
849   }
850 
851   /* Check accessibility */
852   if (lfe->lfe_fe_fd <= 0) {
853     if (lfe->lfe_fe_path && access(lfe->lfe_fe_path, R_OK | W_OK)) {
854       tvherror(LS_LINUXDVB, "%s - device is not accessible", buf);
855       // TODO: disable device
856       return;
857     }
858   }
859 
860   /* Stop timer */
861   if (!mmi || !lfe->lfe_ready) return;
862 
863   /* re-arm */
864   mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, ms2mono(period));
865 
866   /* Get current status */
867   if (ioctl(lfe->lfe_fe_fd, FE_READ_STATUS, &fe_status) == -1) {
868     tvhwarn(LS_LINUXDVB, "%s - FE_READ_STATUS error %s", buf, strerror(errno));
869     /* TODO: check error value */
870     return;
871 
872   } else if (fe_status & FE_HAS_LOCK)
873     status = SIGNAL_GOOD;
874   else if (fe_status & (FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_CARRIER))
875     status = SIGNAL_BAD;
876   else if (fe_status & FE_HAS_SIGNAL)
877     status = SIGNAL_FAINT;
878   else
879     status = SIGNAL_NONE;
880 
881   /* Set default period */
882   if (fe_status != lfe->lfe_status) {
883     tvhdebug(LS_LINUXDVB, "%s - status %7s (%s%s%s%s%s%s)", buf,
884              signal2str(status),
885              (fe_status & FE_HAS_SIGNAL) ?  "SIGNAL"  : "",
886              (fe_status & FE_HAS_CARRIER) ? " | CARRIER" : "",
887              (fe_status & FE_HAS_VITERBI) ? " | VITERBI" : "",
888              (fe_status & FE_HAS_SYNC) ?    " | SYNC"    : "",
889              (fe_status & FE_HAS_LOCK) ?    " | LOCK"  : "",
890              (fe_status & FE_TIMEDOUT) ?    "TIMEOUT" : "");
891   } else {
892     tvhtrace(LS_LINUXDVB, "%s - status %d (%04X)", buf, status, fe_status);
893   }
894   retune = NOSIGNAL(fe_status) && NOSIGNAL(lfe->lfe_status) && !NOSIGNAL(lfe->lfe_status2);
895   lfe->lfe_status2 = lfe->lfe_status;
896   lfe->lfe_status = fe_status;
897 
898   /* Retune check - we lost signal or no data were received */
899   if (retune || lfe->lfe_nodata) {
900     lfe->lfe_nodata = 0;
901     if (lfe->lfe_locked && lfe->lfe_freq > 0) {
902       tvhwarn(LS_LINUXDVB, "%s - %s", buf, retune ? "retune" : "retune nodata");
903       linuxdvb_frontend_tune0(lfe, mmi, lfe->lfe_freq);
904       mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, ms2mono(50));
905       lfe->lfe_locked = 1;
906     }
907   }
908 
909   /* Get current mux */
910   mm = mmi->mmi_mux;
911 
912   /* Waiting for lock */
913   if (!lfe->lfe_locked) {
914 
915     /* Locked */
916     if (status == SIGNAL_GOOD) {
917       tvhdebug(LS_LINUXDVB, "%s - locked", buf);
918       lfe->lfe_locked = 1;
919 
920       /* Start input */
921       tvh_pipe(O_NONBLOCK, &lfe->lfe_dvr_pipe);
922       pthread_mutex_lock(&lfe->lfe_dvr_lock);
923       tvhthread_create(&lfe->lfe_dvr_thread, NULL,
924                        linuxdvb_frontend_input_thread, lfe, "lnxdvb-front");
925       do {
926         e = tvh_cond_wait(&lfe->lfe_dvr_cond, &lfe->lfe_dvr_lock);
927         if (e == ETIMEDOUT)
928           break;
929       } while (ERRNO_AGAIN(e));
930       pthread_mutex_unlock(&lfe->lfe_dvr_lock);
931 
932       /* Table handlers */
933       psi_tables_install((mpegts_input_t *)lfe, mm,
934                          ((dvb_mux_t *)mm)->lm_tuning.dmc_fe_delsys);
935 
936     /* Re-arm (quick) */
937     } else {
938       mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor,
939                      lfe, ms2mono(50));
940 
941       /* Monitor 1 per sec */
942       if (mclk() < lfe->lfe_monitor)
943         return;
944       lfe->lfe_monitor = mclk() + sec2mono(1);
945     }
946   } else {
947     if (mclk() < lfe->lfe_monitor)
948       return;
949     lfe->lfe_monitor = mclk() + ms2mono(period);
950   }
951 
952 
953   pthread_mutex_lock(&mmi->tii_stats_mutex);
954 
955   /* Statistics - New API */
956 #if DVB_VER_ATLEAST(5,10)
957   memset(&fe_properties, 0, sizeof(fe_properties));
958 
959   /* Signal strength */
960   fe_properties[0].cmd = DTV_STAT_SIGNAL_STRENGTH;
961 
962   /* BER */
963   fe_properties[1].cmd = DTV_STAT_PRE_ERROR_BIT_COUNT;
964   fe_properties[2].cmd = DTV_STAT_PRE_TOTAL_BIT_COUNT;
965 
966   /* SNR */
967   fe_properties[3].cmd = DTV_STAT_CNR;
968 
969   /* PER / UNC */
970   fe_properties[4].cmd = DTV_STAT_ERROR_BLOCK_COUNT;
971   fe_properties[5].cmd = DTV_STAT_TOTAL_BLOCK_COUNT;
972   dtv_prop.num = 6;
973   dtv_prop.props = fe_properties;
974 
975   logit = tvhlog_limit(&lfe->lfe_status_log, 3600);
976 
977   if(ioctl_check(lfe, 0) && !lfe->lfe_old_status &&
978      !ioctl(lfe->lfe_fe_fd, FE_GET_PROPERTY, &dtv_prop)) {
979     /* Signal strength */
980     gotprop = 0;
981     if(ioctl_check(lfe, 1) && fe_properties[0].u.st.len > 0) {
982       if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_RELATIVE) {
983         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
984         mmi->tii_stats.signal = fe_properties[0].u.st.stat[0].uvalue;
985         gotprop = 1;
986       }
987       else if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_DECIBEL) {
988         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_DECIBEL;
989         mmi->tii_stats.signal = fe_properties[0].u.st.stat[0].svalue;
990         gotprop = 1;
991       }
992       else if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
993         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
994         gotprop = 1;
995       }
996       else {
997         ioctl_bad(lfe, 1);
998         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
999         if (logit)
1000           tvhwarn(LS_LINUXDVB, "Unhandled signal scale: %d",
1001                   fe_properties[0].u.st.stat[0].scale);
1002       }
1003     }
1004     if(!gotprop && ioctl_check(lfe, 2)) {
1005       /* try old API */
1006       if (!ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) {
1007         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
1008         mmi->tii_stats.signal = u16;
1009       }
1010       else {
1011         ioctl_bad(lfe, 2);
1012         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
1013         if (logit)
1014           tvhwarn(LS_LINUXDVB, "Unable to provide signal strength value.");
1015       }
1016     }
1017 
1018     /* ERROR_BIT_COUNT */
1019     gotprop = 0;
1020     if(ioctl_check(lfe, 3) && fe_properties[1].u.st.len > 0) {
1021       if(fe_properties[1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
1022         mmi->tii_stats.ec_bit = fe_properties[1].u.st.stat[0].uvalue;
1023         gotprop = 1;
1024       }
1025       else {
1026         ioctl_bad(lfe, 3);
1027         if (logit)
1028           tvhwarn(LS_LINUXDVB, "Unhandled ERROR_BIT_COUNT scale: %d",
1029                   fe_properties[1].u.st.stat[0].scale);
1030       }
1031     }
1032     /* TOTAL_BIT_COUNT */
1033     if(gotprop && (fe_properties[2].u.st.len > 0)) {
1034       gotprop = 0;
1035       if(ioctl_check(lfe, 4) && fe_properties[2].u.st.stat[0].scale == FE_SCALE_COUNTER) {
1036         mmi->tii_stats.tc_bit = fe_properties[2].u.st.stat[0].uvalue;
1037         gotprop = 1;
1038       }
1039       else {
1040         ioctl_bad(lfe, 4);
1041         mmi->tii_stats.ec_bit = 0; /* both values or none */
1042         if (logit)
1043           tvhwarn(LS_LINUXDVB, "Unhandled TOTAL_BIT_COUNT scale: %d",
1044                   fe_properties[2].u.st.stat[0].scale);
1045       }
1046     }
1047     if(!gotprop && ioctl_check(lfe, 5)) {
1048       /* try old API */
1049       if (!ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32))
1050         mmi->tii_stats.ber = u32;
1051       else {
1052         ioctl_bad(lfe, 5);
1053         if (logit)
1054           tvhwarn(LS_LINUXDVB, "Unable to provide BER value.");
1055       }
1056     }
1057 
1058     /* SNR */
1059     gotprop = 0;
1060     if(ioctl_check(lfe, 6) && fe_properties[3].u.st.len > 0) {
1061       if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_RELATIVE) {
1062         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
1063         mmi->tii_stats.snr = fe_properties[3].u.st.stat[0].uvalue;
1064         gotprop = 1;
1065       }
1066       else if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_DECIBEL) {
1067         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_DECIBEL;
1068         mmi->tii_stats.snr = fe_properties[3].u.st.stat[0].svalue;
1069         gotprop = 1;
1070       }
1071       else if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
1072         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
1073         gotprop = 1;
1074       }
1075       else {
1076         ioctl_bad(lfe, 6);
1077         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
1078         if (logit)
1079           tvhwarn(LS_LINUXDVB, "Unhandled SNR scale: %d",
1080                   fe_properties[3].u.st.stat[0].scale);
1081       }
1082     }
1083     if(!gotprop && ioctl_check(lfe, 7)) {
1084       /* try old API */
1085       if (!ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) {
1086         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
1087         mmi->tii_stats.snr = u16;
1088       }
1089       else {
1090         ioctl_bad(lfe, 7);
1091         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
1092         if (logit)
1093           tvhwarn(LS_LINUXDVB, "Unable to provide SNR value.");
1094       }
1095     }
1096 
1097     /* ERROR_BLOCK_COUNT == Uncorrected blocks (UNC) */
1098     gotprop = 0;
1099     if(ioctl_check(lfe, 8) && fe_properties[4].u.st.len > 0) {
1100       if(fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) {
1101         atomic_set(&mmi->tii_stats.unc, fe_properties[4].u.st.stat[0].uvalue);
1102         mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue;
1103         gotprop = 1;
1104       }
1105       else {
1106         ioctl_bad(lfe, 8);
1107         if (logit)
1108           tvhwarn(LS_LINUXDVB, "Unhandled ERROR_BLOCK_COUNT scale: %d",
1109                   fe_properties[4].u.st.stat[0].scale);
1110       }
1111     }
1112 
1113     /* TOTAL_BLOCK_COUNT */
1114     if(gotprop && (fe_properties[5].u.st.len > 0)) {
1115       gotprop = 0;
1116       if(ioctl_check(lfe, 9) && fe_properties[5].u.st.stat[0].scale == FE_SCALE_COUNTER) {
1117         mmi->tii_stats.tc_block = fe_properties[5].u.st.stat[0].uvalue;
1118         gotprop = 1;
1119       }
1120       else {
1121         ioctl_bad(lfe, 9);
1122         /* both values to none */
1123         mmi->tii_stats.ec_block = 0;
1124         atomic_set(&mmi->tii_stats.unc, 0);
1125         if (logit)
1126           tvhwarn(LS_LINUXDVB, "Unhandled TOTAL_BLOCK_COUNT scale: %d",
1127                  fe_properties[5].u.st.stat[0].scale);
1128       }
1129     }
1130     if(!gotprop && ioctl_check(lfe, 10)) {
1131       /* try old API */
1132       if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) {
1133         atomic_set(&mmi->tii_stats.unc, u32);
1134         gotprop = 1;
1135       }
1136       else {
1137         ioctl_bad(lfe, 10);
1138         if (logit)
1139           tvhwarn(LS_LINUXDVB, "Unable to provide UNC value.");
1140       }
1141     }
1142   /* Older API */
1143   } else
1144 #endif
1145   {
1146     ioctl_bad(lfe, 0);
1147     if (ioctl_check(lfe, 1) && !ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) {
1148       mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
1149       mmi->tii_stats.signal = u16;
1150     }
1151     else {
1152       ioctl_bad(lfe, 1);
1153       mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
1154       if (logit)
1155         tvhwarn(LS_LINUXDVB, "Unable to provide signal strength value.");
1156     }
1157     if (ioctl_check(lfe, 2) && !ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32))
1158       mmi->tii_stats.ber = u32;
1159     else {
1160       ioctl_bad(lfe, 2);
1161       if (logit)
1162         tvhwarn(LS_LINUXDVB, "Unable to provide BER value.");
1163     }
1164     if (ioctl_check(lfe, 3) && !ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) {
1165       mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
1166       mmi->tii_stats.snr = u16;
1167     }
1168     else {
1169       ioctl_bad(lfe, 3);
1170       mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
1171       if (logit)
1172         tvhwarn(LS_LINUXDVB, "Unable to provide SNR value.");
1173     }
1174     if (ioctl_check(lfe, 4) && !ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32))
1175       atomic_set(&mmi->tii_stats.unc, u32);
1176     else {
1177       ioctl_bad(lfe, 4);
1178       if (logit)
1179         tvhwarn(LS_LINUXDVB, "Unable to provide UNC value.");
1180     }
1181   }
1182 
1183   /* Send message */
1184   sigstat.status_text  = signal2str(status);
1185   sigstat.snr          = mmi->tii_stats.snr;
1186   sigstat.signal       = mmi->tii_stats.signal;
1187   sigstat.ber          = mmi->tii_stats.ber;
1188   sigstat.unc          = atomic_get(&mmi->tii_stats.unc);
1189   sigstat.signal_scale = mmi->tii_stats.signal_scale;
1190   sigstat.snr_scale    = mmi->tii_stats.snr_scale;
1191   sigstat.ec_bit       = mmi->tii_stats.ec_bit;
1192   sigstat.tc_bit       = mmi->tii_stats.tc_bit;
1193   sigstat.ec_block     = mmi->tii_stats.ec_block;
1194   sigstat.tc_block     = mmi->tii_stats.tc_block;
1195   sm.sm_type = SMT_SIGNAL_STATUS;
1196   sm.sm_data = &sigstat;
1197 
1198   pthread_mutex_unlock(&mmi->tii_stats_mutex);
1199 
1200   LIST_FOREACH(s, &mmi->mmi_mux->mm_transports, s_active_link) {
1201     pthread_mutex_lock(&s->s_stream_mutex);
1202     streaming_pad_deliver(&s->s_streaming_pad, streaming_msg_clone(&sm));
1203     pthread_mutex_unlock(&s->s_stream_mutex);
1204   }
1205 }
1206 
1207 typedef struct linuxdvb_pid {
1208   int fd;
1209   int pid;
1210 } linuxdvb_pid_t;
1211 
1212 static void
linuxdvb_frontend_open_pid0(linuxdvb_frontend_t * lfe,const char * name,linuxdvb_pid_t * pids,int pids_size,int pid)1213 linuxdvb_frontend_open_pid0
1214   ( linuxdvb_frontend_t *lfe, const char *name,
1215     linuxdvb_pid_t *pids, int pids_size, int pid )
1216 {
1217   struct dmx_pes_filter_params dmx_param;
1218   int fd;
1219 
1220   for ( ; pids_size > 0 && pids->fd >= 0; pids_size--, pids++);
1221   if (pids_size == 0) {
1222     tvherror(LS_LINUXDVB, "%s - maximum PID count reached, pid %d ignored",
1223              name, pid);
1224     return;
1225   }
1226 
1227   /* Open DMX */
1228   fd = tvh_open(lfe->lfe_dmx_path, O_RDWR, 0);
1229   if(fd == -1) {
1230     tvherror(LS_LINUXDVB, "%s - failed to open dmx for pid %d [e=%s]",
1231              name, pid, strerror(errno));
1232     return;
1233   }
1234 
1235   /* Install filter */
1236   tvhtrace(LS_LINUXDVB, "%s - open PID %04X (%d) fd %d", name, pid, pid, fd);
1237   memset(&dmx_param, 0, sizeof(dmx_param));
1238   dmx_param.pid      = pid;
1239   dmx_param.input    = DMX_IN_FRONTEND;
1240   dmx_param.output   = DMX_OUT_TS_TAP;
1241   dmx_param.pes_type = DMX_PES_OTHER;
1242   dmx_param.flags    = DMX_IMMEDIATE_START;
1243 
1244   if(ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) {
1245     tvherror(LS_LINUXDVB, "%s - failed to config dmx for pid %d [e=%s]",
1246              name, pid, strerror(errno));
1247     close(fd);
1248     return;
1249   }
1250 
1251   /* Store */
1252   pids->fd = fd;
1253   pids->pid = pid;
1254 }
1255 
1256 static void
linuxdvb_frontend_close_pid0(linuxdvb_frontend_t * lfe,const char * name,linuxdvb_pid_t * pids,int pids_size,int pid)1257 linuxdvb_frontend_close_pid0
1258   ( linuxdvb_frontend_t *lfe, const char *name,
1259     linuxdvb_pid_t *pids, int pids_size, int pid )
1260 {
1261   for ( ; pids_size > 0 && pids->pid != pid;
1262           pids_size--, pids++);
1263   if (pids_size == 0)
1264     return;
1265   tvhtrace(LS_LINUXDVB, "%s - close PID %04X (%d) fd %d", name, pid, pid, pids->fd);
1266   close(pids->fd);
1267   pids->fd = -1;
1268   pids->pid = -1;
1269 }
1270 
1271 static int
linuxdvb_pid_exists(linuxdvb_pid_t * pids,int pids_size,int pid)1272 linuxdvb_pid_exists ( linuxdvb_pid_t *pids, int pids_size, int pid )
1273 {
1274   int i;
1275   for (i = 0; i < pids_size; i++)
1276     if (pids[i].fd >= 0 && pids[i].pid == pid)
1277       return 1;
1278   return 0;
1279 }
1280 
1281 static void
linuxdvb_update_pids(linuxdvb_frontend_t * lfe,const char * name,mpegts_apids_t * tuned,linuxdvb_pid_t * pids,int pids_size)1282 linuxdvb_update_pids ( linuxdvb_frontend_t *lfe, const char *name,
1283                        mpegts_apids_t *tuned, linuxdvb_pid_t *pids,
1284                        int pids_size )
1285 {
1286   mpegts_apids_t wpid, padd, pdel;
1287   int i, max = MAX(14, lfe->lfe_pids_max);
1288   int all = lfe->lfe_pids.all;
1289 
1290   pthread_mutex_lock(&lfe->lfe_dvr_lock);
1291 
1292   if (!all) {
1293     mpegts_pid_weighted(&wpid, &lfe->lfe_pids, max);
1294     if (wpid.count > max && lfe->lfe_pids_use_all) {
1295       all = 1;
1296       mpegts_pid_done(&wpid);
1297     } else {
1298       mpegts_pid_compare(&wpid, tuned, &padd, &pdel);
1299       mpegts_pid_done(&wpid);
1300       for (i = 0; i < pdel.count; i++)
1301         linuxdvb_frontend_close_pid0(lfe, name, pids, pids_size, pdel.pids[i].pid);
1302       for (i = 0; i < padd.count; i++)
1303        linuxdvb_frontend_open_pid0(lfe, name, pids, pids_size, padd.pids[i].pid);
1304       mpegts_pid_done(&padd);
1305       mpegts_pid_done(&pdel);
1306       mpegts_pid_done(tuned);
1307       mpegts_pid_weighted(tuned, &lfe->lfe_pids, max);
1308     }
1309   }
1310 
1311   if (all && !linuxdvb_pid_exists(pids, pids_size, MPEGTS_FULLMUX_PID))
1312     linuxdvb_frontend_open_pid0(lfe, name, pids, pids_size, MPEGTS_FULLMUX_PID);
1313   else if (!all && linuxdvb_pid_exists(pids, pids_size, MPEGTS_FULLMUX_PID))
1314     linuxdvb_frontend_close_pid0(lfe, name, pids, pids_size, MPEGTS_FULLMUX_PID);
1315 
1316   tuned->all = lfe->lfe_pids.all;
1317 
1318   pthread_mutex_unlock(&lfe->lfe_dvr_lock);
1319 }
1320 
1321 static void *
linuxdvb_frontend_input_thread(void * aux)1322 linuxdvb_frontend_input_thread ( void *aux )
1323 {
1324   linuxdvb_frontend_t *lfe = aux;
1325   mpegts_mux_instance_t *mmi;
1326   char name[256], b;
1327   tvhpoll_event_t ev[2];
1328   tvhpoll_t *efd;
1329   ssize_t n;
1330   size_t skip = (MIN(lfe->lfe_skip_bytes, 1024*1024) / 188) * 188;
1331   size_t counter = 0;
1332   linuxdvb_pid_t pids[128];
1333   mpegts_apids_t tuned;
1334   sbuf_t sb;
1335   int i, dvr = -1, nfds, nodata = 4;
1336 
1337   mpegts_pid_init(&tuned);
1338   for (i = 0; i < ARRAY_SIZE(pids); i++) {
1339     pids[i].fd = -1;
1340     pids[i].pid = -1;
1341   }
1342 
1343   /* Get MMI */
1344   pthread_mutex_lock(&lfe->lfe_dvr_lock);
1345   lfe->mi_display_name((mpegts_input_t*)lfe, name, sizeof(name));
1346   mmi = LIST_FIRST(&lfe->mi_mux_active);
1347   tvh_cond_signal(&lfe->lfe_dvr_cond, 0);
1348   pthread_mutex_unlock(&lfe->lfe_dvr_lock);
1349   if (mmi == NULL) return NULL;
1350 
1351   /* Open DVR */
1352   dvr = tvh_open(lfe->lfe_dvr_path, O_RDONLY | O_NONBLOCK, 0);
1353   if (dvr < 0) {
1354     tvherror(LS_LINUXDVB, "%s - failed to open %s", name, lfe->lfe_dvr_path);
1355     return NULL;
1356   }
1357 
1358   /* Setup poll */
1359   efd = tvhpoll_create(2);
1360   memset(ev, 0, sizeof(ev));
1361   ev[0].events             = TVHPOLL_IN;
1362   ev[0].fd = ev[0].data.fd = dvr;
1363   ev[1].events             = TVHPOLL_IN;
1364   ev[1].fd = ev[1].data.fd = lfe->lfe_dvr_pipe.rd;
1365   tvhpoll_add(efd, ev, 2);
1366 
1367   /* Allocate memory */
1368   sbuf_init_fixed(&sb, MINMAX(lfe->lfe_ibuf_size, 18800, 1880000));
1369 
1370   /* Subscribe PIDs */
1371   linuxdvb_update_pids(lfe, name, &tuned, pids, ARRAY_SIZE(pids));
1372 
1373   /* Read */
1374   while (tvheadend_is_running()) {
1375     nfds = tvhpoll_wait(efd, ev, 1, 150);
1376     if (nfds == 0) { /* timeout */
1377       if (nodata == 0) {
1378         tvhwarn(LS_LINUXDVB, "%s - poll TIMEOUT", name);
1379         nodata = 50;
1380         lfe->lfe_nodata = 1;
1381       } else {
1382         nodata--;
1383       }
1384     }
1385     if (nfds < 1) continue;
1386     if (ev[0].data.fd == lfe->lfe_dvr_pipe.rd) {
1387       if (read(lfe->lfe_dvr_pipe.rd, &b, 1) > 0) {
1388         if (b == 'c')
1389           linuxdvb_update_pids(lfe, name, &tuned, pids, ARRAY_SIZE(pids));
1390         else
1391           break;
1392       }
1393       continue;
1394     }
1395     if (ev[0].data.fd != dvr) break;
1396 
1397     nodata = 50;
1398     lfe->lfe_nodata = 0;
1399 
1400     /* Read */
1401     if ((n = sbuf_tsdebug_read(mmi->mmi_mux, &sb, dvr)) < 0) {
1402       if (ERRNO_AGAIN(errno))
1403         continue;
1404       if (errno == EOVERFLOW) {
1405         tvhwarn(LS_LINUXDVB, "%s - read() EOVERFLOW", name);
1406         continue;
1407       }
1408       tvherror(LS_LINUXDVB, "%s - read() error %d (%s)",
1409                name, errno, strerror(errno));
1410       break;
1411     }
1412 
1413     /* Skip the initial bytes */
1414     if (counter < skip) {
1415       counter += n;
1416       if (counter < skip) {
1417         sbuf_cut(&sb, n);
1418       } else {
1419         sbuf_cut(&sb, skip - (counter - n));
1420       }
1421     }
1422 
1423     /* Process */
1424     mpegts_input_recv_packets((mpegts_input_t*)lfe, mmi, &sb, 0, NULL);
1425   }
1426 
1427   sbuf_free(&sb);
1428   tvhpoll_destroy(efd);
1429   for (i = 0; i < ARRAY_SIZE(pids); i++)
1430     if (pids[i].fd >= 0)
1431       close(pids[i].fd);
1432   mpegts_pid_done(&tuned);
1433   close(dvr);
1434   return NULL;
1435 }
1436 
1437 /* **************************************************************************
1438  * Tuning
1439  * *************************************************************************/
1440 
1441 typedef struct linuxdvb_tbl {
1442   int t; ///< TVH internal value
1443   int l; ///< LinuxDVB API value
1444 } linuxdvb_tbl_t;
1445 
1446 #define TABLE_EOD -1
1447 
1448 #if DVB_API_VERSION >= 5
1449 static int
linuxdvb2tvh(const char * prefix,linuxdvb_tbl_t * tbl,int key,int defval)1450 linuxdvb2tvh ( const char *prefix, linuxdvb_tbl_t *tbl, int key, int defval )
1451 {
1452   while (tbl->t != TABLE_EOD) {
1453     if (tbl->l == key)
1454       return tbl->t;
1455     tbl++;
1456   }
1457   tvhtrace(LS_LINUXDVB, "%s - linuxdvb2tvh failed %d", prefix, key);
1458   return defval;
1459 }
1460 #endif
1461 
1462 static int
tvh2linuxdvb(const char * prefix,linuxdvb_tbl_t * tbl,int key,int defval)1463 tvh2linuxdvb ( const char *prefix, linuxdvb_tbl_t *tbl, int key, int defval )
1464 {
1465   while (tbl->t != TABLE_EOD) {
1466     if (tbl->t == key)
1467       return tbl->l;
1468     tbl++;
1469   }
1470   tvhtrace(LS_LINUXDVB, "%s - tvh2linuxdvb failed %d", prefix, key);
1471   return defval;
1472 }
1473 
1474 #define TOSTR(s) #s
1475 #define TR(s, t, d)  tvh2linuxdvb(TOSTR(s), t, dmc->dmc_fe_##s , d)
1476 #define TRU(s, t, d) tvh2linuxdvb(TOSTR(s), t, dmc->u.dmc_fe_##s , d)
1477 
1478 #if DVB_API_VERSION >= 5
1479 static linuxdvb_tbl_t delsys_tbl[] = {
1480   { .t = DVB_SYS_DVBC_ANNEX_B,        .l = SYS_DVBC_ANNEX_B },
1481 #if DVB_VER_ATLEAST(5,6)
1482   { .t = DVB_SYS_DVBC_ANNEX_A,        .l = SYS_DVBC_ANNEX_A },
1483   { .t = DVB_SYS_DVBC_ANNEX_C,        .l = SYS_DVBC_ANNEX_C },
1484 #else
1485   { .t = DVB_SYS_DVBC_ANNEX_A,        .l = SYS_DVBC_ANNEX_AC },
1486   { .t = DVB_SYS_DVBC_ANNEX_C,        .l = SYS_DVBC_ANNEX_AC },
1487 #endif
1488   { .t = DVB_SYS_DVBT,                .l = SYS_DVBT         },
1489 #if DVB_VER_ATLEAST(5,3)
1490   { .t = DVB_SYS_DVBT2,               .l = SYS_DVBT2        },
1491 #endif
1492   { .t = DVB_SYS_DVBS,                .l = SYS_DVBS         },
1493   { .t = DVB_SYS_DVBS2,               .l = SYS_DVBS2        },
1494   { .t = DVB_SYS_DVBH,                .l = SYS_DVBH         },
1495 #if DVB_VER_ATLEAST(5,1)
1496   { .t = DVB_SYS_DSS,                 .l = SYS_DSS          },
1497 #endif
1498   { .t = DVB_SYS_ISDBT,               .l = SYS_ISDBT        },
1499   { .t = DVB_SYS_ISDBS,               .l = SYS_ISDBS        },
1500   { .t = DVB_SYS_ISDBC,               .l = SYS_ISDBC        },
1501   { .t = DVB_SYS_ATSC,                .l = SYS_ATSC         },
1502   { .t = DVB_SYS_ATSCMH,              .l = SYS_ATSCMH       },
1503 #if DVB_VER_ATLEAST(5,7)
1504   { .t = DVB_SYS_DTMB,                .l = SYS_DTMB         },
1505 #endif
1506   { .t = DVB_SYS_CMMB,                .l = SYS_CMMB         },
1507   { .t = DVB_SYS_DAB,                 .l = SYS_DAB          },
1508 #if DVB_VER_ATLEAST(5,4)
1509   { .t = DVB_SYS_TURBO,               .l = SYS_TURBO        },
1510 #endif
1511   { .t = TABLE_EOD }
1512 };
linuxdvb2tvh_delsys(int delsys)1513 int linuxdvb2tvh_delsys ( int delsys )
1514 {
1515   return linuxdvb2tvh("delsys", delsys_tbl, delsys, DVB_SYS_NONE);
1516 }
1517 #endif
1518 
1519 int
linuxdvb_frontend_clear(linuxdvb_frontend_t * lfe,mpegts_mux_instance_t * mmi)1520 linuxdvb_frontend_clear
1521   ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi )
1522 {
1523   char buf1[256];
1524 
1525   /* Open FE */
1526   lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1));
1527   tvhtrace(LS_LINUXDVB, "%s - frontend clear", buf1);
1528 
1529   if (linuxdvb_frontend_open_fd(lfe, buf1))
1530     return SM_CODE_TUNING_FAILED;
1531 
1532   lfe->lfe_locked  = 0;
1533   lfe->lfe_status  = 0;
1534   lfe->lfe_status2 = 0;
1535 
1536 #if DVB_API_VERSION >= 5
1537   static struct dtv_property clear_p[] = {
1538     { .cmd = DTV_CLEAR },
1539   };
1540   static struct dtv_properties clear_cmdseq = {
1541     .num = 1,
1542     .props = clear_p
1543   };
1544   if ((ioctl(lfe->lfe_fe_fd, FE_SET_PROPERTY, &clear_cmdseq)) != 0) {
1545     tvherror(LS_LINUXDVB, "%s - DTV_CLEAR failed [e=%s]", buf1, strerror(errno));
1546     return -1;
1547   }
1548 
1549   if (mmi) {
1550     dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux;
1551     dvb_mux_conf_t *dmc = &lm->lm_tuning;
1552 
1553     struct dtv_property delsys_p;
1554     struct dtv_properties delsys_cmdseq = {
1555       .num = 1,
1556       .props = &delsys_p
1557     };
1558     delsys_p.cmd = DTV_DELIVERY_SYSTEM;
1559     delsys_p.u.data = TR(delsys, delsys_tbl, SYS_UNDEFINED);
1560     if ((ioctl(lfe->lfe_fe_fd, FE_SET_PROPERTY, &delsys_cmdseq)) != 0) {
1561       tvherror(LS_LINUXDVB, "%s - DTV_DELIVERY_SYSTEM failed [e=%s]", buf1, strerror(errno));
1562       return -1;
1563     }
1564   }
1565 #endif
1566 
1567   return 0;
1568 }
1569 
1570 int
linuxdvb_frontend_tune0(linuxdvb_frontend_t * lfe,mpegts_mux_instance_t * mmi,uint32_t freq)1571 linuxdvb_frontend_tune0
1572   ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi, uint32_t freq )
1573 {
1574   static linuxdvb_tbl_t inv_tbl[] = {
1575     { .t = DVB_INVERSION_AUTO,          .l = INVERSION_AUTO  },
1576     { .t = DVB_INVERSION_OFF,           .l = INVERSION_OFF   },
1577     { .t = DVB_INVERSION_ON,            .l = INVERSION_ON    },
1578     { .t = TABLE_EOD }
1579   };
1580   static linuxdvb_tbl_t bw_tbl[] = {
1581     { .t = DVB_BANDWIDTH_AUTO,          .l = BANDWIDTH_AUTO      },
1582 #if DVB_VER_ATLEAST(5,3)
1583     { .t = DVB_BANDWIDTH_1_712_MHZ,     .l = BANDWIDTH_1_712_MHZ },
1584     { .t = DVB_BANDWIDTH_5_MHZ,         .l = BANDWIDTH_5_MHZ     },
1585 #endif
1586     { .t = DVB_BANDWIDTH_6_MHZ,         .l = BANDWIDTH_6_MHZ     },
1587     { .t = DVB_BANDWIDTH_7_MHZ,         .l = BANDWIDTH_7_MHZ     },
1588     { .t = DVB_BANDWIDTH_8_MHZ,         .l = BANDWIDTH_8_MHZ     },
1589 #if DVB_VER_ATLEAST(5,3)
1590     { .t = DVB_BANDWIDTH_10_MHZ,        .l = BANDWIDTH_10_MHZ    },
1591 #endif
1592     { .t = TABLE_EOD }
1593   };
1594   static linuxdvb_tbl_t fec_tbl[] = {
1595     { .t = DVB_FEC_NONE,                .l = FEC_NONE  },
1596     { .t = DVB_FEC_AUTO,                .l = FEC_AUTO  },
1597     { .t = DVB_FEC_1_2,                 .l = FEC_1_2   },
1598     { .t = DVB_FEC_2_3,                 .l = FEC_2_3   },
1599 #if DVB_VER_ATLEAST(5,7)
1600     { .t = DVB_FEC_2_5,                 .l = FEC_2_5   },
1601 #endif
1602     { .t = DVB_FEC_3_4,                 .l = FEC_3_4   },
1603 #if DVB_VER_ATLEAST(5,0)
1604     { .t = DVB_FEC_3_5,                 .l = FEC_3_5   },
1605 #endif
1606     { .t = DVB_FEC_4_5,                 .l = FEC_4_5   },
1607     { .t = DVB_FEC_5_6,                 .l = FEC_5_6   },
1608     { .t = DVB_FEC_6_7,                 .l = FEC_6_7   },
1609     { .t = DVB_FEC_7_8,                 .l = FEC_7_8   },
1610     { .t = DVB_FEC_8_9,                 .l = FEC_8_9   },
1611 #if DVB_VER_ATLEAST(5,0)
1612     { .t = DVB_FEC_9_10,                .l = FEC_9_10  },
1613 #endif
1614     { .t = TABLE_EOD }
1615   };
1616   static linuxdvb_tbl_t mod_tbl[] = {
1617     { .t = DVB_MOD_AUTO,                .l = QAM_AUTO },
1618     { .t = DVB_MOD_QPSK,                .l = QPSK     },
1619     { .t = DVB_MOD_QAM_16,              .l = QAM_16   },
1620     { .t = DVB_MOD_QAM_32,              .l = QAM_32   },
1621     { .t = DVB_MOD_QAM_64,              .l = QAM_64   },
1622     { .t = DVB_MOD_QAM_128,             .l = QAM_128  },
1623     { .t = DVB_MOD_QAM_256,             .l = QAM_256  },
1624     { .t = DVB_MOD_QAM_AUTO,            .l = QAM_AUTO },
1625     { .t = DVB_MOD_VSB_8,               .l = VSB_8    },
1626     { .t = DVB_MOD_VSB_16,              .l = VSB_16   },
1627 #if DVB_VER_ATLEAST(5,1)
1628     { .t = DVB_MOD_PSK_8,               .l = PSK_8,   },
1629     { .t = DVB_MOD_APSK_16,             .l = APSK_16  },
1630     { .t = DVB_MOD_APSK_32,             .l = APSK_32  },
1631 #endif
1632 #if DVB_VER_ATLEAST(5,0)
1633     { .t = DVB_MOD_DQPSK,               .l = DQPSK    },
1634 #endif
1635 #if DVB_VER_ATLEAST(5,7)
1636     { .t = DVB_MOD_QAM_4_NR,            .l = QAM_4_NR },
1637 #endif
1638     { .t = TABLE_EOD }
1639   };
1640   static linuxdvb_tbl_t trans_tbl[] = {
1641     { .t = DVB_TRANSMISSION_MODE_AUTO,  .l = TRANSMISSION_MODE_AUTO  },
1642 #if DVB_VER_ATLEAST(5,3)
1643     { .t = DVB_TRANSMISSION_MODE_1K,    .l = TRANSMISSION_MODE_1K    },
1644 #endif
1645     { .t = DVB_TRANSMISSION_MODE_2K,    .l = TRANSMISSION_MODE_2K    },
1646 #if DVB_VER_ATLEAST(5,1)
1647     { .t = DVB_TRANSMISSION_MODE_4K,    .l = TRANSMISSION_MODE_4K    },
1648 #endif
1649     { .t = DVB_TRANSMISSION_MODE_8K,    .l = TRANSMISSION_MODE_8K    },
1650 #if DVB_VER_ATLEAST(5,3)
1651     { .t = DVB_TRANSMISSION_MODE_16K,   .l = TRANSMISSION_MODE_16K   },
1652     { .t = DVB_TRANSMISSION_MODE_32K,   .l = TRANSMISSION_MODE_32K   },
1653 #endif
1654 #if DVB_VER_ATLEAST(5,7)
1655     { .t = DVB_TRANSMISSION_MODE_C3780, .l = TRANSMISSION_MODE_C3780 },
1656     { .t = DVB_TRANSMISSION_MODE_C1,    .l = TRANSMISSION_MODE_C1    },
1657 #endif
1658     { .t = TABLE_EOD }
1659   };
1660   static linuxdvb_tbl_t guard_tbl[] = {
1661     { .t = DVB_GUARD_INTERVAL_AUTO,     .l = GUARD_INTERVAL_AUTO   },
1662     { .t = DVB_GUARD_INTERVAL_1_4,      .l = GUARD_INTERVAL_1_4    },
1663     { .t = DVB_GUARD_INTERVAL_1_8,      .l = GUARD_INTERVAL_1_8    },
1664     { .t = DVB_GUARD_INTERVAL_1_16,     .l = GUARD_INTERVAL_1_16   },
1665     { .t = DVB_GUARD_INTERVAL_1_32,     .l = GUARD_INTERVAL_1_32   },
1666 #if DVB_VER_ATLEAST(5,3)
1667     { .t = DVB_GUARD_INTERVAL_1_128,    .l = GUARD_INTERVAL_1_128  },
1668     { .t = DVB_GUARD_INTERVAL_19_128,   .l = GUARD_INTERVAL_19_128 },
1669     { .t = DVB_GUARD_INTERVAL_19_256,   .l = GUARD_INTERVAL_19_256 },
1670 #endif
1671     { .t = TABLE_EOD }
1672   };
1673   static linuxdvb_tbl_t h_tbl[] = {
1674     { .t = DVB_HIERARCHY_NONE,          .l = HIERARCHY_NONE },
1675     { .t = DVB_HIERARCHY_AUTO,          .l = HIERARCHY_AUTO },
1676     { .t = DVB_HIERARCHY_1,             .l = HIERARCHY_1    },
1677     { .t = DVB_HIERARCHY_2,             .l = HIERARCHY_2    },
1678     { .t = DVB_HIERARCHY_4,             .l = HIERARCHY_4    },
1679     { .t = TABLE_EOD }
1680   };
1681 #if DVB_API_VERSION >= 5
1682   static linuxdvb_tbl_t pilot_tbl[] = {
1683     { .t = DVB_PILOT_AUTO,              .l = PILOT_AUTO },
1684     { .t = DVB_PILOT_ON,                .l = PILOT_ON   },
1685     { .t = DVB_PILOT_OFF,               .l = PILOT_OFF  },
1686     { .t = TABLE_EOD }
1687   };
1688   static linuxdvb_tbl_t rolloff_tbl[] = {
1689     { .t = DVB_HIERARCHY_AUTO,          .l = ROLLOFF_AUTO },
1690     { .t = DVB_ROLLOFF_20,              .l = ROLLOFF_20   },
1691     { .t = DVB_ROLLOFF_25,              .l = ROLLOFF_25   },
1692     { .t = DVB_ROLLOFF_35,              .l = ROLLOFF_35   },
1693     { .t = TABLE_EOD },
1694   };
1695 #endif
1696   int r;
1697   struct dvb_frontend_event ev;
1698   char buf1[256];
1699   dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux;
1700   dvb_mux_conf_t *dmc;
1701   struct dvb_frontend_parameters p;
1702 
1703   r = linuxdvb_frontend_clear(lfe, NULL);
1704   if (r) return r;
1705 
1706   lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1));
1707 
1708   /*
1709    * copy the universal parameters to the Linux kernel structure
1710    */
1711 
1712   dmc = &lm->lm_tuning;
1713   if (tvhtrace_enabled()) {
1714     char buf2[256];
1715     dvb_mux_conf_str(&lm->lm_tuning, buf2, sizeof(buf2));
1716     tvhtrace(LS_LINUXDVB, "tuner %s tuning to %s (freq %i)", buf1, buf2, freq);
1717   }
1718   memset(&p, 0, sizeof(p));
1719   p.frequency                = dmc->dmc_fe_freq;
1720   p.inversion                = TR(inversion, inv_tbl, INVERSION_AUTO);
1721   switch (dmc->dmc_fe_type) {
1722   case DVB_TYPE_T:
1723 #define _OFDM(xyz) p.u.ofdm.xyz
1724     _OFDM(bandwidth)         = TRU(ofdm.bandwidth, bw_tbl, BANDWIDTH_AUTO);
1725     _OFDM(code_rate_HP)      = TRU(ofdm.code_rate_HP, fec_tbl, FEC_AUTO);
1726     _OFDM(code_rate_LP)      = TRU(ofdm.code_rate_LP, fec_tbl, FEC_AUTO);
1727     _OFDM(constellation)     = TR(modulation, mod_tbl, QAM_AUTO);
1728     _OFDM(transmission_mode) = TRU(ofdm.transmission_mode, trans_tbl, TRANSMISSION_MODE_AUTO);
1729     _OFDM(guard_interval)    = TRU(ofdm.guard_interval, guard_tbl, GUARD_INTERVAL_AUTO);
1730     _OFDM(hierarchy_information)
1731                              = TRU(ofdm.hierarchy_information, h_tbl, HIERARCHY_AUTO);
1732 #undef _OFDM
1733     break;
1734   case DVB_TYPE_C:
1735   case DVB_TYPE_ATSC_C:
1736   case DVB_TYPE_ISDB_C:
1737     p.u.qam.symbol_rate      = dmc->u.dmc_fe_qam.symbol_rate;
1738     p.u.qam.fec_inner        = TRU(qam.fec_inner, fec_tbl, FEC_AUTO);
1739     p.u.qam.modulation       = TR(modulation, mod_tbl, QAM_AUTO);
1740     break;
1741   case DVB_TYPE_S:
1742     p.u.qpsk.symbol_rate     = dmc->u.dmc_fe_qpsk.symbol_rate;
1743     p.u.qpsk.fec_inner       = TRU(qpsk.fec_inner, fec_tbl, FEC_AUTO);
1744     break;
1745   case DVB_TYPE_ATSC_T:
1746     p.u.vsb.modulation       = TR(modulation, mod_tbl, QAM_AUTO);
1747     break;
1748 #if DVB_API_VERSION >= 5
1749   case DVB_TYPE_ISDB_T:
1750   case DVB_TYPE_DAB:
1751     break;
1752 #endif
1753   default:
1754     tvherror(LS_LINUXDVB, "%s - unknown FE type %d", buf1, dmc->dmc_fe_type);
1755     return SM_CODE_TUNING_FAILED;
1756   }
1757 
1758   if (freq != (uint32_t)-1)
1759     p.frequency = lfe->lfe_freq = freq;
1760 
1761   if (dmc->dmc_fe_type != lfe->lfe_type) {
1762     tvherror(LS_LINUXDVB, "%s - failed to tune [type does not match %i != %i]", buf1, dmc->dmc_fe_type, lfe->lfe_type);
1763     return SM_CODE_TUNING_FAILED;
1764   }
1765 
1766   /* S2 tuning */
1767 #if DVB_API_VERSION >= 5
1768   struct dtv_property cmds[32];
1769   struct dtv_properties cmdseq;
1770 
1771 
1772   if (freq == (uint32_t)-1)
1773     freq = p.frequency;
1774 
1775   memset(&cmdseq, 0, sizeof(cmdseq));
1776   cmdseq.props = cmds;
1777   memset(&cmds, 0, sizeof(cmds));
1778 
1779   /* Tune */
1780 #define S2CMD(c, d) do { \
1781   cmds[cmdseq.num].cmd      = c; \
1782   cmds[cmdseq.num++].u.data = d; \
1783 } while (0)
1784 
1785   memset(&cmds, 0, sizeof(cmds));
1786   S2CMD(DTV_DELIVERY_SYSTEM, TR(delsys, delsys_tbl, SYS_UNDEFINED));
1787   S2CMD(DTV_FREQUENCY,       freq);
1788   S2CMD(DTV_INVERSION,       p.inversion);
1789 
1790   /* DVB-T */
1791   if (lfe->lfe_type == DVB_TYPE_T) {
1792     S2CMD(DTV_BANDWIDTH_HZ,      dvb_bandwidth(dmc->u.dmc_fe_ofdm.bandwidth));
1793 #if DVB_VER_ATLEAST(5,1)
1794     S2CMD(DTV_CODE_RATE_HP,      p.u.ofdm.code_rate_HP);
1795     S2CMD(DTV_CODE_RATE_LP,      p.u.ofdm.code_rate_LP);
1796 #endif
1797     S2CMD(DTV_MODULATION,        p.u.ofdm.constellation);
1798 #if DVB_VER_ATLEAST(5,1)
1799     S2CMD(DTV_TRANSMISSION_MODE, p.u.ofdm.transmission_mode);
1800     S2CMD(DTV_GUARD_INTERVAL,    p.u.ofdm.guard_interval);
1801     S2CMD(DTV_HIERARCHY,         p.u.ofdm.hierarchy_information);
1802 #endif
1803     if (lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBT2) {
1804 #if DVB_VER_ATLEAST(5,9)
1805       S2CMD(DTV_STREAM_ID, dmc->dmc_fe_stream_id);
1806 #elif DVB_VER_ATLEAST(5,3)
1807       S2CMD(DTV_DVBT2_PLP_ID, dmc->dmc_fe_stream_id);
1808 #endif
1809     }
1810 #if DVB_VER_ATLEAST(5,9)
1811     if (lfe->lfe_lna)
1812       S2CMD(DTV_LNA, 1);
1813 #endif
1814 
1815   /* DVB-C */
1816   } else if (lfe->lfe_type == DVB_TYPE_C ||
1817              lfe->lfe_type == DVB_TYPE_ATSC_C ||
1818              lfe->lfe_type == DVB_TYPE_ISDB_C) {
1819     S2CMD(DTV_SYMBOL_RATE,       p.u.qam.symbol_rate);
1820     S2CMD(DTV_MODULATION,        p.u.qam.modulation);
1821     S2CMD(DTV_INNER_FEC,         p.u.qam.fec_inner);
1822     r = dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER ? (dmc->dmc_fe_stream_id & 0xFF) |
1823           ((dmc->dmc_fe_data_slice & 0xFF)<<8) : DVB_NO_STREAM_ID_FILTER;
1824 #if DVB_VER_ATLEAST(5,9)
1825     S2CMD(DTV_STREAM_ID,         r);
1826 #endif
1827 
1828   /* DVB-S */
1829   } else if (lfe->lfe_type == DVB_TYPE_S) {
1830     S2CMD(DTV_SYMBOL_RATE,       p.u.qpsk.symbol_rate);
1831     S2CMD(DTV_INNER_FEC,         p.u.qpsk.fec_inner);
1832     S2CMD(DTV_MODULATION,        TR(modulation, mod_tbl, QPSK));
1833     if (lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBS) {
1834       S2CMD(DTV_ROLLOFF,         ROLLOFF_35);
1835     } else {
1836       S2CMD(DTV_PILOT,           TR(pilot, pilot_tbl, PILOT_AUTO));
1837       S2CMD(DTV_ROLLOFF,         TR(rolloff, rolloff_tbl, ROLLOFF_AUTO));
1838       r = dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER ? (dmc->dmc_fe_stream_id & 0xFF) |
1839           ((dmc->dmc_fe_pls_code & 0x3FFFF)<<8) | ((dmc->dmc_fe_pls_mode & 0x3)<<26) :
1840           DVB_NO_STREAM_ID_FILTER;
1841 #if DVB_VER_ATLEAST(5,9)
1842       S2CMD(DTV_STREAM_ID,       r);
1843 #if DVB_VER_ATLEAST(5,11)
1844       r = dvb_sat_pls(dmc);
1845       if (r != 0) /* default PLS gold code */
1846         S2CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, r);
1847 #endif
1848 #elif DVB_VER_ATLEAST(5,3)
1849       S2CMD(DTV_DVBT2_PLP_ID,    r);
1850 #endif
1851     }
1852 
1853   /* ATSC-T */
1854   } else if (lfe->lfe_type == DVB_TYPE_ATSC_T) {
1855     S2CMD(DTV_MODULATION,        p.u.vsb.modulation);
1856 
1857 #if DVB_VER_ATLEAST(5,0)
1858   /* ISDB-T */
1859   } else if (lfe->lfe_type == DVB_TYPE_ISDB_T) {
1860     int i, j;
1861     S2CMD(DTV_BANDWIDTH_HZ,      dvb_bandwidth(dmc->u.dmc_fe_isdbt.bandwidth));
1862 #if DVB_VER_ATLEAST(5,1)
1863     S2CMD(DTV_GUARD_INTERVAL, TRU(isdbt.guard_interval, guard_tbl, GUARD_INTERVAL_AUTO));
1864     S2CMD(DTV_TRANSMISSION_MODE, TRANSMISSION_MODE_AUTO);
1865     S2CMD(DTV_ISDBT_LAYER_ENABLED,     7);
1866     S2CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1);
1867     S2CMD(DTV_ISDBT_SOUND_BROADCASTING,0);
1868     S2CMD(DTV_ISDBT_SB_SUBCHANNEL_ID,  0);
1869     S2CMD(DTV_ISDBT_SB_SEGMENT_IDX,    0);
1870     S2CMD(DTV_ISDBT_SB_SEGMENT_COUNT,  0);
1871     for (i = j = 0; i < 3; i++, j += DTV_ISDBT_LAYERB_FEC - DTV_ISDBT_LAYERA_FEC) {
1872       S2CMD(DTV_ISDBT_LAYERA_FEC               + j, TRU(isdbt.layers[i].fec, fec_tbl, FEC_AUTO));
1873       S2CMD(DTV_ISDBT_LAYERA_MODULATION        + j, TRU(isdbt.layers[i].modulation, mod_tbl, QAM_AUTO));
1874       S2CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT     + j, dmc->u.dmc_fe_isdbt.layers[i].segment_count);
1875       S2CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING + j, dmc->u.dmc_fe_isdbt.layers[i].time_interleaving);
1876     }
1877 #endif
1878 
1879   /* ISDB-S */
1880   } else if (lfe->lfe_type == DVB_TYPE_ISDB_S) {
1881     r = dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER ? (dmc->dmc_fe_stream_id & 0xFF) |
1882         ((dmc->dmc_fe_pls_code & 0x3FFFF)<<8) | ((dmc->dmc_fe_pls_mode & 0x3)<<26) :
1883         DVB_NO_STREAM_ID_FILTER;
1884 #if DVB_VER_ATLEAST(5,9)
1885     S2CMD(DTV_STREAM_ID,       r);
1886 #if DVB_VER_ATLEAST(5,11)
1887     r = dvb_sat_pls(dmc);
1888     if (r != 0) /* default PLS gold code */
1889       S2CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, r);
1890 #endif
1891 #elif DVB_VER_ATLEAST(5,3)
1892     S2CMD(DTV_DVBT2_PLP_ID,    r);
1893 #endif
1894 
1895   /* DAB */
1896   } else if (lfe->lfe_type == DVB_TYPE_DAB) {
1897 #endif /* 5.0+ */
1898   }
1899 
1900   /* Tune */
1901   S2CMD(DTV_TUNE, 0);
1902 #undef S2CMD
1903 #endif
1904 
1905   /* discard stale events */
1906   while (1) {
1907     if (ioctl(lfe->lfe_fe_fd, FE_GET_EVENT, &ev) < 0)
1908       break;
1909   }
1910 
1911   /* S2 tuning */
1912 #if DVB_API_VERSION >= 5
1913   if (tvhtrace_enabled()) {
1914     int i;
1915     for (i = 0; i < cmdseq.num; i++)
1916       tvhtrace(LS_LINUXDVB, "S2CMD %02u => %u", cmds[i].cmd, cmds[i].u.data);
1917   }
1918   r = ioctl(lfe->lfe_fe_fd, FE_SET_PROPERTY, &cmdseq);
1919 
1920   /* v3 tuning */
1921 #else
1922   r = ioctl(lfe->lfe_fe_fd, FE_SET_FRONTEND, p);
1923 #endif
1924 
1925   /* Failed */
1926   if (r != 0) {
1927     tvherror(LS_LINUXDVB, "%s - failed to tune [e=%s]", buf1, strerror(errno));
1928     if (errno == EINVAL)
1929       mmi->mmi_tune_failed = 1;
1930     return SM_CODE_TUNING_FAILED;
1931   }
1932 
1933   return r;
1934 }
1935 
1936 int
linuxdvb_frontend_tune1(linuxdvb_frontend_t * lfe,mpegts_mux_instance_t * mmi,uint32_t freq)1937 linuxdvb_frontend_tune1
1938   ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi, uint32_t freq )
1939 {
1940   int r = 0, i, rep;
1941   char buf1[256], buf2[256];
1942 
1943   lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1));
1944   mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2));
1945   tvhdebug(LS_LINUXDVB, "%s - starting %s", buf1, buf2);
1946 
1947   /* Tune */
1948   tvhtrace(LS_LINUXDVB, "%s - tuning", buf1);
1949   rep = lfe->lfe_tune_repeats > 0 ? lfe->lfe_tune_repeats : 0;
1950   for (i = 0; i <= rep; i++) {
1951     if (i > 0)
1952       tvh_safe_usleep(15000);
1953     r = linuxdvb_frontend_tune0(lfe, mmi, freq);
1954     if (r)
1955       break;
1956   }
1957 
1958   /* Start monitor */
1959   if (!r) {
1960     time(&lfe->lfe_monitor);
1961     lfe->lfe_monitor += 4;
1962     mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, ms2mono(50));
1963     lfe->lfe_ready = 1;
1964   }
1965 
1966   lfe->lfe_in_setup = 0;
1967 
1968   return r;
1969 }
1970 
1971 
1972 /* **************************************************************************
1973  * Creation/Config
1974  * *************************************************************************/
1975 
1976 static mpegts_network_t *
linuxdvb_frontend_wizard_network(linuxdvb_frontend_t * lfe)1977 linuxdvb_frontend_wizard_network ( linuxdvb_frontend_t *lfe )
1978 {
1979   linuxdvb_satconf_ele_t *ele = NULL;
1980 
1981   if (lfe->lfe_satconf) {
1982     ele = TAILQ_FIRST(&lfe->lfe_satconf->ls_elements);
1983     if (ele && ele->lse_networks && ele->lse_networks->is_count > 0)
1984       return (mpegts_network_t *)ele->lse_networks->is_array[0];
1985   }
1986   return (mpegts_network_t *)LIST_FIRST(&lfe->mi_networks);
1987 }
1988 
1989 static htsmsg_t *
linuxdvb_frontend_wizard_get(tvh_input_t * ti,const char * lang)1990 linuxdvb_frontend_wizard_get( tvh_input_t *ti, const char *lang )
1991 {
1992   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ti;
1993   mpegts_network_t *mn;
1994   const idclass_t *idc = NULL;
1995 
1996   mn = linuxdvb_frontend_wizard_network(lfe);
1997   if ((lfe->lfe_master == 0 && mn == NULL) || (mn && mn->mn_wizard))
1998     idc = dvb_network_class_by_fe_type(lfe->lfe_type);
1999   return mpegts_network_wizard_get((mpegts_input_t *)lfe, idc, mn, lang);
2000 }
2001 
2002 static void
linuxdvb_frontend_wizard_set(tvh_input_t * ti,htsmsg_t * conf,const char * lang)2003 linuxdvb_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang )
2004 {
2005   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ti;
2006   const char *ntype = htsmsg_get_str(conf, "mpegts_network_type");
2007   mpegts_network_t *mn;
2008   htsmsg_t *nlist;
2009 
2010   if (LIST_FIRST(&lfe->mi_mux_active))
2011     return;
2012   mpegts_network_wizard_create(ntype, &nlist, lang);
2013   mn = linuxdvb_frontend_wizard_network(lfe);
2014   if (ntype && (mn == NULL || mn->mn_wizard)) {
2015     if (lfe->lfe_satconf) {
2016       htsmsg_t *conf = htsmsg_create_map();
2017       htsmsg_t *elems = htsmsg_create_list();
2018       htsmsg_t *elem = htsmsg_create_map();
2019       htsmsg_add_str(conf, "type", "4port");
2020       htsmsg_add_bool(elem, "enable", 1);
2021       htsmsg_add_msg(elem, "networks", nlist);
2022       htsmsg_add_msg(elems, NULL, elem);
2023       htsmsg_add_msg(conf, "elements", elems);
2024       if (lfe->lfe_satconf) {
2025         linuxdvb_satconf_delete(lfe->lfe_satconf, 0);
2026         lfe->lfe_satconf = NULL;
2027       }
2028       lfe->lfe_satconf = linuxdvb_satconf_create(lfe, conf);
2029       htsmsg_destroy(conf);
2030     } else {
2031       mpegts_input_set_networks((mpegts_input_t *)lfe, nlist);
2032       htsmsg_destroy(nlist);
2033     }
2034     if (linuxdvb_frontend_wizard_network(lfe))
2035       mpegts_input_set_enabled((mpegts_input_t *)lfe, 1);
2036     linuxdvb_adapter_changed(lfe->lfe_adapter);
2037   } else {
2038     htsmsg_destroy(nlist);
2039   }
2040 }
2041 
2042 linuxdvb_frontend_t *
linuxdvb_frontend_create(htsmsg_t * conf,linuxdvb_adapter_t * la,int number,const char * fe_path,const char * dmx_path,const char * dvr_path,dvb_fe_type_t type,const char * name)2043 linuxdvb_frontend_create
2044   ( htsmsg_t *conf, linuxdvb_adapter_t *la, int number,
2045     const char *fe_path, const char *dmx_path, const char *dvr_path,
2046     dvb_fe_type_t type, const char *name )
2047 {
2048   const idclass_t *idc;
2049   const char *str, *uuid = NULL, *muuid = NULL;
2050   char id[16], lname[256], buf[256];
2051   linuxdvb_frontend_t *lfe;
2052   htsmsg_t *scconf;
2053   ssize_t r;
2054 
2055   /* Tuner slave */
2056   snprintf(id, sizeof(id), "master for #%d", number);
2057   if (conf && type == DVB_TYPE_S) {
2058     muuid = htsmsg_get_str(conf, id);
2059     if (muuid && uuid && !strcmp(muuid, uuid))
2060       muuid = NULL;
2061   }
2062 
2063   /* Internal config ID */
2064   snprintf(id, sizeof(id), "%s #%d", dvb_type2str(type), number);
2065   if (conf)
2066     conf = htsmsg_get_map(conf, id);
2067   if (conf)
2068     uuid = htsmsg_get_str(conf, "uuid");
2069 
2070   /* Fudge configuration for old network entry */
2071   if (conf) {
2072     if (!htsmsg_get_list(conf, "networks") &&
2073         (str = htsmsg_get_str(conf, "network"))) {
2074       htsmsg_t *l = htsmsg_create_list();
2075       htsmsg_add_str(l, NULL, str);
2076       htsmsg_add_msg(conf, "networks", l);
2077     }
2078   }
2079 
2080   /* Class */
2081   if (type == DVB_TYPE_S)
2082     idc = muuid ? &linuxdvb_frontend_dvbs_slave_class :
2083                   &linuxdvb_frontend_dvbs_class;
2084   else if (type == DVB_TYPE_C)
2085     idc = &linuxdvb_frontend_dvbc_class;
2086   else if (type == DVB_TYPE_T)
2087     idc = &linuxdvb_frontend_dvbt_class;
2088   else if (type == DVB_TYPE_ATSC_T)
2089     idc = &linuxdvb_frontend_atsc_t_class;
2090   else if (type == DVB_TYPE_ATSC_C)
2091     idc = &linuxdvb_frontend_atsc_c_class;
2092   else if (type == DVB_TYPE_ISDB_T)
2093     idc = &linuxdvb_frontend_isdb_t_class;
2094   else if (type == DVB_TYPE_ISDB_C)
2095     idc = &linuxdvb_frontend_isdb_c_class;
2096   else if (type == DVB_TYPE_ISDB_S)
2097     idc = &linuxdvb_frontend_isdb_s_class;
2098   else if (type == DVB_TYPE_DAB)
2099     idc = &linuxdvb_frontend_dab_class;
2100   else {
2101     tvherror(LS_LINUXDVB, "unknown FE type %d", type);
2102     return NULL;
2103   }
2104 
2105   /* Create */
2106   // Note: there is a bit of a chicken/egg issue below, without the
2107   //       correct "fe_type" we cannot set the network (which is done
2108   //       in mpegts_input_create()). So we must set early.
2109   lfe = calloc(1, sizeof(linuxdvb_frontend_t));
2110   lfe->lfe_number = number;
2111   lfe->lfe_type   = type;
2112   lfe->lfe_master = muuid ? strdup(muuid) : NULL;
2113   strncpy(lfe->lfe_name, name, sizeof(lfe->lfe_name));
2114   lfe->lfe_name[sizeof(lfe->lfe_name)-1] = '\0';
2115   lfe->lfe_ibuf_size = 188000;
2116   lfe->lfe_status_period = 1000;
2117   lfe->lfe_pids_max = 32;
2118   lfe->lfe_pids_use_all = 1;
2119   lfe = (linuxdvb_frontend_t*)mpegts_input_create0((mpegts_input_t*)lfe, idc, uuid, conf);
2120   if (!lfe) return NULL;
2121 
2122   /* Sysfs path */
2123   snprintf(lname, sizeof(lname), "/sys/class/dvb/dvb%d.frontend%d", la->la_dvb_number, number);
2124   r = readlink(lname, buf, sizeof(buf));
2125   if (r > 0) {
2126     if (r == sizeof(buf)) r--;
2127     buf[r] = '\0';
2128     if (strncmp(str = buf, "../../", 6) == 0) str += 6;
2129     lfe->lfe_sysfs = strdup(str);
2130   }
2131 
2132   /* Callbacks */
2133   lfe->mi_get_weight   = linuxdvb_frontend_get_weight;
2134   lfe->mi_get_priority = linuxdvb_frontend_get_priority;
2135   lfe->mi_get_grace    = linuxdvb_frontend_get_grace;
2136 
2137   /* Default name */
2138   if (!lfe->mi_name) {
2139     snprintf(lname, sizeof(lname), "%s : %s", name, id);
2140     lfe->mi_name = strdup(lname);
2141   }
2142 
2143   /* Set paths */
2144   lfe->lfe_fe_path  = strdup(fe_path);
2145   lfe->lfe_dmx_path = strdup(dmx_path);
2146   lfe->lfe_dvr_path = strdup(dvr_path);
2147 
2148   /* Input callbacks */
2149   lfe->ti_wizard_get      = linuxdvb_frontend_wizard_get;
2150   lfe->ti_wizard_set      = linuxdvb_frontend_wizard_set;
2151   lfe->mi_is_enabled      = linuxdvb_frontend_is_enabled;
2152   lfe->mi_warm_mux        = linuxdvb_frontend_warm_mux;
2153   lfe->mi_start_mux       = linuxdvb_frontend_start_mux;
2154   lfe->mi_stop_mux        = linuxdvb_frontend_stop_mux;
2155   lfe->mi_network_list    = linuxdvb_frontend_network_list;
2156   lfe->mi_update_pids     = linuxdvb_frontend_update_pids;
2157   lfe->mi_enabled_updated = linuxdvb_frontend_enabled_updated;
2158   lfe->mi_empty_status    = mpegts_input_empty_status;
2159 
2160   /* Adapter link */
2161   lfe->lfe_adapter = la;
2162   LIST_INSERT_HEAD(&la->la_frontends, lfe, lfe_link);
2163 
2164   /* DVR lock/cond */
2165   pthread_mutex_init(&lfe->lfe_dvr_lock, NULL);
2166   tvh_cond_init(&lfe->lfe_dvr_cond);
2167   mpegts_pid_init(&lfe->lfe_pids);
2168 
2169   /* Create satconf */
2170   if (lfe->lfe_type == DVB_TYPE_S && !lfe->lfe_satconf && !muuid) {
2171     scconf = conf ? htsmsg_get_map(conf, "satconf") : NULL;
2172     lfe->lfe_satconf = linuxdvb_satconf_create(lfe, scconf);
2173   }
2174 
2175   /* Double check enabled */
2176   linuxdvb_frontend_enabled_updated((mpegts_input_t*)lfe);
2177 
2178   return lfe;
2179 }
2180 
2181 void
linuxdvb_frontend_save(linuxdvb_frontend_t * lfe,htsmsg_t * fe)2182 linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *fe )
2183 {
2184   char id[16], ubuf[UUID_HEX_SIZE];
2185   htsmsg_t *m = htsmsg_create_map();
2186 
2187   /* Save frontend */
2188   mpegts_input_save((mpegts_input_t*)lfe, m);
2189   htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_type));
2190   htsmsg_add_str(m, "uuid", idnode_uuid_as_str(&lfe->ti_id, ubuf));
2191   if (lfe->lfe_satconf && !lfe->lfe_master) {
2192     htsmsg_t *s = htsmsg_create_map();
2193     linuxdvb_satconf_save(lfe->lfe_satconf, s);
2194     htsmsg_add_str(s, "uuid", idnode_uuid_as_str(&lfe->lfe_satconf->ls_id, ubuf));
2195     htsmsg_add_msg(m, "satconf", s);
2196   }
2197   htsmsg_delete_field(m, "fe_master");
2198 
2199   /* Add to list */
2200   snprintf(id, sizeof(id), "%s #%d", dvb_type2str(lfe->lfe_type), lfe->lfe_number);
2201   htsmsg_add_msg(fe, id, m);
2202 
2203   if (lfe->lfe_master) {
2204     snprintf(id, sizeof(id), "master for #%d", lfe->lfe_number);
2205     htsmsg_add_str(fe, id, lfe->lfe_master);
2206   }
2207 }
2208 
2209 void
linuxdvb_frontend_delete(linuxdvb_frontend_t * lfe)2210 linuxdvb_frontend_delete ( linuxdvb_frontend_t *lfe )
2211 {
2212   lock_assert(&global_lock);
2213 
2214   /* Ensure we're stopped */
2215   mpegts_input_stop_all((mpegts_input_t*)lfe);
2216 
2217   /* Stop monitor */
2218   mtimer_disarm(&lfe->lfe_monitor_timer);
2219 
2220   /* Close FDs */
2221   if (lfe->lfe_fe_fd > 0)
2222     close(lfe->lfe_fe_fd);
2223 
2224   /* Remove from adapter */
2225   LIST_REMOVE(lfe, lfe_link);
2226 
2227   /* Free memory */
2228   free(lfe->lfe_sysfs);
2229   free(lfe->lfe_fe_path);
2230   free(lfe->lfe_dmx_path);
2231   free(lfe->lfe_dvr_path);
2232   free(lfe->lfe_master);
2233 
2234   /* Delete satconf */
2235   if (lfe->lfe_satconf)
2236     linuxdvb_satconf_delete(lfe->lfe_satconf, 0);
2237 
2238   /* Finish */
2239   mpegts_input_delete((mpegts_input_t*)lfe, 0);
2240 }
2241 
2242 /******************************************************************************
2243  * Editor Configuration
2244  *
2245  * vim:sts=2:ts=2:sw=2:et
2246  *****************************************************************************/
2247