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