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