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 /*****************************************************************************
30 *****************************************************************************/
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_access.h>
38 #include <vlc_input.h>
40 #include <sys/types.h>
45 /* Include dvbpsi headers */
46 # include <dvbpsi/dvbpsi.h>
47 # include <dvbpsi/descriptor.h>
48 # include <dvbpsi/pat.h>
49 # include <dvbpsi/pmt.h>
50 # include <dvbpsi/dr.h>
51 # include <dvbpsi/psi.h>
52 # include <dvbpsi/demux.h>
53 # include <dvbpsi/sdt.h>
58 /*****************************************************************************
60 *****************************************************************************/
61 static int Open( vlc_object_t *p_this );
62 static void Close( vlc_object_t *p_this );
64 #define CACHING_TEXT N_("Caching value in ms")
65 #define CACHING_LONGTEXT N_( \
66 "Caching value for DVB streams. This " \
67 "value should be set in milliseconds." )
69 #define ADAPTER_TEXT N_("Adapter card to tune")
70 #define ADAPTER_LONGTEXT N_("Adapter cards have a device file in directory named /dev/dvb/adapter[n] with n>=0.")
72 #define DEVICE_TEXT N_("Device number to use on adapter")
73 #define DEVICE_LONGTEXT ""
75 #define FREQ_TEXT N_("Transponder/multiplex frequency")
76 #define FREQ_LONGTEXT N_("In kHz for DVB-S or Hz for DVB-C/T")
78 #define INVERSION_TEXT N_("Inversion mode")
79 #define INVERSION_LONGTEXT N_("Inversion mode [0=off, 1=on, 2=auto]")
81 #define PROBE_TEXT N_("Probe DVB card for capabilities")
82 #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.")
84 #define BUDGET_TEXT N_("Budget mode")
85 #define BUDGET_LONGTEXT N_("This allows you to stream an entire transponder with a \"budget\" card.")
88 #define SATELLITE_TEXT N_("Satellite scanning config")
89 #define SATELLITE_LONGTEXT N_("filename of config file in share/dvb/dvb-s")
91 #define SATNO_TEXT N_("Satellite number in the Diseqc system")
92 #define SATNO_LONGTEXT N_("[0=no diseqc, 1-4=satellite number].")
94 #define VOLTAGE_TEXT N_("LNB voltage (V)")
95 #define VOLTAGE_LONGTEXT ""
96 static const int voltages[] = { 0, 13, 18 };
97 static const char *const voltages_text[] = { N_("off"), N_("13 V"), N_("18 V") };
99 #define HIGH_VOLTAGE_TEXT N_("High LNB voltage")
100 #define HIGH_VOLTAGE_LONGTEXT N_("Enable high voltage if your cables are " \
101 "particularly long. This is not supported by all frontends.")
103 #define TONE_TEXT N_("22 kHz tone")
104 #define TONE_LONGTEXT N_("[0=off, 1=on, -1=auto].")
106 #define FEC_TEXT N_("Transponder FEC")
107 #define FEC_LONGTEXT N_("FEC=Forward Error Correction mode [9=auto].")
109 #define SRATE_TEXT N_("Transponder symbol rate in kHz")
110 #define SRATE_LONGTEXT ""
112 #define LNB_LOF1_TEXT N_("Antenna lnb_lof1 (kHz)")
113 #define LNB_LOF1_LONGTEXT ""
115 #define LNB_LOF2_TEXT N_("Antenna lnb_lof2 (kHz)")
116 #define LNB_LOF2_LONGTEXT ""
118 #define LNB_SLOF_TEXT N_("Antenna lnb_slof (kHz)")
119 #define LNB_SLOF_LONGTEXT ""
122 #define MODULATION_TEXT N_("Modulation type")
123 #define MODULATION_LONGTEXT ""
124 static const int modulations[] = {
125 -1, 0, 8, 16, 32, 64, 128, 256 };
126 static const char *const modulations_text[] = {
127 N_("QPSK"), N_("Auto (QAM)"), N_("VSB 8"), N_("QAM 16"), N_("QAM 32"),
128 N_("QAM 64"), N_("QAM 128"), N_("QAM 256") };
131 #define CODE_RATE_HP_TEXT N_("Terrestrial high priority stream code rate (FEC)")
132 #define CODE_RATE_HP_LONGTEXT ""
134 #define CODE_RATE_LP_TEXT N_("Terrestrial low priority stream code rate (FEC)")
135 #define CODE_RATE_LP_LONGTEXT ""
137 #define BANDWIDTH_TEXT N_("Terrestrial bandwidth")
138 #define BANDWIDTH_LONGTEXT N_("Terrestrial bandwidth [0=auto,6,7,8 in MHz]")
140 #define GUARD_TEXT N_("Terrestrial guard interval")
141 #define GUARD_LONGTEXT ""
143 #define TRANSMISSION_TEXT N_("Terrestrial transmission mode")
144 #define TRANSMISSION_LONGTEXT ""
146 #define HIERARCHY_TEXT N_("Terrestrial hierarchy mode")
147 #define HIERARCHY_LONGTEXT ""
149 #define HOST_TEXT N_( "HTTP Host address" )
150 #define HOST_LONGTEXT N_( \
151 "To enable the internal HTTP server, set its address and port here." )
153 #define USER_TEXT N_( "HTTP user name" )
154 #define USER_LONGTEXT N_( \
155 "User name the administrator will use to log into " \
156 "the internal HTTP server." )
158 #define PASSWORD_TEXT N_( "HTTP password" )
159 #define PASSWORD_LONGTEXT N_( \
160 "Password the administrator will use to log into " \
161 "the internal HTTP server." )
163 #define ACL_TEXT N_( "HTTP ACL" )
164 #define ACL_LONGTEXT N_( \
165 "Access control list (equivalent to .hosts) file path, " \
166 "which will limit the range of IPs entitled to log into the internal " \
169 #define CERT_TEXT N_( "Certificate file" )
170 #define CERT_LONGTEXT N_( "HTTP interface x509 PEM certificate file " \
173 #define KEY_TEXT N_( "Private key file" )
174 #define KEY_LONGTEXT N_( "HTTP interface x509 PEM private key file" )
176 #define CA_TEXT N_( "Root CA file" )
177 #define CA_LONGTEXT N_( "HTTP interface x509 PEM trusted root CA " \
178 "certificates file" )
180 #define CRL_TEXT N_( "CRL file" )
181 #define CRL_LONGTEXT N_( "HTTP interface Certificates Revocation List file" )
184 set_shortname( N_("DVB") )
185 set_description( N_("DVB input with v4l2 support") )
186 set_category( CAT_INPUT )
187 set_subcategory( SUBCAT_INPUT_ACCESS )
189 add_integer( "dvb-caching", DEFAULT_PTS_DELAY / 1000, CACHING_TEXT,
190 CACHING_LONGTEXT, true )
192 add_integer( "dvb-adapter", 0, ADAPTER_TEXT, ADAPTER_LONGTEXT,
194 add_integer( "dvb-device", 0, DEVICE_TEXT, DEVICE_LONGTEXT,
196 add_integer( "dvb-frequency", 0, FREQ_TEXT, FREQ_LONGTEXT,
199 add_integer( "dvb-inversion", 2, INVERSION_TEXT, INVERSION_LONGTEXT,
201 add_bool( "dvb-probe", true, PROBE_TEXT, PROBE_LONGTEXT, true )
202 add_bool( "dvb-budget-mode", false, BUDGET_TEXT, BUDGET_LONGTEXT,
204 /* DVB-S (satellite) */
205 add_string( "dvb-satellite", NULL, SATELLITE_TEXT, SATELLITE_LONGTEXT,
207 add_integer( "dvb-satno", 0, SATNO_TEXT, SATNO_LONGTEXT,
209 add_integer( "dvb-voltage", 13, VOLTAGE_TEXT, VOLTAGE_LONGTEXT,
211 change_integer_list( voltages, voltages_text )
212 add_bool( "dvb-high-voltage", false, HIGH_VOLTAGE_TEXT,
213 HIGH_VOLTAGE_LONGTEXT, true )
214 add_integer( "dvb-tone", -1, TONE_TEXT, TONE_LONGTEXT,
216 add_integer( "dvb-fec", 9, FEC_TEXT, FEC_LONGTEXT, true )
217 add_integer( "dvb-srate", 0, SRATE_TEXT, SRATE_LONGTEXT,
219 add_integer( "dvb-lnb-lof1", 0, LNB_LOF1_TEXT,
220 LNB_LOF1_LONGTEXT, true )
221 add_integer( "dvb-lnb-lof2", 0, LNB_LOF2_TEXT,
222 LNB_LOF2_LONGTEXT, true )
223 add_integer( "dvb-lnb-slof", 0, LNB_SLOF_TEXT,
224 LNB_SLOF_LONGTEXT, true )
226 add_integer( "dvb-modulation", 0, MODULATION_TEXT,
227 MODULATION_LONGTEXT, true )
228 change_integer_list( modulations, modulations_text )
229 /* DVB-T (terrestrial) */
230 add_integer( "dvb-code-rate-hp", 9, CODE_RATE_HP_TEXT,
231 CODE_RATE_HP_LONGTEXT, true )
232 add_integer( "dvb-code-rate-lp", 9, CODE_RATE_LP_TEXT,
233 CODE_RATE_LP_LONGTEXT, true )
234 add_integer( "dvb-bandwidth", 0, BANDWIDTH_TEXT, BANDWIDTH_LONGTEXT,
237 add_integer( "dvb-guard", 0, GUARD_TEXT, GUARD_LONGTEXT, true )
238 add_integer( "dvb-transmission", 0, TRANSMISSION_TEXT,
239 TRANSMISSION_LONGTEXT, true )
240 add_integer( "dvb-hierarchy", 0, HIERARCHY_TEXT, HIERARCHY_LONGTEXT,
243 /* MMI HTTP interface */
244 set_section( N_("HTTP server" ), 0 )
245 add_string( "dvb-http-host", NULL, HOST_TEXT, HOST_LONGTEXT,
247 add_string( "dvb-http-user", NULL, USER_TEXT, USER_LONGTEXT,
249 add_password( "dvb-http-password", NULL, PASSWORD_TEXT,
250 PASSWORD_LONGTEXT, true )
251 add_string( "dvb-http-acl", NULL, ACL_TEXT, ACL_LONGTEXT,
253 add_loadfile( "dvb-http-intf-cert", NULL, CERT_TEXT, CERT_LONGTEXT,
255 add_loadfile( "dvb-http-intf-key", NULL, KEY_TEXT, KEY_LONGTEXT,
257 add_loadfile( "dvb-http-intf-ca", NULL, CA_TEXT, CA_LONGTEXT,
259 add_loadfile( "dvb-http-intf-crl", NULL, CRL_TEXT, CRL_LONGTEXT,
263 set_capability( "access", 0 )
264 add_shortcut( "dvb", /* Generic name */
265 "dvb-s", "qpsk", "satellite", /* Satellite */
266 "dvb-c", "cable", /* Cable */
267 "dvb-t", "terrestrial", /* Terrestrial */
269 add_shortcut( "usdigital" )
271 set_callbacks( Open, Close )
276 /*****************************************************************************
278 *****************************************************************************/
279 static block_t *Block( access_t * );
280 static int Control( access_t *, int, va_list );
282 static block_t *BlockScan( access_t * );
284 #define DVB_READ_ONCE 20
285 #define DVB_READ_ONCE_START 2
286 #define DVB_READ_ONCE_SCAN 1
287 #define TS_PACKET_SIZE 188
289 #define DVB_SCAN_MAX_SIGNAL_TIME (1000*1000)
290 #define DVB_SCAN_MAX_LOCK_TIME (5000*1000)
291 #define DVB_SCAN_MAX_PROBE_TIME (45000*1000)
293 static void FilterUnset( access_t *, int i_max );
294 static void FilterUnsetPID( access_t *, int i_pid );
295 static void FilterSet( access_t *, int i_pid, int i_type );
297 static void VarInit( access_t * );
298 static int ParseMRL( access_t * );
300 /*****************************************************************************
301 * Open: open the frontend device
302 *****************************************************************************/
303 static int Open( vlc_object_t *p_this )
305 access_t *p_access = (access_t*)p_this;
308 /* Only if selected */
309 if( *p_access->psz_access == '\0' )
313 p_access->pf_read = NULL;
314 p_access->pf_block = Block;
315 p_access->pf_control = Control;
316 p_access->pf_seek = NULL;
318 access_InitFields( p_access );
320 p_access->p_sys = p_sys = calloc( 1, sizeof( access_sys_t ) );
324 /* Create all variables */
327 /* Parse the command line */
328 if( ParseMRL( p_access ) )
334 /* Getting frontend info */
335 if( FrontendOpen( p_access) )
342 bool b_scan_mode = var_GetInteger( p_access, "dvb-frequency" ) == 0;
345 msg_Dbg( p_access, "DVB scan mode selected" );
346 p_access->pf_block = BlockScan;
350 /* Setting frontend parameters for tuning the hardware */
351 msg_Dbg( p_access, "trying to tune the frontend...");
352 if( FrontendSet( p_access ) < 0 )
354 FrontendClose( p_access );
360 /* Opening DVR device */
361 if( DVROpen( p_access ) < 0 )
363 FrontendClose( p_access );
370 scan_parameter_t parameter;
373 msg_Dbg( p_access, "setting filter on PAT/NIT/SDT (DVB only)" );
374 FilterSet( p_access, 0x00, OTHER_TYPE ); // PAT
375 FilterSet( p_access, 0x10, OTHER_TYPE ); // NIT
376 FilterSet( p_access, 0x11, OTHER_TYPE ); // SDT
378 if( FrontendGetScanParameter( p_access, ¶meter ) ||
379 (p_scan = scan_New( VLC_OBJECT(p_access), ¶meter )) == NULL )
381 Close( VLC_OBJECT(p_access) );
384 p_sys->scan = p_scan;
385 p_sys->i_read_once = DVB_READ_ONCE_SCAN;
389 p_sys->b_budget_mode = var_GetBool( p_access, "dvb-budget-mode" );
390 if( p_sys->b_budget_mode )
392 msg_Dbg( p_access, "setting filter on all PIDs" );
393 FilterSet( p_access, 0x2000, OTHER_TYPE );
394 p_sys->i_read_once = DVB_READ_ONCE;
398 msg_Dbg( p_access, "setting filter on PAT" );
399 FilterSet( p_access, 0x0, OTHER_TYPE );
400 p_sys->i_read_once = DVB_READ_ONCE_START;
406 HTTPOpen( p_access );
410 free( p_access->psz_demux );
411 p_access->psz_demux = strdup( p_sys->scan ? "m3u8" : "ts" );
415 /*****************************************************************************
416 * Close : Close the device
417 *****************************************************************************/
418 static void Close( vlc_object_t *p_this )
420 access_t *p_access = (access_t*)p_this;
421 access_sys_t *p_sys = p_access->p_sys;
423 FilterUnset( p_access, p_sys->b_budget_mode && !p_sys->scan ? 1 : MAX_DEMUX );
425 DVRClose( p_access );
426 FrontendClose( p_access );
427 if( p_sys->scan != NULL )
428 scan_Destroy( p_sys->scan );
431 CAMClose( p_access );
433 HTTPClose( p_access );
440 /*****************************************************************************
442 *****************************************************************************/
443 static block_t *Block( access_t *p_access )
445 access_sys_t *p_sys = p_access->p_sys;
450 struct pollfd ufds[2];
453 /* Initialize file descriptor sets */
454 memset (ufds, 0, sizeof (ufds));
455 ufds[0].fd = p_sys->i_handle;
456 ufds[0].events = POLLIN;
457 ufds[1].fd = p_sys->i_frontend_handle;
458 ufds[1].events = POLLPRI;
460 /* We'll wait 0.5 second if nothing happens */
461 /* Find if some data is available */
462 i_ret = poll( ufds, 2, 500 );
464 if ( !vlc_object_alive (p_access) )
472 msg_Err( p_access, "poll error: %m" );
478 if ( ufds[1].revents )
480 FrontendPoll( p_access );
484 if ( p_sys->i_httpd_timeout && mdate() > p_sys->i_httpd_timeout )
486 vlc_mutex_lock( &p_sys->httpd_mutex );
487 if ( p_sys->b_request_frontend_info )
489 msg_Warn( p_access, "frontend timeout for HTTP interface" );
490 p_sys->b_request_frontend_info = false;
491 p_sys->psz_frontend_info = strdup( "Timeout getting info\n" );
493 if ( p_sys->b_request_mmi_info )
495 msg_Warn( p_access, "MMI timeout for HTTP interface" );
496 p_sys->b_request_mmi_info = false;
497 p_sys->psz_mmi_info = strdup( "Timeout getting info\n" );
499 vlc_cond_signal( &p_sys->httpd_cond );
500 vlc_mutex_unlock( &p_sys->httpd_mutex );
503 if ( p_sys->b_request_frontend_info )
505 FrontendStatus( p_access );
508 if ( p_sys->b_request_mmi_info )
510 CAMStatus( p_access );
514 if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout )
516 msg_Warn( p_access, "no lock, tuning again" );
517 FrontendSet( p_access );
520 if ( ufds[0].revents )
522 p_block = block_New( p_access,
523 p_sys->i_read_once * TS_PACKET_SIZE );
524 if( ( i_ret = read( p_sys->i_handle, p_block->p_buffer,
525 p_sys->i_read_once * TS_PACKET_SIZE ) ) <= 0 )
527 msg_Warn( p_access, "read failed (%m)" );
528 block_Release( p_block );
531 p_block->i_buffer = i_ret;
536 if( p_sys->i_read_once < DVB_READ_ONCE )
537 p_sys->i_read_once++;
539 /* Update moderatly the signal properties */
540 if( (p_sys->i_stat_counter++ % 100) == 0 )
541 p_access->info.i_update |= INPUT_UPDATE_SIGNAL;
546 /*****************************************************************************
548 *****************************************************************************/
549 static block_t *BlockScan( access_t *p_access )
551 access_sys_t *p_sys = p_access->p_sys;
552 scan_t *p_scan = p_sys->scan;
553 scan_configuration_t cfg;
556 if( scan_Next( p_scan, &cfg ) )
558 const bool b_first_eof = !p_access->info.b_eof;
561 msg_Warn( p_access, "Scanning finished" );
564 p_access->info.b_eof = true;
565 return b_first_eof ? scan_GetM3U( p_scan ) : NULL;
569 scan_session_t *session = scan_session_New( VLC_OBJECT(p_access), &cfg );
570 if( session == NULL )
574 msg_Dbg( p_access, "Scanning frequency %d", cfg.i_frequency );
575 var_SetInteger( p_access, "dvb-frequency", cfg.i_frequency );
576 msg_Dbg( p_access, " bandwidth %d", cfg.i_bandwidth );
577 var_SetInteger( p_access, "dvb-bandwidth", cfg.i_bandwidth );
580 msg_Dbg( p_access, " FEC %d", cfg.i_fec );
581 var_SetInteger( p_access, "dvb-fec", cfg.i_fec );
583 if ( cfg.c_polarization )
584 var_SetInteger( p_access, "dvb-voltage", cfg.c_polarization == 'H' ? 18 : 13 );
586 if ( cfg.i_modulation )
587 var_SetInteger( p_access, "dvb-modulation", cfg.i_modulation );
589 if ( cfg.i_symbolrate )
590 var_SetInteger( p_access, "dvb-srate", cfg.i_symbolrate );
592 /* Setting frontend parameters for tuning the hardware */
593 if( FrontendSet( p_access ) < 0 )
595 msg_Err( p_access, "Failed to tune the frontend" );
596 p_access->info.b_eof = true;
597 scan_session_Destroy( p_scan, session );
602 int64_t i_scan_start = mdate();
604 bool b_has_dvb_signal = false;
605 bool b_has_lock = false;
610 struct pollfd ufds[2];
613 /* Initialize file descriptor sets */
614 memset (ufds, 0, sizeof (ufds));
615 ufds[0].fd = p_sys->i_handle;
616 ufds[0].events = POLLIN;
617 ufds[1].fd = p_sys->i_frontend_handle;
618 ufds[1].events = POLLPRI;
620 /* We'll wait 0.1 second if nothing happens */
621 /* Find if some data is available */
622 i_ret = poll( ufds, 2, 100 );
624 if( !vlc_object_alive (p_access) || scan_IsCancelled( p_scan ) )
629 const mtime_t i_scan_time = mdate() - i_scan_start;
630 frontend_status_t status;
632 FrontendGetStatus( p_access, &status );
634 b_has_dvb_signal |= status.b_has_carrier;
635 b_has_lock |= status.b_has_lock;
637 if( ( !b_has_dvb_signal && i_scan_time > DVB_SCAN_MAX_SIGNAL_TIME ) ||
638 ( !b_has_lock && i_scan_time > DVB_SCAN_MAX_LOCK_TIME ) ||
639 ( i_scan_time > DVB_SCAN_MAX_PROBE_TIME ) )
641 msg_Dbg( p_access, "timed out scanning current frequency (s=%d l=%d)", b_has_dvb_signal, b_has_lock );
651 msg_Err( p_access, "poll error: %m" );
652 scan_session_Destroy( p_scan, session );
654 p_access->info.b_eof = true;
658 if( ufds[1].revents )
660 frontend_statistic_t stat;
662 FrontendPoll( p_access );
664 if( !FrontendGetStatistic( p_access, &stat ) )
666 if( stat.i_snr > i_best_snr )
667 i_best_snr = stat.i_snr;
671 if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout )
673 msg_Warn( p_access, "no lock, tuning again" );
674 FrontendSet( p_access );
677 if ( ufds[0].revents )
679 const int i_read_once = 1;
680 block_t *p_block = block_New( p_access, i_read_once * TS_PACKET_SIZE );
682 if( ( i_ret = read( p_sys->i_handle, p_block->p_buffer,
683 i_read_once * TS_PACKET_SIZE ) ) <= 0 )
685 msg_Warn( p_access, "read failed (%m)" );
686 block_Release( p_block );
689 p_block->i_buffer = i_ret;
692 if( scan_session_Push( session, p_block ) )
694 msg_Dbg( p_access, "finished scanning current frequency" );
702 scan_service_SetSNR( session, i_best_snr );
704 scan_session_Destroy( p_scan, session );
708 /*****************************************************************************
710 *****************************************************************************/
711 static int Control( access_t *p_access, int i_query, va_list args )
713 access_sys_t *p_sys = p_access->p_sys;
714 bool *pb_bool, b_bool;
719 frontend_statistic_t stat;
724 case ACCESS_CAN_SEEK:
725 case ACCESS_CAN_FASTSEEK:
726 case ACCESS_CAN_PAUSE:
727 case ACCESS_CAN_CONTROL_PACE:
728 pb_bool = (bool*)va_arg( args, bool* );
732 case ACCESS_GET_PTS_DELAY:
733 pi_64 = (int64_t*)va_arg( args, int64_t * );
734 *pi_64 = var_GetInteger( p_access, "dvb-caching" ) * 1000;
738 case ACCESS_SET_PAUSE_STATE:
739 case ACCESS_GET_TITLE_INFO:
740 case ACCESS_SET_TITLE:
741 case ACCESS_SET_SEEKPOINT:
742 case ACCESS_GET_CONTENT_TYPE:
745 case ACCESS_GET_SIGNAL:
746 pf1 = (double*)va_arg( args, double * );
747 pf2 = (double*)va_arg( args, double * );
750 if( !FrontendGetStatistic( p_access, &stat ) )
752 *pf1 = (double)stat.i_snr / 65535.0;
753 *pf2 = (double)stat.i_signal_strenth / 65535.0;
757 case ACCESS_SET_PRIVATE_ID_STATE:
761 i_int = (int)va_arg( args, int ); /* Private data (pid for now)*/
762 b_bool = (bool)va_arg( args, int ); /* b_selected */
763 if( !p_sys->b_budget_mode )
765 /* FIXME we may want to give the real type (me ?, I don't ;) */
767 FilterSet( p_access, i_int, OTHER_TYPE );
769 FilterUnsetPID( p_access, i_int );
773 case ACCESS_SET_PRIVATE_ID_CA:
777 p_pmt = (dvbpsi_pmt_t *)va_arg( args, dvbpsi_pmt_t * );
779 CAMSet( p_access, p_pmt );
783 msg_Warn( p_access, "unimplemented query in control" );
790 /*****************************************************************************
791 * FilterSet/FilterUnset:
792 *****************************************************************************/
793 static void FilterSet( access_t *p_access, int i_pid, int i_type )
795 access_sys_t *p_sys = p_access->p_sys;
798 /* Find first free slot */
799 for( i = 0; i < MAX_DEMUX; i++ )
801 if( !p_sys->p_demux_handles[i].i_type )
804 if( p_sys->p_demux_handles[i].i_pid == i_pid )
805 return; /* Already set */
810 msg_Err( p_access, "no free p_demux_handles !" );
814 if( DMXSetFilter( p_access, i_pid,
815 &p_sys->p_demux_handles[i].i_handle, i_type ) )
817 msg_Err( p_access, "DMXSetFilter failed" );
820 p_sys->p_demux_handles[i].i_type = i_type;
821 p_sys->p_demux_handles[i].i_pid = i_pid;
823 if( p_sys->i_read_once < DVB_READ_ONCE )
824 p_sys->i_read_once++;
827 static void FilterUnset( access_t *p_access, int i_max )
829 access_sys_t *p_sys = p_access->p_sys;
832 for( i = 0; i < i_max; i++ )
834 if( p_sys->p_demux_handles[i].i_type )
836 DMXUnsetFilter( p_access, p_sys->p_demux_handles[i].i_handle );
837 p_sys->p_demux_handles[i].i_type = 0;
842 static void FilterUnsetPID( access_t *p_access, int i_pid )
844 access_sys_t *p_sys = p_access->p_sys;
847 for( i = 0; i < MAX_DEMUX; i++ )
849 if( p_sys->p_demux_handles[i].i_type &&
850 p_sys->p_demux_handles[i].i_pid == i_pid )
852 DMXUnsetFilter( p_access, p_sys->p_demux_handles[i].i_handle );
853 p_sys->p_demux_handles[i].i_type = 0;
858 /*****************************************************************************
860 *****************************************************************************/
861 static void VarInit( access_t *p_access )
864 var_Create( p_access, "dvb-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
867 var_Create( p_access, "dvb-adapter", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
868 var_Create( p_access, "dvb-device", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
869 var_Create( p_access, "dvb-frequency", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
870 var_Create( p_access, "dvb-inversion", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
871 var_Create( p_access, "dvb-probe", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
872 var_Create( p_access, "dvb-budget-mode", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
875 var_Create( p_access, "dvb-satellite", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
876 var_Create( p_access, "dvb-satno", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
877 var_Create( p_access, "dvb-voltage", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
878 var_Create( p_access, "dvb-high-voltage", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
879 var_Create( p_access, "dvb-tone", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
880 var_Create( p_access, "dvb-fec", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
881 var_Create( p_access, "dvb-srate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
882 var_Create( p_access, "dvb-lnb-lof1", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
883 var_Create( p_access, "dvb-lnb-lof2", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
884 var_Create( p_access, "dvb-lnb-slof", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
887 var_Create( p_access, "dvb-modulation", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
890 var_Create( p_access, "dvb-code-rate-hp", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
891 var_Create( p_access, "dvb-code-rate-lp", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
892 var_Create( p_access, "dvb-bandwidth", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
893 var_Create( p_access, "dvb-transmission", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
894 var_Create( p_access, "dvb-guard", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
895 var_Create( p_access, "dvb-hierarchy", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
898 var_Create( p_access, "dvb-http-host", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
899 var_Create( p_access, "dvb-http-user", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
900 var_Create( p_access, "dvb-http-password", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
901 var_Create( p_access, "dvb-http-acl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
902 var_Create( p_access, "dvb-http-intf-cert", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
903 var_Create( p_access, "dvb-http-intf-key", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
904 var_Create( p_access, "dvb-http-intf-ca", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
905 var_Create( p_access, "dvb-http-intf-crl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
910 static int ParseMRL( access_t *p_access )
912 char *psz_dup = strdup( p_access->psz_location );
913 char *psz_parser = psz_dup;
916 #define GET_OPTION_INT( option ) \
917 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
919 val.i_int = strtol( psz_parser + strlen(option "="), &psz_parser, \
921 var_Set( p_access, "dvb-" option, val ); \
924 #define GET_OPTION_BOOL( option ) \
925 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
927 val.b_bool = strtol( psz_parser + strlen(option "="), &psz_parser, \
929 var_Set( p_access, "dvb-" option, val ); \
932 #define GET_OPTION_STRING( option ) \
933 if ( !strncmp( psz_parser, option "=", strlen( option "=" ) ) ) \
935 psz_parser += strlen( option "=" ); \
936 val.psz_string = psz_parser; \
938 char *tok = strtok_r(val.psz_string, ":", &p_save); \
939 val.psz_string[tok - val.psz_string - 1] = 0; \
940 var_Set( p_access, "dvb-" option, val ); \
941 psz_parser += strlen( val.psz_string ); \
946 GET_OPTION_INT("adapter")
947 else GET_OPTION_INT("device")
948 else GET_OPTION_INT("frequency")
949 else GET_OPTION_INT("inversion")
950 else GET_OPTION_BOOL("probe")
951 else GET_OPTION_BOOL("budget-mode")
953 else GET_OPTION_STRING("satellite")
954 else GET_OPTION_INT("voltage")
955 else GET_OPTION_BOOL("high-voltage")
956 else GET_OPTION_INT("tone")
957 else GET_OPTION_INT("satno")
958 else GET_OPTION_INT("fec")
959 else GET_OPTION_INT("srate")
960 else GET_OPTION_INT("lnb-lof1")
961 else GET_OPTION_INT("lnb-lof2")
962 else GET_OPTION_INT("lnb-slof")
964 else GET_OPTION_INT("modulation")
966 else GET_OPTION_INT("code-rate-hp")
967 else GET_OPTION_INT("code-rate-lp")
968 else GET_OPTION_INT("bandwidth")
969 else GET_OPTION_INT("transmission")
970 else GET_OPTION_INT("guard")
971 else GET_OPTION_INT("hierarchy")
973 /* Redundant with voltage but much easier to use */
974 else if( !strncmp( psz_parser, "polarization=",
975 strlen( "polarization=" ) ) )
977 psz_parser += strlen( "polarization=" );
978 if ( *psz_parser == 'V' || *psz_parser == 'v' )
980 else if ( *psz_parser == 'H' || *psz_parser == 'h' )
984 msg_Err( p_access, "illegal polarization %c", *psz_parser );
988 var_Set( p_access, "dvb-voltage", val );
992 msg_Err( p_access, "unknown option (%s)", psz_parser );
1000 #undef GET_OPTION_INT
1001 #undef GET_OPTION_BOOL
1002 #undef GET_OPTION_STRING