Linux::DVB patch to support S2API FE_SET_PROPERTY

Simon Lockhart simon at slimey.org
Wed Mar 7 01:53:10 CET 2012


Whilst working with Linux::DVB for an IPTV project I'm doing, I found that
I needed to support the S2API (Linux DVB API v5) in order to drive DVB-S2
cards.

I've added support for FE_SET_PROPERTY by adding a new function to 
Linux::DVB::Frontend (set_property) which takes a array of hashes to closely
match C code which implements this:

    $ok = $fe->set_property([
        { cmd => DTV_FREQUENCY,       data => $freq - 9750000 },
        { cmd => DTV_MODULATION,      data => QPSK },
        { cmd => DTV_INVERSION,       data => INVERSION_AUTO },
        { cmd => DTV_SYMBOL_RATE,     data => 27500000 },
        { cmd => DTV_INNER_FEC,       data => FEC_AUTO },
        { cmd => DTV_DELIVERY_SYSTEM, data => SYS_DVBS },
        { cmd => DTV_TUNE },
        ]
      );

See the attached patch (which also includes a minor fix for 
satellite_delivery_system_descriptor decoding in Linux::DVB::Decode::si)

As I continue development using this module, I'm sure I'll need to add support
for more of the DVB API, or more SI decoding, which I'm happy to feed back if
there's interest.

Simon

