12 #include <sys/select.h>
13 #include <sys/ioctl.h>
17 #include <QCoreApplication>
18 #include <QRegularExpression>
32 #define LOC QString("CetonSH[%1](%2): ").arg(m_inputId).arg(m_device)
44 QString devkey = devname.toUpper();
46 QMap<QString,CetonStreamHandler*>::iterator it =
s_handlers.find(devkey);
55 LOG(VB_RECORD, LOG_INFO,
56 QString(
"CetonSH[%1]: Creating new stream handler %2 for %3")
57 .arg(QString::number(inputid), devkey, devname));
63 LOG(VB_RECORD, LOG_INFO,
64 QString(
"CetonSH[%1]: Using existing stream handler %2 for %3")
65 .arg(QString::number(inputid), devkey, devname) +
66 QString(
" (%1 in use)").arg(rcount));
82 QMap<QString,CetonStreamHandler*>::iterator it =
s_handlers.find(devname);
93 LOG(VB_RECORD, LOG_INFO, QString(
"CetonSH[%1]: Closing handler for %2")
94 .arg(inputid).arg(devname));
101 LOG(VB_GENERAL, LOG_ERR,
102 QString(
"CetonSH[%1] Error: Couldn't find handler for %2")
103 .arg(inputid).arg(devname));
112 "", 0,
"", 0), inputid)
116 QStringList parts = device.split(
"-");
117 if (parts.size() != 2)
119 LOG(VB_GENERAL, LOG_ERR,
LOC +
120 QString(
"Invalid device id %1").arg(
m_device));
125 QStringList tuner_parts = parts.at(1).split(
".");
126 if (tuner_parts.size() == 2)
128 m_card = tuner_parts.at(0).toUInt();
129 m_tuner = tuner_parts.at(1).toUInt();
133 LOG(VB_GENERAL, LOG_ERR,
LOC +
134 QString(
"Invalid device id %1").arg(
m_device));
138 if (
GetVar(
"diag",
"Host_IP_Address") ==
"")
140 LOG(VB_GENERAL, LOG_ERR,
LOC +
141 "Ceton tuner does not seem to be available at IP");
146 QString url = QString(
"rtsp://%1:%2/cetonmpeg%3")
153 QString cardstatus =
GetVar(
"cas",
"CardStatus");
158 QString sernum =
GetVar(
"diag",
"Host_Serial_Number");
159 QString firmware_ver =
GetVar(
"diag",
"Host_Firmware");
160 QString hardware_ver =
GetVar(
"diag",
"Hardware_Revision");
162 LOG(VB_RECORD, LOG_INFO,
LOC +
163 QString(
"Ceton device %1 initialized. SN: %2, "
164 "Firmware ver. %3, Hardware ver. %4")
165 .arg(
m_ipAddress, sernum, firmware_ver, hardware_ver));
169 QString brand =
GetVar(
"cas",
"CardManufacturer");
170 QString
auth =
GetVar(
"cas",
"CardAuthorization");
172 LOG(VB_RECORD, LOG_INFO,
LOC +
173 QString(
"Cable card installed (%1) - %2").arg(brand,
auth));
177 LOG(VB_RECORD, LOG_INFO,
LOC +
178 "Cable card NOT installed (operating in QAM tuner mode)");
214 LOG(VB_RECORD, LOG_INFO,
LOC +
215 "Ignoring request - video streaming active");
233 uint prog =
GetVar(
"mux",
"ProgramNumber").toUInt();
236 LOG(VB_RECORD, LOG_WARNING,
LOC +
237 "VerifyTuning detected program = 0");
243 uint frequency =
GetVar(
"tuner",
"Frequency").toUInt();
246 LOG(VB_RECORD, LOG_WARNING,
LOC +
247 "VerifyTuning detected wrong frequency");
251 QString modulation =
GetVar(
"tuner",
"Modulation");
254 LOG(VB_RECORD, LOG_WARNING,
LOC +
255 "VerifyTuning detected wrong modulation");
259 uint program =
GetVar(
"mux",
"ProgramNumber").toUInt();
262 LOG(VB_RECORD, LOG_WARNING,
LOC +
263 "VerifyTuning detected wrong program");
268 QString carrier_lock =
GetVar(
"tuner",
"CarrierLock");
269 if (carrier_lock !=
"1")
271 LOG(VB_RECORD, LOG_WARNING,
LOC +
272 "VerifyTuning detected no carrier lock");
276 QString pcr_lock =
GetVar(
"tuner",
"PCRLock");
279 LOG(VB_RECORD, LOG_WARNING,
LOC +
280 "VerifyTuning detected no PCR lock");
312 uint frequency,
const QString &modulation)
314 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TuneFrequency(%1, %2)")
315 .arg(frequency).arg(modulation));
317 if (frequency >= 100000000)
320 QString modulation_id = (modulation ==
"qam_256") ?
"2" :
321 (modulation ==
"qam_64") ?
"0" :
322 (modulation ==
"ntsc-m") ?
"4" :
323 (modulation ==
"8vsb") ?
"6" :
325 if (modulation_id ==
"")
332 params.addQueryItem(
"instance_id", QString::number(
m_tuner));
333 params.addQueryItem(
"frequency", QString::number(frequency));
334 params.addQueryItem(
"modulation",modulation_id);
335 params.addQueryItem(
"tuner",
"1");
336 params.addQueryItem(
"demod",
"1");
337 params.addQueryItem(
"rst_chnl",
"0");
338 params.addQueryItem(
"force_tune",
"0");
343 "POST",
"/tune_request.cgi", params, response, status);
347 LOG(VB_GENERAL, LOG_ERR,
LOC +
348 QString(
"TuneFrequency() - HTTP status = %1 - response = %2")
349 .arg(status).arg(response));
357 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TuneProgram(%1)").arg(program));
360 if (!program_list.contains(QString::number(program)))
362 LOG(VB_GENERAL, LOG_ERR,
LOC +
363 QString(
"TuneProgram(%1) - Requested program not in the program list")
372 params.addQueryItem(
"instance_id", QString::number(
m_tuner));
373 params.addQueryItem(
"program", QString::number(program));
378 "POST",
"/program_request.cgi", params, response, status);
382 LOG(VB_GENERAL, LOG_ERR,
LOC +
383 QString(
"TuneProgram() - HTTP status = %1 - response = %2")
384 .arg(status).arg(response));
392 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"PerformTuneVChannel(%1)")
396 params.addQueryItem(
"instance_id", QString::number(
m_tuner));
397 params.addQueryItem(
"channel", vchannel);
402 "POST",
"/channel_request.cgi", params, response, status);
406 LOG(VB_GENERAL, LOG_ERR,
LOC +
407 QString(
"PerformTuneVChannel() - HTTP status = %1 - response = %2")
408 .arg(status).arg(response));
417 if (
GetVar(
"cas",
"VirtualChannelNumber") == vchannel)
419 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"Not Re-Tuning channel %1")
427 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"TuneVChannel(%1)").arg(vchannel));
436 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"ClearProgramNumber()"));
438 for(
int i=0; i<50; i++)
440 if (
GetVar(
"mux",
"ProgramNumber") ==
"0")
445 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Program number failed to clear");
450 for(
int i = 1; i <= 30; i++)
452 QString prog =
GetVar(
"mux",
"ProgramNumber");
453 LOG(VB_RECORD, LOG_INFO,
LOC +
454 QString(
"GetProgramNumber() got %1 on attempt %2")
457 uint prognum = prog.toUInt();
464 LOG(VB_GENERAL, LOG_ERR,
LOC +
465 "GetProgramNumber() failed to get a non-zero program number");
471 const QString §ion,
const QString &variable)
const
473 QString loc =
LOC + QString(
"DoGetVar(%1,%2,%3,%4) - ")
477 params.addQueryItem(
"i", QString::number(
m_tuner));
478 params.addQueryItem(
"s", section);
479 params.addQueryItem(
"v", variable);
483 if (!
HttpRequest(
"GET",
"/get_var.json", params, response, status))
485 LOG(VB_GENERAL, LOG_ERR, loc +
486 QString(
"HttpRequest failed - %1").arg(response));
490 static const QRegularExpression regex {
"^\\{ \"?result\"?: \"(.*)\" \\}$"};
491 auto match = regex.match(response);
492 if (!match.hasMatch())
494 LOG(VB_GENERAL, LOG_ERR, loc +
495 QString(
"unexpected http response: -->%1<--").arg(response));
499 QString result = match.captured(1);
500 LOG(VB_RECORD, LOG_DEBUG, loc + QString(
"got: -->%1<--").arg(result));
506 QString loc =
LOC + QString(
"CetonHTTP: DoGetProgramList(%1,%2) - ")
510 params.addQueryItem(
"i", QString::number(
m_tuner));
514 if (!
HttpRequest(
"GET",
"/get_pat.json", params, response, status))
516 LOG(VB_GENERAL, LOG_ERR,
517 loc + QString(
"HttpRequest failed - %1").arg(response));
521 static const QRegularExpression regex(
522 R
"(^\{ "?length"?: \d+(, "?results"?: \[ (.*) \])? \}$)");
524 auto match = regex.match(response);
525 if (!match.hasMatch())
527 LOG(VB_GENERAL, LOG_ERR,
528 loc + QString(
"returned unexpected output: -->%1<--")
533 LOG(VB_RECORD, LOG_DEBUG, loc + QString(
"got: -->%1<--")
534 .arg(match.captured(2)));
535 return match.captured(2).split(
", ");
539 const QString &method,
const QString &script,
540 const QUrlQuery ¶ms,
541 QString &response,
uint &status_code)
const
544 auto *request =
new QNetworkRequest();
548 url.setScheme(
"http");
556 request->setAttribute(QNetworkRequest::CacheLoadControlAttribute,
557 QNetworkRequest::AlwaysNetwork);
561 url.setQuery(params);
562 request->setUrl(url);
563 if (
manager->download(request, &data))
565 response = QString(data);
570 response =
"Download failed";
574 if (
"POST" == method)
576 request->setUrl(url);
577 request->setHeader(QNetworkRequest::ContentTypeHeader,
578 "application/x-www-form-urlencoded");
579 data = params.query(QUrl::FullyEncoded).toUtf8();
582 if (
manager->post(request, &data))
584 response = QString(data);
589 response =
"Download failed";
596 response =
"Unsupported HttpRequest method";