DVB API wrapper patch v0.2 for VDR-1.5.14

Message ID 47A5AFC5.2010709@gmx.de
State New
Headers

Commit Message

Udo Richter Feb. 3, 2008, 12:12 p.m. UTC
  Hi list,


Based on the original DVB API patch of last week, I've done a cleaner 
rewrite of the patch. This time, the changes to the VDR sources are 
limited to a few #includes and replacements of ioctl calls by the new 
DVBFE_ioctl wrapper call. All the magic goes into this API wrapper, that 
translates multiproto calls into DVB 3.0 API calls.

There's also more control on the behavior. Adding DEFINES += 
-DDVB_MULTIPROTO_WRAPPER=1 to Make.config will enforce the API 
translation even if the multiproto API is present, setting it =0 will 
disable API translation, requiring the multiproto API to be present. By 
default, the present API is automatically detected, and the wrapper is 
enabled accordingly.

The patch currently doesn't translate the whole API, just the parts that 
are used by VDR. But if required, the missing parts can surely be 
integrated.


Cheers,

Udo
  

Patch

diff -Nu vdr-1.5.14/channels.c vdr-1.5.14-wrapper/channels.c
--- vdr-1.5.14/channels.c	2008-01-27 14:59:53.000000000 +0100
+++ vdr-1.5.14-wrapper/channels.c	2008-02-02 23:37:38.000000000 +0100
@@ -11,6 +11,7 @@ 
 #include <linux/dvb/frontend.h>
 #include <ctype.h>
 #include "device.h"
+#include "dvb_api_wrapper.h"
 #include "epg.h"
 #include "timers.h"
 
