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 <QString>
00019 #include <QMutex>
00020 #include <QMap>
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 static bool Exists(int id);
00118
00119 protected:
00120 bool ApplyVoltage(const DiSEqCDevSettings &settings,
00121 const DTVMultiplex &tuning);
00122
00123 int m_fd_frontend;
00124 DiSEqCDevDevice *m_root;
00125 uint m_last_voltage;
00126 uint m_previous_fake_diseqcid;
00127 vector<uint> m_delete;
00128
00129 static const uint kFirstFakeDiSEqCID;
00130 };
00131
00132 class DiSEqCDevDevice
00133 {
00134 public:
00135 DiSEqCDevDevice(DiSEqCDevTree &tree, uint devid);
00136 virtual ~DiSEqCDevDevice();
00137
00138
00139 virtual void Reset(void) {}
00140 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&) = 0;
00141 virtual bool Load(void) = 0;
00142 virtual bool Store(void) const = 0;
00143
00144
00145 enum dvbdev_t { kTypeSwitch = 0, kTypeRotor = 1, kTypeLNB = 2, };
00146 void SetDeviceType(dvbdev_t type) { m_dev_type = type; }
00147 void SetParent(DiSEqCDevDevice* parent) { m_parent = parent; }
00148 void SetOrdinal(uint ordinal) { m_ordinal = ordinal; }
00149 void SetDescription(const QString &desc) { m_desc = desc; }
00150 void SetRepeatCount(uint repeat) { m_repeat = repeat; }
00151 virtual bool SetChild(uint, DiSEqCDevDevice*){return false; }
00152
00153
00154 dvbdev_t GetDeviceType(void) const { return m_dev_type; }
00155 uint GetDeviceID(void) const { return m_devid; }
00156 bool IsRealDeviceID(void) const
00157 { return !DiSEqCDevTree::IsFakeDiSEqCID(m_devid); }
00158 DiSEqCDevDevice *GetParent(void) const { return m_parent; }
00159 uint GetOrdinal(void) const { return m_ordinal; }
00160 QString GetDescription(void) const { return m_desc; }
00161 uint GetRepeatCount(void) const { return m_repeat; }
00162 virtual uint GetChildCount(void) const { return 0; }
00163 virtual bool IsCommandNeeded(
00164 const DiSEqCDevSettings&, const DTVMultiplex&)
00165 const { return false; }
00166 virtual uint GetVoltage(
00167 const DiSEqCDevSettings&, const DTVMultiplex&) const = 0;
00168
00169
00170 DiSEqCDevDevice *FindDevice(uint dev_id);
00171 virtual DiSEqCDevDevice *GetSelectedChild(
00172 const DiSEqCDevSettings&) const { return NULL; }
00173 virtual DiSEqCDevDevice *GetChild(uint) { return NULL; }
00174
00175
00176 static QString DevTypeToString(dvbdev_t type)
00177 { return TableToString((uint)type, dvbdev_lookup); }
00178 static dvbdev_t DevTypeFromString(const QString &type)
00179 { return (dvbdev_t) TableFromString(type, dvbdev_lookup); }
00180
00181 static DiSEqCDevDevice *CreateById( DiSEqCDevTree &tree,
00182 uint devid);
00183 static DiSEqCDevDevice *CreateByType(DiSEqCDevTree &tree,
00184 dvbdev_t type,
00185 uint devid = 0);
00186
00187 protected:
00188 void SetDeviceID(uint devid) const { m_devid = devid; }
00189
00190 mutable uint m_devid;
00191 dvbdev_t m_dev_type;
00192 QString m_desc;
00193 DiSEqCDevTree &m_tree;
00194 DiSEqCDevDevice *m_parent;
00195 uint m_ordinal;
00196 uint m_repeat;
00197
00198 typedef struct { QString name; uint value; } TypeTable;
00199 static QString TableToString(uint type, const TypeTable *table);
00200 static uint TableFromString(const QString &type,
00201 const TypeTable *table);
00202
00203 private:
00204 static const TypeTable dvbdev_lookup[4];
00205 };
00206
00207 class DiSEqCDevSwitch : public DiSEqCDevDevice
00208 {
00209 public:
00210 DiSEqCDevSwitch(DiSEqCDevTree &tree, uint devid);
00211 ~DiSEqCDevSwitch();
00212
00213
00214 virtual void Reset(void);
00215 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&);
00216 virtual bool Load(void);
00217 virtual bool Store(void) const;
00218
00219
00220 enum dvbdev_switch_t
00221 {
00222 kTypeTone = 0,
00223 kTypeDiSEqCCommitted = 1,
00224 kTypeDiSEqCUncommitted = 2,
00225 kTypeLegacySW21 = 3,
00226 kTypeLegacySW42 = 4,
00227 kTypeLegacySW64 = 5,
00228 kTypeVoltage = 6,
00229 kTypeMiniDiSEqC = 7,
00230 };
00231 void SetType(dvbdev_switch_t type) { m_type = type; }
00232 void SetAddress(uint address) { m_address = address; }
00233 void SetNumPorts(uint num_ports);
00234 virtual bool SetChild(uint, DiSEqCDevDevice*);
00235
00236
00237 dvbdev_switch_t GetType(void) const { return m_type; }
00238 uint GetAddress(void) const { return m_address; }
00239 uint GetNumPorts(void) const { return m_num_ports; }
00240 bool ShouldSwitch(const DiSEqCDevSettings &settings,
00241 const DTVMultiplex &tuning) const;
00242 virtual uint GetChildCount(void) const;
00243 virtual bool IsCommandNeeded(const DiSEqCDevSettings&,
00244 const DTVMultiplex&) const;
00245 virtual uint GetVoltage(const DiSEqCDevSettings&,
00246 const DTVMultiplex&) const;
00247
00248
00249 virtual DiSEqCDevDevice *GetSelectedChild(const DiSEqCDevSettings&) const;
00250 virtual DiSEqCDevDevice *GetChild(uint);
00251
00252
00253 static QString SwitchTypeToString(dvbdev_switch_t type)
00254 { return TableToString((uint)type, SwitchTypeTable); }
00255 static dvbdev_switch_t SwitchTypeFromString(const QString &type)
00256 { return (dvbdev_switch_t) TableFromString(type, SwitchTypeTable); }
00257
00258
00259 protected:
00260 bool ExecuteLegacy(
00261 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00262 bool ExecuteTone(
00263 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00264 bool ExecuteVoltage(
00265 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00266 bool ExecuteMiniDiSEqC(
00267 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00268 bool ExecuteDiseqc(
00269 const DiSEqCDevSettings&, const DTVMultiplex&, uint pos);
00270
00271 int GetPosition( const DiSEqCDevSettings&) const;
00272
00273 private:
00274 dvbdev_switch_t m_type;
00275 uint m_address;
00276 uint m_num_ports;
00277 uint m_last_pos;
00278 uint m_last_high_band;
00279 uint m_last_horizontal;
00280 dvbdev_vec_t m_children;
00281
00282 static const TypeTable SwitchTypeTable[9];
00283 };
00284
00285 class DiSEqCDevRotor : public DiSEqCDevDevice
00286 {
00287 public:
00288 DiSEqCDevRotor(DiSEqCDevTree &tree, uint devid);
00289 ~DiSEqCDevRotor();
00290
00291
00292 virtual void Reset(void);
00293 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&);
00294 virtual bool Load(void);
00295 virtual bool Store(void) const;
00296
00297
00298 enum dvbdev_rotor_t { kTypeDiSEqC_1_2 = 0, kTypeDiSEqC_1_3 = 1, };
00299 void SetType(dvbdev_rotor_t type) { m_type = type; }
00300 void SetLoSpeed(double speed) { m_speed_lo = speed; }
00301 void SetHiSpeed(double speed) { m_speed_hi = speed; }
00302 void SetPosMap(const uint_to_dbl_t &posmap);
00303 virtual bool SetChild(uint ordinal, DiSEqCDevDevice* device);
00304 void RotationComplete(void) const;
00305
00306
00307 dvbdev_rotor_t GetType(void) const { return m_type; }
00308 double GetLoSpeed(void) const { return m_speed_lo; }
00309 double GetHiSpeed(void) const { return m_speed_hi; }
00310 uint_to_dbl_t GetPosMap(void) const;
00311 double GetProgress(void) const;
00312 bool IsPositionKnown(void) const;
00313 virtual uint GetChildCount(void) const { return 1; }
00314 virtual bool IsCommandNeeded(const DiSEqCDevSettings&,
00315 const DTVMultiplex&) const;
00316 bool IsMoving(const DiSEqCDevSettings&) const;
00317 virtual uint GetVoltage(const DiSEqCDevSettings&,
00318 const DTVMultiplex&) const;
00319
00320
00321 virtual DiSEqCDevDevice *GetSelectedChild(const DiSEqCDevSettings&) const;
00322 virtual DiSEqCDevDevice *GetChild(uint) { return m_child; }
00323
00324
00325 static QString RotorTypeToString(dvbdev_rotor_t type)
00326 { return TableToString((uint)type, RotorTypeTable); }
00327 static dvbdev_rotor_t RotorTypeFromString(const QString &type)
00328 { return (dvbdev_rotor_t) TableFromString(type, RotorTypeTable); }
00329
00330 protected:
00331 bool ExecuteRotor(const DiSEqCDevSettings&, const DTVMultiplex&,
00332 double angle);
00333 bool ExecuteUSALS(const DiSEqCDevSettings&, const DTVMultiplex&,
00334 double angle);
00335 void StartRotorPositionTracking(double azimuth);
00336
00337 double CalculateAzimuth(double angle) const;
00338 double GetApproxAzimuth(void) const;
00339
00340 private:
00341
00342 dvbdev_rotor_t m_type;
00343 double m_speed_hi;
00344 double m_speed_lo;
00345 dbl_to_uint_t m_posmap;
00346 DiSEqCDevDevice *m_child;
00347
00348
00349 double m_last_position;
00350 double m_desired_azimuth;
00351 bool m_reset;
00352
00353
00354 mutable double m_move_time;
00355 mutable bool m_last_pos_known;
00356 mutable double m_last_azimuth;
00357
00358
00359 static const TypeTable RotorTypeTable[3];
00360 };
00361
00362 class DiSEqCDevLNB : public DiSEqCDevDevice
00363 {
00364 public:
00365 DiSEqCDevLNB(DiSEqCDevTree &tree, uint devid);
00366
00367
00368 virtual bool Execute(const DiSEqCDevSettings&, const DTVMultiplex&);
00369 virtual bool Load(void);
00370 virtual bool Store(void) const;
00371
00372
00373 enum dvbdev_lnb_t
00374 {
00375 kTypeFixed = 0,
00376 kTypeVoltageControl = 1,
00377 kTypeVoltageAndToneControl = 2,
00378 kTypeBandstacked = 3,
00379 };
00380 void SetType(dvbdev_lnb_t type) { m_type = type; }
00381 void SetLOFSwitch(uint lof_switch) { m_lof_switch = lof_switch; }
00382 void SetLOFHigh( uint lof_hi) { m_lof_hi = lof_hi; }
00383 void SetLOFLow( uint lof_lo) { m_lof_lo = lof_lo; }
00384 void SetPolarityInverted(bool inv) { m_pol_inv = inv; }
00385
00386
00387 dvbdev_lnb_t GetType(void) const { return m_type; }
00388 uint GetLOFSwitch(void) const { return m_lof_switch; }
00389 uint GetLOFHigh(void) const { return m_lof_hi; }
00390 uint GetLOFLow(void) const { return m_lof_lo; }
00391 bool IsPolarityInverted(void) const { return m_pol_inv; }
00392 bool IsHighBand(const DTVMultiplex&) const;
00393 bool IsHorizontal(const DTVMultiplex&) const;
00394 uint32_t GetIntermediateFrequency(const DiSEqCDevSettings&,
00395 const DTVMultiplex&) const;
00396 virtual uint GetVoltage(const DiSEqCDevSettings&,
00397 const DTVMultiplex&) const;
00398
00399
00400 static QString LNBTypeToString(dvbdev_lnb_t type)
00401 { return TableToString((uint)type, LNBTypeTable); }
00402
00403 static dvbdev_lnb_t LNBTypeFromString(const QString &type)
00404 { return (dvbdev_lnb_t) TableFromString(type, LNBTypeTable); }
00405
00406 private:
00407 dvbdev_lnb_t m_type;
00408 uint m_lof_switch;
00409 uint m_lof_hi;
00410 uint m_lof_lo;
00414 bool m_pol_inv;
00415
00416 static const TypeTable LNBTypeTable[5];
00417 };
00418
00419 #endif // _DISEQC_H_