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", 27500000, 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" );
476 if ( p_sys->i_ca_handle && mdate() > p_sys->i_ca_next_event )
479 p_sys->i_ca_next_event = mdate() + p_sys->i_ca_timeout;
482 if ( ufds[1].revents )
484 FrontendPoll( p_access );
488 if ( p_sys->i_httpd_timeout && mdate() > p_sys->i_httpd_timeout )
490 vlc_mutex_lock( &p_sys->httpd_mutex );
491 if ( p_sys->b_request_frontend_info )
493 msg_Warn( p_access, "frontend timeout for HTTP interface" );
494 p_sys->b_request_frontend_info = false;
495 p_sys->psz_frontend_info = strdup( "Timeout getting info\n" );
497 if ( p_sys->b_request_mmi_info )
499 msg_Warn( p_access, "MMI timeout for HTTP interface" );
500 p_sys->b_request_mmi_info = false;
501 p_sys->psz_mmi_info = strdup( "Timeout getting info\n" );
503 vlc_cond_signal( &p_sys->httpd_cond );
504 vlc_mutex_unlock( &p_sys->httpd_mutex );
507 if ( p_sys->b_request_frontend_info )
509 FrontendStatus( p_access );
512 if ( p_sys->b_request_mmi_info )
514 CAMStatus( p_access );
518 if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout )
520 msg_Warn( p_access, "no lock, tuning again" );
521 FrontendSet( p_access );
524 if ( ufds[0].revents )
526 p_block = block_New( p_access,
527 p_sys->i_read_once * TS_PACKET_SIZE );
528 if( ( i_ret = read( p_sys->i_handle, p_block->p_buffer,
529 p_sys->i_read_once * TS_PACKET_SIZE ) ) <= 0 )
531 msg_Warn( p_access, "read failed (%m)" );
532 block_Release( p_block );
535 p_block->i_buffer = i_ret;
540 if( p_sys->i_read_once < DVB_READ_ONCE )
541 p_sys->i_read_once++;
543 /* Update moderatly the signal properties */
544 if( (p_sys->i_stat_counter++ % 100) == 0 )
545 p_access->info.i_update |= INPUT_UPDATE_SIGNAL;
550 /*****************************************************************************
552 *****************************************************************************/
553 static block_t *BlockScan( access_t *p_access )
555 access_sys_t *p_sys = p_access->p_sys;
556 scan_t *p_scan = p_sys->scan;
557 scan_configuration_t cfg;
558 scan_session_t session;
561 if( scan_Next( p_scan, &cfg ) )
563 const bool b_first_eof = !p_access->info.b_eof;
566 msg_Warn( p_access, "Scanning finished" );
569 p_access->info.b_eof = true;
570 return b_first_eof ? scan_GetM3U( p_scan ) : NULL;
575 if( scan_session_Init( VLC_OBJECT(p_access), &session, &cfg ) )
579 msg_Dbg( p_access, "Scanning frequency %d", cfg.i_frequency );
580 var_SetInteger( p_access, "dvb-frequency", cfg.i_frequency );
581 msg_Dbg( p_access, " bandwidth %d", cfg.i_bandwidth );
582 var_SetInteger( p_access, "dvb-bandwidth", cfg.i_bandwidth );
585 msg_Dbg( p_access, " FEC %d", cfg.i_fec );
586 var_SetInteger( p_access, "dvb-fec", cfg.i_fec );
588 if ( cfg.c_polarization )
589 var_SetInteger( p_access, "dvb-voltage", cfg.c_polarization == 'H' ? 18 : 13 );
591 /* Setting frontend parameters for tuning the hardware */
592 if( FrontendSet( p_access ) < 0 )
594 msg_Err( p_access, "Failed to tune the frontend" );
595 p_access->info.b_eof = true;
600 int64_t i_scan_start = mdate();
602 bool b_has_dvb_signal = false;
603 bool b_has_lock = false;
608 struct pollfd ufds[2];
611 /* Initialize file descriptor sets */
612 memset (ufds, 0, sizeof (ufds));
613 ufds[0].fd = p_sys->i_handle;
614 ufds[0].events = POLLIN;
615 ufds[1].fd = p_sys->i_frontend_handle;
616 ufds[1].events = POLLPRI;
618 /* We'll wait 0.1 second if nothing happens */
619 /* Find if some data is available */
620 i_ret = poll( ufds, 2, 100 );
622 if( !vlc_object_alive (p_access) || scan_IsCancelled( p_scan ) )
627 const mtime_t i_scan_time = mdate() - i_scan_start;
628 frontend_status_t status;
630 FrontendGetStatus( p_access, &status );
632 b_has_dvb_signal |= status.b_has_carrier;
633 b_has_lock |= status.b_has_lock;
635 if( ( !b_has_dvb_signal && i_scan_time > DVB_SCAN_MAX_SIGNAL_TIME ) ||
636 ( !b_has_lock && i_scan_time > DVB_SCAN_MAX_LOCK_TIME ) ||
637 ( i_scan_time > DVB_SCAN_MAX_PROBE_TIME ) )
639 msg_Dbg( p_access, "timed out scanning current frequency (s=%d l=%d)", b_has_dvb_signal, b_has_lock );
649 msg_Err( p_access, "poll error: %m" );
650 scan_session_Clean( p_scan, &session );
652 p_access->info.b_eof = true;
656 if( ufds[1].revents )
658 frontend_statistic_t stat;
660 FrontendPoll( p_access );
662 if( !FrontendGetStatistic( p_access, &stat ) )
664 if( stat.i_snr > i_best_snr )
665 i_best_snr = stat.i_snr;
669 if ( p_sys->i_frontend_timeout && mdate() > p_sys->i_frontend_timeout )
671 msg_Warn( p_access, "no lock, tuning again" );
672 FrontendSet( p_access );
675 if ( ufds[0].revents )
677 const int i_read_once = 1;
678 block_t *p_block = block_New( p_access, i_read_once * TS_PACKET_SIZE );
680 if( ( i_ret = read( p_sys->i_handle, p_block->p_buffer,
681 i_read_once * TS_PACKET_SIZE ) ) <= 0 )
683 msg_Warn( p_access, "read failed (%m)" );
684 block_Release( p_block );
687 p_block->i_buffer = i_ret;
690 if( scan_session_Push( &session, p_block ) )
692 msg_Dbg( p_access, "finished scanning current frequency" );
700 scan_service_SetSNR( &session, i_best_snr );
702 scan_session_Clean( p_scan, &session );
706 /*****************************************************************************
708 *****************************************************************************/
709 static int Control( access_t *p_access, int i_query, va_list args )
711 access_sys_t *p_sys = p_access->p_sys;
712 bool *pb_bool, b_bool;
717 frontend_statistic_t stat;
722 case ACCESS_CAN_SEEK:
723 case ACCESS_CAN_FASTSEEK:
724 case ACCESS_CAN_PAUSE:
725 case ACCESS_CAN_CONTROL_PACE:
726 pb_bool = (bool*)va_arg( args, bool* );
730 case ACCESS_GET_PTS_DELAY:
731 pi_64 = (int64_t*)va_arg( args, int64_t * );
732 *pi_64 = var_GetInteger( p_access, "dvb-caching" ) * 1000;
736 case ACCESS_SET_PAUSE_STATE:
737 case ACCESS_GET_TITLE_INFO:
738 case ACCESS_SET_TITLE:
739 case ACCESS_SET_SEEKPOINT:
740 case ACCESS_GET_CONTENT_TYPE:
743 case ACCESS_GET_SIGNAL:
744 pf1 = (double*)va_arg( args, double * );
745 pf2 = (double*)va_arg( args, double * );
748 if( !FrontendGetStatistic( p_access, &stat ) )
750 *pf1 = (double)stat.i_snr / 65535.0;
751 *pf2 = (double)stat.i_signal_strenth / 65535.0;
755 case ACCESS_SET_PRIVATE_ID_STATE:
759 i_int = (int)va_arg( args, int ); /* Private data (pid for now)*/
760 b_bool = (bool)va_arg( args, int ); /* b_selected */
761 if( !p_sys->b_budget_mode )
763 /* FIXME we may want to give the real type (me ?, I don't ;) */
765 FilterSet( p_access, i_int, OTHER_TYPE );
767 FilterUnsetPID( p_access, i_int );
771 case ACCESS_SET_PRIVATE_ID_CA:
775 p_pmt = (dvbpsi_pmt_t *)va_arg( args, dvbpsi_pmt_t * );
777 CAMSet( p_access, p_pmt );
781 msg_Warn( p_access, "unimplemented query in control" );
788 /*****************************************************************************
789 * FilterSet/FilterUnset:
790 *****************************************************************************/
791 static void FilterSet( access_t *p_access, int i_pid, int i_type )
793 access_sys_t *p_sys = p_access->p_sys;
796 /* Find first free slot */
797 for( i = 0; i < MAX_DEMUX; i++ )
799 if( !p_sys->p_demux_handles[i].i_type )
802 if( p_sys->p_demux_handles[i].i_pid == i_pid )
803 return; /* Already set */
808 msg_Err( p_access, "no free p_demux_handles !" );
812 if( DMXSetFilter( p_access, i_pid,
813 &p_sys->p_demux_handles[i].i_handle, i_type ) )
815 msg_Err( p_access, "DMXSetFilter failed" );
818 p_sys->p_demux_handles[i].i_type = i_type;
819 p_sys->p_demux_handles[i].i_pid = i_pid;
821 if( p_sys->i_read_once < DVB_READ_ONCE )
822 p_sys->i_read_once++;
825 static void FilterUnset( access_t *p_access, int i_max )
827 access_sys_t *p_sys = p_access->p_sys;
830 for( i = 0; i < i_max; i++ )
832 if( p_sys->p_demux_handles[i].i_type )
834 DMXUnsetFilter( p_access, p_sys->p_demux_handles[i].i_handle );
835 p_sys->p_demux_handles[i].i_type = 0;
840 static void FilterUnsetPID( access_t *p_access, int i_pid )
842 access_sys_t *p_sys = p_access->p_sys;
845 for( i = 0; i < MAX_DEMUX; i++ )
847 if( p_sys->p_demux_handles[i].i_type &&
848 p_sys->p_demux_handles[i].i_pid == i_pid )
850 DMXUnsetFilter( p_access, p_sys->p_demux_handles[i].i_handle );
851 p_sys->p_demux_handles[i].i_type = 0;
856 /*****************************************************************************
858 *****************************************************************************/
859 static void VarInit( access_t *p_access )
862 var_Create( p_access, "dvb-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
865 var_Create( p_access, "dvb-adapter", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
866 var_Create( p_access, "dvb-device", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
867 var_Create( p_access, "dvb-frequency", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
868 var_Create( p_access, "dvb-inversion", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
869 var_Create( p_access, "dvb-probe", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
870 var_Create( p_access, "dvb-budget-mode", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
873 var_Create( p_access, "dvb-satellite", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
874 var_Create( p_access, "dvb-satno", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
875 var_Create( p_access, "dvb-voltage", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
876 var_Create( p_access, "dvb-high-voltage", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
877 var_Create( p_access, "dvb-tone", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
878 var_Create( p_access, "dvb-fec", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
879 var_Create( p_access, "dvb-srate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
880 var_Create( p_access, "dvb-lnb-lof1", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
881 var_Create( p_access, "dvb-lnb-lof2", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
882 var_Create( p_access, "dvb-lnb-slof", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
885 var_Create( p_access, "dvb-modulation", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
888 var_Create( p_access, "dvb-code-rate-hp", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
889 var_Create( p_access, "dvb-code-rate-lp", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
890 var_Create( p_access, "dvb-bandwidth", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
891 var_Create( p_access, "dvb-transmission", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
892 var_Create( p_access, "dvb-guard", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
893 var_Create( p_access, "dvb-hierarchy", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
896 var_Create( p_access, "dvb-http-host", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
897 var_Create( p_access, "dvb-http-user", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
898 var_Create( p_access, "dvb-http-password", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
899 var_Create( p_access, "dvb-http-acl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
900 var_Create( p_access, "dvb-http-intf-cert", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
901 var_Create( p_access, "dvb-http-intf-key", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
902 var_Create( p_access, "dvb-http-intf-ca", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
903 var_Create( p_access, "dvb-http-intf-crl", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
908 static int ParseMRL( access_t *p_access )
910 char *psz_dup = strdup( p_access->psz_location );
911 char *psz_parser = psz_dup;
914 #define GET_OPTION_INT( option ) \
915 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
917 val.i_int = strtol( psz_parser + strlen(option "="), &psz_parser, \
919 var_Set( p_access, "dvb-" option, val ); \
922 #define GET_OPTION_BOOL( option ) \
923 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
925 val.b_bool = strtol( psz_parser + strlen(option "="), &psz_parser, \
927 var_Set( p_access, "dvb-" option, val ); \
930 #define GET_OPTION_STRING( option ) \
931 if ( !strncmp( psz_parser, option "=", strlen( option "=" ) ) ) \
933 psz_parser += strlen( option "=" ); \
934 val.psz_string = psz_parser; \
936 char *tok = strtok_r(val.psz_string, ":", &p_save); \
937 val.psz_string[tok - val.psz_string - 1] = 0; \
938 var_Set( p_access, "dvb-" option, val ); \
939 psz_parser += strlen( val.psz_string ); \
944 GET_OPTION_INT("adapter")
945 else GET_OPTION_INT("device")
946 else GET_OPTION_INT("frequency")
947 else GET_OPTION_INT("inversion")
948 else GET_OPTION_BOOL("probe")
949 else GET_OPTION_BOOL("budget-mode")
951 else GET_OPTION_STRING("satellite")
952 else GET_OPTION_INT("voltage")
953 else GET_OPTION_BOOL("high-voltage")
954 else GET_OPTION_INT("tone")
955 else GET_OPTION_INT("satno")
956 else GET_OPTION_INT("fec")
957 else GET_OPTION_INT("srate")
958 else GET_OPTION_INT("lnb-lof1")
959 else GET_OPTION_INT("lnb-lof2")
960 else GET_OPTION_INT("lnb-slof")
962 else GET_OPTION_INT("modulation")
964 else GET_OPTION_INT("code-rate-hp")
965 else GET_OPTION_INT("code-rate-lp")
966 else GET_OPTION_INT("bandwidth")
967 else GET_OPTION_INT("transmission")
968 else GET_OPTION_INT("guard")
969 else GET_OPTION_INT("hierarchy")
971 /* Redundant with voltage but much easier to use */
972 else if( !strncmp( psz_parser, "polarization=",
973 strlen( "polarization=" ) ) )
975 psz_parser += strlen( "polarization=" );
976 if ( *psz_parser == 'V' || *psz_parser == 'v' )
978 else if ( *psz_parser == 'H' || *psz_parser == 'h' )
982 msg_Err( p_access, "illegal polarization %c", *psz_parser );
986 var_Set( p_access, "dvb-voltage", val );
990 msg_Err( p_access, "unknown option (%s)", psz_parser );
998 #undef GET_OPTION_INT
999 #undef GET_OPTION_BOOL
1000 #undef GET_OPTION_STRING