diff -Nu vdr-1.5.14/dvb_api_wrapper.c vdr-1.5.14-wrapper/dvb_api_wrapper.c
--- vdr-1.5.14/dvb_api_wrapper.c	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.14-wrapper/dvb_api_wrapper.c	2008-02-02 23:57:09.000000000 +0100
@@ -0,0 +1,203 @@ 
+/*
+ * dvb_api_wrapper.c:
+ * Wrapper to translate Multiproto DVB API to DVB 3.0 API calls
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: $
+ */
+
+#include "dvb_api_wrapper.h"
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#ifdef DVB_MULTIPROTO_WRAPPER
+
+static bool TranslateCodeRate(fe_code_rate &oldfec, dvbfe_fec fec) {
+  switch (fec) {
+    case DVBFE_FEC_NONE: oldfec = FEC_NONE; return true;
+    case DVBFE_FEC_1_2:  oldfec = FEC_1_2;  return true;
+    case DVBFE_FEC_2_3:  oldfec = FEC_2_3;  return true;
+    case DVBFE_FEC_3_4:  oldfec = FEC_3_4;  return true;
+    case DVBFE_FEC_4_5:  oldfec = FEC_4_5;  return true;
+    case DVBFE_FEC_5_6:  oldfec = FEC_5_6;  return true;
+    case DVBFE_FEC_6_7:  oldfec = FEC_6_7;  return true;
+    case DVBFE_FEC_7_8:  oldfec = FEC_7_8;  return true;
+    case DVBFE_FEC_8_9:  oldfec = FEC_8_9;  return true;
+    case DVBFE_FEC_AUTO: oldfec = FEC_AUTO; return true;
+    default: return false;
+    }
+}
+
+static bool TranslateModulation(fe_modulation &oldmod, dvbfe_modulation mod) {
+  switch (mod) {
+    case DVBFE_MOD_QPSK:    oldmod = QPSK;     return true;
+    case DVBFE_MOD_QAM16:   oldmod = QAM_16;   return true;
+    case DVBFE_MOD_QAM32:   oldmod = QAM_32;   return true;
+    case DVBFE_MOD_QAM64:   oldmod = QAM_64;   return true;
+    case DVBFE_MOD_QAM128:  oldmod = QAM_128;  return true;
+    case DVBFE_MOD_QAM256:  oldmod = QAM_256;  return true;
+    case DVBFE_MOD_QAMAUTO: oldmod = QAM_AUTO; return true;
+    default: return false;
+  }
+}
+
+static bool TranslateBandwidth(fe_bandwidth_t &oldbw, dvbfe_bandwidth bandwidth) {
+  switch (bandwidth) {
+    case DVBFE_BANDWIDTH_8_MHZ: oldbw = BANDWIDTH_8_MHZ; return true;
+    case DVBFE_BANDWIDTH_7_MHZ: oldbw = BANDWIDTH_7_MHZ; return true;
+    case DVBFE_BANDWIDTH_6_MHZ: oldbw = BANDWIDTH_6_MHZ; return true;
+    case DVBFE_BANDWIDTH_AUTO:  oldbw = BANDWIDTH_AUTO;  return true;
+    default: return false;
+  }
+}
+
+static bool TranslateTransmission(fe_transmit_mode_t &oldtrans, dvbfe_transmission_mode trans) {
+  switch (trans) {
+    case DVBFE_TRANSMISSION_MODE_2K:   oldtrans = TRANSMISSION_MODE_2K;   return true;
+    case DVBFE_TRANSMISSION_MODE_8K:   oldtrans = TRANSMISSION_MODE_8K;   return true;
+    case DVBFE_TRANSMISSION_MODE_AUTO: oldtrans = TRANSMISSION_MODE_AUTO; return true;
+    default: return false;
+  }
+}
+
+static bool TranslateGuard(fe_guard_interval_t &oldguard, dvbfe_guard_interval guard) {
+  switch (guard) {
+    case DVBFE_GUARD_INTERVAL_1_32: oldguard = GUARD_INTERVAL_1_32; return true;
+    case DVBFE_GUARD_INTERVAL_1_16: oldguard = GUARD_INTERVAL_1_16; return true;
+    case DVBFE_GUARD_INTERVAL_1_8:  oldguard = GUARD_INTERVAL_1_8;  return true;
+    case DVBFE_GUARD_INTERVAL_1_4:  oldguard = GUARD_INTERVAL_1_4;  return true;
+    case DVBFE_GUARD_INTERVAL_AUTO: oldguard = GUARD_INTERVAL_AUTO; return true;
+    default: return false;
+  }
+}
+
+static bool TranslateHierarchy(fe_hierarchy_t &oldhier, dvbfe_hierarchy hierarchy, dvbfe_alpha alpha) {
+  switch (hierarchy) {
+    case DVBFE_HIERARCHY_OFF:  oldhier = HIERARCHY_NONE; return true;
+    case DVBFE_HIERARCHY_AUTO: oldhier = HIERARCHY_AUTO; return true;
+    case DVBFE_HIERARCHY_ON:
+         switch (alpha) {
+           case DVBFE_ALPHA_1: oldhier = HIERARCHY_1; return true;
+           case DVBFE_ALPHA_2: oldhier = HIERARCHY_2; return true;
+           case DVBFE_ALPHA_4: oldhier = HIERARCHY_4; return true;
+           default: return false;
+           }
+    default: return false;
+    }
+}
+
+static int ioctl_DVBFE_SET_PARAMS(int d, dvbfe_params *params) {
+  dvb_frontend_parameters oldparams;
+  memset(&oldparams, 0, sizeof(oldparams));
+
+  oldparams.frequency = params->frequency;
+  oldparams.inversion = params->inversion;
+
+  switch (params->delivery) {
+    case DVBFE_DELSYS_DVBS:
+         if (   params->delsys.dvbs.modulation != DVBFE_MOD_QPSK
+             || !TranslateCodeRate(oldparams.u.qpsk.fec_inner, params->delsys.dvbs.fec)) {
+            errno = EINVAL;
+            return -1;
+            }
+         oldparams.u.qpsk.symbol_rate = params->delsys.dvbs.symbol_rate;
+         break;
+    case DVBFE_DELSYS_DVBC:
+         if (   !TranslateModulation(oldparams.u.qam.modulation, params->delsys.dvbc.modulation)
+             || !TranslateCodeRate(oldparams.u.qam.fec_inner, params->delsys.dvbc.fec)) {
+            errno = EINVAL;
+            return -1;
+            }
+         oldparams.u.qam.symbol_rate = params->delsys.dvbc.symbol_rate;
+         break;
+    case DVBFE_DELSYS_DVBT:
+         if (   !TranslateModulation(oldparams.u.ofdm.constellation, params->delsys.dvbt.constellation)
+             || !TranslateBandwidth(oldparams.u.ofdm.bandwidth, params->delsys.dvbt.bandwidth)
+             || !TranslateCodeRate(oldparams.u.ofdm.code_rate_HP, params->delsys.dvbt.code_rate_HP)
+             || !TranslateCodeRate(oldparams.u.ofdm.code_rate_LP, params->delsys.dvbt.code_rate_LP)
+             || !TranslateTransmission(oldparams.u.ofdm.transmission_mode, params->delsys.dvbt.transmission_mode)
+             || !TranslateGuard(oldparams.u.ofdm.guard_interval, params->delsys.dvbt.guard_interval)
+             || !TranslateHierarchy(oldparams.u.ofdm.hierarchy_information, params->delsys.dvbt.hierarchy, params->delsys.dvbt.alpha)) {
+            errno = EINVAL;
+            return -1;
+            }
+         // ignored: params->delsys.dvbt.priority
+         break;
+    default:
+        errno = EINVAL;
+        return -1;
+    }
+  return ioctl(d, FE_SET_FRONTEND, &oldparams);
+}
+
+static int ioctl_DVBFE_GET_DELSYS(int d, dvbfe_delsys *delsys) {
+  dvb_frontend_info oldinfo;
+
+  int err = ioctl(d, FE_GET_INFO, &oldinfo);
+  if (err < 0) return err;
+
+  switch (oldinfo.type) {
+    case FE_QPSK: *delsys = DVBFE_DELSYS_DVBS; return 0;
+    case FE_QAM:  *delsys = DVBFE_DELSYS_DVBC; return 0;
+    case FE_OFDM: *delsys = DVBFE_DELSYS_DVBT; return 0;
+    default:;
+    }
+  errno = EINVAL;
+  return -1;
+}
+
+static int ioctl_DVBFE_GET_INFO(int d, dvbfe_info *feinfo) {
+  dvb_frontend_info oldinfo;
+
+  int err = ioctl(d, FE_GET_INFO, &oldinfo);
+  if (err < 0) return err;
+
+  strncpy(feinfo->name, oldinfo.name, 128);
+
+  feinfo->frequency_min = oldinfo.frequency_min;
+  feinfo->frequency_max = oldinfo.frequency_max;
+  feinfo->frequency_step = oldinfo.frequency_stepsize;
+  feinfo->frequency_tolerance = oldinfo.frequency_tolerance;
+  feinfo->symbol_rate_min = oldinfo.symbol_rate_min;
+  feinfo->symbol_rate_max = oldinfo.symbol_rate_max;
+  feinfo->symbol_rate_tolerance = oldinfo.symbol_rate_tolerance;
+
+  switch (oldinfo.type) {
+    case FE_QPSK:
+         if (feinfo->delivery == DVBFE_DELSYS_DVBS)
+            return err; // ok
+         break;
+    case FE_QAM:
+         if (feinfo->delivery == DVBFE_DELSYS_DVBC)
+            return err; // ok
+         break;
+    case FE_OFDM:
+         if (feinfo->delivery == DVBFE_DELSYS_DVBT)
+            return err; // ok
+         break;
+    default:;
+    }
+  errno = EINVAL;
+  return -1;
+}
+
+int DVBFE_ioctl(int d, int request, void *data) {
+  switch (request) {
+    case DVBFE_SET_PARAMS:
+         return ioctl_DVBFE_SET_PARAMS(d, (dvbfe_params*)data);
+    case DVBFE_GET_DELSYS:
+         return ioctl_DVBFE_GET_DELSYS(d, (dvbfe_delsys*)data);
+    case DVBFE_GET_INFO:
+         return ioctl_DVBFE_GET_INFO(d, (dvbfe_info*)data);
+    case DVBFE_GET_PARAMS:
+    case DVBFE_GET_EVENT:
+         errno = EINVAL;
+         return -1;
+  }
+  return ioctl(d, request, data);
+}
+
+#endif // ifdef DVB_MULTIPROTO_WRAPPER
diff -Nu vdr-1.5.14/dvb_api_wrapper.h vdr-1.5.14-wrapper/dvb_api_wrapper.h
--- vdr-1.5.14/dvb_api_wrapper.h	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.14-wrapper/dvb_api_wrapper.h	2008-02-03 00:04:51.000000000 +0100
@@ -0,0 +1,418 @@ 
+/*
+ * dvb_api_wrapper.h:
+ * Wrapper to translate Multiproto DVB API to DVB 3.0 API calls
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: $
+ */
+
+#ifndef __DVB_API_WRAPPER_H
+#define __DVB_API_WRAPPER_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/version.h>
+
+#if DVB_API_VERSION != 3
+#error VDR requires Linux DVB driver API version 3!
+#endif
+
+#if !defined(DVB_MULTIPROTO_WRAPPER) && DVB_API_VERSION_MINOR < 3
+#define DVB_MULTIPROTO_WRAPPER 1
+#endif
+
+#if defined(DVB_MULTIPROTO_WRAPPER) && DVB_MULTIPROTO_WRAPPER == 0
+#undef DVB_MULTIPROTO_WRAPPER
+#endif
+
+#if DVB_API_VERSION_MINOR < 3
+
+// DVB API is missing multiproto structs, so we declare them.
+// The following is based on frontend.h from multiproto DVB driver
+
+/*
+ * Delivery Systems
+ * needs to set/queried for multistandard frontends
+ */
+enum dvbfe_delsys {
+	DVBFE_DELSYS_DVBS		= (1 <<  0),
+	DVBFE_DELSYS_DSS		= (1 <<  1),
+	DVBFE_DELSYS_DVBS2		= (1 <<  2),
+	DVBFE_DELSYS_DVBC		= (1 <<  3),
+	DVBFE_DELSYS_DVBT		= (1 <<  4),
+	DVBFE_DELSYS_DVBH		= (1 <<  5),
+	DVBFE_DELSYS_ATSC		= (1 <<  6),
+	DVBFE_DELSYS_DUMMY		= (1 << 31)
+};
+#define DVBFE_GET_DELSYS		_IOR('o', 82, enum dvbfe_delsys)
+
+/* Modulation types			*/
+enum dvbfe_modulation {
+	DVBFE_MOD_NONE			= (0 <<  0),
+	DVBFE_MOD_BPSK			= (1 <<  0),
+	DVBFE_MOD_QPSK			= (1 <<  1),
+	DVBFE_MOD_OQPSK			= (1 <<  2),
+	DVBFE_MOD_8PSK			= (1 <<  3),
+	DVBFE_MOD_16APSK		= (1 <<  4),
+	DVBFE_MOD_32APSK		= (1 <<  5),
+	DVBFE_MOD_QAM4			= (1 <<  6),
+	DVBFE_MOD_QAM16			= (1 <<  7),
+	DVBFE_MOD_QAM32			= (1 <<  8),
+	DVBFE_MOD_QAM64			= (1 <<  9),
+	DVBFE_MOD_QAM128		= (1 << 10),
+	DVBFE_MOD_QAM256		= (1 << 11),
+	DVBFE_MOD_QAM512		= (1 << 12),
+	DVBFE_MOD_QAM1024		= (1 << 13),
+	DVBFE_MOD_QAMAUTO		= (1 << 14),
+	DVBFE_MOD_OFDM			= (1 << 15),
+	DVBFE_MOD_COFDM			= (1 << 16),
+	DVBFE_MOD_VSB8			= (1 << 17),
+	DVBFE_MOD_VSB16			= (1 << 18),
+	DVBFE_MOD_AUTO			= (1 << 31)
+};
+
+/*
+ * Convolution Code Rate (Viterbi Inner Code Rate)
+ * DVB-S2 uses LDPC. Information on LDPC can be found at
+ * http://www.ldpc-codes.com
+ */
+enum dvbfe_fec {
+	DVBFE_FEC_NONE			= (0 <<  0),
+	DVBFE_FEC_1_4			= (1 <<  0),
+	DVBFE_FEC_1_3			= (1 <<  1),
+	DVBFE_FEC_2_5			= (1 <<  2),
+	DVBFE_FEC_1_2			= (1 <<  3),
+	DVBFE_FEC_3_5			= (1 <<  4),
+	DVBFE_FEC_2_3			= (1 <<  5),
+	DVBFE_FEC_3_4			= (1 <<  6),
+	DVBFE_FEC_4_5			= (1 <<  7),
+	DVBFE_FEC_5_6			= (1 <<  8),
+	DVBFE_FEC_6_7			= (1 <<  9),
+	DVBFE_FEC_7_8			= (1 << 10),
+	DVBFE_FEC_8_9			= (1 << 11),
+	DVBFE_FEC_9_10			= (1 << 12),
+	DVBFE_FEC_AUTO			= (1 << 31)
+};
+
+/* Frontend Inversion (I/Q Swap)	*/
+enum dvbfe_inversion {
+	DVBFE_INVERSION_OFF		= 0,
+	DVBFE_INVERSION_ON		= 1,
+	DVBFE_INVERSION_AUTO		= 2
+};
+
+/* DVB-S parameters			*/
+struct dvbs_params {
+	__u32				symbol_rate;
+
+	enum dvbfe_modulation		modulation;
+	enum dvbfe_fec			fec;
+};
+
+/* DSS parameters			*/
+struct dss_params {
+	__u32				symbol_rate;
+
+	enum dvbfe_modulation		modulation;
+	enum dvbfe_fec			fec;
+};
+
+/*
+ * Rolloff Rate (Nyquist Filter Rolloff)
+ * NOTE: DVB-S2 has rates of 0.20, 0.25, 0.35
+ * Values are x100
+ * Applies to DVB-S2
+ */
+enum dvbfe_rolloff {
+	DVBFE_ROLLOFF_35		= 0,
+	DVBFE_ROLLOFF_25		= 1,
+	DVBFE_ROLLOFF_20		= 2,
+	DVBFE_ROLLOFF_UNKNOWN		= 3
+};
+
+/* DVB-S2 parameters			*/
+struct dvbs2_params {
+	__u32				symbol_rate;
+
+	enum dvbfe_modulation		modulation;
+	enum dvbfe_fec			fec;
+
+	/* Informational fields only	*/
+	enum dvbfe_rolloff		rolloff;
+
+	__u8				matype_1;
+	__u8				matype_2;
+	__u8				upl_1;
+	__u8				upl_2;
+	__u8				dfl_1;
+	__u8				dfl_2;
+	__u8				sync;
+	__u8				syncd_1;
+	__u8				syncd_2;
+
+	__u8				pad[32];
+};
+
+/* DVB-C parameters			*/
+struct dvbc_params {
+	__u32				symbol_rate;
+	enum dvbfe_modulation		modulation;
+	enum dvbfe_fec			fec;
+};
+
+/* DVB-T Channel bandwidth		*/
+enum dvbfe_bandwidth {
+	DVBFE_BANDWIDTH_8_MHZ		= (1 <<  0),
+	DVBFE_BANDWIDTH_7_MHZ		= (1 <<  1),
+	DVBFE_BANDWIDTH_6_MHZ		= (1 <<  2),
+	DVBFE_BANDWIDTH_5_MHZ		= (1 <<  3),
+	DVBFE_BANDWIDTH_AUTO		= (1 << 31)
+};
+
+/* DVB-T/DVB-H transmission mode	*/
+enum dvbfe_transmission_mode {
+	DVBFE_TRANSMISSION_MODE_2K	= (1 <<  0),
+	DVBFE_TRANSMISSION_MODE_4K	= (1 <<  1),
+	DVBFE_TRANSMISSION_MODE_8K	= (1 <<  2),
+	DVBFE_TRANSMISSION_MODE_AUTO	= (1 << 31)
+};
+
+/* DVB-T/DVB-H Guard interval		*/
+enum dvbfe_guard_interval {
+	DVBFE_GUARD_INTERVAL_1_32	= (1 <<  1),
+	DVBFE_GUARD_INTERVAL_1_16	= (1 <<  2),
+	DVBFE_GUARD_INTERVAL_1_8	= (1 <<  3),
+	DVBFE_GUARD_INTERVAL_1_4	= (1 <<  4),
+	DVBFE_GUARD_INTERVAL_AUTO	= (1 << 31)
+};
+
+/* DVB-T/DVB-H Hierarchial modulation	*/
+enum dvbfe_hierarchy {
+	DVBFE_HIERARCHY_OFF		= (1 <<  0),
+	DVBFE_HIERARCHY_ON		= (1 <<  1),
+	DVBFE_HIERARCHY_AUTO		= (1 <<  2)
+};
+
+/* DVB-T/DVB-H Rolloff's		*/
+enum dvbfe_alpha {
+	DVBFE_ALPHA_1			= (1 <<  0),
+	DVBFE_ALPHA_2			= (1 <<  1),
+	DVBFE_ALPHA_4			= (1 <<  2)
+};
+
+/* Stream priority (Hierachial coding)	*/
+enum dvbfe_stream_priority {
+	DVBFE_STREAM_PRIORITY_HP	= (0 << 0),
+	DVBFE_STREAM_PRIORITY_LP	= (1 << 0)
+};
+
+/* DVB-T parameters			*/
+struct dvbt_params {
+	enum dvbfe_modulation		constellation;
+	enum dvbfe_bandwidth		bandwidth;
+	enum dvbfe_fec			code_rate_HP;
+	enum dvbfe_fec			code_rate_LP;
+	enum dvbfe_transmission_mode	transmission_mode;
+	enum dvbfe_guard_interval	guard_interval;
+	enum dvbfe_hierarchy		hierarchy;
+	enum dvbfe_alpha		alpha;
+	enum dvbfe_stream_priority	priority;
+
+	__u8				pad[32];
+};
+
+/* DVB-H Interleaver type		*/
+enum dvbfe_interleaver {
+	DVBFE_INTERLEAVER_NATIVE	= (1 <<  0),
+	DVBFE_INTERLEAVER_INDEPTH	= (1 <<  1),
+	DVBFE_INTERLEAVER_AUTO		= (1 << 31)
+};
+
+/* DVB-H MPE-FEC Indicator		*/
+enum dvbfe_mpefec {
+	DVBFE_MPEFEC_OFF		= (1 <<  0),
+	DVBFE_MPEFEC_ON			= (1 <<  1)
+};
+
+/* DVB-H Timeslicing Indicator		*/
+enum dvbfe_timeslicing {
+	DVBFE_TIMESLICING_OFF		= (1 <<  0),
+	DVBFE_TIMESLICING_ON		= (1 <<  1)
+};
+
+/* DVB-H parameters			*/
+struct dvbh_params {
+	enum dvbfe_modulation		constellation;
+	enum dvbfe_fec			code_rate_HP;
+	enum dvbfe_fec			code_rate_LP;
+	enum dvbfe_transmission_mode	transmission_mode;
+	enum dvbfe_guard_interval	guard_interval;
+	enum dvbfe_hierarchy		hierarchy;
+	enum dvbfe_alpha		alpha;
+	enum dvbfe_interleaver		interleaver;
+	enum dvbfe_mpefec		mpefec;
+	enum dvbfe_timeslicing		timeslicing;
+	enum dvbfe_stream_priority	priority;
+
+	__u32				bandwidth;
+	__u8				pad[32];
+};
+
+/* ATSC parameters			*/
+struct atsc_params {
+	enum dvbfe_modulation		modulation;
+
+	__u8				pad[32];
+};
+
+/* DVB Frontend Tuning Parameters	*/
+struct dvbfe_params {
+	__u32				frequency;
+	enum fe_spectral_inversion	inversion;
+	enum dvbfe_delsys		delivery;
+
+	__u8				pad[32];
+
+	union {
+		struct dvbs_params	dvbs;
+		struct dss_params	dss;
+		struct dvbs2_params	dvbs2;
+		struct dvbc_params	dvbc;
+		struct dvbt_params	dvbt;
+		struct dvbh_params	dvbh;
+		struct atsc_params	atsc;
+
+		__u8			pad[128];
+	} delsys;
+};
+#define DVBFE_SET_PARAMS		_IOW('o', 83, struct dvbfe_params)
+#define DVBFE_GET_PARAMS		_IOWR('o', 84, struct dvbfe_params)
+
+/* DVB-S capability bitfields		*/
+struct dvbfe_dvbs_info {
+	enum dvbfe_modulation		UNSUPPORTED_modulation;
+	enum dvbfe_fec			UNSUPPORTED_fec;
+};
+
+/* DSS capability bitfields		*/
+struct dvbfe_dss_info {
+	enum dvbfe_modulation		modulation;
+	enum dvbfe_fec			fec;
+};
+
+/* DVB-S2 capability bitfields		*/
+struct dvbfe_dvbs2_info {
+	enum dvbfe_modulation		modulation;
+	enum dvbfe_fec			fec;
+
+	__u8				pad[32];
+};
+
+/* DVB-C capability bitfields		*/
+struct dvbfe_dvbc_info {
+	enum dvbfe_modulation		UNSUPPORTED_modulation;
+};
+
+/* DVB-T capability bitfields		*/
+struct dvbfe_dvbt_info {
+	enum dvbfe_modulation		UNSUPPORTED_modulation;
+	enum dvbfe_stream_priority	UNSUPPORTED_stream_priority;
+
+	__u8				pad[32];
+};
+
+/* DVB-H capability bitfields		*/
+struct dvbfe_dvbh_info {
+	enum dvbfe_modulation		modulation;
+	enum dvbfe_stream_priority	stream_priority;
+
+	__u8				pad[32];
+};
+
+/* ATSC capability bitfields		*/
+struct dvbfe_atsc_info {
+	enum dvbfe_modulation		modulation;
+
+	__u8				pad[32];
+};
+
+/* DVB Frontend related Information	*/
+struct dvbfe_info {
+	char				name[128];
+
+	/* For Multi Standard tuners, set "delivery"
+	 * to the relevant delivery system to retrieve the
+	 * relevant delivery system related information.
+	 */
+	enum dvbfe_delsys		delivery;
+
+	union {
+		struct dvbfe_dvbs_info	dvbs;
+		struct dvbfe_dss_info	dss;
+		struct dvbfe_dvbs2_info	dvbs2;
+		struct dvbfe_dvbc_info	dvbc;
+		struct dvbfe_dvbt_info	dvbt;
+		struct dvbfe_dvbh_info	dvbh;
+		struct dvbfe_atsc_info	atsc;
+
+		__u8			pad[128];
+	} delsys;
+
+	__u32				frequency_min;
+	__u32				frequency_max;
+	__u32				frequency_step;
+	__u32				frequency_tolerance;
+	__u32				symbol_rate_min;
+	__u32				symbol_rate_max;
+	__u32				symbol_rate_tolerance;
+
+	enum fe_spectral_inversion	UNSUPPORTED_inversion;
+
+	__u8				pad[128];
+};
+#define DVBFE_GET_INFO			_IOWR('o', 85, struct dvbfe_info)
+
+enum dvbfe_status {
+	DVBFE_HAS_SIGNAL		= (1 <<  0),	/*  something above noise floor	*/
+	DVBFE_HAS_CARRIER		= (1 <<  1),	/*  Signal found		*/
+	DVBFE_HAS_VITERBI		= (1 <<  2),	/*  FEC is stable		*/
+	DVBFE_HAS_SYNC			= (1 <<  3),	/*  SYNC found			*/
+	DVBFE_HAS_LOCK			= (1 <<  4),	/*  OK ..			*/
+	DVBFE_TIMEDOUT			= (1 <<  5),	/*  no lock in last ~2 s	*/
+	DVBFE_STATUS_DUMMY		= (1 << 31)
+};
+
+/* DVB Frontend events			*/
+struct dvbfe_events {
+	enum dvbfe_status		status;
+
+	__u8				pad[32];
+};
+
+struct dvbfe_event {
+	struct dvbfe_events fe_events;
+	struct dvbfe_params fe_params;
+};
+#define DVBFE_GET_EVENT			_IOR('o', 86, struct dvbfe_event)
+
+
+// End of copied section of frontend.h
+
+#endif // DVB_API_VERSION_MINOR < 3
+
+
+
+#ifdef DVB_MULTIPROTO_WRAPPER
+
+// Wrapper for multiproto ioctl calls:
+int DVBFE_ioctl(int d, int request, void *data);
+
+#else // ifdef DVB_MULTIPROTO_WRAPPER
+
+// Null wrapper for multiproto ioctl calls:
+int DVBFE_ioctl(int d, int request, void *data) { return ioctl(d, request, data); }
+
+#endif // ifdef DVB_MULTIPROTO_WRAPPER
+
+#endif // ifndef __DVB_API_EMULATE_H
diff -Nu vdr-1.5.14/dvbdevice.c vdr-1.5.14-wrapper/dvbdevice.c
--- vdr-1.5.14/dvbdevice.c	2008-02-03 00:08:05.000000000 +0100
+++ vdr-1.5.14-wrapper/dvbdevice.c	2008-02-03 00:08:05.000000000 +0100
@@ -269,7 +269,7 @@ 
 
      dvbfe_info feinfo;
      feinfo.delivery = Frontend.delivery;
