11#include <QRegularExpression>
25#define LOC QString("CetonSH[%1](%2): ").arg(m_inputId).arg(m_device)
37 QString devkey = devname.toUpper();
39 QMap<QString,CetonStreamHandler*>::iterator it =
s_handlers.find(devkey);
48 LOG(VB_RECORD, LOG_INFO,
49 QString(
"CetonSH[%1]: Creating new stream handler %2 for %3")
50 .arg(QString::number(inputid), devkey, devname));
56 LOG(VB_RECORD, LOG_INFO,
57 QString(
"CetonSH[%1]: Using existing stream handler %2 for %3")
58 .arg(QString::number(inputid), devkey, devname) +
59 QString(
" (%1 in use)").arg(rcount));
75 QMap<QString,CetonStreamHandler*>::iterator it =
s_handlers.find(devname);
86 LOG(VB_RECORD, LOG_INFO, QString(
"CetonSH[%1]: Closing handler for %2")
87 .arg(inputid).arg(devname));
94 LOG(VB_GENERAL, LOG_ERR,
95 QString(
"CetonSH[%1] Error: Couldn't find handler for %2")
96 .arg(inputid).arg(devname));
105 "", 0,
"", 0), inputid)
109 QStringList parts = device.split(
"-");
110 if (parts.size() != 2)
112 LOG(VB_GENERAL, LOG_ERR,
LOC +
113 QString(
"Invalid device id %1").arg(
m_device));
118 QStringList tuner_parts = parts.at(1).split(
".");
119 if (tuner_parts.size() == 2)
121 m_card = tuner_parts.at(0).toUInt();
122 m_tuner = tuner_parts.at(1).toUInt();
126 LOG(VB_GENERAL, LOG_ERR,
LOC +
127 QString(
"Invalid device id %1").arg(
m_device));
131 if (
GetVar(
"diag",
"Host_IP_Address") ==
"")
133 LOG(VB_GENERAL, LOG_ERR,
LOC +
134 "Ceton tuner does not seem to be available at IP");
139 QString url = QString(
"rtsp://%1:%2/cetonmpeg%3")
146 QString cardstatus =
GetVar(
"cas",
"CardStatus");
151 QString sernum =
GetVar(
"diag",
"Host_Serial_Number");
152 QString firmware_ver =
GetVar(
"diag",
"Host_Firmware");
153 QString hardware_ver =
GetVar(
"diag",
"Hardware_Revision");
155 LOG(VB_RECORD, LOG_INFO,
LOC +
156 QString(
"Ceton device %1 initialized. SN: %2, "
157 "Firmware ver. %3, Hardware ver. %4")
158 .arg(
m_ipAddress, sernum, firmware_ver, hardware_ver));
162 QString brand =
GetVar(
"cas",
"CardManufacturer");
163 QString
auth =
GetVar(
"cas",
"CardAuthorization");
165 LOG(VB_RECORD, LOG_INFO,
LOC +
166 QString(
"Cable card installed (%1) - %2").arg(brand,
auth));
170 LOG(VB_RECORD, LOG_INFO,
LOC +
171 "Cable card NOT installed (operating in QAM tuner mode)");
207 LOG(VB_RECORD, LOG_INFO,
LOC +
208 "Ignoring request - video streaming active");
226 uint prog =
GetVar(
"mux",
"ProgramNumber").toUInt();
229 LOG(VB_RECORD, LOG_WARNING,
LOC +
230 "VerifyTuning detected program = 0");
236 uint frequency =
GetVar(
"tuner",
"Frequency").toUInt();
239 LOG(VB_RECORD, LOG_WARNING,
LOC +
240 "VerifyTuning detected wrong frequency");
244 QString modulation =
GetVar(
"tuner",
"Modulation");
247 LOG(VB_RECORD, LOG_WARNING,
LOC +
248 "VerifyTuning detected wrong modulation");
252 uint program =
GetVar(
"mux",
"ProgramNumber").toUInt();
255 LOG(VB_RECORD, LOG_WARNING,
LOC +
256 "VerifyTuning detected wrong program");
261 QString carrier_lock =
GetVar(
"tuner",
"CarrierLock");
262 if (carrier_lock !=
"1")
264 LOG(VB_RECORD, LOG_WARNING,
LOC +
265 "VerifyTuning detected no carrier lock");
269 QString pcr_lock =
GetVar(
"tuner",
"PCRLock");
272 LOG(VB_RECORD, LOG_WARNING,
LOC +
273 "VerifyTuning detected no PCR lock");
305 uint frequency,
const QString &modulation)
307 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TuneFrequency(%1, %2)")
308 .arg(frequency).arg(modulation));
310 if (frequency >= 100000000)
313 QString modulation_id;
314 if (modulation ==
"qam_256")
316 else if (modulation ==
"qam_64")
318 else if (modulation ==
"ntsc-m")
320 else if (modulation ==
"8vsb")
329 params.addQueryItem(
"instance_id", QString::number(
m_tuner));
330 params.addQueryItem(
"frequency", QString::number(frequency));
331 params.addQueryItem(
"modulation",modulation_id);
332 params.addQueryItem(
"tuner",
"1");
333 params.addQueryItem(
"demod",
"1");
334 params.addQueryItem(
"rst_chnl",
"0");
335 params.addQueryItem(
"force_tune",
"0");
340 "POST",
"/tune_request.cgi", params, response, status);
344 LOG(VB_GENERAL, LOG_ERR,
LOC +
345 QString(
"TuneFrequency() - HTTP status = %1 - response = %2")
346 .arg(status).arg(response));
354 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TuneProgram(%1)").arg(program));
357 if (!program_list.contains(QString::number(program)))
359 LOG(VB_GENERAL, LOG_ERR,
LOC +
360 QString(
"TuneProgram(%1) - Requested program not in the program list")
369 params.addQueryItem(
"instance_id", QString::number(
m_tuner));
370 params.addQueryItem(
"program", QString::number(program));
375 "POST",
"/program_request.cgi", params, response, status);
379 LOG(VB_GENERAL, LOG_ERR,
LOC +
380 QString(
"TuneProgram() - HTTP status = %1 - response = %2")
381 .arg(status).arg(response));
389 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"PerformTuneVChannel(%1)")
393 params.addQueryItem(
"instance_id", QString::number(
m_tuner));
394 params.addQueryItem(
"channel", vchannel);
399 "POST",
"/channel_request.cgi", params, response, status);
403 LOG(VB_GENERAL, LOG_ERR,
LOC +
404 QString(
"PerformTuneVChannel() - HTTP status = %1 - response = %2")
405 .arg(status).arg(response));
414 if (
GetVar(
"cas",
"VirtualChannelNumber") == vchannel)
416 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"Not Re-Tuning channel %1")
424 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TuneVChannel(%1)").arg(vchannel));
433 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"ClearProgramNumber()"));
435 for(
int i=0; i<50; i++)
437 if (
GetVar(
"mux",
"ProgramNumber") ==
"0")
439 std::this_thread::sleep_for(20ms);
442 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Program number failed to clear");
447 for(
int i = 1; i <= 30; i++)
449 QString prog =
GetVar(
"mux",
"ProgramNumber");
450 LOG(VB_RECORD, LOG_INFO,
LOC +
451 QString(
"GetProgramNumber() got %1 on attempt %2")
454 uint prognum = prog.toUInt();
458 std::this_thread::sleep_for(100ms);
461 LOG(VB_GENERAL, LOG_ERR,
LOC +
462 "GetProgramNumber() failed to get a non-zero program number");
468 const QString §ion,
const QString &variable)
const
470 QString loc =
LOC + QString(
"DoGetVar(%1,%2,%3,%4) - ")
474 params.addQueryItem(
"i", QString::number(
m_tuner));
475 params.addQueryItem(
"s", section);
476 params.addQueryItem(
"v", variable);
480 if (!
HttpRequest(
"GET",
"/get_var.json", params, response, status))
482 LOG(VB_GENERAL, LOG_ERR, loc +
483 QString(
"HttpRequest failed - %1").arg(response));
487 static const QRegularExpression regex {
"^\\{ \"?result\"?: \"(.*)\" \\}$"};
488 auto match = regex.match(response);
489 if (!match.hasMatch())
491 LOG(VB_GENERAL, LOG_ERR, loc +
492 QString(
"unexpected http response: -->%1<--").arg(response));
496 QString result = match.captured(1);
497 LOG(VB_RECORD, LOG_DEBUG, loc + QString(
"got: -->%1<--").arg(result));
503 QString loc =
LOC + QString(
"CetonHTTP: DoGetProgramList(%1,%2) - ")
507 params.addQueryItem(
"i", QString::number(
m_tuner));
511 if (!
HttpRequest(
"GET",
"/get_pat.json", params, response, status))
513 LOG(VB_GENERAL, LOG_ERR,
514 loc + QString(
"HttpRequest failed - %1").arg(response));
518 static const QRegularExpression regex(
519 R
"(^\{ "?length"?: \d+(, "?results"?: \[ (.*) \])? \}$)");
521 auto match = regex.match(response);
522 if (!match.hasMatch())
524 LOG(VB_GENERAL, LOG_ERR,
525 loc + QString(
"returned unexpected output: -->%1<--")
530 LOG(VB_RECORD, LOG_DEBUG, loc + QString(
"got: -->%1<--")
531 .arg(match.captured(2)));
532 return match.captured(2).split(
", ");
536 const QString &method,
const QString &script,
537 const QUrlQuery ¶ms,
538 QString &response,
uint &status_code)
const
541 auto *request =
new QNetworkRequest();
545 url.setScheme(
"http");
553 request->setAttribute(QNetworkRequest::CacheLoadControlAttribute,
554 QNetworkRequest::AlwaysNetwork);
558 url.setQuery(params);
559 request->setUrl(url);
560 if (
manager->download(request, &data))
562 response = QString(data);
567 response =
"Download failed";
571 if (
"POST" == method)
573 request->setUrl(url);
574 request->setHeader(QNetworkRequest::ContentTypeHeader,
575 "application/x-www-form-urlencoded");
576 data = params.query(QUrl::FullyEncoded).toUtf8();
579 if (
manager->post(request, &data))
581 response = QString(data);
586 response =
"Download failed";
593 response =
"Unsupported HttpRequest method";
#define LOC
-*- Mode: c++ -*- CetonStreamHandler Copyright (c) 2011 Ronald Frazier Copyright (c) 2009-2011 Daniel...
CetonStreamHandler(const QString &device, int inputid)
bool IsCableCardInstalled() const
static void Return(CetonStreamHandler *&ref, int inputid)
static QMap< QString, uint > s_handlersRefCnt
static QMap< QString, bool > s_infoQueried
bool EnterPowerSavingMode(void)
static QMutex s_handlersLock
bool TuneVChannel(const QString &vchannel)
bool IsConnected(void) const
void ClearProgramNumber(void)
static CetonStreamHandler * Get(const QString &devname, int inputid)
bool TuneFrequency(uint frequency, const QString &modulation)
uint GetProgramNumber(void) const
bool TuneProgram(uint program)
QString GetVar(const QString §ion, const QString &variable) const
QStringList GetProgramList()
bool HttpRequest(const QString &method, const QString &script, const QUrlQuery ¶ms, QString &response, uint &status_code) const
static QMap< QString, CetonStreamHandler * > s_handlers
bool PerformTuneVChannel(const QString &vchannel)
void setObjectName(const QString &name)
StreamDataList m_streamDataList
QRecursiveMutex m_listenerLock
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static MythSystemLegacyManager * manager