Simon
-------------- next part --------------
cvs diff: Diffing .
Index: DVB.pm
===================================================================
RCS file: /schmorpforge/Linux-DVB/DVB.pm,v
retrieving revision 1.15
diff -u -r1.15 DVB.pm
--- DVB.pm      24 May 2010 01:52:59 -0000      1.15
+++ DVB.pm      7 Mar 2012 00:44:32 -0000
@@ -31,7 +31,7 @@
 use Fcntl ();
 
 BEGIN {
-   $VERSION = '1.01';
+   $VERSION = '1.02';
    @ISA = qw(Exporter);
 
    require XSLoader;
Index: DVB.xs
===================================================================
RCS file: /schmorpforge/Linux-DVB/DVB.xs,v
retrieving revision 1.8
diff -u -r1.8 DVB.xs
--- DVB.xs      24 May 2010 01:52:59 -0000      1.8
+++ DVB.xs      7 Mar 2012 00:44:32 -0000
@@ -6,6 +6,7 @@
 
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/dmx.h>
+#include <linux/dvb/version.h>
 
 #define CONST(name) { #name, name }
 
@@ -205,6 +206,88 @@
   //CONST (DMX_SCRAMBLING_OFF),
   //CONST (DMX_SCRAMBLING_ON),
 
+#if DVB_API_VERSION >= 5
+  CONST (DTV_UNDEFINED),
+  CONST (DTV_TUNE),
+  CONST (DTV_CLEAR),
+  CONST (DTV_FREQUENCY),
+  CONST (DTV_MODULATION),
+  CONST (DTV_BANDWIDTH_HZ),
+  CONST (DTV_INVERSION),
+  CONST (DTV_DISEQC_MASTER),
+  CONST (DTV_SYMBOL_RATE),
+  CONST (DTV_INNER_FEC),
+  CONST (DTV_VOLTAGE),
+  CONST (DTV_TONE),
+  CONST (DTV_PILOT),
+  CONST (DTV_ROLLOFF),
+  CONST (DTV_DISEQC_SLAVE_REPLY),
+  CONST (DTV_FE_CAPABILITY_COUNT),
+  CONST (DTV_FE_CAPABILITY),
+  CONST (DTV_DELIVERY_SYSTEM),
+  CONST (DTV_ISDBT_PARTIAL_RECEPTION),
+  CONST (DTV_ISDBT_SOUND_BROADCASTING),
+  CONST (DTV_ISDBT_SB_SUBCHANNEL_ID),
+  CONST (DTV_ISDBT_SB_SEGMENT_IDX),
+  CONST (DTV_ISDBT_SB_SEGMENT_COUNT),
+  CONST (DTV_ISDBT_LAYERA_FEC),
+  CONST (DTV_ISDBT_LAYERA_MODULATION),
+  CONST (DTV_ISDBT_LAYERA_SEGMENT_COUNT),
+  CONST (DTV_ISDBT_LAYERA_TIME_INTERLEAVING),
+  CONST (DTV_ISDBT_LAYERB_FEC),
+  CONST (DTV_ISDBT_LAYERB_MODULATION),
+  CONST (DTV_ISDBT_LAYERB_SEGMENT_COUNT),
+  CONST (DTV_ISDBT_LAYERB_TIME_INTERLEAVING),
+  CONST (DTV_ISDBT_LAYERC_FEC),
+  CONST (DTV_ISDBT_LAYERC_MODULATION),
+  CONST (DTV_ISDBT_LAYERC_SEGMENT_COUNT),
+  CONST (DTV_ISDBT_LAYERC_TIME_INTERLEAVING),
+  CONST (DTV_API_VERSION),
+  CONST (DTV_CODE_RATE_HP),
+  CONST (DTV_CODE_RATE_LP),
+  CONST (DTV_GUARD_INTERVAL),
+  CONST (DTV_TRANSMISSION_MODE),
+  CONST (DTV_HIERARCHY),
+  CONST (DTV_ISDBT_LAYER_ENABLED),
+  CONST (DTV_ISDBS_TS_ID),
+  // CONST (DTV_DVBT2_PLP_ID),
+
+  CONST (SYS_UNDEFINED),
+  CONST (SYS_DVBC_ANNEX_AC),
+  CONST (SYS_DVBC_ANNEX_B),
+  CONST (SYS_DVBT),
+  CONST (SYS_DSS),
+  CONST (SYS_DVBS),
+  CONST (SYS_DVBS2),
+  CONST (SYS_DVBH),
+  CONST (SYS_ISDBT),
+  CONST (SYS_ISDBS),
+  CONST (SYS_ISDBC),
+  CONST (SYS_ATSC),
+  CONST (SYS_ATSCMH),
+  CONST (SYS_DMBTH),
+  CONST (SYS_CMMB),
+  CONST (SYS_DAB),
+  // CONST (SYS_DVBT2),
+
+  CONST (VSB_8),
+  CONST (VSB_16),
+  CONST (PSK_8),
+  CONST (APSK_16),
+  CONST (APSK_32),
+  CONST (DQPSK),
+
+  CONST (PILOT_ON),
+  CONST (PILOT_OFF),
+  CONST (PILOT_AUTO),
+
+  CONST (ROLLOFF_35), /* Implied value in DVB-S, default for DVB-S2 */
+  CONST (ROLLOFF_20),
+  CONST (ROLLOFF_25),
+  CONST (ROLLOFF_AUTO),
+
+#endif
+
   // constants defined by this file
   CONST (SCT_PAT),
   CONST (SCT_CAT),
@@ -476,7 +559,7 @@
 
          case DT_satellite_delivery_system: 
            HVS (hv, frequency, newSVuv (bcd_to_int (decode_field (32))));
-           HVS (hv, orbital_position, newSVnv (bcd_to_int (decode_field (32)) / 10));
+           HVS (hv, orbital_position, newSVnv (bcd_to_int (decode_field (16)) / 10.0));
            DEC_I (hv,  1, west_east_flag);
            DEC_I (hv,  2, polarization);
            DEC_I (hv,  5, modulation);
@@ -778,6 +861,55 @@
        OUTPUT:
         RETVAL
 
+#if DVB_API_VERSION >= 5
+int
+set_property (FE_fd fd, SV *parameters)
+       CODE:
+       AV *props;
+       int numprops, i, ret;
+       struct dtv_property *dtv_prop;
+       struct dtv_properties dtv_props;
+
+        if (!SvROK (parameters) || SvTYPE (SvRV (parameters)) != SVt_PVAV)
+          croak ("Linux::DVB::Frontend::set_property requires an arrayref as argument");
+
+       props = (AV *)SvRV(parameters);
+       numprops = av_len(props) + 1;
+
+       Newxz(dtv_prop, numprops, struct dtv_property);
+
+       dtv_props.num = numprops;
+       dtv_props.props = dtv_prop;
+
+       for(i = 0; i < numprops; i++)
+       {
+         SV **v_cmd, **v_data;
+         SV *p = av_shift(props);
+
+          if (!SvROK (p) || SvTYPE(SvRV(p)) != SVt_PVHV)
+           croak ("Linux::DVB::Frontend::set_property arrayref must only contain hashrefs");
+
+         v_cmd = hv_fetch((HV *)SvRV(p), "cmd", 3, 0);
+         v_data = hv_fetch((HV *)SvRV(p), "data", 4, 0);
+         if (!v_cmd) 
+           croak ("Linux::DVB::Frontend::set_property must have cmd key");
+           
+         dtv_prop[i].cmd = SvIV(*v_cmd);
+
+         if (v_data) 
+           dtv_prop[i].u.data = SvIV(*v_data);
+       }
+
+       ret = ioctl(fd, FE_SET_PROPERTY, &dtv_props);
+
+       Safefree(dtv_prop);
+
+       RETVAL = ret;
+       OUTPUT:
+       RETVAL
+
+#endif
+
 SV *
 _get (int fd, int type)
        CODE:
cvs diff: Diffing eg
cvs diff: Diffing t


More information about the perl mailing list