-     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+     CHECK(DVBFE_ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
      }
   else if (frontendType & DVBFE_DELSYS_DVBC) {
      Frontend.delivery = DVBFE_DELSYS_DVBC;
@@ -284,7 +284,7 @@ 
 
      dvbfe_info feinfo;
      feinfo.delivery = Frontend.delivery;
-     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+     CHECK(DVBFE_ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
      }
   else if (frontendType & DVBFE_DELSYS_DVBT) {
      Frontend.delivery = DVBFE_DELSYS_DVBT;
@@ -305,13 +305,13 @@ 
 
      dvbfe_info feinfo;
      feinfo.delivery = Frontend.delivery;
-     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+     CHECK(DVBFE_ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
      }
   else {
      esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
      return false;
     }
-  if (ioctl(fd_frontend, DVBFE_SET_PARAMS, &Frontend) < 0) {
+  if (DVBFE_ioctl(fd_frontend, DVBFE_SET_PARAMS, &Frontend) < 0) {
      esyslog("ERROR: frontend %d: %m", cardIndex);
      return false;
      }
@@ -460,7 +460,7 @@ 
   // We only check the devices that must be present - the others will be checked before accessing them://XXX
 
   if (fd_frontend >= 0) {
-     if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0) {
+     if (DVBFE_ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0) {
         const char **DeliverySystem = DeliverySystems;
         cString ds;
         for (int i = 0; i < 32; i++) {
diff -Nu vdr-1.5.14/dvbdevice.h vdr-1.5.14-wrapper/dvbdevice.h
--- vdr-1.5.14/dvbdevice.h	2008-01-27 11:21:02.000000000 +0100
+++ vdr-1.5.14-wrapper/dvbdevice.h	2008-02-02 23:37:53.000000000 +0100
@@ -14,9 +14,10 @@ 
 #include <linux/dvb/version.h>
 #include "device.h"
 #include "dvbspu.h"
+#include "dvb_api_wrapper.h"
 
-#if DVB_API_VERSION != 3 || DVB_API_VERSION_MINOR != 3
-#error VDR requires Linux DVB driver API version 3.3!
+#if DVB_API_VERSION != 3
+#error VDR requires Linux DVB driver API version 3!
 #endif
 
 #define MAXDVBDEVICES  8
diff -Nu vdr-1.5.14/Makefile vdr-1.5.14-wrapper/Makefile
--- vdr-1.5.14/Makefile	2008-01-13 13:53:17.000000000 +0100
+++ vdr-1.5.14-wrapper/Makefile	2008-01-28 20:46:07.000000000 +0100
@@ -36,7 +36,7 @@ 
 
 SILIB    = $(LSIDIR)/libsi.a
 
-OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o dvbosd.o\
+OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvb_api_wrapper.o dvbdevice.o dvbci.o dvbosd.o\
        dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
        lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\
        receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\
diff -Nu vdr-1.5.14/nit.c vdr-1.5.14-wrapper/nit.c
--- vdr-1.5.14/nit.c	2008-01-26 16:08:01.000000000 +0100
+++ vdr-1.5.14-wrapper/nit.c	2008-02-02 23:38:08.000000000 +0100
@@ -10,6 +10,7 @@ 
 #include "nit.h"
 #include <linux/dvb/frontend.h>
 #include "channels.h"
+#include "dvb_api_wrapper.h"
 #include "eitscan.h"
 #include "libsi/section.h"
 #include "libsi/descriptor.h"