Remove legacy parameter from add_string()
[vlc/asuraparaju-public.git] / modules / access / dvb / access.c
blob70e6a7a429df2dc5020593ea3da345f5d6a15ad2
1 /*****************************************************************************
2 * access.c: DVB card input v4l2 only
3 *****************************************************************************
4 * Copyright (C) 1998-2010 the VideoLAN team
6 * Authors: Johan Bilien <jobi@via.ecp.fr>
7 * Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Laurent Aimar <fenrir@via.ecp.fr>
10 * David Kaplan <david@2of1.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
28 /*****************************************************************************
29 * Preamble
30 *****************************************************************************/
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_access.h>
38 #include <vlc_input.h>
39 #include <vlc_interface.h>
40 #include <vlc_dialog.h>
41 #include <vlc_fs.h>
43 #ifdef HAVE_UNISTD_H
44 # include <unistd.h>
45 #endif
47 #include <sys/types.h>
48 #include <poll.h>
50 #include <errno.h>
52 /* Include dvbpsi headers */
53 #ifdef HAVE_DVBPSI_DR_H
54 # include <dvbpsi/dvbpsi.h>
55 # include <dvbpsi/descriptor.h>
56 # include <dvbpsi/pat.h>
57 # include <dvbpsi/pmt.h>
58 # include <dvbpsi/dr.h>
59 # include <dvbpsi/psi.h>
60 # include <dvbpsi/demux.h>
61 # include <dvbpsi/sdt.h>
62 #else
63 # include "dvbpsi.h"
64 # include "descriptor.h"
65 # include "tables/pat.h"
66 # include "tables/pmt.h"
67 # include "descriptors/dr.h"
68 # include "psi.h"
69 # include "demux.h"
70 # include "tables/sdt.h"
71 #endif
73 #ifdef ENABLE_HTTPD
74 # include <vlc_httpd.h>
75 #endif
77 #include "dvb.h"
79 /*****************************************************************************
80 * Module descriptor
81 *****************************************************************************/
82 static int Open( vlc_object_t *p_this );
83 static void Close( vlc_object_t *p_this );
85 #define CACHING_TEXT N_("Caching value in ms")
86 #define CACHING_LONGTEXT N_( \
87 "Caching value for DVB streams. This " \
88 "value should be set in milliseconds." )
90 #define ADAPTER_TEXT N_("Adapter card to tune")
91 #define ADAPTER_LONGTEXT N_("Adapter cards have a device file in directory named /dev/dvb/adapter[n] with n>=0.")
93 #define DEVICE_TEXT N_("Device number to use on adapter")
94 #define DEVICE_LONGTEXT ""
96 #define FREQ_TEXT N_("Transponder/multiplex frequency")
97 #define FREQ_LONGTEXT N_("In kHz for DVB-S or Hz for DVB-C/T")
99 #define INVERSION_TEXT N_("Inversion mode")
100 #define INVERSION_LONGTEXT N_("Inversion mode [0=off, 1=on, 2=auto]")
102 #define PROBE_TEXT N_("Probe DVB card for capabilities")
103 #define PROBE_LONGTEXT N_("Some DVB cards do not like to be probed for their capabilities, you can disable this feature if you experience some trouble.")
105 #define BUDGET_TEXT N_("Budget mode")
106 #define BUDGET_LONGTEXT N_("This allows you to stream an entire transponder with a \"budget\" card.")
108 /* Satellite */
109 #define SATELLITE_TEXT N_("Satellite scanning config")
110 #define SATELLITE_LONGTEXT N_("filename of config file in share/dvb/dvb-s")
112 #define SATNO_TEXT N_("Satellite number in the Diseqc system")
113 #define SATNO_LONGTEXT N_("[0=no diseqc, 1-4=satellite number].")
115 #define VOLTAGE_TEXT N_("LNB voltage")
116 #define VOLTAGE_LONGTEXT N_("In Volts [0, 13=vertical, 18=horizontal].")
118 #define HIGH_VOLTAGE_TEXT N_("High LNB voltage")
119 #define HIGH_VOLTAGE_LONGTEXT N_("Enable high voltage if your cables are " \
120 "particularly long. This is not supported by all frontends.")
122 #define TONE_TEXT N_("22 kHz tone")
123 #define TONE_LONGTEXT N_("[0=off, 1=on, -1=auto].")
125 #define FEC_TEXT N_("Transponder FEC")
126 #define FEC_LONGTEXT N_("FEC=Forward Error Correction mode [9=auto].")
128 #define SRATE_TEXT N_("Transponder symbol rate in kHz")
129 #define SRATE_LONGTEXT ""
131 #define LNB_LOF1_TEXT N_("Antenna lnb_lof1 (kHz)")
132 #define LNB_LOF1_LONGTEXT ""
134 #define LNB_LOF2_TEXT N_("Antenna lnb_lof2 (kHz)")
135 #define LNB_LOF2_LONGTEXT ""
137 #define LNB_SLOF_TEXT N_("Antenna lnb_slof (kHz)")
138 #define LNB_SLOF_LONGTEXT ""
140 /* Cable */
141 #define MODULATION_TEXT N_("Modulation type")
142 #define MODULATION_LONGTEXT N_("Modulation type for front-end device.")
144 /* Terrestrial */
145 #define CODE_RATE_HP_TEXT N_("Terrestrial high priority stream code rate (FEC)")
146 #define CODE_RATE_HP_LONGTEXT ""
148 #define CODE_RATE_LP_TEXT N_("Terrestrial low priority stream code rate (FEC)")
149 #define CODE_RATE_LP_LONGTEXT ""
151 #define BANDWIDTH_TEXT N_("Terrestrial bandwidth")
152 #define BANDWIDTH_LONGTEXT N_("Terrestrial bandwidth [0=auto,6,7,8 in MHz]")
154 #define GUARD_TEXT N_("Terrestrial guard interval")
155 #define GUARD_LONGTEXT ""
157 #define TRANSMISSION_TEXT N_("Terrestrial transmission mode")
158 #define TRANSMISSION_LONGTEXT ""
160 #define HIERARCHY_TEXT N_("Terrestrial hierarchy mode")
161 #define HIERARCHY_LONGTEXT ""
163 #define HOST_TEXT N_( "HTTP Host address" )
164 #define HOST_LONGTEXT N_( \
165 "To enable the internal HTTP server, set its address and port here." )
167 #define USER_TEXT N_( "HTTP user name" )
168 #define USER_LONGTEXT N_( \
169 "User name the administrator will use to log into " \
170 "the internal HTTP server." )
172 #define PASSWORD_TEXT N_( "HTTP password" )
173 #define PASSWORD_LONGTEXT N_( \
174 "Password the administrator will use to log into " \
175 "the internal HTTP server." )
177 #define ACL_TEXT N_( "HTTP ACL" )
178 #define ACL_LONGTEXT N_( \
179 "Access control list (equivalent to .hosts) file path, " \
180 "which will limit the range of IPs entitled to log into the internal " \
181 "HTTP server." )
183 #define CERT_TEXT N_( "Certificate file" )
184 #define CERT_LONGTEXT N_( "HTTP interface x509 PEM certificate file " \
185 "(enables SSL)" )
187 #define KEY_TEXT N_( "Private key file" )
188 #define KEY_LONGTEXT N_( "HTTP interface x509 PEM private key file" )
190 #define CA_TEXT N_( "Root CA file" )
191 #define CA_LONGTEXT N_( "HTTP interface x509 PEM trusted root CA " \
192 "certificates file" )
194 #define CRL_TEXT N_( "CRL file" )
195 #define CRL_LONGTEXT N_( "HTTP interface Certificates Revocation List file" )
197 vlc_module_begin ()
198 set_shortname( N_("DVB") )
199 set_description( N_("DVB input with v4l2 support") )
200 set_category( CAT_INPUT )
201 set_subcategory( SUBCAT_INPUT_ACCESS )
203 add_integer( "dvb-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT,
204 CACHING_LONGTEXT, true )
205 change_safe()
206 add_integer( "dvb-adapter", 0, NULL, ADAPTER_TEXT, ADAPTER_LONGTEXT,
207 false )
208 add_integer( "dvb-device", 0, NULL, DEVICE_TEXT, DEVICE_LONGTEXT,
209 true )
210 add_integer( "dvb-frequency", 0, NULL, FREQ_TEXT, FREQ_LONGTEXT,
211 false )
212 change_safe()
213 add_integer( "dvb-inversion", 2, NULL, INVERSION_TEXT, INVERSION_LONGTEXT,
214 true )
215 add_bool( "dvb-probe", true, NULL, PROBE_TEXT, PROBE_LONGTEXT, true )
216 add_bool( "dvb-budget-mode", false, NULL, BUDGET_TEXT, BUDGET_LONGTEXT,
217 true )
218 /* DVB-S (satellite) */
219 add_string( "dvb-satellite", NULL, SATELLITE_TEXT, SATELLITE_LONGTEXT,
220 true )
221 add_integer( "dvb-satno", 0, NULL, SATNO_TEXT, SATNO_LONGTEXT,
222 true )
223 add_integer( "dvb-voltage", 13, NULL, VOLTAGE_TEXT, VOLTAGE_LONGTEXT,
224 true )
225 add_bool( "dvb-high-voltage", false, NULL, HIGH_VOLTAGE_TEXT,
226 HIGH_VOLTAGE_LONGTEXT, true )
227 add_integer( "dvb-tone", -1, NULL, TONE_TEXT, TONE_LONGTEXT,
228 true )
229 add_integer( "dvb-fec", 9, NULL, FEC_TEXT, FEC_LONGTEXT, true )
230 add_integer( "dvb-srate", 27500000, NULL, SRATE_TEXT, SRATE_LONGTEXT,
231 false )
232 add_integer( "dvb-lnb-lof1", 0, NULL, LNB_LOF1_TEXT,
233 LNB_LOF1_LONGTEXT, true )
234 add_integer( "dvb-lnb-lof2", 0, NULL, LNB_LOF2_TEXT,
235 LNB_LOF2_LONGTEXT, true )
236 add_integer( "dvb-lnb-slof", 0, NULL, LNB_SLOF_TEXT,
237 LNB_SLOF_LONGTEXT, true )
238 /* DVB-C (cable) */
239 add_integer( "dvb-modulation", 0, NULL, MODULATION_TEXT,
240 MODULATION_LONGTEXT, true )
241 /* DVB-T (terrestrial) */
242 add_integer( "dvb-code-rate-hp", 9, NULL, CODE_RATE_HP_TEXT,
243 CODE_RATE_HP_LONGTEXT, true )
244 add_integer( "dvb-code-rate-lp", 9, NULL, CODE_RATE_LP_TEXT,
245 CODE_RATE_LP_LONGTEXT, true )
246 add_integer( "dvb-bandwidth", 0, NULL, BANDWIDTH_TEXT, BANDWIDTH_LONGTEXT,
247 true )
248 change_safe()
249 add_integer( "dvb-guard", 0, NULL, GUARD_TEXT, GUARD_LONGTEXT, true )
250 add_integer( "dvb-transmission", 0, NULL, TRANSMISSION_TEXT,
251 TRANSMISSION_LONGTEXT, true )
252 add_integer( "dvb-hierarchy", 0, NULL, HIERARCHY_TEXT, HIERARCHY_LONGTEXT,
253 true )
254 #ifdef ENABLE_HTTPD
255 /* MMI HTTP interface */
256 set_section( N_("HTTP server" ), 0 )
257 add_string( "dvb-http-host", NULL, HOST_TEXT, HOST_LONGTEXT,
258 true )
259 add_string( "dvb-http-user", NULL, USER_TEXT, USER_LONGTEXT,
260 true )
261 add_password( "dvb-http-password", NULL, NULL, PASSWORD_TEXT,
262 PASSWORD_LONGTEXT, true )
263 add_string( "dvb-http-acl", NULL, ACL_TEXT, ACL_LONGTEXT,
264 true )
265 add_string( "dvb-http-intf-cert", NULL, CERT_TEXT, CERT_LONGTEXT,
266 true )
267 add_string( "dvb-http-intf-key", NULL, KEY_TEXT, KEY_LONGTEXT,
268 true )
269 add_string( "dvb-http-intf-ca", NULL, CA_TEXT, CA_LONGTEXT,
270 true )
271 add_string( "dvb-http-intf-crl", NULL, CRL_TEXT, CRL_LONGTEXT,
272 true )
273 #endif
275 set_capability( "access", 0 )
276 add_shortcut( "dvb", /* Generic name */
277 "dvb-s", "qpsk", "satellite", /* Satellite */
278 "dvb-c", "cable", /* Cable */
279 "dvb-t", "terrestrial", /* Terrestrial */
280 "atsc" ) /* Atsc */
281 add_shortcut( "usdigital" )
283 set_callbacks( Open, Close )
285 vlc_module_end ()
288 /*****************************************************************************
289 * Local prototypes
290 *****************************************************************************/
291 static block_t *Block( access_t * );
292 static int Control( access_t *, int, va_list );
294 static block_t *BlockScan( access_t * );
296 #define DVB_READ_ONCE 20
297 #define DVB_READ_ONCE_START 2
298 #define DVB_READ_ONCE_SCAN 1
299 #define TS_PACKET_SIZE 188
301 #define DVB_SCAN_MAX_SIGNAL_TIME (1000*1000)
302 #define DVB_SCAN_MAX_LOCK_TIME (5000*1000)
303 #define DVB_SCAN_MAX_PROBE_TIME (45000*1000)
305 static void FilterUnset( access_t *, int i_max );
306 static void FilterUnsetPID( access_t *, int i_pid );
307 static void FilterSet( access_t *, int i_pid, int i_type );
309 static void VarInit( access_t * );
310 static int ParseMRL( access_t * );
312 /*****************************************************************************
313 * Open: open the frontend device
314 *****************************************************************************/
315 static int Open( vlc_object_t *p_this )
317 access_t *p_access = (access_t*)p_this;
318 access_sys_t *p_sys;
320 /* Only if selected */
321 if( *p_access->psz_access == '\0' )
322 return VLC_EGENERIC;
324 /* Set up access */
325 p_access->pf_read = NULL;
326 p_access->pf_block = Block;
327 p_access->pf_control = Control;
328 p_access->pf_seek = NULL;
330 access_InitFields( p_access );
332 p_access->p_sys = p_sys = calloc( 1, sizeof( access_sys_t ) );
333 if( !p_sys )
334 return VLC_ENOMEM;
336 /* Create all variables */
337 VarInit( p_access );
339 /* Parse the command line */
340 if( ParseMRL( p_access ) )
342 free( p_sys );
343 return VLC_EGENERIC;
346 /* Getting frontend info */
347 if( FrontendOpen( p_access) )
349 free( p_sys );
350 return VLC_EGENERIC;
353 /* */
354 p_sys->b_scan_mode = var_GetInteger( p_access, "dvb-frequency" ) == 0;
355 if( p_sys->b_scan_mode )
357 msg_Dbg( p_access, "DVB scan mode selected" );
358 p_access->pf_block = BlockScan;
360 else
362 /* Setting frontend parameters for tuning the hardware */
363 msg_Dbg( p_access, "trying to tune the frontend...");
364 if( FrontendSet( p_access ) < 0 )
366 FrontendClose( p_access );
367 free( p_sys );
368 return VLC_EGENERIC;
372 /* Opening DVR device */
373 if( DVROpen( p_access ) < 0 )
375 FrontendClose( p_access );
376 free( p_sys );
377 return VLC_EGENERIC;
380 if( p_sys->b_scan_mode )
382 scan_parameter_t parameter;
384 msg_Dbg( p_access, "setting filter on PAT/NIT/SDT (DVB only)" );
385 FilterSet( p_access, 0x00, OTHER_TYPE ); // PAT
386 FilterSet( p_access, 0x10, OTHER_TYPE ); // NIT
387 FilterSet( p_access, 0x11, OTHER_TYPE ); // SDT
389 if( FrontendGetScanParameter( p_access, &parameter ) ||
390 scan_Init( VLC_OBJECT(p_access), &p_sys->scan, &parameter ) )
392 Close( VLC_OBJECT(p_access) );
393 return VLC_EGENERIC;
396 else
398 p_sys->b_budget_mode = var_GetBool( p_access, "dvb-budget-mode" );
399 if( p_sys->b_budget_mode )
401 msg_Dbg( p_access, "setting filter on all PIDs" );
402 FilterSet( p_access, 0x2000, OTHER_TYPE );
404 else
406 msg_Dbg( p_access, "setting filter on PAT" );
407 FilterSet( p_access, 0x0, OTHER_TYPE );
410 CAMOpen( p_access );
412 #ifdef ENABLE_HTTPD
413 HTTPOpen( p_access );
414 #endif
417 if( p_sys->b_scan_mode )
418 p_sys->i_read_once = DVB_READ_ONCE_SCAN;
419 else if( p_sys->b_budget_mode )
420 p_sys->i_read_once = DVB_READ_ONCE;
421 else
422 p_sys->i_read_once = DVB_READ_ONCE_START;
424 free( p_access->psz_demux );
425 p_access->psz_demux = strdup( p_sys->b_scan_mode ? "m3u8" : "ts" );
426 return VLC_SUCCESS;
429 /*****************************************************************************
430 * Close : Close the device
431 *****************************************************************************/
432 static void Close( vlc_object_t *p_this )
434 access_t *p_access = (access_t*)p_this;
435 access_sys_t *p_sys = p_access->p_sys;
437 FilterUnset( p_access, p_sys->b_budget_mode && !p_sys->b_scan_mode ? 1 : MAX_DEMUX );
439 DVRClose( p_access );
440 FrontendClose( p_access );
441 if( p_sys->b_scan_mode )
442 scan_Clean( &p_sys->scan );
443 else
444 CAMClose( p_access );
446 #ifdef ENABLE_HTTPD
447 if( !p_sys->b_scan_mode )
448 HTTPClose( p_access );
449 #endif
451 free( p_sys );
454 /*****************************************************************************
455 * Block:
456 *****************************************************************************/
457 static block_t *Block( access_t *p_access )
459 access_sys_t *p_sys = p_access->p_sys;
460 block_t *p_block;
462 for ( ; ; )
464 struct pollfd ufds[2];
465 int i_ret;
467 /* Initialize file descriptor sets */
468 memset (ufds, 0, sizeof (ufds));
469 ufds[0].fd = p_sys->i_handle;
470 ufds[0].events = POLLIN;
471 ufds[1].fd = p_sys->i_frontend_handle;
472 ufds[1].events = POLLPRI;
474 /* We'll wait 0.5 second if nothing happens */
475 /* Find if some data is available */
476 i_ret = poll( ufds, 2, 500 );
478 if ( !vlc_object_alive (p_access) )
479 return NULL;
481 if ( i_ret < 0 )
483 if( errno == EINTR )
484 continue;
486 msg_Err( p_access, "poll error: %m" );
487 return NULL;
490 if ( p_sys->i_ca_handle && mdate() > p_sys->i_ca_next_event )
492 CAMPoll( p_access );
493 p_sys->i_ca_next_event = mdate() + p_sys->i_ca_timeout;
496 if ( ufds[1].revents )
498 FrontendPoll( p_access );
501 #ifdef ENABLE_HTTPD
502 if ( p_sys->i_httpd_timeout && mdate() > p_sys->i_httpd_timeout )
504 vlc_mutex_lock( &p_sys->httpd_mutex );
505 if ( p_sys->b_request_frontend_info )
507 msg_Warn( p_access, "frontend timeout for HTTP interface" );
508 p_sys->b_request_frontend_info = false;
509 p_sys->psz_frontend_info = strdup( "Timeout getting info\n" );
511 if ( p_sys->b_request_mmi_info )
513 msg_Warn( p_access, "MMI timeout for HTTP interface" );
514 p_sys->b_request_mmi_info = false;
515 p_sys->psz_mmi_info = strdup( "Timeout getting info\n" );
517 vlc_cond_signal( &p_sys->httpd_cond );
518 vlc_mutex_unlock( &p_sys->httpd_mutex );
521 if ( p_sys->b_request_frontend_info )
523 FrontendStatus( p_access );
526 if ( p_sys->b_request_mmi_info )
528 CAMStatus( p_access );
530 #endif
532 if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout )
534 msg_Warn( p_access, "no lock, tuning again" );
535 FrontendSet( p_access );
538 if ( ufds[0].revents )
540 p_block = block_New( p_access,
541 p_sys->i_read_once * TS_PACKET_SIZE );
542 if( ( i_ret = read( p_sys->i_handle, p_block->p_buffer,
543 p_sys->i_read_once * TS_PACKET_SIZE ) ) <= 0 )
545 msg_Warn( p_access, "read failed (%m)" );
546 block_Release( p_block );
547 continue;
549 p_block->i_buffer = i_ret;
550 break;
554 if( p_sys->i_read_once < DVB_READ_ONCE )
555 p_sys->i_read_once++;
557 /* Update moderatly the signal properties */
558 if( (p_sys->i_stat_counter++ % 100) == 0 )
559 p_access->info.i_update |= INPUT_UPDATE_SIGNAL;
561 return p_block;
564 /*****************************************************************************
565 * BlockScan:
566 *****************************************************************************/
567 static block_t *BlockScan( access_t *p_access )
569 access_sys_t *p_sys = p_access->p_sys;
570 scan_t *p_scan = &p_sys->scan;
571 scan_configuration_t cfg;
572 scan_session_t session;
574 /* set satellite config file path */
575 if( p_scan->parameter.type == SCAN_DVB_S )
576 p_scan->parameter.sat_info.psz_name = var_GetString( p_access, "dvb-satellite" );
578 /* */
579 if( scan_Next( p_scan, &cfg ) )
581 const bool b_first_eof = !p_access->info.b_eof;
583 if( b_first_eof )
584 msg_Warn( p_access, "Scanning finished" );
586 /* */
587 p_access->info.b_eof = true;
588 return b_first_eof ? scan_GetM3U( p_scan ) : NULL;
591 /* */
593 if( scan_session_Init( VLC_OBJECT(p_access), &session, &cfg ) )
594 return NULL;
596 /* */
597 if( p_scan->parameter.type == SCAN_DVB_S )
599 msg_Dbg( p_access,
600 "Scanning frequency %d, symbol rate = %d, fec = %d",
601 cfg.i_frequency,
602 cfg.i_bandwidth,
603 cfg.i_fec );
605 else
606 msg_Dbg( p_access, "Scanning frequency %d, bandwidth = %d",
607 cfg.i_frequency,
608 cfg.i_bandwidth );
610 var_SetInteger( p_access, "dvb-frequency", cfg.i_frequency );
611 var_SetInteger( p_access, "dvb-bandwidth", cfg.i_bandwidth );
612 if ( cfg.i_fec )
613 var_SetInteger( p_access, "dvb-fec", cfg.i_fec );
614 if ( cfg.c_polarization )
615 var_SetInteger( p_access, "dvb-voltage", cfg.c_polarization == 'H' ? 18 : 13 );
617 /* Setting frontend parameters for tuning the hardware */
618 if( FrontendSet( p_access ) < 0 )
620 msg_Err( p_access, "Failed to tune the frontend" );
621 p_access->info.b_eof = true;
622 return NULL;
625 /* */
626 int64_t i_scan_start = mdate();
628 bool b_has_dvb_signal = false;
629 bool b_has_lock = false;
630 int i_best_snr = -1;
632 for ( ; ; )
634 struct pollfd ufds[2];
635 int i_ret;
637 /* Initialize file descriptor sets */
638 memset (ufds, 0, sizeof (ufds));
639 ufds[0].fd = p_sys->i_handle;
640 ufds[0].events = POLLIN;
641 ufds[1].fd = p_sys->i_frontend_handle;
642 ufds[1].events = POLLPRI;
644 /* We'll wait 0.1 second if nothing happens */
645 /* Find if some data is available */
646 i_ret = poll( ufds, 2, 100 );
648 if( !vlc_object_alive (p_access) || scan_IsCancelled( p_scan ) )
649 break;
651 if( i_ret <= 0 )
653 const mtime_t i_scan_time = mdate() - i_scan_start;
654 frontend_status_t status;
656 FrontendGetStatus( p_access, &status );
658 b_has_dvb_signal |= status.b_has_carrier;
659 b_has_lock |= status.b_has_lock;
661 if( ( !b_has_dvb_signal && i_scan_time > DVB_SCAN_MAX_SIGNAL_TIME ) ||
662 ( !b_has_lock && i_scan_time > DVB_SCAN_MAX_LOCK_TIME ) ||
663 ( i_scan_time > DVB_SCAN_MAX_PROBE_TIME ) )
665 msg_Dbg( p_access, "timed out scanning current frequency (s=%d l=%d)", b_has_dvb_signal, b_has_lock );
666 break;
670 if( i_ret < 0 )
672 if( errno == EINTR )
673 continue;
675 msg_Err( p_access, "poll error: %m" );
676 scan_session_Clean( p_scan, &session );
678 p_access->info.b_eof = true;
679 return NULL;
682 if( ufds[1].revents )
684 frontend_statistic_t stat;
686 FrontendPoll( p_access );
688 if( !FrontendGetStatistic( p_access, &stat ) )
690 if( stat.i_snr > i_best_snr )
691 i_best_snr = stat.i_snr;
695 if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout )
697 msg_Warn( p_access, "no lock, tuning again" );
698 FrontendSet( p_access );
701 if ( ufds[0].revents )
703 const int i_read_once = 1;
704 block_t *p_block = block_New( p_access, i_read_once * TS_PACKET_SIZE );
706 if( ( i_ret = read( p_sys->i_handle, p_block->p_buffer,
707 i_read_once * TS_PACKET_SIZE ) ) <= 0 )
709 msg_Warn( p_access, "read failed (%m)" );
710 block_Release( p_block );
711 continue;
713 p_block->i_buffer = i_ret;
715 /* */
716 if( scan_session_Push( &session, p_block ) )
718 msg_Dbg( p_access, "finished scanning current frequency" );
719 break;
724 /* */
725 if( i_best_snr > 0 )
726 scan_service_SetSNR( &session, i_best_snr );
728 scan_session_Clean( p_scan, &session );
729 return NULL;
732 /*****************************************************************************
733 * Control:
734 *****************************************************************************/
735 static int Control( access_t *p_access, int i_query, va_list args )
737 access_sys_t *p_sys = p_access->p_sys;
738 bool *pb_bool, b_bool;
739 int i_int;
740 int64_t *pi_64;
741 double *pf1, *pf2;
742 dvbpsi_pmt_t *p_pmt;
743 frontend_statistic_t stat;
745 switch( i_query )
747 /* */
748 case ACCESS_CAN_SEEK:
749 case ACCESS_CAN_FASTSEEK:
750 case ACCESS_CAN_PAUSE:
751 case ACCESS_CAN_CONTROL_PACE:
752 pb_bool = (bool*)va_arg( args, bool* );
753 *pb_bool = false;
754 break;
755 /* */
756 case ACCESS_GET_PTS_DELAY:
757 pi_64 = (int64_t*)va_arg( args, int64_t * );
758 *pi_64 = var_GetInteger( p_access, "dvb-caching" ) * 1000;
759 break;
761 /* */
762 case ACCESS_SET_PAUSE_STATE:
763 case ACCESS_GET_TITLE_INFO:
764 case ACCESS_SET_TITLE:
765 case ACCESS_SET_SEEKPOINT:
766 case ACCESS_GET_CONTENT_TYPE:
767 return VLC_EGENERIC;
769 case ACCESS_GET_SIGNAL:
770 pf1 = (double*)va_arg( args, double * );
771 pf2 = (double*)va_arg( args, double * );
773 *pf1 = *pf2 = 0;
774 if( !FrontendGetStatistic( p_access, &stat ) )
776 *pf1 = (double)stat.i_snr / 65535.0;
777 *pf2 = (double)stat.i_signal_strenth / 65535.0;
779 return VLC_SUCCESS;
781 case ACCESS_SET_PRIVATE_ID_STATE:
782 if( p_sys->b_scan_mode )
783 return VLC_EGENERIC;
785 i_int = (int)va_arg( args, int ); /* Private data (pid for now)*/
786 b_bool = (bool)va_arg( args, int ); /* b_selected */
787 if( !p_sys->b_budget_mode )
789 /* FIXME we may want to give the real type (me ?, I don't ;) */
790 if( b_bool )
791 FilterSet( p_access, i_int, OTHER_TYPE );
792 else
793 FilterUnsetPID( p_access, i_int );
795 break;
797 case ACCESS_SET_PRIVATE_ID_CA:
798 if( p_sys->b_scan_mode )
799 return VLC_EGENERIC;
801 p_pmt = (dvbpsi_pmt_t *)va_arg( args, dvbpsi_pmt_t * );
803 CAMSet( p_access, p_pmt );
804 break;
806 default:
807 msg_Warn( p_access, "unimplemented query in control" );
808 return VLC_EGENERIC;
811 return VLC_SUCCESS;
814 /*****************************************************************************
815 * FilterSet/FilterUnset:
816 *****************************************************************************/
817 static void FilterSet( access_t *p_access, int i_pid, int i_type )
819 access_sys_t *p_sys = p_access->p_sys;
820 int i;
822 /* Find first free slot */
823 for( i = 0; i < MAX_DEMUX; i++ )
825 if( !p_sys->p_demux_handles[i].i_type )
826 break;
828 if( p_sys->p_demux_handles[i].i_pid == i_pid )
829 return; /* Already set */
832 if( i >= MAX_DEMUX )
834 msg_Err( p_access, "no free p_demux_handles !" );
835 return;
838 if( DMXSetFilter( p_access, i_pid,
839 &p_sys->p_demux_handles[i].i_handle, i_type ) )
841 msg_Err( p_access, "DMXSetFilter failed" );
842 return;
844 p_sys->p_demux_handles[i].i_type = i_type;
845 p_sys->p_demux_handles[i].i_pid = i_pid;
847 if( p_sys->i_read_once < DVB_READ_ONCE )
848 p_sys->i_read_once++;
851 static void FilterUnset( access_t *p_access, int i_max )
853 access_sys_t *p_sys = p_access->p_sys;
854 int i;
856 for( i = 0; i < i_max; i++ )
858 if( p_sys->p_demux_handles[i].i_type )
860 DMXUnsetFilter( p_access, p_sys->p_demux_handles[i].i_handle );
861 p_sys->p_demux_handles[i].i_type = 0;
866 static void FilterUnsetPID( access_t *p_access, int i_pid )
868 access_sys_t *p_sys = p_access->p_sys;
869 int i;
871 for( i = 0; i < MAX_DEMUX; i++ )
873 if( p_sys->p_demux_handles[i].i_type &&
874 p_sys->p_demux_handles[i].i_pid == i_pid )
876 DMXUnsetFilter( p_access, p_sys->p_demux_handles[i].i_handle );
877 p_sys->p_demux_handles[i].i_type = 0;
882 /*****************************************************************************
883 * VarInit/ParseMRL:
884 *****************************************************************************/
885 static void VarInit( access_t *p_access )
887 /* */
888 var_Create( p_access, "dvb-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
890 /* */
891 var_Create( p_access, "dvb-adapter", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
892 var_Create( p_access, "dvb-device", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
893 var_Create( p_access, "dvb-frequency", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
894 var_Create( p_access, "dvb-inversion", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
895 var_Create( p_access, "dvb-probe", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
896 var_Create( p_access, "dvb-budget-mode", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
898 /* */
899 var_Create( p_access, "dvb-satellite", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
900 var_Create( p_access, "dvb-satno", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
901 var_Create( p_access, "dvb-voltage", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
902 var_Create( p_access, "dvb-high-voltage", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
903 var_Create( p_access, "dvb-tone", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
904 var_Create( p_access, "dvb-fec", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
905 var_Create( p_access, "dvb-srate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
906 var_Create( p_access, "dvb-lnb-lof1", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
907 var_Create( p_access, "dvb-lnb-lof2", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
908 var_Create( p_access, "dvb-lnb-slof", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
910 /* */
911 var_Create( p_access, "dvb-modulation", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
913 /* */
914 var_Create( p_access, "dvb-code-rate-hp", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
915 var_Create( p_access, "dvb-code-rate-lp", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
916 var_Create( p_access, "dvb-bandwidth", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
917 var_Create( p_access, "dvb-transmission", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
918 var_Create( p_access, "dvb-guard", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
919 var_Create( p_access, "dvb-hierarchy", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
921 #ifdef ENABLE_HTTPD
922 var_Create( p_access, "dvb-http-host", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
923 var_Create( p_access, "dvb-http-user", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
924 var_Create( p_access, "dvb-http-password", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
925 var_Create( p_access, "dvb-http-acl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
926 var_Create( p_access, "dvb-http-intf-cert", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
927 var_Create( p_access, "dvb-http-intf-key", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
928 var_Create( p_access, "dvb-http-intf-ca", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
929 var_Create( p_access, "dvb-http-intf-crl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
930 #endif
933 /* */
934 static int ParseMRL( access_t *p_access )
936 char *psz_dup = strdup( p_access->psz_location );
937 char *psz_parser = psz_dup;
938 char *psz_next;
939 vlc_value_t val;
941 #define GET_OPTION_INT( option ) \
942 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
944 val.i_int = strtol( psz_parser + strlen(option "="), &psz_parser, \
945 0 ); \
946 var_Set( p_access, "dvb-" option, val ); \
949 #define GET_OPTION_BOOL( option ) \
950 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
952 val.b_bool = strtol( psz_parser + strlen(option "="), &psz_parser, \
953 0 ); \
954 var_Set( p_access, "dvb-" option, val ); \
957 #define GET_OPTION_STRING( option ) \
958 if ( !strncmp( psz_parser, option "=", strlen( option "=" ) ) ) \
960 psz_parser += strlen( option "=" ); \
961 val.psz_string = psz_parser; \
962 char *p_save; \
963 char *tok = strtok_r(val.psz_string, ":", &p_save); \
964 val.psz_string[tok - val.psz_string - 1] = 0; \
965 var_Set( p_access, "dvb-" option, val ); \
966 psz_parser += strlen( val.psz_string ); \
969 /* Test for old syntax */
970 strtol( psz_parser, &psz_next, 10 );
971 if( psz_next != psz_parser )
973 msg_Err( p_access, "the DVB input old syntax is deprecated, use vlc "
974 "-p dvb to see an explanation of the new syntax" );
975 dialog_FatalWait( p_access, _("Input syntax is deprecated"), "%s",
976 _("The given syntax is deprecated. Run \"vlc -p dvb\" to see an " \
977 "explanation of the new syntax.") );
978 free( psz_dup );
979 return VLC_EGENERIC;
982 while( *psz_parser )
984 GET_OPTION_INT("adapter")
985 else GET_OPTION_INT("device")
986 else GET_OPTION_INT("frequency")
987 else GET_OPTION_INT("inversion")
988 else GET_OPTION_BOOL("probe")
989 else GET_OPTION_BOOL("budget-mode")
991 else GET_OPTION_STRING("satellite")
992 else GET_OPTION_INT("voltage")
993 else GET_OPTION_BOOL("high-voltage")
994 else GET_OPTION_INT("tone")
995 else GET_OPTION_INT("satno")
996 else GET_OPTION_INT("fec")
997 else GET_OPTION_INT("srate")
998 else GET_OPTION_INT("lnb-lof1")
999 else GET_OPTION_INT("lnb-lof2")
1000 else GET_OPTION_INT("lnb-slof")
1002 else GET_OPTION_INT("modulation")
1004 else GET_OPTION_INT("code-rate-hp")
1005 else GET_OPTION_INT("code-rate-lp")
1006 else GET_OPTION_INT("bandwidth")
1007 else GET_OPTION_INT("transmission")
1008 else GET_OPTION_INT("guard")
1009 else GET_OPTION_INT("hierarchy")
1011 /* Redundant with voltage but much easier to use */
1012 else if( !strncmp( psz_parser, "polarization=",
1013 strlen( "polarization=" ) ) )
1015 psz_parser += strlen( "polarization=" );
1016 if ( *psz_parser == 'V' || *psz_parser == 'v' )
1017 val.i_int = 13;
1018 else if ( *psz_parser == 'H' || *psz_parser == 'h' )
1019 val.i_int = 18;
1020 else
1022 msg_Err( p_access, "illegal polarization %c", *psz_parser );
1023 dialog_Fatal( p_access, _("Invalid polarization"),
1024 _("The provided polarization \"%c\" is not valid."),
1025 *psz_parser );
1026 free( psz_dup );
1027 return VLC_EGENERIC;
1029 var_Set( p_access, "dvb-voltage", val );
1031 else
1033 msg_Err( p_access, "unknown option (%s)", psz_parser );
1034 free( psz_dup );
1035 return VLC_EGENERIC;
1038 if ( *psz_parser )
1039 psz_parser++;
1041 #undef GET_OPTION_INT
1042 #undef GET_OPTION_BOOL
1043 #undef GET_OPTION_STRING
1045 free( psz_dup );
1046 return VLC_SUCCESS;