MythTV  master
diseqc.cpp
Go to the documentation of this file.
1 /* -*- Mode: c++ -*-
2  * \file dvbdevtree.cpp
3  * \brief DVB-S Device Tree Control Classes.
4  * \author Copyright (C) 2006, Yeasah Pell
5  */
6 
7 // Std C headers
8 #include <cstring>
9 #include <cmath>
10 #include <unistd.h>
11 
12 // POSIX headers
13 #include <sys/time.h>
14 
15 // Qt headers
16 #include <QString>
17 
18 // MythTV headers
19 #include "mythcorecontext.h"
20 #include "mythdb.h"
21 #include "mythlogging.h"
22 #include "diseqc.h"
23 #include "dtvmultiplex.h"
24 #include "compat.h"
25 
26 #ifdef USING_DVB
27 # include "dvbtypes.h"
28 #else
29 # define SEC_VOLTAGE_13 0
30 # define SEC_VOLTAGE_18 1
31 # define SEC_VOLTAGE_OFF 2
32 # define SEC_MINI_A 0
33 # define SEC_MINI_B 1
34 #endif
35 
36 // DiSEqC sleep intervals per eutelsat spec
37 #define DISEQC_SHORT_WAIT (15 * 1000)
38 #define DISEQC_LONG_WAIT (100 * 1000)
39 #define DISEQC_POWER_OFF_WAIT ((1000 * 1000) - 1)
40 #define DISEQC_POWER_ON_WAIT (500 * 1000)
41 
42 // Number of times to retry ioctls after receiving ETIMEDOUT before giving up
43 #define TIMEOUT_RETRIES 10
44 #define TIMEOUT_WAIT (250 * 1000)
45 
46 // Framing byte
47 #define DISEQC_FRM 0xe0
48 #define DISEQC_FRM_REPEAT (1 << 0)
49 #define DISEQC_FRM_REPLY_REQ (1 << 1)
50 
51 // Address byte
52 #define DISEQC_ADR_ALL 0x00
53 #define DISEQC_ADR_SW_ALL 0x10
54 #define DISEQC_ADR_LNB 0x11
55 #define DISEQC_ADR_LNB_SW 0x12
56 #define DISEQC_ADR_SW_BLK 0x14
57 #define DISEQC_ADR_SW 0x15
58 #define DISEQC_ADR_SMATV 0x18
59 #define DISEQC_ADR_POL_ALL 0x20
60 #define DISEQC_ADR_POL_LIN 0x21
61 #define DISEQC_ADR_POS_ALL 0x30
62 #define DISEQC_ADR_POS_AZ 0x31
63 #define DISEQC_ADR_POS_EL 0x32
64 
65 // Command byte
66 #define DISEQC_CMD_RESET 0x00
67 #define DISEQC_CMD_CLR_RESET 0x01
68 #define DISEQC_CMD_WRITE_N0 0x38
69 #define DISEQC_CMD_WRITE_N1 0x39
70 #define DISEQC_CMD_WRITE_FREQ 0x58
71 #define DISEQC_CMD_ODU 0x5A
72 #define DISEQC_CMD_ODU_MDU 0x5C
73 #define DISEQC_CMD_HALT 0x60
74 #define DISEQC_CMD_LMT_OFF 0x63
75 #define DISEQC_CMD_LMT_E 0x66
76 #define DISEQC_CMD_LMT_W 0x67
77 #define DISEQC_CMD_DRIVE_E 0x68
78 #define DISEQC_CMD_DRIVE_W 0x69
79 #define DISEQC_CMD_STORE_POS 0x6a
80 #define DISEQC_CMD_GOTO_POS 0x6b
81 #define DISEQC_CMD_GOTO_X 0x6e
82 
83 #define TO_RADS (M_PI / 180.0)
84 #define TO_DEC (180.0 / M_PI)
85 
86 #define EPS 1E-4
87 
88 #define LOC QString("DiSEqCDevTree: ")
89 
91 
93 {
94  for (const auto &item : table)
95  if (type == item.value)
96  return item.name;
97  return QString();
98 }
99 
101  const TypeTableVec &table)
102 {
103  for (const auto &item : table)
104  if (type == item.name)
105  return item.value;
106  return table[0].value;
107 }
108 
110 
123 bool DiSEqCDevSettings::Load(uint card_input_id)
124 {
125  if (card_input_id == m_inputId)
126  return true;
127 
128  m_config.clear();
129 
130  // load settings from DB
132  query.prepare(
133  "SELECT diseqcid, value "
134  "FROM diseqc_config "
135  "WHERE cardinputid = :INPUTID");
136 
137  query.bindValue(":INPUTID", card_input_id);
138  if (!query.exec() || !query.isActive())
139  {
140  MythDB::DBError("DiSEqCDevSettings::Load", query);
141  return false;
142  }
143 
144  while (query.next())
145  m_config[query.value(0).toUInt()] = query.value(1).toDouble();
146 
147  m_inputId = card_input_id;
148 
149  return true;
150 }
151 
157 bool DiSEqCDevSettings::Store(uint card_input_id) const
158 {
160 
161  // clear out previous settings
162  query.prepare(
163  "DELETE from diseqc_config "
164  "WHERE cardinputid = :INPUTID");
165  query.bindValue(":INPUTID", card_input_id);
166 
167  if (!query.exec() || !query.isActive())
168  {
169  MythDB::DBError("DiSEqCDevSettings::Store 1", query);
170  return false;
171  }
172 
173  // insert new settings
174  query.prepare(
175  "INSERT INTO diseqc_config "
176  " ( cardinputid, diseqcid, value) "
177  "VALUES (:INPUTID, :DEVID, :VALUE) ");
178 
179  for (auto it = m_config.cbegin(); it != m_config.cend(); ++it)
180  {
181  query.bindValue(":INPUTID", card_input_id);
182  query.bindValue(":DEVID", it.key());
183  query.bindValue(":VALUE", *it);
184  if (!query.exec() || !query.isActive())
185  {
186  MythDB::DBError("DiSEqCDevSettings::Store 2", query);
187  return false;
188  }
189  }
190 
191  return true;
192 }
193 
200 {
201  uint_to_dbl_t::const_iterator it = m_config.find(devid);
202 
203  if (it != m_config.end())
204  return *it;
205 
206  return 0.0;
207 }
208 
214 void DiSEqCDevSettings::SetValue(uint devid, double value)
215 {
216  m_config[devid] = value;
217  m_inputId = UINT_MAX;
218 }
219 
221 
227 
233 {
234  return s_trees.FindTree(cardid);
235 }
236 
241 {
243 }
244 
246 
252 {
253  InvalidateTrees();
254 }
255 
261 {
262  QMutexLocker lock(&m_treesLock);
263 
264  cardid_to_diseqc_tree_t::iterator it = m_trees.find(cardid);
265  if (it != m_trees.end())
266  return *it;
267 
268  auto *tree = new DiSEqCDevTree;
269  tree->Load(cardid);
270  m_trees[cardid] = tree;
271 
272  return tree;
273 }
274 
279 {
280  QMutexLocker lock(&m_treesLock);
281 
282  for (auto & tree : m_trees)
283  delete tree;
284 
285  m_trees.clear();
286 }
287 
289 
294 const uint DiSEqCDevTree::kFirstFakeDiSEqCID = 0xf0000000;
295 
297 {
298  delete m_root;
299 }
300 
306 bool DiSEqCDevTree::Load(const QString &device)
307 {
308  // lookup configuration for this card
310  query.prepare(
311  "SELECT cardid "
312  "FROM capturecard "
313  "WHERE hostname = :HOSTNAME AND "
314  " videodevice = :VIDEODEVICE "
315  "LIMIT 1");
316  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
317  query.bindValue(":VIDEODEVICE", device);
318 
319  uint cardid = 0;
320 
321  if (!query.exec())
322  {
323  MythDB::DBError("DiSEqCDevTree::Load", query);
324  }
325  else if (query.next())
326  {
327  cardid = query.value(0).toUInt();
328  }
329 
330  return Load(cardid);
331 }
332 
339 {
340  // clear children
341 
342  // TODO find root cause so that "delete m_root" can be enabled again, see ticket #13465
343  // Not doing the "delete m_root" fixes a segfault but creates a memory leak
344 #if 0
345  delete m_root;
346 #endif
347  m_delete.clear();
348  m_root = nullptr;
349 
350  // lookup configuration for this card
352  query.prepare(
353  "SELECT diseqcid, cardtype, inputname "
354  "FROM capturecard "
355  "WHERE cardid = :CARDID");
356  query.bindValue(":CARDID", cardid);
357 
358  if (!query.exec())
359  {
360  MythDB::DBError("DiSEqCDevTree::Load", query);
361  }
362  else if (!query.next())
363  {
364  return m_root;
365  }
366 
367  if (query.value(0).toBool())
368  {
370  *this, query.value(0).toUInt());
371  }
372  else if ((query.value(1).toString().toUpper() == "DVB") &&
373  ((query.value(2).toString().toUpper() == "DVB-S" ) ||
374  (query.value(2).toString().toUpper() == "DVB-S2") ))
375  {
376  LOG(VB_GENERAL, LOG_WARNING, LOC +
377  QString("No device tree for cardid %1").arg(cardid));
378  }
379 
380  return m_root;
381 }
382 
388 bool DiSEqCDevTree::Exists(int cardid)
389 {
390  // lookup configuration for this card
392  query.prepare(
393  "SELECT diseqcid "
394  "FROM capturecard "
395  "WHERE cardid = :CARDID");
396  query.bindValue(":CARDID", cardid);
397 
398  if (!query.exec())
399  {
400  MythDB::DBError("DiSEqCDevTree::Load", query);
401  }
402  else if (query.next())
403  {
404  if (query.value(0).toUInt() > 0)
405  return true;
406  }
407 
408  return false;
409 }
410 
417 bool DiSEqCDevTree::Store(uint cardid, const QString &device)
418 {
419  MSqlQuery query0(MSqlQuery::InitCon());
420 
421  // apply pending node deletions
422  if (!m_delete.empty())
423  {
424  MSqlQuery query1(MSqlQuery::InitCon());
425 
426  query0.prepare(
427  "DELETE FROM diseqc_tree "
428  "WHERE diseqcid = :DEVID");
429  query1.prepare(
430  "DELETE FROM diseqc_config "
431  "WHERE diseqcid = :DEVID");
432 
433  for (uint devid : m_delete)
434  {
435  query0.bindValue(":DEVID", devid);
436  if (!query0.exec())
437  MythDB::DBError("DiSEqCDevTree::Store 1", query0);
438 
439  query1.bindValue(":DEVID", devid);
440  if (!query1.exec())
441  MythDB::DBError("DiSEqCDevTree::Store 2", query1);
442 
443  }
444  m_delete.clear();
445  }
446 
447  // store changed and new nodes
448  uint devid = 0;
449  if (m_root && m_root->Store())
450  devid = m_root->GetDeviceID();
451  else if (m_root)
452  {
453  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to save DiSEqC tree.");
454  return false;
455  }
456 
457  // update capture card to point to tree, or 0 if there is no tree
458  query0.prepare(
459  "UPDATE capturecard "
460  "SET diseqcid = :DEVID "
461  "WHERE (hostname = :HOSTNAME AND "
462  " videodevice = :VIDEODEVICE) "
463  " OR cardid = :CARDID");
464  query0.bindValue(":DEVID", devid);
465  query0.bindValue(":HOSTNAME", gCoreContext->GetHostName());
466  query0.bindValue(":VIDEODEVICE", device);
467  query0.bindValue(":CARDID", cardid);
468  if (!query0.exec())
469  {
470  MythDB::DBError("DiSEqCDevTree::Store 3", query0);
471  return false;
472  }
473 
474  return true;
475 }
476 
477 bool DiSEqCDevTree::SetTone(bool on) const
478 {
479  (void) on;
480 
481  bool success = false;
482 
483 #ifdef USING_DVB
484  for (uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
485  {
486  if (ioctl(m_fdFrontend, FE_SET_TONE,
487  on ? SEC_TONE_ON : SEC_TONE_OFF) == 0)
488  success = true;
489  else
490  usleep(TIMEOUT_WAIT);
491  }
492 #endif // USING_DVB
493 
494  if (!success)
495  LOG(VB_GENERAL, LOG_ERR, LOC + "FE_SET_TONE failed" + ENO);
496 
497  return success;
498 }
499 
507  const DTVMultiplex &tuning)
508 {
509  if (!m_root)
510  {
511  LOG(VB_GENERAL, LOG_ERR, LOC + "No root device tree node!");
512  return false;
513  }
514 
515  // apply any voltage change
516  ApplyVoltage(settings, tuning);
517 
518  // turn off tone burst first if commands need to be sent
519  if (m_root->IsCommandNeeded(settings, tuning))
520  {
521  SetTone(false);
522  usleep(DISEQC_SHORT_WAIT);
523  }
524 
525  return m_root->Execute(settings, tuning);
526 }
527 
534 {
535  if (m_root)
536  m_root->Reset();
537 
538  m_lastVoltage = UINT_MAX;
539 }
540 
548 {
549  DiSEqCDevDevice *node = m_root;
550  DiSEqCDevRotor *rotor = nullptr;
551 
552  for (uint count = 0; node;)
553  {
554  rotor = dynamic_cast<DiSEqCDevRotor*>(node);
555 
556  if (rotor && (++count > index))
557  break;
558 
559  node = node->GetSelectedChild(settings);
560  }
561 
562  return rotor;
563 }
564 
571 {
572  DiSEqCDevDevice *node = m_root;
573  DiSEqCDevLNB *lnb = nullptr;
574 
575  while (node)
576  {
577  lnb = dynamic_cast<DiSEqCDevLNB*>(node);
578 
579  if (lnb)
580  break;
581 
582  node = node->GetSelectedChild(settings);
583  }
584 
585  return lnb;
586 }
587 
594 {
595  DiSEqCDevDevice *node = m_root;
596  DiSEqCDevSCR *scr = nullptr;
597 
598  while (node)
599  {
600  scr = dynamic_cast<DiSEqCDevSCR*>(node);
601 
602  if (scr)
603  break;
604 
605  node = node->GetSelectedChild(settings);
606  }
607 
608  return scr;
609 }
610 
611 
618 {
619  if (m_root)
620  return m_root->FindDevice(dev_id);
621 
622  return nullptr;
623 }
624 
630 {
631  DiSEqCDevDevice *old_root = m_root;
632 
633  m_root = root;
634 
635  delete old_root;
636 }
637 
638 #ifdef USING_DVB
639 static bool send_diseqc(int fd, const dvb_diseqc_master_cmd cmd)
640 {
641  bool success = false;
642 
643  for (uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
644  {
645  if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd) == 0)
646  success = true;
647  else
648  usleep(TIMEOUT_WAIT);
649  }
650 
651  if (!success)
652  {
653  LOG(VB_GENERAL, LOG_ERR, LOC +
654  "send_diseqc FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
655  }
656 
657  return success;
658 }
659 #endif //USING_DVB
660 
669 bool DiSEqCDevTree::SendCommand(uint adr, uint cmd, uint repeats,
670  cmd_vec_t &data) const
671 {
672  // check payload validity
673  if (data.size() > 3)
674  {
675  LOG(VB_GENERAL, LOG_ERR, LOC + "Bad DiSEqC command");
676  return false;
677  }
678 
679 #ifndef USING_DVB
680 
681  (void) adr;
682  (void) cmd;
683  (void) repeats;
684  return false;
685 
686 #else // if USING_DVB
687 
688  bool resend_cmd = false;
689 
690  // prepare command
691  dvb_diseqc_master_cmd mcmd = {};
692  mcmd.msg[0] = DISEQC_FRM;
693  mcmd.msg[1] = adr;
694  mcmd.msg[2] = cmd;
695  mcmd.msg_len = data.size() + 3;
696 
697  if (!data.empty())
698  std::copy(data.cbegin(), data.cend(), mcmd.msg + 3);
699 
700  // diagnostic
701  QString cmdstr;
702  for (uint byte = 0; byte < mcmd.msg_len; byte++)
703  cmdstr += QString("%1 ").arg(mcmd.msg[byte], 2, 16);
704 
705  LOG(VB_CHANNEL, LOG_INFO, LOC + "Sending DiSEqC Command: " + cmdstr);
706 
707  if (repeats >= 10)
708  {
709  repeats = repeats - 10;
710  resend_cmd = true;
711  }
712 
713  // send the command
714  for (uint i = 0; i <= repeats; i++)
715  {
716  if (!send_diseqc(GetFD(), mcmd))
717  {
718  LOG(VB_GENERAL, LOG_ERR, LOC + "DiSEqC command failed" + ENO);
719  return false;
720  }
721 
722  if (!resend_cmd)
723  mcmd.msg[0] |= DISEQC_FRM_REPEAT;
724 
725  usleep(DISEQC_SHORT_WAIT);
726  }
727 
728  return true;
729 
730 #endif // USING_DVB
731 }
732 
739 bool DiSEqCDevTree::ResetDiseqc(bool hard_reset, bool is_SCR)
740 {
741  Reset();
742 
743  // power cycle the bus if requested
744  // tests show that the wait times required can be very long (~1sec)
745  if (hard_reset)
746  {
747  LOG(VB_CHANNEL, LOG_INFO, LOC + "Power-cycling DiSEqC Bus");
748 
749  SetVoltage(SEC_VOLTAGE_OFF);
750  usleep(DISEQC_POWER_OFF_WAIT);
751  diseqc_bus_already_reset = false;
752  }
753 
754  if (!diseqc_bus_already_reset || !is_SCR)
755  {
756  // make sure the bus is powered
757  SetVoltage(SEC_VOLTAGE_18);
758  usleep(DISEQC_POWER_ON_WAIT);
759  // some DiSEqC devices need more time. see #8465
760  usleep(DISEQC_POWER_ON_WAIT);
761 
762  // issue a global reset command
763  LOG(VB_CHANNEL, LOG_INFO, LOC + "Resetting DiSEqC Bus");
765  {
766  LOG(VB_GENERAL, LOG_ERR, LOC + "DiSEqC reset failed" + ENO);
767  return false;
768  }
769 
770  if (is_SCR)
772  }
773  else
774  {
775  LOG(VB_CHANNEL, LOG_INFO, LOC + "Skipping reset: already done for this SCR bus");
776  }
777 
778  usleep(DISEQC_LONG_WAIT);
779 
780  return true;
781 }
782 
788 void DiSEqCDevTree::Open(int fd_frontend, bool is_SCR)
789 {
790  m_fdFrontend = fd_frontend;
791 
792  // issue reset command
793  ResetDiseqc(false, is_SCR);
794 }
795 
797 {
798 
799  if (voltage == m_lastVoltage)
800  return true;
801 
802  int volts = ((voltage == SEC_VOLTAGE_18) ? 18 :
803  ((voltage == SEC_VOLTAGE_13) ? 13 : 0));
804 
805  LOG(VB_CHANNEL, LOG_INFO, LOC + "Changing LNB voltage to " +
806  QString("%1V").arg(volts));
807 
808  bool success = false;
809 
810 #ifdef USING_DVB
811  for (uint retry = 0; !success && retry < TIMEOUT_RETRIES; retry++)
812  {
813  if (ioctl(m_fdFrontend, FE_SET_VOLTAGE, voltage) == 0)
814  success = true;
815  else
816  usleep(TIMEOUT_WAIT);
817  }
818 #endif // USING_DVB
819 
820  if (!success)
821  {
822  LOG(VB_GENERAL, LOG_ERR, LOC + "FE_SET_VOLTAGE failed" + ENO);
823  return false;
824  }
825 
826  m_lastVoltage = voltage;
827  return true;
828 }
829 
831 {
832  if (m_root)
834 
835  return false;
836 }
837 
839  const DTVMultiplex &tuning)
840 {
841  uint voltage = SEC_VOLTAGE_18;
842 
843  if (m_root)
844  voltage = m_root->GetVoltage(settings, tuning);
845 
846  return SetVoltage(voltage);
847 }
848 
850 
855 const std::vector<DiSEqCDevDevice::TypeTable> DiSEqCDevDevice::kDvbdevLookup
856 {
857  { "switch", kTypeSwitch },
858  { "rotor", kTypeRotor },
859  { "scr", kTypeSCR },
860  { "lnb", kTypeLNB },
861  { QString(), kTypeLNB },
862 };
863 
864 
866 {
867  if (IsRealDeviceID())
869 }
870 
872 {
873  DiSEqCDevDevice *dev = nullptr;
874 
875  if (GetDeviceID() == dev_id)
876  dev = this;
877 
878  uint num_children = GetChildCount();
879 
880  for (uint ch = 0; !dev && ch < num_children; ch++)
881  {
882  DiSEqCDevDevice *child = GetChild(ch);
883  if (child)
884  {
885  if (child->GetDeviceID() == dev_id)
886  dev = child;
887  else
888  dev = child->FindDevice(dev_id);
889  }
890  }
891 
892  return dev;
893 }
894 
896 {
897  // load settings from DB
899  query.prepare(
900  "SELECT type, description "
901  "FROM diseqc_tree "
902  "WHERE diseqcid = :DEVID");
903  query.bindValue(":DEVID", devid);
904 
905  if (!query.exec() || !query.isActive())
906  {
907  MythDB::DBError("DiSEqCDevDevice::CreateById", query);
908  return nullptr;
909  }
910  if (!query.next())
911  {
912  LOG(VB_GENERAL, LOG_ERR, LOC + "CreateById failed to find dtv dev " +
913  QString("%1").arg(devid));
914 
915  return nullptr;
916  }
917 
918  dvbdev_t type = DevTypeFromString(query.value(0).toString());
919  QString desc = query.value(1).toString();
920  DiSEqCDevDevice *node = CreateByType(tree, type, devid);
921 
922  if (node)
923  {
924  node->SetDescription(desc);
925  node->Load();
926  }
927 
928  return node;
929 }
930 
932  dvbdev_t type,
933  uint dev_id)
934 {
935  if (!dev_id)
936  dev_id = tree.CreateFakeDiSEqCID();
937 
938  DiSEqCDevDevice *node = nullptr;
939  switch (type)
940  {
941  case kTypeSwitch:
942  node = new DiSEqCDevSwitch(tree, dev_id);
943  if (node)
944  node->SetDescription("Switch");
945  break;
946  case kTypeRotor:
947  node = new DiSEqCDevRotor(tree, dev_id);
948  if (node)
949  node->SetDescription("Rotor");
950  break;
951  case kTypeSCR:
952  node = new DiSEqCDevSCR(tree, dev_id);
953  if (node)
954  node->SetDescription("Unicable");
955  break;
956  case kTypeLNB:
957  node = new DiSEqCDevLNB(tree, dev_id);
958  if (node)
959  node->SetDescription("LNB");
960  break;
961  default:
962  break;
963  }
964 
965  if (node)
966  node->SetDeviceType(type);
967 
968  return node;
969 }
970 
1040 
1046 const std::vector<DiSEqCDevDevice::TypeTable> DiSEqCDevSwitch::kSwitchTypeTable
1047 {
1048  { "legacy_sw21", kTypeLegacySW21 },
1049  { "legacy_sw42", kTypeLegacySW42 },
1050  { "legacy_sw64", kTypeLegacySW64 },
1051  { "tone", kTypeTone },
1052  { "diseqc", kTypeDiSEqCCommitted },
1053  { "diseqc_uncom", kTypeDiSEqCUncommitted },
1054  { "voltage", kTypeVoltage },
1055  { "mini_diseqc", kTypeMiniDiSEqC },
1056  { QString(), kTypeTone },
1057 };
1058 
1060  : DiSEqCDevDevice(tree, devid)
1061 {
1062  m_children.resize(m_numPorts);
1063 
1064  for (uint i = 0; i < m_numPorts; i++)
1065  m_children[i] = nullptr;
1066 
1068 }
1069 
1071 {
1072  for (auto & child : m_children)
1073  delete child;
1074 }
1075 
1077  const DTVMultiplex &tuning)
1078 {
1079  bool success = true;
1080 
1081  // sanity check switch position
1082  int pos = GetPosition(settings);
1083  if (pos < 0)
1084  return false;
1085 
1086  // perform switching
1087  if (ShouldSwitch(settings, tuning))
1088  {
1089  switch (m_type)
1090  {
1091  case kTypeTone:
1092  success = ExecuteTone(settings, tuning, pos);
1093  break;
1094  case kTypeDiSEqCCommitted:
1096  success = ExecuteDiseqc(settings, tuning, pos);
1097  break;
1098  case kTypeLegacySW21:
1099  case kTypeLegacySW42:
1100  case kTypeLegacySW64:
1101  success = ExecuteLegacy(settings, tuning, pos);
1102  break;
1103  case kTypeVoltage:
1104  success = ExecuteVoltage(settings, tuning, pos);
1105  break;
1106  case kTypeMiniDiSEqC:
1107  success = ExecuteMiniDiSEqC(settings, tuning, pos);
1108  break;
1109  default:
1110  success = false;
1111  LOG(VB_GENERAL, LOG_ERR, LOC +
1112  QString("Unknown switch type (%1)").arg((uint)m_type));
1113  break;
1114  }
1115 
1116  // if a child device will be sending a diseqc command, wait 100ms
1117  if (m_children[pos]->IsCommandNeeded(settings, tuning))
1118  {
1119  LOG(VB_CHANNEL, LOG_INFO, LOC + "Waiting for switch");
1120  usleep(DISEQC_LONG_WAIT);
1121  }
1122 
1123  m_lastPos = pos;
1124  }
1125 
1126  // chain to child if the switch was successful
1127  if (success)
1128  success = m_children[pos]->Execute(settings, tuning);
1129 
1130  return success;
1131 }
1132 
1134 {
1135  m_lastPos = UINT_MAX;
1136  m_lastHighBand = UINT_MAX;
1137  m_lastHorizontal = UINT_MAX;
1138  for (auto & child : m_children)
1139  {
1140  if (child)
1141  child->Reset();
1142  }
1143 }
1144 
1146  const DTVMultiplex &tuning) const
1147 {
1148  int pos = GetPosition(settings);
1149  if (pos < 0)
1150  return false;
1151 
1152  return (ShouldSwitch(settings, tuning) ||
1153  m_children[pos]->IsCommandNeeded(settings, tuning));
1154 }
1155 
1157 {
1158  // sanity check switch position
1159  int pos = GetPosition(settings);
1160  if (pos < 0)
1161  return nullptr;
1162 
1163  return m_children[pos];
1164 }
1165 
1167 {
1168  return m_numPorts;
1169 }
1170 
1172 {
1173  if (ordinal < m_children.size())
1174  return m_children[ordinal];
1175 
1176  return nullptr;
1177 }
1178 
1180 {
1181  if (ordinal >= m_children.size())
1182  return false;
1183 
1184  if (m_children[ordinal])
1185  delete m_children[ordinal];
1186 
1187  m_children[ordinal] = device;
1188  if (device)
1189  {
1190  device->SetOrdinal(ordinal);
1191  device->SetParent(this);
1192  }
1193 
1194  return true;
1195 }
1196 
1198  const DTVMultiplex &tuning) const
1199 {
1200  uint voltage = SEC_VOLTAGE_18;
1201  DiSEqCDevDevice *child = GetSelectedChild(settings);
1202 
1203  if (child)
1204  voltage = child->GetVoltage(settings, tuning);
1205 
1206  return voltage;
1207 }
1208 
1210 {
1211  // clear old children
1212  for (auto & child : m_children)
1213  delete child;
1214 
1215  m_children.clear();
1216 
1217  // populate switch parameters from db
1219  query.prepare(
1220  "SELECT subtype, address, switch_ports, cmd_repeat "
1221  "FROM diseqc_tree "
1222  "WHERE diseqcid = :DEVID");
1223  query.bindValue(":DEVID", GetDeviceID());
1224 
1225  if (!query.exec() || !query.isActive())
1226  {
1227  MythDB::DBError("DiSEqCDevSwitch::Load 1", query);
1228  return false;
1229  }
1230  if (query.next())
1231  {
1232  m_type = SwitchTypeFromString(query.value(0).toString());
1233  m_address = query.value(1).toUInt();
1234  m_numPorts = query.value(2).toUInt();
1235  m_repeat = query.value(3).toUInt();
1236  m_children.resize(m_numPorts);
1237  for (uint i = 0; i < m_numPorts; i++)
1238  m_children[i] = nullptr;
1239  }
1240 
1241  // load children from db
1242  query.prepare(
1243  "SELECT diseqcid, ordinal "
1244  "FROM diseqc_tree "
1245  "WHERE parentid = :DEVID");
1246  query.bindValue(":DEVID", GetDeviceID());
1247  if (!query.exec() || !query.isActive())
1248  {
1249  MythDB::DBError("DiSEqCDevSwitch::Load 2", query);
1250  return false;
1251  }
1252 
1253  while (query.next())
1254  {
1255  uint child_dev_id = query.value(0).toUInt();
1256  uint ordinal = query.value(1).toUInt();
1257  DiSEqCDevDevice *child = CreateById(m_tree, child_dev_id);
1258  if (child && !SetChild(ordinal, child))
1259  {
1260  LOG(VB_GENERAL, LOG_ERR, LOC +
1261  QString("Switch port out of range (%1 > %2)")
1262  .arg(ordinal + 1).arg(m_numPorts));
1263  delete child;
1264  }
1265  }
1266 
1267  return true;
1268 }
1269 
1270 bool DiSEqCDevSwitch::Store(void) const
1271 {
1272  QString type = SwitchTypeToString(m_type);
1274 
1275  // insert new or update old
1276  if (IsRealDeviceID())
1277  {
1278  query.prepare(
1279  "UPDATE diseqc_tree "
1280  "SET parentid = :PARENT, "
1281  " ordinal = :ORDINAL, "
1282  " type = 'switch', "
1283  " description = :DESC, "
1284  " subtype = :TYPE, "
1285  " address = :ADDRESS, "
1286  " switch_ports = :PORTS, "
1287  " cmd_repeat = :REPEAT "
1288  "WHERE diseqcid = :DEVID");
1289  query.bindValue(":DEVID", GetDeviceID());
1290  }
1291  else
1292  {
1293  query.prepare(
1294  "INSERT INTO diseqc_tree"
1295  " ( parentid, ordinal, type, "
1296  " description, address, subtype, "
1297  " switch_ports, cmd_repeat ) "
1298  "VALUES "
1299  " (:PARENT, :ORDINAL, 'switch', "
1300  " :DESC, :ADDRESS, :TYPE, "
1301  " :PORTS, :REPEAT )");
1302  }
1303 
1304  if (m_parent)
1305  query.bindValue(":PARENT", m_parent->GetDeviceID());
1306 
1307  query.bindValue(":ORDINAL", m_ordinal);
1308  query.bindValue(":DESC", GetDescription());
1309  query.bindValue(":ADDRESS", m_address);
1310  query.bindValue(":TYPE", type);
1311  query.bindValue(":PORTS", m_numPorts);
1312  query.bindValue(":REPEAT", m_repeat);
1313 
1314  if (!query.exec())
1315  {
1316  MythDB::DBError("DiSEqCDevSwitch::Store", query);
1317  return false;
1318  }
1319 
1320  // figure out devid if we did an insert
1321  if (!IsRealDeviceID())
1322  SetDeviceID(query.lastInsertId().toUInt());
1323 
1324  // chain to children
1325  bool success = true;
1326  for (auto *child : m_children)
1327  {
1328  if (child)
1329  success &= child->Store();
1330  }
1331 
1332  return success;
1333 }
1334 
1336 {
1337  uint old_num = m_children.size();
1338 
1339  if (old_num > num_ports)
1340  {
1341  for (uint ch = num_ports; ch < old_num; ch++)
1342  {
1343  if (m_children[ch])
1344  delete m_children[ch];
1345  }
1346  m_children.resize(num_ports);
1347  }
1348  else if (old_num < num_ports)
1349  {
1350  m_children.resize(num_ports);
1351  for (uint ch = old_num; ch < num_ports; ch++)
1352  m_children[ch] = nullptr;
1353  }
1354 
1355  m_numPorts = num_ports;
1356 }
1357 
1359  const DTVMultiplex &tuning,
1360  uint pos)
1361 {
1362  (void) settings;
1363  (void) tuning;
1364  (void) pos;
1365 
1366 #if defined(USING_DVB) && defined(FE_DISHNETWORK_SEND_LEGACY_CMD)
1367  static const cmd_vec_t kSw21Cmds { 0x34, 0x65, };
1368  static const cmd_vec_t kSw42Cmds { 0x46, 0x17, };
1369  static const cmd_vec_t kSw64VCmds { 0x39, 0x4b, 0x0d, };
1370  static const cmd_vec_t kSw64HCmds { 0x1a, 0x5c, 0x2e, };
1371 
1372  cmd_vec_t cmds {};
1373  unsigned char horizcmd = 0x00;
1374 
1375  // determine polarity from lnb
1376  bool horizontal = false;
1377  DiSEqCDevLNB *lnb = m_tree.FindLNB(settings);
1378  if (lnb)
1379  horizontal = lnb->IsHorizontal(tuning);
1380 
1381  // get command table for this switch
1382  switch (m_type)
1383  {
1384  case kTypeLegacySW21:
1385  cmds = kSw21Cmds;
1386  if (horizontal)
1387  horizcmd = 0x80;
1388  break;
1389  case kTypeLegacySW42:
1390  cmds = kSw42Cmds;
1391  break;
1392  case kTypeLegacySW64:
1393  if (horizontal)
1394  cmds = kSw64HCmds;
1395  else
1396  cmds = kSw64VCmds;
1397  break;
1398  default:
1399  return false;
1400  }
1401  pos %= cmds.size();
1402 
1403  LOG(VB_CHANNEL, LOG_INFO, LOC +
1404  QString("Changing to Legacy switch port %1/%2")
1405  .arg(pos + 1).arg(cmds.size()));
1406 
1407  // send command
1408  if (ioctl(m_tree.GetFD(), FE_DISHNETWORK_SEND_LEGACY_CMD,
1409  cmds[pos] | horizcmd) == -1)
1410  {
1411  LOG(VB_GENERAL, LOG_ERR, LOC +
1412  "FE_DISHNETWORK_SEND_LEGACY_CMD failed" + ENO);
1413 
1414  return false;
1415  }
1416 
1417  return true;
1418 
1419 #else // !FE_DISHNETWORK_SEND_LEGACY_CMD
1420 
1421  LOG(VB_GENERAL, LOG_ERR, LOC + "You must compile with a newer "
1422  "version of the linux headers for DishNet Legacy switch support.");
1423  return false;
1424 
1425 #endif // !FE_DISHNETWORK_SEND_LEGACY_CMD
1426 }
1427 
1428 #ifdef USING_DVB
1429 static bool set_tone(int fd, fe_sec_tone_mode tone)
1430 {
1431  (void) fd;
1432  (void) tone;
1433 
1434  bool success = false;
1435 
1436  for (uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
1437  {
1438  if (ioctl(fd, FE_SET_TONE, tone) == 0)
1439  success = true;
1440  else
1441  usleep(TIMEOUT_WAIT);
1442  }
1443 
1444  if (!success)
1445  {
1446  LOG(VB_GENERAL, LOG_ERR, LOC + "set_tone failed" + ENO);
1447  }
1448 
1449  return success;
1450 }
1451 #endif // USING_DVB
1452 
1453 #ifdef USING_DVB
1454 static bool set_voltage(int fd, fe_sec_voltage volt)
1455 {
1456  (void) fd;
1457  (void) volt;
1458 
1459  bool success = false;
1460 
1461  for (uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
1462  {
1463  if (0 == ioctl(fd, FE_SET_VOLTAGE, volt))
1464  success = true;
1465  else
1466  usleep(TIMEOUT_WAIT);
1467  }
1468 
1469  if (!success)
1470  {
1471  LOG(VB_GENERAL, LOG_ERR, LOC + "FE_SET_VOLTAGE failed" + ENO);
1472  }
1473 
1474  return success;
1475 }
1476 #endif // USING_DVB
1477 
1478 #ifdef USING_DVB
1479 static bool mini_diseqc(int fd, fe_sec_mini_cmd cmd)
1480 {
1481  (void) fd;
1482  (void) cmd;
1483 
1484  bool success = false;
1485 
1486  for (uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
1487  {
1488  if (ioctl(fd, FE_DISEQC_SEND_BURST, cmd) == 0)
1489  success = true;
1490  else
1491  usleep(TIMEOUT_WAIT);
1492  }
1493 
1494  if (!success)
1495  {
1496  LOG(VB_GENERAL, LOG_ERR, LOC +
1497  "mini_diseqc FE_DISEQC_SEND_BURST failed" + ENO);
1498  }
1499 
1500  return success;
1501 }
1502 #endif // USING_DVB
1503 
1505  const DTVMultiplex &/*tuning*/,
1506  uint pos)
1507 {
1508  LOG(VB_CHANNEL, LOG_INFO, LOC + "Changing to Tone switch port " +
1509  QString("%1/2").arg(pos + 1));
1510 
1511 #ifdef USING_DVB
1512  if (set_tone(m_tree.GetFD(), (0 == pos) ? SEC_TONE_OFF : SEC_TONE_ON))
1513  return true;
1514 #endif // USING_DVB
1515 
1516  LOG(VB_GENERAL, LOG_ERR, LOC + "Setting Tone Switch failed." + ENO);
1517  return false;
1518 }
1519 
1521  const DTVMultiplex &tuning, uint pos)
1522 {
1523  (void) settings;
1524  (void) tuning;
1525 
1526  LOG(VB_CHANNEL, LOG_INFO, LOC + "Changing to Voltage Switch port " +
1527  QString("%1/2").arg(pos + 1));
1528 
1529 #ifdef USING_DVB
1530  if (set_voltage(m_tree.GetFD(),
1531  (0 == pos) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18))
1532  {
1533  return true;
1534  }
1535 #endif // USING_DVB
1536 
1537  LOG(VB_GENERAL, LOG_ERR, LOC + "Setting Voltage Switch failed." + ENO);
1538 
1539  return false;
1540 }
1541 
1543  const DTVMultiplex &tuning, uint pos)
1544 {
1545  (void) settings;
1546  (void) tuning;
1547 
1548  LOG(VB_CHANNEL, LOG_INFO, LOC + "Changing to MiniDiSEqC Switch port " +
1549  QString("%1/2").arg(pos + 1));
1550 
1551 #ifdef USING_DVB
1552  if (mini_diseqc(m_tree.GetFD(), (0 == pos) ? SEC_MINI_A : SEC_MINI_B))
1553  return true;
1554 #endif // USING_DVB
1555 
1556  LOG(VB_GENERAL, LOG_ERR, LOC + "Setting Mini DiSEqC Switch failed." + ENO);
1557 
1558  return false;
1559 }
1560 
1562  const DTVMultiplex &tuning) const
1563 {
1564  int pos = GetPosition(settings);
1565  if (pos < 0)
1566  return false;
1567 
1568  // committed switch should change for band and polarity as well
1570  {
1571  // retrieve LNB info
1572  bool high_band = false;
1573  bool horizontal = false;
1574  DiSEqCDevLNB *lnb = m_tree.FindLNB(settings);
1575  if (lnb)
1576  {
1577  high_band = lnb->IsHighBand(tuning);
1578  horizontal = lnb->IsHorizontal(tuning);
1579  }
1580 
1581  if(static_cast<uint>(high_band) != m_lastHighBand ||
1582  static_cast<uint>(horizontal) != m_lastHorizontal)
1583  return true;
1584  }
1585  else if (kTypeLegacySW42 == m_type ||
1587  {
1588  // retrieve LNB info
1589  bool horizontal = false;
1590  DiSEqCDevLNB *lnb = m_tree.FindLNB(settings);
1591  if (lnb)
1592  horizontal = lnb->IsHorizontal(tuning);
1593 
1594  if (static_cast<unsigned int>(horizontal) != m_lastHorizontal)
1595  return true;
1596  }
1597  else if (kTypeVoltage == m_type ||
1598  kTypeTone == m_type)
1599  return true;
1600 
1601  return m_lastPos != (uint)pos;
1602 }
1603 
1605  const DTVMultiplex &tuning,
1606  uint pos32)
1607 {
1608  auto pos = static_cast<uint8_t>(pos32);
1609  // retrieve LNB info
1610  bool high_band = false;
1611  bool horizontal = false;
1612  DiSEqCDevLNB *lnb = m_tree.FindLNB(settings);
1613  if (lnb)
1614  {
1615  high_band = lnb->IsHighBand(tuning);
1616  horizontal = lnb->IsHorizontal(tuning);
1617  }
1618 
1619  // check number of ports
1620  if (((kTypeDiSEqCCommitted == m_type) && (m_numPorts > 4)) ||
1621  ((kTypeDiSEqCUncommitted == m_type) && (m_numPorts > 16)))
1622  {
1623  LOG(VB_GENERAL, LOG_ERR, LOC +
1624  QString("Invalid number of ports for DiSEqC 1.x Switch (%1)")
1625  .arg(m_numPorts));
1626  return false;
1627  }
1628 
1629  // build command
1630  uint cmd = DISEQC_CMD_WRITE_N1;
1631  cmd_vec_t data { pos };
1633  {
1634  cmd = DISEQC_CMD_WRITE_N0;
1635  data[0] = ((pos << 2) | (horizontal ? 2 : 0) | (high_band ? 1 : 0));
1636  }
1637  data[0] |= 0xf0;
1638 
1639  LOG(VB_CHANNEL, LOG_INFO, LOC + "Changing to DiSEqC switch port " +
1640  QString("%1/%2").arg(pos + 1).arg(m_numPorts));
1641 
1642  bool ret = m_tree.SendCommand(m_address, cmd, m_repeat, data);
1643  if(ret)
1644  {
1645  m_lastHighBand = static_cast<uint>(high_band);
1646  m_lastHorizontal = static_cast<uint>(horizontal);
1647  }
1648  return ret;
1649 }
1650 
1652 {
1653  int pos = (int) settings.GetValue(GetDeviceID());
1654 
1655  if (pos >= (int)m_numPorts)
1656  {
1657  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Port %1 ").arg(pos + 1) +
1658  QString("is not in range [0..%1)").arg(m_numPorts));
1659 
1660  return -1;
1661  }
1662 
1663  if ((pos >= 0) && !m_children[pos])
1664  {
1665  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Port %1 ").arg(pos + 1) +
1666  "has no connected devices configured.");
1667 
1668  return -1;
1669  }
1670 
1671  return pos;
1672 }
1673 
1675 
1676 static double GetCurTimeFloating(void)
1677 {
1678  struct timeval curtime {};
1679  gettimeofday(&curtime, nullptr);
1680  return (double)curtime.tv_sec + (((double)curtime.tv_usec) / 1000000);
1681 }
1682 
1687 const std::vector<DiSEqCDevDevice::TypeTable> DiSEqCDevRotor::kRotorTypeTable
1688 {
1689  { "diseqc_1_2", kTypeDiSEqC_1_2 },
1690  { "diseqc_1_3", kTypeDiSEqC_1_3 },
1691  { nullptr, kTypeDiSEqC_1_3 }
1692 };
1693 
1695 {
1696  delete m_child;
1697 }
1698 
1700  const DTVMultiplex &tuning)
1701 {
1702  bool success = true;
1703 
1704  double position = settings.GetValue(GetDeviceID());
1705  if (m_reset || (position != m_lastPosition))
1706  {
1707  switch (m_type)
1708  {
1709  case kTypeDiSEqC_1_2:
1710  success = ExecuteRotor(settings, tuning, position);
1711  break;
1712  case kTypeDiSEqC_1_3:
1713  success = ExecuteUSALS(settings, tuning, position);
1714  break;
1715  default:
1716  success = false;
1717  LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown rotor type " +
1718  QString("(%1)").arg((uint) m_type));
1719  break;
1720  }
1721 
1722  m_lastPosition = position;
1723  m_reset = false;
1724  if (success)
1725  // prevent tuning paramaters overiding rotor parameters
1726  usleep(DISEQC_LONG_WAIT);
1727  }
1728 
1729  // chain to child
1730  if (success && m_child)
1731  success = m_child->Execute(settings, tuning);
1732 
1733  return success;
1734 }
1735 
1737 {
1738  m_reset = true;
1739  if (m_child)
1740  m_child->Reset();
1741 }
1742 
1744  const DTVMultiplex &tuning) const
1745 {
1746  double position = settings.GetValue(GetDeviceID());
1747 
1748  if (m_reset || (position != m_lastPosition))
1749  return true;
1750 
1751  if (m_child)
1752  return m_child->IsCommandNeeded(settings, tuning);
1753 
1754  return false;
1755 }
1756 
1758 {
1759  return m_child;
1760 }
1761 
1763 {
1764  if (ordinal)
1765  return false;
1766 
1767  DiSEqCDevDevice *old_child = m_child;
1768  m_child = nullptr;
1769  delete old_child;
1770 
1771  m_child = device;
1772  if (m_child)
1773  {
1774  m_child->SetOrdinal(ordinal);
1775  m_child->SetParent(this);
1776  }
1777 
1778  return true;
1779 }
1780 
1781 bool DiSEqCDevRotor::IsMoving(const DiSEqCDevSettings &settings) const
1782 {
1783  double position = settings.GetValue(GetDeviceID());
1784  double completed = GetProgress();
1785  bool moving = (completed < 1.0) || (position != m_lastPosition);
1786 
1787  return (m_lastPosKnown && moving);
1788 }
1789 
1791  const DTVMultiplex &tuning) const
1792 {
1793  // override voltage if the last position is known and the rotor is moving
1794  if (IsMoving(settings))
1795  {
1796  LOG(VB_CHANNEL, LOG_INFO, LOC +
1797  "Overriding voltage to 18V for faster rotor movement");
1798  }
1799  else if (m_child)
1800  {
1801  return m_child->GetVoltage(settings, tuning);
1802  }
1803 
1804  return SEC_VOLTAGE_18;
1805 }
1806 
1808 {
1809  // populate switch parameters from db
1811  query.prepare(
1812  "SELECT subtype, rotor_positions, "
1813  " rotor_hi_speed, rotor_lo_speed, "
1814  " cmd_repeat "
1815  "FROM diseqc_tree "
1816  "WHERE diseqcid = :DEVID");
1817  query.bindValue(":DEVID", GetDeviceID());
1818 
1819  if (!query.exec() || !query.isActive())
1820  {
1821  MythDB::DBError("DiSEqCDevRotor::Load 1", query);
1822  return false;
1823  }
1824  if (query.next())
1825  {
1826  m_type = RotorTypeFromString(query.value(0).toString());
1827  m_speedHi = query.value(2).toDouble();
1828  m_speedLo = query.value(3).toDouble();
1829  m_repeat = query.value(4).toUInt();
1830 
1831  // form of "angle1=index1:angle2=index2:..."
1832  QString positions = query.value(1).toString();
1833 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
1834  QStringList pos = positions.split(":", QString::SkipEmptyParts);
1835 #else
1836  QStringList pos = positions.split(":", Qt::SkipEmptyParts);
1837 #endif
1838  for (const auto & kv : qAsConst(pos))
1839  {
1840 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
1841  const QStringList eq = kv.split("=", QString::SkipEmptyParts);
1842 #else
1843  const QStringList eq = kv.split("=", Qt::SkipEmptyParts);
1844 #endif
1845  if (eq.size() == 2)
1846  m_posmap[eq[0].toFloat()] = eq[1].toUInt();
1847  }
1848  }
1849 
1850  // load children from db
1851  if (m_child)
1852  {
1853  delete m_child;
1854  m_child = nullptr;
1855  }
1856 
1857  query.prepare(
1858  "SELECT diseqcid "
1859  "FROM diseqc_tree "
1860  "WHERE parentid = :DEVID");
1861  query.bindValue(":DEVID", GetDeviceID());
1862 
1863  if (!query.exec() || !query.isActive())
1864  {
1865  MythDB::DBError("DiSEqCDevRotor::Load 2", query);
1866  return false;
1867  }
1868  if (query.next())
1869  {
1870  uint child_dev_id = query.value(0).toUInt();
1871  SetChild(0, CreateById(m_tree, child_dev_id));
1872  }
1873 
1874  return true;
1875 }
1876 
1877 bool DiSEqCDevRotor::Store(void) const
1878 {
1879  QString posmap = "";
1880  QString type = RotorTypeToString(m_type);
1881 
1882  if (!m_posmap.empty())
1883  {
1884  QStringList pos;
1885 
1886  dbl_to_uint_t::const_iterator it = m_posmap.begin();
1887  for (; it != m_posmap.end(); ++it)
1888  pos.push_back(QString("%1=%2").arg(it.key()).arg(*it));
1889 
1890  posmap = pos.join(":");
1891  }
1892 
1894 
1895  // insert new or update old
1896  if (IsRealDeviceID())
1897  {
1898  query.prepare(
1899  "UPDATE diseqc_tree "
1900  "SET parentid = :PARENT, "
1901  " ordinal = :ORDINAL, "
1902  " type = 'rotor', "
1903  " description = :DESC, "
1904  " subtype = :TYPE, "
1905  " rotor_hi_speed = :HISPEED, "
1906  " rotor_lo_speed = :LOSPEED, "
1907  " rotor_positions = :POSMAP, "
1908  " cmd_repeat = :REPEAT "
1909  "WHERE diseqcid = :DEVID");
1910  query.bindValue(":DEVID", GetDeviceID());
1911  }
1912  else
1913  {
1914  query.prepare(
1915  "INSERT INTO diseqc_tree "
1916  " ( parentid, ordinal, type, "
1917  " description, subtype, rotor_hi_speed, "
1918  " rotor_lo_speed, rotor_positions, cmd_repeat ) "
1919  "VALUES "
1920  " (:PARENT, :ORDINAL, 'rotor', "
1921  " :DESC, :TYPE, :HISPEED, "
1922  " :LOSPEED, :POSMAP, :REPEAT )");
1923  }
1924 
1925  if (m_parent)
1926  query.bindValue(":PARENT", m_parent->GetDeviceID());
1927 
1928  query.bindValue(":ORDINAL", m_ordinal);
1929  query.bindValue(":DESC", GetDescription());
1930  query.bindValue(":TYPE", type);
1931  query.bindValue(":HISPEED", m_speedHi);
1932  query.bindValue(":LOSPEED", m_speedLo);
1933  query.bindValue(":POSMAP", posmap);
1934  query.bindValue(":REPEAT", m_repeat);
1935 
1936  if (!query.exec())
1937  {
1938  MythDB::DBError("DiSEqCDevRotor::Store", query);
1939  return false;
1940  }
1941 
1942  // figure out devid if we did an insert
1943  if (!IsRealDeviceID())
1944  SetDeviceID(query.lastInsertId().toUInt());
1945 
1946  // chain to child
1947  if (m_child)
1948  return m_child->Store();
1949 
1950  return true;
1951 }
1952 
1959 {
1960  if (m_moveTime == 0.0)
1961  return 1.0;
1962 
1963  // calculate duration of move
1964  double speed = ((m_tree.GetVoltage() == SEC_VOLTAGE_18) ?
1965  m_speedHi : m_speedLo);
1966  double change = abs(m_desiredAzimuth - m_lastAzimuth);
1967  double duration = change / speed;
1968 
1969  // determine completion percentage
1970  double time_since_move = GetCurTimeFloating() - m_moveTime;
1971  double completed = time_since_move / duration;
1972  if(completed > 1.0)
1973  {
1974  RotationComplete();
1975  completed = 1.0;
1976  }
1977 
1978  return completed;
1979 }
1980 
1989 {
1990  return m_lastPosKnown;
1991 }
1992 
1994 {
1995  uint_to_dbl_t inv_posmap;
1996  dbl_to_uint_t::const_iterator it;
1997  for (it = m_posmap.begin(); it != m_posmap.end(); ++it)
1998  inv_posmap[*it] = it.key();
1999 
2000  return inv_posmap;
2001 }
2002 
2004 {
2005  m_posmap.clear();
2006 
2007  uint_to_dbl_t::const_iterator it;
2008  for (it = inv_posmap.begin(); it != inv_posmap.end(); ++it)
2009  m_posmap[*it] = it.key();
2010 }
2011 
2013  const DTVMultiplex& /*tuning*/,
2014  double angle)
2015 {
2016  // determine stored position from position map
2017  dbl_to_uint_t::const_iterator it =
2018  m_posmap.lowerBound(angle - EPS); // clazy:exclude=strict-iterators
2019  cmd_vec_t index { static_cast<uint8_t>(angle) };
2020  if (it != m_posmap.cend())
2021  {
2022  index[0] = *it;
2024  }
2025 
2026  LOG(VB_CHANNEL, LOG_INFO, LOC + "Rotor - " +
2027  QString("Goto Stored Position %1").arg(index[0]));
2028 
2030  m_repeat, index);
2031 }
2032 
2034  const DTVMultiplex& /*tuning*/,
2035  double angle)
2036 {
2037  double azimuth = CalculateAzimuth(angle);
2038  StartRotorPositionTracking(azimuth);
2039 
2040  LOG(VB_CHANNEL, LOG_INFO, LOC + "USALS Rotor - " +
2041  QString("Goto %1 (Azimuth %2)").arg(angle).arg(azimuth));
2042 
2043  uint az16 = (uint) (abs(azimuth) * 16.0);
2044  cmd_vec_t cmd {
2045  static_cast<uint8_t>(((azimuth > 0.0) ? 0xE0 : 0xD0) | ((az16 >> 8) & 0x0f)),
2046  static_cast<uint8_t>(az16 & 0xff) };
2047 
2049  m_repeat, cmd);
2050 }
2051 
2053 {
2054  // Azimuth Calculation references:
2055  // http://engr.nmsu.edu/~etti/3_2/3_2e.html
2056  // http://www.angelfire.com/trek/ismail/theory.html
2057 
2058  // Earth Station Latitude and Longitude in radians
2059  double P = gCoreContext->GetSetting("Latitude", "").toDouble() * TO_RADS;
2060  double Ue = gCoreContext->GetSetting("Longitude", "").toDouble() * TO_RADS;
2061 
2062  // Satellite Longitude in radians
2063  double Us = angle * TO_RADS;
2064 
2065  return TO_DEC * atan( tan(Us - Ue) / sin(P) );
2066 }
2067 
2069 {
2070  if (m_moveTime == 0.0)
2071  return m_lastAzimuth;
2072 
2073  double change = m_desiredAzimuth - m_lastAzimuth;
2074  return m_lastAzimuth + (change * GetProgress());
2075 }
2076 
2078 {
2079  // save time and angle of this command
2080  m_desiredAzimuth = azimuth;
2081 
2082  // set last to approximate current position (or worst case if unknown)
2083  if (m_lastPosKnown || m_moveTime > 0.0)
2085  else
2086  m_lastAzimuth = azimuth > 0.0 ? -75.0 : 75.0;
2087 
2089 }
2090 
2092 {
2093  m_moveTime = 0.0;
2094  m_lastPosKnown = true;
2096 }
2097 
2099 
2104 const std::vector<DiSEqCDevDevice::TypeTable> DiSEqCDevSCR::kSCRPositionTable
2105 {
2106  { "A", kTypeScrPosA },
2107  { "B", kTypeScrPosB },
2108  { QString(), kTypeScrPosA },
2109 };
2110 
2112 {
2113  delete m_child;
2114 }
2115 
2117 {
2118  if (m_child)
2119  m_child->Reset();
2120 }
2121 
2122 bool DiSEqCDevSCR::Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning)
2123 {
2124  // retrieve LNB info
2125  DiSEqCDevLNB *lnb = m_tree.FindLNB(settings);
2126  if (!lnb)
2127  {
2128  LOG(VB_GENERAL, LOG_ERR, LOC + "SCR: No LNB for this configuration!");
2129  return false;
2130  }
2131 
2132  bool high_band = lnb->IsHighBand(tuning);
2133  bool horizontal = lnb->IsHorizontal(tuning);
2134  uint32_t frequency = lnb->GetIntermediateFrequency(settings, tuning);
2135  uint t = (frequency / 1000 + m_scrFrequency + 2) / 4 - 350;
2136 
2137  // retrieve position settings (value should be 0 or 1)
2138  auto scr_position = (dvbdev_pos_t)int(settings.GetValue(GetDeviceID()));
2139 
2140  // check parameters
2141  if (m_scrUserband > 8)
2142  {
2143  LOG(VB_GENERAL, LOG_INFO, QString("SCR: Userband ID=%1 is out of standard range!")
2144  .arg(m_scrUserband));
2145  }
2146 
2147  if (t >= 1024)
2148  {
2149  LOG(VB_GENERAL, LOG_ERR, LOC + "SCR: T out of range!");
2150  return false;
2151  }
2152 
2153  LOG(VB_GENERAL, LOG_INFO, QString("SCR: Tuning to %1kHz, %2, %3 using UB=%4, FREQ=%5MHz, POS=%6%7")
2154  .arg(tuning.m_frequency)
2155  .arg(high_band ? "HiBand" : "LoBand")
2156  .arg(horizontal ? "H" : "V")
2157  .arg(m_scrUserband)
2158  .arg(m_scrFrequency)
2159  .arg((scr_position) ? "B" : "A")
2160  .arg((m_scrPin >= 0 && m_scrPin <= 255) ?
2161  QString(", PIN=%1").arg(m_scrPin) : QString("")));
2162 
2163  // build command
2164  cmd_vec_t data {
2165  static_cast<uint8_t>(t >> 8 | m_scrUserband << 5),
2166  static_cast<uint8_t>(t & 0x00FF) };
2167 
2168  if (high_band)
2169  data[0] |= (1 << 2);
2170 
2171  if (horizontal)
2172  data[0] |= (1 << 3);
2173 
2174  if (scr_position)
2175  data[0] |= (1 << 4);
2176 
2177  // send command
2178  if (m_scrPin >= 0 && m_scrPin <= 255)
2179  data.push_back(m_scrPin);
2180  return SendCommand(DISEQC_CMD_ODU, m_repeat, data);
2181 }
2182 
2183 bool DiSEqCDevSCR::PowerOff(void) const
2184 {
2185  // check parameters
2186  if (m_scrUserband > 8)
2187  {
2188  LOG(VB_GENERAL, LOG_INFO, QString("SCR: Userband ID=%1 is out of standard range!")
2189  .arg(m_scrUserband));
2190  }
2191 
2192  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("SCR: Power off UB=%1%7")
2193  .arg(m_scrUserband)
2194  .arg((m_scrPin >= 0 && m_scrPin <= 255)
2195  ? QString(", PIN=%1").arg(m_scrPin)
2196  : QString("")));
2197 
2198  // build command
2199  cmd_vec_t data {
2200  static_cast<uint8_t>(m_scrUserband << 5), 0x00 };
2201 
2202  // send command
2203  if (m_scrPin >= 0 && m_scrPin <= 255)
2204  data.push_back(m_scrPin);
2205  return SendCommand(DISEQC_CMD_ODU, m_repeat, data);
2206 }
2207 
2208 bool DiSEqCDevSCR::SendCommand(uint cmd, uint repeats, cmd_vec_t &data) const
2209 {
2210  (void) repeats;
2211 
2212  // power on bus
2213  if (!m_tree.SetVoltage(SEC_VOLTAGE_18))
2214  return false;
2215  usleep(DISEQC_LONG_WAIT);
2216 
2217  // send command
2218  bool ret = m_tree.SendCommand(DISEQC_ADR_SW_ALL, cmd, repeats, data);
2219 
2220  // power off bus
2221  if (!m_tree.SetVoltage(SEC_VOLTAGE_13))
2222  return false;
2223 
2224  return ret;
2225 }
2226 
2228  const DTVMultiplex &/*tuning*/) const
2229 {
2230  return SEC_VOLTAGE_13;
2231 }
2232 
2233 uint32_t DiSEqCDevSCR::GetIntermediateFrequency(const uint32_t frequency) const
2234 {
2235  uint t = (frequency / 1000 + m_scrFrequency + 2) / 4 - 350;
2236  return ((t + 350) * 4) * 1000 - frequency;
2237 }
2238 
2240 {
2241  // populate scr parameters from db
2243  query.prepare(
2244  "SELECT scr_userband, scr_frequency, "
2245  " scr_pin, cmd_repeat "
2246  "FROM diseqc_tree "
2247  "WHERE diseqcid = :DEVID");
2248  query.bindValue(":DEVID", GetDeviceID());
2249 
2250  if (!query.exec() || !query.isActive())
2251  {
2252  MythDB::DBError("DiSEqCDevSCR::Load 1", query);
2253  return false;
2254  }
2255  if (query.next())
2256  {
2257  m_scrUserband = query.value(0).toUInt();
2258  m_scrFrequency = query.value(1).toUInt();
2259  m_scrPin = query.value(2).toInt();
2260  m_repeat = query.value(3).toUInt();
2261  }
2262 
2263  // load children from db
2264  if (m_child)
2265  {
2266  delete m_child;
2267  m_child = nullptr;
2268  }
2269 
2270  query.prepare(
2271  "SELECT diseqcid "
2272  "FROM diseqc_tree "
2273  "WHERE parentid = :DEVID");
2274  query.bindValue(":DEVID", GetDeviceID());
2275 
2276  if (!query.exec() || !query.isActive())
2277  {
2278  MythDB::DBError("DiSEqCDevSCR::Load 2", query);
2279  return false;
2280  }
2281  if (query.next())
2282  {
2283  uint child_dev_id = query.value(0).toUInt();
2284  SetChild(0, CreateById(m_tree, child_dev_id));
2285  }
2286 
2287  return true;
2288 }
2289 
2290 bool DiSEqCDevSCR::Store(void) const
2291 {
2293 
2294  // insert new or update old
2295  if (IsRealDeviceID())
2296  {
2297  query.prepare(
2298  "UPDATE diseqc_tree "
2299  "SET parentid = :PARENT, "
2300  " ordinal = :ORDINAL, "
2301  " type = 'scr', "
2302  " description = :DESC, "
2303  " scr_userband = :USERBAND, "
2304  " scr_frequency = :FREQUENCY, "
2305  " scr_pin = :PIN, "
2306  " cmd_repeat = :REPEAT "
2307  "WHERE diseqcid = :DEVID");
2308  query.bindValue(":DEVID", GetDeviceID());
2309  }
2310  else
2311  {
2312  query.prepare(
2313  "INSERT INTO diseqc_tree"
2314  " ( parentid, ordinal, type, "
2315  " description, scr_userband, scr_frequency, "
2316  " scr_pin, cmd_repeat) "
2317  "VALUES "
2318  " (:PARENT, :ORDINAL, 'scr', "
2319  " :DESC, :USERBAND, :FREQUENCY,"
2320  " :PIN, :REPEAT) ");
2321  }
2322 
2323  if (m_parent)
2324  query.bindValue(":PARENT", m_parent->GetDeviceID());
2325 
2326  query.bindValue(":ORDINAL", m_ordinal);
2327  query.bindValue(":DESC", GetDescription());
2328  query.bindValue(":USERBAND", m_scrUserband);
2329  query.bindValue(":FREQUENCY", m_scrFrequency);
2330  query.bindValue(":PIN", m_scrPin);
2331  query.bindValue(":REPEAT", m_repeat);
2332 
2333  // update dev_id
2334  if (!query.exec())
2335  {
2336  MythDB::DBError("DiSEqCDevSCR::Store", query);
2337  return false;
2338  }
2339 
2340  // figure out devid if we did an insert
2341  if (!IsRealDeviceID())
2342  SetDeviceID(query.lastInsertId().toUInt());
2343 
2344  // chain to child
2345  if (m_child)
2346  return m_child->Store();
2347 
2348  return true;
2349 }
2350 
2352 {
2353  if (ordinal)
2354  return false;
2355 
2356  DiSEqCDevDevice *old_child = m_child;
2357  m_child = nullptr;
2358  delete old_child;
2359 
2360  m_child = device;
2361  if (m_child)
2362  {
2363  m_child->SetOrdinal(ordinal);
2364  m_child->SetParent(this);
2365  }
2366 
2367  return true;
2368 }
2369 
2371 
2376 const std::vector<DiSEqCDevDevice::TypeTable> DiSEqCDevLNB::kLNBTypeTable
2377 {
2378  { "fixed", kTypeFixed },
2379  { "voltage", kTypeVoltageControl },
2380  { "voltage_tone", kTypeVoltageAndToneControl },
2381  { "bandstacked", kTypeBandstacked },
2382  { QString(), kTypeVoltageAndToneControl },
2383 };
2384 
2385 bool DiSEqCDevLNB::Execute(const DiSEqCDevSettings& /*settings*/, const DTVMultiplex &tuning)
2386 {
2387  // set tone for bandselect
2389  m_tree.SetTone(IsHighBand(tuning));
2390 
2391  return true;
2392 }
2393 
2395  const DTVMultiplex &tuning) const
2396 {
2397  uint voltage = SEC_VOLTAGE_18;
2398 
2399  if ((kTypeVoltageControl == m_type) ||
2401  {
2402  voltage = (IsHorizontal(tuning) ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13);
2403  }
2404 
2405  return voltage;
2406 }
2407 
2409 {
2410  // populate lnb parameters from db
2412  query.prepare(
2413  "SELECT subtype, lnb_lof_switch, "
2414  " lnb_lof_hi, lnb_lof_lo, "
2415  " lnb_pol_inv, cmd_repeat "
2416  "FROM diseqc_tree "
2417  "WHERE diseqcid = :DEVID");
2418  query.bindValue(":DEVID", GetDeviceID());
2419 
2420  if (!query.exec() || !query.isActive())
2421  {
2422  MythDB::DBError("DiSEqCDevLNB::Load", query);
2423  return false;
2424  }
2425  if (query.next())
2426  {
2427  m_type = LNBTypeFromString(query.value(0).toString());
2428  m_lofSwitch = query.value(1).toInt();
2429  m_lofHi = query.value(2).toInt();
2430  m_lofLo = query.value(3).toInt();
2431  m_polInv = query.value(4).toBool();
2432  m_repeat = query.value(5).toUInt();
2433  }
2434 
2435  return true;
2436 }
2437 
2438 bool DiSEqCDevLNB::Store(void) const
2439 {
2440  QString type = LNBTypeToString(m_type);
2442 
2443  // insert new or update old
2444  if (IsRealDeviceID())
2445  {
2446  query.prepare(
2447  "UPDATE diseqc_tree "
2448  "SET parentid = :PARENT, "
2449  " ordinal = :ORDINAL, "
2450  " type = 'lnb', "
2451  " description = :DESC, "
2452  " subtype = :TYPE, "
2453  " lnb_lof_switch = :LOFSW, "
2454  " lnb_lof_lo = :LOFLO, "
2455  " lnb_lof_hi = :LOFHI, "
2456  " lnb_pol_inv = :POLINV, "
2457  " cmd_repeat = :REPEAT "
2458  "WHERE diseqcid = :DEVID");
2459  query.bindValue(":DEVID", GetDeviceID());
2460  }
2461  else
2462  {
2463  query.prepare(
2464  "INSERT INTO diseqc_tree"
2465  " ( parentid, ordinal, type, "
2466  " description, subtype, lnb_lof_switch, "
2467  " lnb_lof_lo, lnb_lof_hi, lnb_pol_inv, "
2468  " cmd_repeat ) "
2469  "VALUES "
2470  " (:PARENT, :ORDINAL, 'lnb', "
2471  " :DESC, :TYPE, :LOFSW, "
2472  " :LOFLO, :LOFHI, :POLINV, "
2473  " :REPEAT ) ");
2474  }
2475 
2476  if (m_parent)
2477  query.bindValue(":PARENT", m_parent->GetDeviceID());
2478 
2479  query.bindValue(":ORDINAL", m_ordinal);
2480  query.bindValue(":DESC", GetDescription());
2481  query.bindValue(":TYPE", type);
2482  query.bindValue(":LOFSW", m_lofSwitch);
2483  query.bindValue(":LOFLO", m_lofLo);
2484  query.bindValue(":LOFHI", m_lofHi);
2485  query.bindValue(":POLINV", m_polInv);
2486  query.bindValue(":REPEAT", m_repeat);
2487 
2488  // update dev_id
2489  if (!query.exec())
2490  {
2491  MythDB::DBError("DiSEqCDevLNB::Store", query);
2492  return false;
2493  }
2494 
2495  // figure out devid if we did an insert
2496  if (!IsRealDeviceID())
2497  SetDeviceID(query.lastInsertId().toUInt());
2498 
2499  return true;
2500 }
2501 
2508 bool DiSEqCDevLNB::IsHighBand(const DTVMultiplex &tuning) const
2509 {
2510  switch (m_type)
2511  {
2513  return (tuning.m_frequency > m_lofSwitch);
2514  case kTypeBandstacked:
2515  return IsHorizontal(tuning);
2516  default:
2517  return false;
2518  }
2519 
2520  return false;
2521 }
2522 
2528 bool DiSEqCDevLNB::IsHorizontal(const DTVMultiplex &tuning) const
2529 {
2530  QString pol = tuning.m_polarity.toString().toLower();
2531  return (pol == "h" || pol == "l") ^ IsPolarityInverted();
2532 }
2533 
2541  const DiSEqCDevSettings& /*settings*/, const DTVMultiplex &tuning) const
2542 {
2543  uint64_t abs_freq = tuning.m_frequency;
2544  uint lof = (IsHighBand(tuning)) ? m_lofHi : m_lofLo;
2545 
2546  return (lof > abs_freq) ? (lof - abs_freq) : (abs_freq - lof);
2547 }
DiSEqCDevSwitch::SwitchTypeToString
static QString SwitchTypeToString(dvbdev_switch_t type)
Definition: diseqc.h:270
DiSEqCDevDevice::m_ordinal
uint m_ordinal
Definition: diseqc.h:210
DISEQC_POWER_ON_WAIT
#define DISEQC_POWER_ON_WAIT
Definition: diseqc.cpp:40
DTVMultiplex::m_frequency
uint64_t m_frequency
Definition: dtvmultiplex.h:94
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:204
DiSEqCDevRotor::IsCommandNeeded
bool IsCommandNeeded(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Determines if this device or any child will be sending a command for the given configuration chain.
Definition: diseqc.cpp:1743
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
DiSEqCDevTree::~DiSEqCDevTree
~DiSEqCDevTree()
Definition: diseqc.cpp:296
DiSEqCDevRotor::kTypeDiSEqC_1_2
@ kTypeDiSEqC_1_2
Definition: diseqc.h:316
DTVMultiplex
Definition: dtvmultiplex.h:25
DiSEqCDevDevice::GetChildCount
virtual uint GetChildCount(void) const
Retrieves the proper number of children for this node.
Definition: diseqc.h:177
DISEQC_CMD_GOTO_POS
#define DISEQC_CMD_GOTO_POS
Definition: diseqc.cpp:80
DiSEqCDevLNB::Store
bool Store(void) const override
Stores this device to the database.
Definition: diseqc.cpp:2438
DiSEqCDevTree::IsInNeedOfConf
bool IsInNeedOfConf(void) const
Definition: diseqc.cpp:830
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:72
DiSEqCDevSwitch::SwitchTypeFromString
static dvbdev_switch_t SwitchTypeFromString(const QString &type)
Definition: diseqc.h:272
root
QDomElement root
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:656
DiSEqCDevDevice::FindDevice
DiSEqCDevDevice * FindDevice(uint dev_id)
Returns a device by ID.
Definition: diseqc.cpp:871
DiSEqCDevDevice::kTypeRotor
@ kTypeRotor
Definition: diseqc.h:156
copy
long long copy(QFile &dst, QFile &src, uint block_size)
Copies src file to dst file.
Definition: mythmiscutil.cpp:309
DiSEqCDevSCR::GetIntermediateFrequency
uint32_t GetIntermediateFrequency(uint32_t frequency) const
Definition: diseqc.cpp:2233
DiSEqCDevSwitch::kSwitchTypeTable
static const TypeTableVec kSwitchTypeTable
Definition: diseqc.h:299
DiSEqCDevSettings::GetValue
double GetValue(uint devid) const
Retrieves a value from this configuration chain by device id.
Definition: diseqc.cpp:199
DiSEqCDevRotor::~DiSEqCDevRotor
~DiSEqCDevRotor() override
Definition: diseqc.cpp:1694
LOC
#define LOC
Definition: diseqc.cpp:88
DiSEqCDevLNB::LNBTypeFromString
static dvbdev_lnb_t LNBTypeFromString(const QString &type)
Definition: diseqc.h:488
DiSEqCDevRotor
Rotor class.
Definition: diseqc.h:303
mythdb.h
DiSEqCDevRotor::kTypeDiSEqC_1_3
@ kTypeDiSEqC_1_3
Definition: diseqc.h:316
DiSEqCDevDevice::SetDeviceID
void SetDeviceID(uint devid) const
Definition: diseqc.h:203
DISEQC_FRM
#define DISEQC_FRM
Definition: diseqc.cpp:47
TO_DEC
#define TO_DEC
Definition: diseqc.cpp:84
DiSEqCDevSCR::GetVoltage
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
Definition: diseqc.cpp:2227
set_tone
static bool set_tone(int fd, fe_sec_tone_mode tone)
Definition: diseqc.cpp:1429
DiSEqCDevTree::m_delete
std::vector< uint > m_delete
Definition: diseqc.h:134
DiSEqCDevSwitch::SetChild
bool SetChild(uint ordinal, DiSEqCDevDevice *device) override
Changes the nth child of this node.
Definition: diseqc.cpp:1179
DiSEqCDevTree::m_fdFrontend
int m_fdFrontend
Definition: diseqc.h:130
DiSEqCDevLNB::kLNBTypeTable
static const TypeTableVec kLNBTypeTable
Definition: diseqc.h:501
DiSEqCDevDevice::m_tree
DiSEqCDevTree & m_tree
Definition: diseqc.h:208
DiSEqCDevTree::SendCommand
bool SendCommand(uint adr, uint cmd, uint repeats, cmd_vec_t &data) const
Definition: diseqc.cpp:669
diseqc.h
EPS
#define EPS
Definition: diseqc.cpp:86
DiSEqCDevSettings::SetValue
void SetValue(uint devid, double value)
Sets a value for this configuration chain by device id.
Definition: diseqc.cpp:214
DiSEqCDevDevice::GetDescription
QString GetDescription(void) const
Definition: diseqc.h:175
MSqlQuery::lastInsertId
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:888
DiSEqCDevSettings::m_config
uint_to_dbl_t m_config
Definition: diseqc.h:47
DiSEqCDevSCR::SendCommand
bool SendCommand(uint cmd, uint repeats, cmd_vec_t &data) const
Definition: diseqc.cpp:2208
DiSEqCDevTree::Execute
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning)
Applies settings to the entire tree.
Definition: diseqc.cpp:506
DISEQC_ADR_SW_ALL
#define DISEQC_ADR_SW_ALL
Definition: diseqc.cpp:53
DiSEqCDevDevice::kTypeSCR
@ kTypeSCR
Definition: diseqc.h:157
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
arg
arg(title).arg(filename).arg(doDelete))
DiSEqCDevRotor::m_moveTime
double m_moveTime
Definition: diseqc.h:374
DiSEqCDevRotor::RotorTypeToString
static QString RotorTypeToString(dvbdev_rotor_t type)
Definition: diseqc.h:345
DiSEqCDevSwitch::GetChild
DiSEqCDevDevice * GetChild(uint ordinal) override
Retrieves the nth child of this node.
Definition: diseqc.cpp:1171
DiSEqCDevRotor::SetPosMap
void SetPosMap(const uint_to_dbl_t &posmap)
Definition: diseqc.cpp:2003
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
DiSEqCDevSwitch::m_numPorts
uint m_numPorts
Definition: diseqc.h:293
DiSEqCDevTree::SetTone
bool SetTone(bool on) const
Definition: diseqc.cpp:477
DiSEqCDevSwitch::Execute
bool Execute(const DiSEqCDevSettings &, const DTVMultiplex &) override
Applies DiSEqC settings to this node and any children.
Definition: diseqc.cpp:1076
DiSEqCDevRotor::m_child
DiSEqCDevDevice * m_child
Definition: diseqc.h:366
DiSEqCDevTrees
Static-scoped locked tree list class.
Definition: diseqc.h:62
TIMEOUT_RETRIES
#define TIMEOUT_RETRIES
Definition: diseqc.cpp:43
TIMEOUT_WAIT
#define TIMEOUT_WAIT
Definition: diseqc.cpp:44
DiSEqCDevRotor::kRotorTypeTable
static const TypeTableVec kRotorTypeTable
Definition: diseqc.h:379
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
DiSEqCDevSwitch::m_lastPos
uint m_lastPos
Definition: diseqc.h:294
DiSEqCDevLNB::kTypeBandstacked
@ kTypeBandstacked
Definition: diseqc.h:463
DiSEqCDevDevice
Represents a node in a DVB-S device network.
Definition: diseqc.h:140
DiSEqCDevDevice::GetVoltage
virtual uint GetVoltage(const DiSEqCDevSettings &, const DTVMultiplex &) const =0
Retrives the desired voltage for this config.
DiSEqCDevSCR::m_scrUserband
uint m_scrUserband
Definition: diseqc.h:437
DiSEqCDevSwitch::m_type
dvbdev_switch_t m_type
Definition: diseqc.h:291
DiSEqCDevSettings::Load
bool Load(uint card_input_id)
Loads configuration chain from DB for specified card input id.
Definition: diseqc.cpp:123
DiSEqCDevSwitch::Reset
void Reset(void) override
Resets to the last known settings for this device.
Definition: diseqc.cpp:1133
DiSEqCDevSwitch::Store
bool Store(void) const override
Stores this device to the database.
Definition: diseqc.cpp:1270
DiSEqCDevSwitch::GetPosition
int GetPosition(const DiSEqCDevSettings &settings) const
Definition: diseqc.cpp:1651
DiSEqCDevTrees::m_treesLock
QMutex m_treesLock
Definition: diseqc.h:71
DiSEqCDevRotor::m_speedLo
double m_speedLo
Definition: diseqc.h:364
DiSEqCDevSwitch::kTypeDiSEqCUncommitted
@ kTypeDiSEqCUncommitted
Definition: diseqc.h:241
dtvmultiplex.h
DiSEqCDevTree::Exists
static bool Exists(int cardid)
Check if a Diseqc device tree exists.
Definition: diseqc.cpp:388
DiSEqCDevRotor::SetChild
bool SetChild(uint ordinal, DiSEqCDevDevice *device) override
Changes the nth child of this node.
Definition: diseqc.cpp:1762
DiSEqCDevTree::Open
void Open(int fd_frontend, bool is_SCR)
Retrieve device tree.
Definition: diseqc.cpp:788
DiSEqCDevDevice::kTypeSwitch
@ kTypeSwitch
Definition: diseqc.h:155
DiSEqCDevSettings::m_inputId
uint m_inputId
current input id
Definition: diseqc.h:48
DiSEqCDevDevice::Reset
virtual void Reset(void)
Resets to the last known settings for this device.
Definition: diseqc.h:147
DiSEqCDevSwitch::ExecuteTone
bool ExecuteTone(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
Definition: diseqc.cpp:1504
DiSEqCDevTrees::~DiSEqCDevTrees
~DiSEqCDevTrees()
Definition: diseqc.cpp:251
DiSEqCDevLNB::m_lofHi
uint m_lofHi
Definition: diseqc.h:494
DiSEqCDevRotor::ExecuteRotor
bool ExecuteRotor(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, double angle)
Definition: diseqc.cpp:2012
DiSEqCDevSettings
DVB-S device settings class.
Definition: diseqc.h:37
DISEQC_FRM_REPEAT
#define DISEQC_FRM_REPEAT
Definition: diseqc.cpp:48
DiSEqCDevRotor::m_lastPosition
double m_lastPosition
Definition: diseqc.h:369
DiSEqCDevLNB::m_lofLo
uint m_lofLo
Definition: diseqc.h:495
DiSEqCDevTree::kFirstFakeDiSEqCID
static const uint kFirstFakeDiSEqCID
Definition: diseqc.h:136
DiSEqCDevDevice::GetDeviceType
dvbdev_t GetDeviceType(void) const
Definition: diseqc.h:169
DiSEqCDevRotor::GetProgress
double GetProgress(void) const
Returns an indication of rotor progress.
Definition: diseqc.cpp:1958
cmd_vec_t
std::vector< uint8_t > cmd_vec_t
Definition: diseqc.h:34
DiSEqCDevRotor::CalculateAzimuth
static double CalculateAzimuth(double angle)
Definition: diseqc.cpp:2052
DiSEqCDevSwitch::GetChildCount
uint GetChildCount(void) const override
Retrieves the proper number of children for this node.
Definition: diseqc.cpp:1166
DiSEqCDevDevice::TableToString
static QString TableToString(uint type, const TypeTableVec &table)
Definition: diseqc.cpp:92
DiSEqCDevLNB::m_lofSwitch
uint m_lofSwitch
Definition: diseqc.h:493
DiSEqCDevLNB::IsPolarityInverted
bool IsPolarityInverted(void) const
Definition: diseqc.h:476
dvbtypes.h
DiSEqCDevRotor::Store
bool Store(void) const override
Stores this device to the database.
Definition: diseqc.cpp:1877
mythlogging.h
DiSEqCDevSCR::kSCRPositionTable
static const TypeTableVec kSCRPositionTable
Definition: diseqc.h:443
GetCurTimeFloating
static double GetCurTimeFloating(void)
Definition: diseqc.cpp:1676
DiSEqCDevTree::ApplyVoltage
bool ApplyVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning)
Definition: diseqc.cpp:838
DiSEqCDevLNB::m_polInv
bool m_polInv
If a signal is circularly polarized the polarity will flip on each reflection, so antenna systems wit...
Definition: diseqc.h:499
DiSEqCDevSwitch::ExecuteMiniDiSEqC
bool ExecuteMiniDiSEqC(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
Definition: diseqc.cpp:1542
DiSEqCDevSCR::Store
bool Store(void) const override
Stores this device to the database.
Definition: diseqc.cpp:2290
DiSEqCDevDevice::TableFromString
static uint TableFromString(const QString &type, const TypeTableVec &table)
Definition: diseqc.cpp:100
DiSEqCDevTree::SetVoltage
bool SetVoltage(uint voltage)
Definition: diseqc.cpp:796
hardwareprofile.i18n.t
t
Definition: i18n.py:36
DiSEqCDevDevice::SetDeviceType
void SetDeviceType(dvbdev_t type)
Definition: diseqc.h:160
DiSEqCDevRotor::Load
bool Load(void) override
Loads this device from the database.
Definition: diseqc.cpp:1807
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
compat.h
DiSEqCDevDevice::TypeTableVec
std::vector< TypeTable > TypeTableVec
Definition: diseqc.h:214
DiSEqCDevSCR::~DiSEqCDevSCR
~DiSEqCDevSCR() override
Definition: diseqc.cpp:2111
DiSEqCDevDevice::Load
virtual bool Load(void)=0
Loads this device from the database.
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
DiSEqCDevRotor::m_posmap
dbl_to_uint_t m_posmap
Definition: diseqc.h:365
DiSEqCDevRotor::IsPositionKnown
bool IsPositionKnown(void) const
Returns true if there is reasonable confidence in the value returned by GetProgress().
Definition: diseqc.cpp:1988
send_diseqc
static bool send_diseqc(int fd, const dvb_diseqc_master_cmd cmd)
Definition: diseqc.cpp:639
DiSEqCDevTree::CreateFakeDiSEqCID
uint CreateFakeDiSEqCID(void)
Definition: diseqc.h:121
uint_to_dbl_t
QMap< uint, double > uint_to_dbl_t
Definition: diseqc.h:30
DiSEqCDevSwitch::m_lastHorizontal
uint m_lastHorizontal
Definition: diseqc.h:296
DiSEqCDevDevice::SetOrdinal
void SetOrdinal(uint ordinal)
Definition: diseqc.h:162
DiSEqCDevSCR
Unicable / SCR Class.
Definition: diseqc.h:383
DiSEqCDevDevice::dvbdev_t
dvbdev_t
Definition: diseqc.h:154
DiSEqCDevRotor::m_type
dvbdev_rotor_t m_type
Definition: diseqc.h:362
DiSEqCDevSCR::Execute
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) override
Applies DiSEqC settings to this node and any children.
Definition: diseqc.cpp:2122
DiSEqCDevDevice::m_repeat
uint m_repeat
Definition: diseqc.h:211
DiSEqCDevRotor::RotorTypeFromString
static dvbdev_rotor_t RotorTypeFromString(const QString &type)
Definition: diseqc.h:347
DISEQC_POWER_OFF_WAIT
#define DISEQC_POWER_OFF_WAIT
Definition: diseqc.cpp:39
DiSEqCDevRotor::RotationComplete
void RotationComplete(void) const
Definition: diseqc.cpp:2091
DiSEqCDevTree::Load
bool Load(const QString &device)
Loads the device tree from the database.
Definition: diseqc.cpp:306
DiSEqCDevDevice::SetParent
void SetParent(DiSEqCDevDevice *parent)
Definition: diseqc.h:161
DiSEqCDevSwitch::ExecuteLegacy
bool ExecuteLegacy(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
Definition: diseqc.cpp:1358
DiSEqCDevTree::SetRoot
void SetRoot(DiSEqCDevDevice *root)
Changes the root node of the tree.
Definition: diseqc.cpp:629
DiSEqCDevLNB
LNB Class.
Definition: diseqc.h:447
DiSEqCDevRotor::GetSelectedChild
DiSEqCDevDevice * GetSelectedChild(const DiSEqCDevSettings &setting) const override
Retrieves the selected child for this configuration, if any.
Definition: diseqc.cpp:1757
DiSEqCDevDevice::GetChild
virtual DiSEqCDevDevice * GetChild(uint)
Retrieves the nth child of this node.
Definition: diseqc.h:188
DiSEqCDevLNB::Load
bool Load(void) override
Loads this device from the database.
Definition: diseqc.cpp:2408
DiSEqCDevSwitch::IsCommandNeeded
bool IsCommandNeeded(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Determines if this device or any child will be sending a command for the given configuration chain.
Definition: diseqc.cpp:1145
DISEQC_CMD_WRITE_N1
#define DISEQC_CMD_WRITE_N1
Definition: diseqc.cpp:69
DiSEqCDevSwitch::GetSelectedChild
DiSEqCDevDevice * GetSelectedChild(const DiSEqCDevSettings &settings) const override
Retrieves the selected child for this configuration, if any.
Definition: diseqc.cpp:1156
DiSEqCDevLNB::IsHorizontal
bool IsHorizontal(const DTVMultiplex &tuning) const
Determine if horizontal polarity is active (for switchable LNBs).
Definition: diseqc.cpp:2528
DISEQC_CMD_ODU
#define DISEQC_CMD_ODU
Definition: diseqc.cpp:71
DiSEqCDevTree::GetFD
int GetFD(void) const
Definition: diseqc.h:109
DiSEqCDevRotor::Execute
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) override
Applies DiSEqC settings to this node and any children.
Definition: diseqc.cpp:1699
DiSEqCDevRotor::m_lastPosKnown
bool m_lastPosKnown
Definition: diseqc.h:375
DiSEqCDevDevice::m_parent
DiSEqCDevDevice * m_parent
Definition: diseqc.h:209
DiSEqCDevSCR::m_scrFrequency
uint m_scrFrequency
Definition: diseqc.h:438
uint
unsigned int uint
Definition: compat.h:141
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
DiSEqCDevRotor::GetPosMap
uint_to_dbl_t GetPosMap(void) const
Definition: diseqc.cpp:1993
DiSEqCDevSwitch::ExecuteVoltage
bool ExecuteVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
Definition: diseqc.cpp:1520
DiSEqCDevLNB::Execute
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) override
Applies DiSEqC settings to this node and any children.
Definition: diseqc.cpp:2385
DiSEqCDev::FindTree
static DiSEqCDevTree * FindTree(uint cardid)
Retrieve device tree.
Definition: diseqc.cpp:232
DiSEqCDev::s_trees
static DiSEqCDevTrees s_trees
Definition: diseqc.h:58
DiSEqCDevDevice::IsCommandNeeded
virtual bool IsCommandNeeded(const DiSEqCDevSettings &, const DTVMultiplex &) const
Determines if this device or any child will be sending a command for the given configuration chain.
Definition: diseqc.h:178
DiSEqCDevDevice::CreateByType
static DiSEqCDevDevice * CreateByType(DiSEqCDevTree &tree, dvbdev_t type, uint dev_id=0)
Definition: diseqc.cpp:931
DiSEqCDevSCR::SetChild
bool SetChild(uint ordinal, DiSEqCDevDevice *device) override
Changes the nth child of this node.
Definition: diseqc.cpp:2351
DiSEqCDevTree::FindDevice
DiSEqCDevDevice * FindDevice(uint dev_id)
Returns a device by ID.
Definition: diseqc.cpp:617
DISEQC_LONG_WAIT
#define DISEQC_LONG_WAIT
Definition: diseqc.cpp:38
DiSEqCDevSCR::PowerOff
bool PowerOff(void) const
Definition: diseqc.cpp:2183
DiSEqCDevTree::m_lastVoltage
uint m_lastVoltage
Definition: diseqc.h:132
DiSEqCDevDevice::kTypeLNB
@ kTypeLNB
Definition: diseqc.h:158
DiSEqCDevSwitch::Load
bool Load(void) override
Loads this device from the database.
Definition: diseqc.cpp:1209
DiSEqCDevTree::FindLNB
DiSEqCDevLNB * FindLNB(const DiSEqCDevSettings &settings)
Returns the LNB device object selected by the configuration chain.
Definition: diseqc.cpp:570
DiSEqCDevLNB::LNBTypeToString
static QString LNBTypeToString(dvbdev_lnb_t type)
Definition: diseqc.h:485
DiSEqCDevSwitch::m_children
dvbdev_vec_t m_children
Definition: diseqc.h:297
DiSEqCDevSwitch::kTypeDiSEqCCommitted
@ kTypeDiSEqCCommitted
Definition: diseqc.h:240
DiSEqCDevRotor::StartRotorPositionTracking
void StartRotorPositionTracking(double azimuth)
Definition: diseqc.cpp:2077
DiSEqCDevRotor::ExecuteUSALS
bool ExecuteUSALS(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, double angle)
Definition: diseqc.cpp:2033
DiSEqCDevSCR::m_scrPin
int m_scrPin
Definition: diseqc.h:439
set_voltage
static bool set_voltage(int fd, fe_sec_voltage volt)
Definition: diseqc.cpp:1454
DTVPolarity::toString
QString toString() const
Definition: dtvconfparserhelpers.h:630
DISEQC_ADR_ALL
#define DISEQC_ADR_ALL
Definition: diseqc.cpp:52
DiSEqCDevSwitch::kTypeMiniDiSEqC
@ kTypeMiniDiSEqC
Definition: diseqc.h:246
diseqc_bus_already_reset
bool diseqc_bus_already_reset
Definition: diseqc.cpp:90
DiSEqCDevSwitch::SetNumPorts
void SetNumPorts(uint num_ports)
Definition: diseqc.cpp:1335
DiSEqCDevSettings::Store
bool Store(uint card_input_id) const
Stores configuration chain to DB for specified card input id.
Definition: diseqc.cpp:157
DiSEqCDev::InvalidateTrees
static void InvalidateTrees(void)
Invalidate cached trees.
Definition: diseqc.cpp:240
DiSEqCDevTree::ResetDiseqc
bool ResetDiseqc(bool hard_reset, bool is_SCR)
Resets the DiSEqC bus.
Definition: diseqc.cpp:739
DISEQC_CMD_GOTO_X
#define DISEQC_CMD_GOTO_X
Definition: diseqc.cpp:81
DiSEqCDevDevice::~DiSEqCDevDevice
virtual ~DiSEqCDevDevice()
Definition: diseqc.cpp:865
DiSEqCDevDevice::kDvbdevLookup
static const TypeTableVec kDvbdevLookup
Definition: diseqc.h:220
DiSEqCDevRotor::m_lastAzimuth
double m_lastAzimuth
Definition: diseqc.h:376
DiSEqCDevSwitch::kTypeTone
@ kTypeTone
Definition: diseqc.h:239
DISEQC_CMD_RESET
#define DISEQC_CMD_RESET
Definition: diseqc.cpp:66
DiSEqCDevTree::FindRotor
DiSEqCDevRotor * FindRotor(const DiSEqCDevSettings &settings, uint index=0)
Returns the nth rotor device object in the tree.
Definition: diseqc.cpp:547
mythcorecontext.h
DiSEqCDevSwitch::kTypeLegacySW64
@ kTypeLegacySW64
Definition: diseqc.h:244
DiSEqCDevRotor::GetVoltage
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
Definition: diseqc.cpp:1790
DiSEqCDevSwitch::kTypeLegacySW42
@ kTypeLegacySW42
Definition: diseqc.h:243
DiSEqCDevDevice::CreateById
static DiSEqCDevDevice * CreateById(DiSEqCDevTree &tree, uint devid)
Definition: diseqc.cpp:895
DiSEqCDevSwitch::kTypeLegacySW21
@ kTypeLegacySW21
Definition: diseqc.h:242
DiSEqCDevSCR::m_child
DiSEqCDevDevice * m_child
Definition: diseqc.h:441
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
DiSEqCDevSwitch::kTypeVoltage
@ kTypeVoltage
Definition: diseqc.h:245
DiSEqCDevRotor::m_reset
bool m_reset
Definition: diseqc.h:371
DiSEqCDevTree::m_root
DiSEqCDevDevice * m_root
Definition: diseqc.h:131
DiSEqCDevDevice::DevTypeFromString
static dvbdev_t DevTypeFromString(const QString &type)
Definition: diseqc.h:193
DiSEqCDevSwitch::~DiSEqCDevSwitch
~DiSEqCDevSwitch() override
Definition: diseqc.cpp:1070
DiSEqCDevTree::FindSCR
DiSEqCDevSCR * FindSCR(const DiSEqCDevSettings &settings)
Returns the SCR device object selected by the configuration chain.
Definition: diseqc.cpp:593
DiSEqCDevDevice::IsRealDeviceID
bool IsRealDeviceID(void) const
Definition: diseqc.h:171
DiSEqCDevSwitch::ExecuteDiseqc
bool ExecuteDiseqc(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
Definition: diseqc.cpp:1604
DiSEqCDevRotor::Reset
void Reset(void) override
Resets to the last known settings for this device.
Definition: diseqc.cpp:1736
DiSEqCDevRotor::GetApproxAzimuth
double GetApproxAzimuth(void) const
Definition: diseqc.cpp:2068
mini_diseqc
static bool mini_diseqc(int fd, fe_sec_mini_cmd cmd)
Definition: diseqc.cpp:1479
DiSEqCDevRotor::IsMoving
bool IsMoving(const DiSEqCDevSettings &settings) const
Definition: diseqc.cpp:1781
DiSEqCDevSCR::Load
bool Load(void) override
Loads this device from the database.
Definition: diseqc.cpp:2239
DiSEqCDevTree
DVB-S device tree class.
Definition: diseqc.h:75
DiSEqCDevDevice::Store
virtual bool Store(void) const =0
Stores this device to the database.
DiSEqCDevDevice::SetDescription
void SetDescription(const QString &desc)
Definition: diseqc.h:163
DiSEqCDevLNB::IsHighBand
bool IsHighBand(const DTVMultiplex &tuning) const
Determine if the high frequency band is active (for switchable LNBs).
Definition: diseqc.cpp:2508
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:859
DTVMultiplex::m_polarity
DTVPolarity m_polarity
Definition: dtvmultiplex.h:104
DiSEqCDevTree::Store
bool Store(uint cardid, const QString &device="")
Stores the device tree to the database.
Definition: diseqc.cpp:417
DiSEqCDevTrees::FindTree
DiSEqCDevTree * FindTree(uint cardid)
Retrieve device tree.
Definition: diseqc.cpp:260
DiSEqCDevDevice::GetDeviceID
uint GetDeviceID(void) const
Definition: diseqc.h:170
DiSEqCDevLNB::kTypeVoltageAndToneControl
@ kTypeVoltageAndToneControl
Definition: diseqc.h:462
DiSEqCDevSwitch::DiSEqCDevSwitch
DiSEqCDevSwitch(DiSEqCDevTree &tree, uint devid)
Definition: diseqc.cpp:1059
TO_RADS
#define TO_RADS
Definition: diseqc.cpp:83
DISEQC_ADR_POS_AZ
#define DISEQC_ADR_POS_AZ
Definition: diseqc.cpp:62
DiSEqCDevSCR::Reset
void Reset(void) override
Resets to the last known settings for this device.
Definition: diseqc.cpp:2116
DiSEqCDevTree::GetVoltage
uint GetVoltage(void) const
Definition: diseqc.h:116
DiSEqCDevLNB::m_type
dvbdev_lnb_t m_type
Definition: diseqc.h:492
DiSEqCDevDevice::GetSelectedChild
virtual DiSEqCDevDevice * GetSelectedChild(const DiSEqCDevSettings &) const
Retrieves the selected child for this configuration, if any.
Definition: diseqc.h:186
DiSEqCDevDevice::Execute
virtual bool Execute(const DiSEqCDevSettings &, const DTVMultiplex &)=0
Applies DiSEqC settings to this node and any children.
DiSEqCDevRotor::m_speedHi
double m_speedHi
Definition: diseqc.h:363
DiSEqCDevSCR::dvbdev_pos_t
dvbdev_pos_t
Definition: diseqc.h:398
DiSEqCDevTrees::m_trees
cardid_to_diseqc_tree_t m_trees
Definition: diseqc.h:70
DiSEqCDevRotor::m_desiredAzimuth
double m_desiredAzimuth
Definition: diseqc.h:370
DISEQC_SHORT_WAIT
#define DISEQC_SHORT_WAIT
Definition: diseqc.cpp:37
DiSEqCDevTrees::InvalidateTrees
void InvalidateTrees(void)
Invalidate cached trees.
Definition: diseqc.cpp:278
query
MSqlQuery query(MSqlQuery::InitCon())
DiSEqCDevSwitch::GetVoltage
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
Definition: diseqc.cpp:1197
DiSEqCDevLNB::GetVoltage
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
Definition: diseqc.cpp:2394
DiSEqCDevTree::Reset
void Reset(void)
Reset state of nodes in tree, forcing updates on the next Execute command.
Definition: diseqc.cpp:533
DiSEqCDevSwitch::m_address
uint m_address
Definition: diseqc.h:292
DISEQC_CMD_WRITE_N0
#define DISEQC_CMD_WRITE_N0
Definition: diseqc.cpp:68
DiSEqCDevLNB::kTypeVoltageControl
@ kTypeVoltageControl
Definition: diseqc.h:461
DiSEqCDevSwitch::m_lastHighBand
uint m_lastHighBand
Definition: diseqc.h:295
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:919
DiSEqCDevLNB::GetIntermediateFrequency
uint32_t GetIntermediateFrequency(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const
Calculate proper intermediate frequency for the given settings and tuning parameters.
Definition: diseqc.cpp:2540
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808
DiSEqCDevTree::AddDeferredDelete
void AddDeferredDelete(uint dev_id)
Definition: diseqc.h:120
DiSEqCDevSwitch
Switch class, including tone, legacy and DiSEqC switches.
Definition: diseqc.h:224
DiSEqCDevSwitch::ShouldSwitch
bool ShouldSwitch(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const
Definition: diseqc.cpp:1561