MythTV master
satiputils.cpp
Go to the documentation of this file.
1// C++
2#include <chrono>
3#include <thread>
4
5// Qt
6#include <QString>
7#include <QStringList>
8
9// MythTV headers
12#include "libmythupnp/ssdp.h"
14
15#include "cardutil.h"
16#include "satiputils.h"
17
18#define LOC QString("SatIP: ")
19
20namespace {
21 const QString SATIP_URI = "urn:ses-com:device:SatIPServer:1";
22 constexpr std::chrono::milliseconds SEARCH_TIME_MS { 3s };
23}
24
25QStringList SatIP::probeDevices(void)
26{
27 const std::chrono::milliseconds totalSearchTime = SEARCH_TIME_MS;
28 auto seconds = duration_cast<std::chrono::seconds>(totalSearchTime);
29
30 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Using UPNP to search for Sat>IP servers (%1 secs)")
31 .arg(seconds.count()));
32
34
35 MythTimer totalTime; totalTime.start();
36 MythTimer searchTime; searchTime.start();
37
38 while (totalTime.elapsed() < totalSearchTime)
39 {
40 std::this_thread::sleep_for(25ms);
41 std::chrono::milliseconds ttl = totalSearchTime - totalTime.elapsed();
42 if (searchTime.elapsed() > 249ms && ttl > 1s)
43 {
44 auto ttl_s = duration_cast<std::chrono::seconds>(ttl);
45 LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("UPNP search %1 ms")
46 .arg(ttl_s.count()));
48 searchTime.start();
49 }
50 }
51
52 return SatIP::doUPNPsearch(true);
53}
54
55QStringList SatIP::doUPNPsearch(bool loginfo)
56{
57 QStringList result;
58
60
61 if (!satipservers)
62 {
63 LOG(VB_GENERAL, LOG_INFO, LOC + "No UPnP Sat>IP servers found");
64 return {};
65 }
66
67 int count = satipservers->Count();
68 if (count > 0)
69 {
70 if (loginfo)
71 {
72 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Found %1 possible Sat>IP servers").arg(count));
73 }
74 }
75 else
76 {
77 LOG(VB_GENERAL, LOG_ERR, LOC + "No UPnP Sat>IP servers found, but SSDPCache::Instance()->Find() != NULL");
78 }
79
80 EntryMap map;
81 satipservers->GetEntryMap(map);
82
83 for (auto *BE : std::as_const(map))
84 {
85 QString friendlyName = BE->GetFriendlyName();
86 UPnpDeviceDesc *desc = BE->GetDeviceDesc();
87
88 if (!desc)
89 {
90 LOG(VB_GENERAL, LOG_ERR, LOC + QString("GetDeviceDesc() failed for %1").arg(friendlyName));
91 continue;
92 }
93
94 QString ip = desc->m_hostUrl.host();
95 QString id = desc->m_rootDevice.GetUDN();
96 QList<NameValue> extraAttribs = desc->m_rootDevice.m_lstExtra;
97
98 for (const auto& attrib : extraAttribs)
99 {
100 if (attrib.m_sName == "satip:X_SATIPCAP")
101 {
102 QStringList caps = attrib.m_sValue.split(",");
103
104 int tuner_id = 0;
105 for (const auto& cap : std::as_const(caps))
106 {
107 QStringList tuner = cap.split("-");
108
109 if (tuner.size() != 2)
110 continue;
111
112 int num_tuners = tuner.at(1).toInt();
113 for (int i = 0; i < num_tuners; i++)
114 {
115 QString device = QString("%1 %2 %3 %4 %5")
116 .arg(id,
117 friendlyName.remove(" "),
118 ip,
119 QString::number(tuner_id),
120 tuner.at(0));
121 result << device;
122 tuner_id++;
123 if (loginfo)
124 {
125 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Found %1").arg(device));
126 }
127 }
128 }
129 }
130 }
131 BE->DecrRef();
132 }
133
134 satipservers->DecrRef();
135 satipservers = nullptr;
136
137 return result;
138}
139
140QStringList SatIP::findServers(void)
141{
142 QStringList devs;
144 if (satipservers && satipservers->Count() > 0)
145 {
146 devs = SatIP::doUPNPsearch(false);
147 }
148 else
149 {
150 devs = SatIP::probeDevices();
151 }
152 return devs;
153}
154
155QString SatIP::findDeviceIP(const QString& deviceuuid)
156{
157 QStringList devs = SatIP::findServers();
158
159 for (const auto& dev : std::as_const(devs))
160 {
161 QStringList devinfo = dev.split(" ");
162 const QString& id = devinfo.at(0);
163
164 if (id.toUpper() == deviceuuid.toUpper())
165 {
166 return devinfo.at(2);
167 }
168 }
169 return nullptr;
170}
171
173{
174 QStringList dev = deviceid.split(":");
175 if (dev.length() < 3)
176 {
178 }
179
180 QString type = dev.at(2).toUpper();
181 if (type == "DVBC")
182 {
184 }
185 if (type == "DVBC2")
186 {
187 return CardUtil::INPUT_TYPES::DVBC; // DVB-C2 is not supported yet.
188 }
189 if (type == "DVBT")
190 {
192 }
193 if (type == "DVBT2")
194 {
196 }
197 if (type == "DVBS2")
198 {
200 }
202}
203
204int SatIP::toTunerType(const QString& deviceid)
205{
206 QStringList devinfo = deviceid.split(":");
207 if (devinfo.length() < 3)
208 {
210 }
211
212 QString type = devinfo.at(2).toUpper();
213
214 if (type.startsWith("DVBC")) // DVB-C2 is not supported yet.
215 {
217 }
218 if (type == "DVBT")
219 {
221 }
222 if (type == "DVBT2")
223 {
225 }
226 if (type == "DVBS")
227 {
229 }
230 if (type == "DVBS2")
231 {
233 }
234
236}
237
239{
241 {
242 return "5";
243 }
245 {
246 return "6";
247 }
249 {
250 return "7";
251 }
253 {
254 return "8";
255 }
257 {
258 return "10";
259 }
261 {
262 return "1.712";
263 }
265 {
266 return "auto";
267 }
268 return "auto";
269}
270
271QString SatIP::freq(uint64_t freq)
272{
273 return QString::number(freq / 1000000.0, 'f', 2);
274}
275
277{
279 {
280 return "dvbs";
281 }
283 {
284 return "dvbs2";
285 }
287 {
288 return "dvbt";
289 }
291 {
292 return "dvbt2";
293 }
295 {
296 return "dvbc";
297 }
298 // Not supported yet: DVB-C2
299 return "auto";
300}
301
303{
305 {
306 return "qpsk";
307 }
309 {
310 return "8psk";
311 }
313 {
314 return "16qam";
315 }
317 {
318 return "32qam";
319 }
321 {
322 return "64qam";
323 }
325 {
326 return "128qam";
327 }
329 {
330 return "256qam";
331 }
332 return "auto";
333}
334
336{
338 {
339 return "2k";
340 }
342 {
343 return "4k";
344 }
346 {
347 return "8k";
348 }
350 {
351 return "1k";
352 }
354 {
355 return "16k";
356 }
358 {
359 return "32k";
360 }
361 return "auto";
362}
363
365{
367 {
368 return "14";
369 }
371 {
372 return "18";
373 }
375 {
376 return "116";
377 }
379 {
380 return "132";
381 }
383 {
384 return "1128";
385 }
387 {
388 return "19128";
389 }
391 {
392 return "19256";
393 }
394 return "auto";
395}
396
398{
400 {
401 return "12";
402 }
404 {
405 return "23";
406 }
408 {
409 return "34";
410 }
412 {
413 return "35";
414 }
416 {
417 return "45";
418 }
420 {
421 return "56";
422 }
424 {
425 return "67";
426 }
428 {
429 return "78";
430 }
432 {
433 return "89";
434 }
436 {
437 return "910";
438 }
439 return "auto";
440}
441
443{
445 {
446 return "0.35";
447 }
449 {
450 return "0.20";
451 }
453 {
454 return "0.25";
455 }
457 {
458 return "auto";
459 }
460 return "auto";
461}
462
464{
466 {
467 return "v";
468 }
470 {
471 return "h";
472 }
474 {
475 return "r";
476 }
478 {
479 return "l";
480 }
481 return "auto";
482}
INPUT_TYPES
all the different inputs
Definition: cardutil.h:50
static const int kTunerTypeDVBS2
static const int kTunerTypeDVBT
static const int kTunerTypeUnknown
static const int kTunerTypeDVBC
static const int kTunerTypeDVBS1
static const int kTunerTypeDVBT2
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:14
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:91
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
uint Count(void) const
Definition: ssdpcache.h:50
void GetEntryMap(EntryMap &map)
Returns a copy of the EntryMap.
Definition: ssdpcache.cpp:87
static SSDPCache * Instance()
Definition: ssdpcache.cpp:285
SSDPCacheEntries * Find(const QString &sURI)
Finds the SSDPCacheEntries in the cache, returns nullptr when absent.
Definition: ssdpcache.cpp:341
static SSDP * Instance()
Definition: ssdp.cpp:57
void PerformSearch(const QString &sST, std::chrono::seconds timeout=2s)
Send a SSDP discover multicast datagram.
Definition: ssdp.cpp:154
static QString freq(uint64_t freq)
Definition: satiputils.cpp:271
static QString bw(DTVBandwidth bw)
Definition: satiputils.cpp:238
static QString msys(DTVModulationSystem msys)
Definition: satiputils.cpp:276
static int toTunerType(const QString &deviceid)
Definition: satiputils.cpp:204
static QStringList doUPNPsearch(bool loginfo)
Definition: satiputils.cpp:55
static QString tmode(DTVTransmitMode tmode)
Definition: satiputils.cpp:335
static QString findDeviceIP(const QString &deviceuuid)
Definition: satiputils.cpp:155
static QString ro(DTVRollOff ro)
Definition: satiputils.cpp:442
static QString gi(DTVGuardInterval gi)
Definition: satiputils.cpp:364
static QString mtype(DTVModulation mtype)
Definition: satiputils.cpp:302
static QStringList findServers(void)
Definition: satiputils.cpp:140
static CardUtil::INPUT_TYPES toDVBInputType(const QString &deviceid)
Definition: satiputils.cpp:172
static QString pol(DTVPolarity pol)
Definition: satiputils.cpp:463
static QString fec(DTVCodeRate fec)
Definition: satiputils.cpp:397
static QStringList probeDevices(void)
Definition: satiputils.cpp:25
UPnpDevice m_rootDevice
Definition: upnpdevice.h:158
NameValues m_lstExtra
Definition: upnpdevice.h:122
QString GetUDN(void) const
Definition: upnpdevice.cpp:780
static const std::array< const uint32_t, 4 > freq
Definition: element.cpp:45
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
constexpr std::chrono::milliseconds SEARCH_TIME_MS
Definition: satiputils.cpp:22
#define LOC
Definition: satiputils.cpp:18
QMap< QString, DeviceLocation * > EntryMap
Key == Unique Service Name (USN)
Definition: ssdpcache.h:34