00001
00002
00003
00004
00005
00006
00007 #ifndef _DISEQC_H_
00008 #define _DISEQC_H_
00009
00010
00011 #include <inttypes.h>
00012
00013
00014 #include <vector>
00015 using namespace std;
00016
00017
00018 #include <qmap.h>
00019 #include <qstring.h>
00020 #include <qmutex.h>
00021
00022 class DTVMultiplex;
00023
00024 class DiSEqCDevSettings;
00025 class DiSEqCDevTrees;
00026 class DiSEqCDevTree;
00027 class DiSEqCDevDevice;
00028 class DiSEqCDevRotor;
00029 class DiSEqCDevLNB;
00030
00031 typedef QMap<uint, double> uint_to_dbl_t;
00032 typedef QMap<double, uint> dbl_to_uint_t;
00033 typedef QMap<uint, DiSEqCDevTree*> cardid_to_diseqc_tree_t;
00034 typedef vector<DiSEqCDevDevice*> dvbdev_vec_t;
00035
00036 class DiSEqCDevSettings
00037 {
00038 public:
00039 DiSEqCDevSettings();
00040
00041 bool Load( uint card_input_id);
00042 bool Store(uint card_input_id) const;
00043 double GetValue(uint devid) const;
00044 void SetValue(uint devid, double value);
00045
00046 protected:
00047 uint_to_dbl_t m_config;
00048 uint m_input_id;
00049 };
00050
00051 class DiSEqCDev
00052 {
00053 public:
00054 DiSEqCDevTree* FindTree(uint cardid);
00055 void InvalidateTrees(void);
00056
00057 protected:
00058 static DiSEqCDevTrees m_trees;
00059 };
00060
00061 class DiSEqCDevTrees
00062 {
00063 public:
00064 ~DiSEqCDevTrees();
00065
00066 DiSEqCDevTree *FindTree(uint cardid);
00067 void InvalidateTrees(void);
00068
00069 protected:
00070 cardid_to_diseqc_tree_t m_trees;
00071 QMutex m_trees_lock;
00072 };
00073
00074 class DiSEqCDevTree
00075 {
00076 public:
00077 DiSEqCDevTree();
00078 ~DiSEqCDevTree();
00079
00080 bool Load(uint cardid);
00081 bool Store(uint cardid);
00082 bool Execute(const DiSEqCDevSettings &settings,
00083 const DTVMultiplex &tuning);
00084 void Reset(void);
00085
00086 DiSEqCDevRotor *FindRotor(const DiSEqCDevSettings &settings, uint index = 0);
00087 DiSEqCDevLNB *FindLNB(const DiSEqCDevSettings &settings);
00088 DiSEqCDevDevice *FindDevice(uint dev_id);
00089
00091 DiSEqCDevDevice *Root(void) { return m_root; }
00092 void SetRoot(DiSEqCDevDevice *root);
00093
00094 bool SendCommand(uint adr, uint cmd, uint repeats = 0,
00095 uint data_len = 0, unsigned char *data = NULL);
00096
00097 bool ResetDiseqc(bool hard_reset);
00098
00099
00100 void Open(int fd_frontend);
00101 void Close(void) { m_fd_frontend = -1; }
00102 int GetFD(void) const { return m_fd_frontend; }
00103
00104
00105 bool SetTone(bool on);
00106 bool SetVoltage(uint voltage);
00107
00108
00109 uint GetVoltage(void) const { return m_last_voltage; }
00110 bool IsInNeedOfConf(void) const;
00111
00112
00113 void AddDeferredDelete(uint dev_id) { m_delete.push_back(dev_id); }
00114 uint CreateFakeDiSEqCID(void) { return m_previous_fake_diseqcid++; }
00115
00116 static bool IsFakeDiSEqCID(uint id) { return id >= kFirstFakeDiSEqCID; }
00117
00118 protected:
00119 bool ApplyVoltage(const DiSEqCDevSettings &settings,
00120 const DTVMultiplex &tuning);
00121
00122 int m_fd_frontend;
00123 DiSEqCDevDevice *m_root;
00124 uint m_last_voltage;
00125 uint m_previous_fake_diseqcid;
00126 vector<uint> m_delete;
00127
00128 static const uint kFirstFakeDiSEqCID;
00129 };
00130
00131 class DiSEqCDevDevice
00132 {
00133 public:
00134 DiSEqCDevDevice(DiSEqCDevTree &tree, uint devid);
00135 virtual ~DiSEqCDevDevice();
00136
00137
00138 virtual void Reset(void) {}
00139 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&) = 0;
00140 virtual bool Load(void) = 0;
00141 virtual bool Store(void) const = 0;
00142
00143
00144 enum dvbdev_t { kTypeSwitch = 0, kTypeRotor = 1, kTypeLNB = 2, };
00145 void SetDeviceType(dvbdev_t type) { m_dev_type = type; }
00146 void SetParent(DiSEqCDevDevice* parent) { m_parent = parent; }
00147 void SetOrdinal(uint ordinal) { m_ordinal = ordinal; }
00148 void SetDescription(const QString &desc) { m_desc = desc; }
00149 void SetRepeatCount(uint repeat) { m_repeat = repeat; }
00150 virtual bool SetChild(uint, DiSEqCDevDevice*){return false; }
00151
00152
00153 dvbdev_t GetDeviceType(void) const { return m_dev_type; }
00154 uint GetDeviceID(void) const { return m_devid; }
00155 bool IsRealDeviceID(void) const
00156 { return !DiSEqCDevTree::IsFakeDiSEqCID(m_devid); }
00157 DiSEqCDevDevice *GetParent(void) const { return m_parent; }
00158 uint GetOrdinal(void) const { return m_ordinal; }
00159 QString GetDescription(void) const { return m_desc; }
00160 uint GetRepeatCount(void) const { return m_repeat; }
00161 virtual uint GetChildCount(void) const { return 0; }
00162 virtual bool IsCommandNeeded(
00163 const DiSEqCDevSettings&, const DTVMultiplex&)
00164 const { return false; }
00165 virtual uint GetVoltage(
00166 const DiSEqCDevSettings&, const DTVMultiplex&) const = 0;
00167
00168
00169 DiSEqCDevDevice *FindDevice(uint dev_id);
00170 virtual DiSEqCDevDevice *GetSelectedChild(
00171 const DiSEqCDevSettings&) const { return NULL; }
00172 virtual DiSEqCDevDevice *GetChild(uint) { return NULL; }
00173
00174
00175 static QString DevTypeToString(dvbdev_t type)
00176 { return TableToString((uint)type, dvbdev_lookup); }
00177 static dvbdev_t DevTypeFromString(const QString &type)
00178 { return (dvbdev_t) TableFromString(type, dvbdev_lookup); }
00179
00180 static DiSEqCDevDevice *CreateById( DiSEqCDevTree &tree,
00181 uint devid);
00182 static DiSEqCDevDevice *CreateByType(DiSEqCDevTree &tree,
00183 dvbdev_t type,
00184 uint devid = 0);
00185
00186 protected:
00187 void SetDeviceID(uint devid) const { m_devid = devid; }
00188
00189 mutable uint m_devid;
00190 dvbdev_t m_dev_type;
00191 QString m_desc;
00192 DiSEqCDevTree &m_tree;
00193 DiSEqCDevDevice *m_parent;
00194 uint m_ordinal;
00195 uint m_repeat;
00196
00197 typedef struct { QString name; uint value; } TypeTable;
00198 static QString TableToString(uint type, const TypeTable *table);
00199 static uint TableFromString(const QString &type,
00200 const TypeTable *table);
00201
00202 private:
00203 static const TypeTable dvbdev_lookup[4];
00204 };
00205
00206 class DiSEqCDevSwitch : public DiSEqCDevDevice
00207 {
00208 public:
00209 DiSEqCDevSwitch(DiSEqCDevTree &tree, uint devid);
00210 ~DiSEqCDevSwitch();
00211
00212
00213 virtual void Reset(void);
00214 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&);
00215 virtual bool Load(void);
00216 virtual bool Store(void) const;
00217
00218
00219 enum dvbdev_switch_t
00220 {
00221 kTypeTone = 0,
00222 kTypeDiSEqCCommitted = 1,
00223 kTypeDiSEqCUncommitted = 2,
00224 kTypeLegacySW21 = 3,
00225 kTypeLegacySW42 = 4,
00226 kTypeLegacySW64 = 5,
00227 kTypeVoltage = 6,
00228 kTypeMiniDiSEqC = 7,
00229 };
00230 void SetType(dvbdev_switch_t type) { m_type = type; }
00231 void SetNumPorts(uint num_ports);
00232 virtual bool SetChild(uint, DiSEqCDevDevice*);
00233
00234
00235 dvbdev_switch_t GetType(void) const { return m_type; }
00236 uint GetNumPorts(void) const { return m_num_ports; }
00237 bool ShouldSwitch(const DiSEqCDevSettings &settings,
00238 const DTVMultiplex &tuning) const;
00239 virtual uint GetChildCount(void) const;
00240 virtual bool IsCommandNeeded(const DiSEqCDevSettings&,
00241 const DTVMultiplex&) const;
00242 virtual uint GetVoltage(const DiSEqCDevSettings&,
00243 const DTVMultiplex&) const;
00244
00245
00246 virtual DiSEqCDevDevice *GetSelectedChild(const DiSEqCDevSettings&) const;
00247 virtual DiSEqCDevDevice *GetChild(uint);
00248
00249
00250 static QString SwitchTypeToString(dvbdev_switch_t type)
00251 { return TableToString((uint)type, SwitchTypeTable); }
00252 static dvbdev_switch_t SwitchTypeFromString(const QString &type)
00253 { return (dvbdev_switch_t) TableFromString(type, SwitchTypeTable); }
00254
00255
00256 protected:
00257 bool ExecuteLegacy(
00258 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00259 bool ExecuteTone(
00260 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00261 bool ExecuteVoltage(
00262 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00263 bool ExecuteMiniDiSEqC(
00264 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00265 bool ExecuteDiseqc(
00266 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00267
00268 int GetPosition( const DiSEqCDevSettings&) const;
00269
00270 private:
00271 dvbdev_switch_t m_type;
00272 uint m_num_ports;
00273 uint m_last_pos;
00274 uint m_last_high_band;
00275 uint m_last_horizontal;
00276 dvbdev_vec_t m_children;
00277
00278 static const TypeTable SwitchTypeTable[9];
00279 };
00280
00281 class DiSEqCDevRotor : public DiSEqCDevDevice
00282 {
00283 public:
00284 DiSEqCDevRotor(DiSEqCDevTree &tree, uint devid);
00285 ~DiSEqCDevRotor();
00286
00287
00288 virtual void Reset(void);
00289 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&);
00290 virtual bool Load(void);
00291 virtual bool Store(void) const;
00292
00293
00294 enum dvbdev_rotor_t { kTypeDiSEqC_1_2 = 0, kTypeDiSEqC_1_3 = 1, };
00295 void SetType(dvbdev_rotor_t type) { m_type = type; }
00296 void SetLoSpeed(double speed) { m_speed_lo = speed; }
00297 void SetHiSpeed(double speed) { m_speed_hi = speed; }
00298 void SetPosMap(const uint_to_dbl_t &posmap);
00299 virtual bool SetChild(uint ordinal, DiSEqCDevDevice* device);
00300 void RotationComplete(void) const;
00301
00302
00303 dvbdev_rotor_t GetType(void) const { return m_type; }
00304 double GetLoSpeed(void) const { return m_speed_lo; }
00305 double GetHiSpeed(void) const { return m_speed_hi; }
00306 uint_to_dbl_t GetPosMap(void) const;
00307 double GetProgress(void) const;
00308 bool IsPositionKnown(void) const;
00309 virtual uint GetChildCount(void) const { return 1; }
00310 virtual bool IsCommandNeeded(const DiSEqCDevSettings&,
00311 const DTVMultiplex&) const;
00312 bool IsMoving(const DiSEqCDevSettings&) const;
00313 virtual uint GetVoltage(const DiSEqCDevSettings&,
00314 const DTVMultiplex&) const;
00315
00316
00317 virtual DiSEqCDevDevice *GetSelectedChild(const DiSEqCDevSettings&) const;
00318 virtual DiSEqCDevDevice *GetChild(uint) { return m_child; }
00319
00320
00321 static QString RotorTypeToString(dvbdev_rotor_t type)
00322 { return TableToString((uint)type, RotorTypeTable); }
00323 static dvbdev_rotor_t RotorTypeFromString(const QString &type)
00324 { return (dvbdev_rotor_t) TableFromString(type, RotorTypeTable); }
00325
00326 protected:
00327 bool ExecuteRotor(const DiSEqCDevSettings&, const DTVMultiplex&,
00328 double angle);
00329 bool ExecuteUSALS(const DiSEqCDevSettings&, const DTVMultiplex&,
00330 double angle);
00331 void StartRotorPositionTracking(double azimuth);
00332
00333 double CalculateAzimuth(double angle) const;
00334 double GetApproxAzimuth(void) const;
00335
00336 private:
00337
00338 dvbdev_rotor_t m_type;
00339 double m_speed_hi;
00340 double m_speed_lo;
00341 dbl_to_uint_t m_posmap;
00342 DiSEqCDevDevice *m_child;
00343
00344
00345 double m_last_position;
00346 double m_desired_azimuth;
00347 bool m_reset;
00348
00349
00350 mutable double m_move_time;
00351 mutable bool m_last_pos_known;
00352 mutable double m_last_azimuth;
00353
00354
00355 static const TypeTable RotorTypeTable[3];
00356 };
00357
00358 class DiSEqCDevLNB : public DiSEqCDevDevice
00359 {
00360 public:
00361 DiSEqCDevLNB(DiSEqCDevTree &tree, uint devid);
00362
00363
00364 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&);
00365 virtual bool Load(void);
00366 virtual bool Store(void) const;
00367
00368
00369 enum dvbdev_lnb_t
00370 {
00371 kTypeFixed = 0,
00372 kTypeVoltageControl = 1,
00373 kTypeVoltageAndToneControl = 2,
00374 kTypeBandstacked = 3,
00375 };
00376 void SetType(dvbdev_lnb_t type) { m_type = type; }
00377 void SetLOFSwitch(uint lof_switch) { m_lof_switch = lof_switch; }
00378 void SetLOFHigh( uint lof_hi) { m_lof_hi = lof_hi; }
00379 void SetLOFLow( uint lof_lo) { m_lof_lo = lof_lo; }
00380 void SetPolarityInverted(bool inv) { m_pol_inv = inv; }
00381
00382
00383 dvbdev_lnb_t GetType(void) const { return m_type; }
00384 uint GetLOFSwitch(void) const { return m_lof_switch; }
00385 uint GetLOFHigh(void) const { return m_lof_hi; }
00386 uint GetLOFLow(void) const { return m_lof_lo; }
00387 bool IsPolarityInverted(void) const { return m_pol_inv; }
00388 bool IsHighBand(const DTVMultiplex&) const;
00389 bool IsHorizontal(const DTVMultiplex&) const;
00390 uint32_t GetIntermediateFrequency(const DiSEqCDevSettings&,
00391 const DTVMultiplex&) const;
00392 virtual uint GetVoltage(const DiSEqCDevSettings&,
00393 const DTVMultiplex&) const;
00394
00395
00396 static QString LNBTypeToString(dvbdev_lnb_t type)
00397 { return TableToString((uint)type, LNBTypeTable); }
00398
00399 static dvbdev_lnb_t LNBTypeFromString(const QString &type)
00400 { return (dvbdev_lnb_t) TableFromString(type, LNBTypeTable); }
00401
00402 private:
00403 dvbdev_lnb_t m_type;
00404 uint m_lof_switch;
00405 uint m_lof_hi;
00406 uint m_lof_lo;
00410 bool m_pol_inv;
00411
00412 static const TypeTable LNBTypeTable[5];
00413 };
00414
00415 #endif // _DISEQC_H_