16#include "libmythbase/mythconfig.h"
20#if CONFIG_FIREWIRE_OSX
25#define LOC QString("FireDev(%1): ").arg(guid_to_string(m_guid))
27static void fw_init(QMap<uint64_t,QString> &id_to_model);
33 m_guid(guid), m_subunitid(subunitid),
47 LOG(VB_RECORD, LOG_INFO,
LOC +
48 QString(
"AddListener() %1").arg(
m_listeners.size()));
60 LOG(VB_RECORD, LOG_INFO,
LOC +
61 QString(
"RemoveListener() %1").arg(
m_listeners.size()));
66 QMutexLocker locker(&
m_lock);
68 std::vector<uint8_t> cmd;
69 std::vector<uint8_t> ret;
76 QString cmdStr = (on) ?
"on" :
"off";
77 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"Powering %1").arg(cmdStr));
81 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Power on cmd failed (no response)");
87 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Power %1 failed").arg(cmdStr));
92 LOG(VB_RECORD, LOG_INFO,
LOC +
93 QString(
"Power %1 cmd sent successfully").arg(cmdStr));
100 QMutexLocker locker(&
m_lock);
102 std::vector<uint8_t> cmd;
103 std::vector<uint8_t> ret;
110 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Requesting STB Power State");
114 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Power cmd failed (no response)");
118 QString loc =
LOC +
"STB Power State: ";
122 LOG(VB_CHANNEL, LOG_INFO, loc +
"Query not implemented");
129 LOG(VB_CHANNEL, LOG_INFO, loc +
"On");
135 LOG(VB_CHANNEL, LOG_INFO, loc +
"Off");
139 LOG(VB_GENERAL, LOG_ERR,
LOC +
"STB Power State: Unknown Response");
147 LOG(VB_CHANNEL, LOG_INFO, QString(
"SetChannel(model %1, alt %2, chan %3)")
148 .arg(panel_model).arg(alt_method).arg(channel));
150 QMutexLocker locker(&
m_lock);
151 LOG(VB_CHANNEL, LOG_INFO,
"SetChannel() -- locked");
155 LOG(VB_GENERAL, LOG_ERR,
LOC +
156 QString(
"Model: '%1' ").arg(panel_model) +
157 "is not supported by internal channel changer.");
161 std::array<uint,3> digit {
162 (channel % 1000) / 100,
163 (channel % 100) / 10,
169 LOG(VB_GENERAL, LOG_ERR,
LOC +
170 "SetChannel: Extended subunits are not supported.");
175 std::vector<uint8_t> cmd;
176 std::vector<uint8_t> ret;
178 if ((panel_model.toUpper() ==
"SA GENERIC") ||
179 (panel_model.toUpper() ==
"SA4200HD") ||
180 (panel_model.toUpper() ==
"SA4250HDC"))
182 if (panel_model.toUpper() ==
"SA4250HDC")
184 LOG(VB_GENERAL, LOG_ERR,
LOC +
185 "The Scientific Atlanta 4250 HDC is not supported "
186 "\n\t\t\tby any MythTV Firewire channel changer."
187 "At the moment you must use an IR blaster.");
196 cmd.push_back((channel>>8) & 0x0f);
197 cmd.push_back(channel & 0xff);
212 if (!press_ok && !release_ok)
214 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Tuning failed");
224 bool is_mot = ((panel_model.startsWith(
"DCT-", Qt::CaseInsensitive)) ||
225 (panel_model.startsWith(
"DCH-", Qt::CaseInsensitive)) ||
226 (panel_model.startsWith(
"DCX-", Qt::CaseInsensitive)) ||
227 (panel_model.startsWith(
"QIP-", Qt::CaseInsensitive)) ||
228 (panel_model.startsWith(
"MOTO", Qt::CaseInsensitive)) ||
229 (panel_model.startsWith(
"PACE-", Qt::CaseInsensitive)));
231 if (is_mot && !alt_method)
248 std::this_thread::sleep_for(500ms);
255 if (is_mot && alt_method)
263 cmd.push_back((channel>>8) & 0x0f);
264 cmd.push_back(channel & 0xff);
275 if (panel_model.toUpper() ==
"SA3250HD")
283 cmd.push_back(0x30 | digit[2]);
284 cmd.push_back(0x30 | digit[1]);
285 cmd.push_back(0x30 | digit[0]);
291 cmd[5] = 0x30 | digit[0];
292 cmd[6] = 0x30 | digit[1];
293 cmd[7] = 0x30 | digit[2];
306 const unsigned char *data,
uint dataSize)
309 ((data[1] & 0x1f) == 0) && (data[2] == 0))
315 listener->AddData(data, dataSize);
323 LOG(VB_GENERAL, LOG_INFO, QString(
"SetLastChannel(%1): cleared: %2")
337 LOG(VB_RECORD, LOG_DEBUG,
LOC +
338 QString(
"ProcessPATPacket: CRC 0x%1 cleared: %2")
344 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't handle large PAT's");
354 QString ret =
s_idToModel[(((uint64_t) vendor_id) << 32) | model_id];
357 return "MOTO GENERIC";
363 std::vector<AVCInfo> list;
365#if CONFIG_FIREWIRE_LINUX
367#elif CONFIG_FIREWIRE_OSX
374 info.m_guid = 0x0016928a7b600001ULL;
376 info.m_vendorid = 0x000014f8;
377 info.m_modelid = 0x00001072;
378 info.m_firmware_revision = 0x0;
379 info.m_product_name =
"Explorer 4200 HD";
380 list.push_back(
info);
382 info.m_guid = 0xff2145a850e39810ULL;
384 info.m_vendorid = 0x000014f8;
385 info.m_modelid = 0x00000be0;
386 info.m_firmware_revision = 0x0;
387 info.m_product_name =
"Explorer 3250 HD";
388 list.push_back(
info);
394static void fw_init(QMap<uint64_t,QString> &id_to_model)
396 const std::array<const uint64_t,16> sa_vendor_ids
398 0x0a73, 0x0f21, 0x11e6, 0x14f8, 0x1692, 0x1868,
399 0x1947, 0x1ac3, 0x1bd7, 0x1cea, 0x1e6b, 0x21be,
400 0x223a, 0x22ce, 0x23be, 0x252e,
403 for (uint64_t vendor_id : sa_vendor_ids)
405 id_to_model[vendor_id << 32 | 0x0be0] =
"SA3250HD";
406 id_to_model[vendor_id << 32 | 0x1072] =
"SA4200HD";
407 id_to_model[vendor_id << 32 | 0x10cc] =
"SA4250HDC";
408 id_to_model[vendor_id << 32 | 0x22ce] =
"SA8300HD";
411 const std::array<uint64_t,59> motorola_vendor_ids
414 0x1c11, 0x1cfb, 0x1fc4, 0x23a3, 0x23ee, 0x25f1,
415 0xfa01, 0x25f1, 0x25f2, 0xcc7d37, 0x946269, 0x6455b1,
425 0x0ce5, 0x0e5c, 0x1225, 0x0f9f, 0x1180,
426 0x12c9, 0x11ae, 0x152f, 0x14e8, 0x16b5, 0x1371,
427 0x19a6, 0x1aad, 0x0b06, 0x195e, 0x10dc,
437 0x04db, 0x0406, 0x0ce5, 0x111a, 0x1225, 0x1404,
438 0x1626, 0x18c0, 0x1ade, 0x1cfb, 0x2040, 0x2180,
439 0x2210, 0x230b, 0x2375, 0x2395, 0x23a2, 0x23ed,
440 0x23ee, 0x23a0, 0x23a1,
443 for (uint64_t vendor_id : motorola_vendor_ids)
445 id_to_model[vendor_id << 32 | 0xf740] =
"DCX-3200";
446 id_to_model[vendor_id << 32 | 0xf804] =
"DCX-3200";
447 id_to_model[vendor_id << 32 | 0xfa03] =
"DCX-3200";
448 id_to_model[vendor_id << 32 | 0xfa05] =
"DCX-3200";
449 id_to_model[vendor_id << 32 | 0xfa07] =
"DCX-3200";
450 id_to_model[vendor_id << 32 | 0x24a1] =
"DCX-3200";
451 id_to_model[vendor_id << 32 | 0x2322] =
"DCX-3200";
452 id_to_model[vendor_id << 32 | 0xea05] =
"DCX-3432";
453 id_to_model[vendor_id << 32 | 0xd330] =
"DCH-3200";
454 id_to_model[vendor_id << 32 | 0xb630] =
"DCH-3416";
455 id_to_model[vendor_id << 32 | 0x34cb] =
"DCT-3412";
456 id_to_model[vendor_id << 32 | 0x346b] =
"DCT-3416";
457 id_to_model[vendor_id << 32 | 0xb630] =
"DCT-3416";
458 id_to_model[vendor_id << 32 | 0x6200] =
"DCT-6200";
459 id_to_model[vendor_id << 32 | 0x620a] =
"DCT-6200";
460 id_to_model[vendor_id << 32 | 0x64ca] =
"DCT-6212";
461 id_to_model[vendor_id << 32 | 0x64cb] =
"DCT-6212";
462 id_to_model[vendor_id << 32 | 0x646b] =
"DCT-6216";
463 id_to_model[vendor_id << 32 | 0x8100] =
"QIP-7100";
464 id_to_model[vendor_id << 32 | 0x7100] =
"QIP-6200";
465 id_to_model[vendor_id << 32 | 0x0001] =
"QIP-7100";
468 const std::array<const uint64_t,2> pace_vendor_ids
474 for (uint64_t vendor_id : pace_vendor_ids)
476 id_to_model[vendor_id << 32 | 0x10551] =
"PACE-550";
477 id_to_model[vendor_id << 32 | 0x10755] =
"PACE-779";
483 QString model = panel_model.toUpper();
484 return ((model ==
"DCH-3200") ||
485 (model ==
"DCH-3416") ||
486 (model ==
"DCT-3412") ||
487 (model ==
"DCT-3416") ||
488 (model ==
"DCT-6200") ||
489 (model ==
"DCT-6212") ||
490 (model ==
"DCT-6216") ||
491 (model ==
"DCX-3200") ||
492 (model ==
"SA3250HD") ||
493 (model ==
"SA4200HD") ||
494 (model ==
"SA4250HDC") ||
495 (model ==
"SA8300HD") ||
496 (model ==
"PACE-550") ||
497 (model ==
"PACE-779") ||
498 (model ==
"QIP-6200") ||
499 (model ==
"QIP-7100") ||
500 (model ==
"SA GENERIC") ||
501 (model ==
"MOTO GENERIC"));
static std::vector< AVCInfo > GetSTBList(void)
virtual void AddListener(TSDataListener *listener)
void ProcessPATPacket(const TSPacket &tspacket)
static QMap< uint64_t, QString > s_idToModel
Vendor ID + Model ID to FirewireDevice STB model string.
virtual void RemoveListener(TSDataListener *listener)
void SetLastChannel(uint channel)
static QMutex s_staticLock
FirewireDevice(uint64_t guid, uint subunitid, uint speed)
virtual PowerState GetPowerState(void)
static std::vector< AVCInfo > GetSTBList(void)
std::vector< TSDataListener * > m_listeners
virtual bool SendAVCCommand(const std::vector< uint8_t > &cmd, std::vector< uint8_t > &result, int retry_cnt)=0
virtual bool SetChannel(const QString &panel_model, uint alt_method, uint channel)
static bool IsSTBSupported(const QString &model)
@ kAVCPanelKeyTuneFunction
static QString GetModelName(uint vendor_id, uint model_id)
virtual bool SetPowerState(bool on)
virtual void BroadcastToListeners(const unsigned char *data, uint dataSize)
@ kAVCResponseImplemented
@ kAVCStatusInquiryCommand
static std::vector< AVCInfo > GetSTBList(void)
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Used to access the data of a Transport Stream packet.
static constexpr unsigned int kSize
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
#define LOC
FirewireDevice Copyright (c) 2005 by Jim Westfall Distributed as part of MythTV under GPL v2 and late...
static void fw_init(QMap< uint64_t, QString > &id_to_model)
static const iso6937table * d
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static constexpr uint8_t SYNC_BYTE