Go to the documentation of this file.
42 #include <sys/ioctl.h>
44 #include <linux/dvb/ca.h>
62 #define LOC QString("DVBCam(%1): ").arg(m_device)
65 : m_device(std::move(device))
68 QByteArray dev = dvbdev.toLatin1();
69 int cafd = open(dev.constData(), O_RDWR);
74 if (ioctl(cafd, CA_GET_CAP, &caps) >= 0)
77 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ioctl CA_GET_CAP failed: " +
ENO);
99 QByteArray dev = dvbdev.toLatin1();
103 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialize CI handler");
115 LOG(VB_DVBCAM, LOG_INFO,
LOC +
"CI handler successfully initialized!");
142 pmt_list_t::iterator it;
160 if (enq->
Text() !=
nullptr)
161 LOG(VB_DVBCAM, LOG_INFO,
LOC + QString(
"CAM: Received message: %1")
169 if (
menu->TitleText() !=
nullptr)
170 LOG(VB_DVBCAM, LOG_INFO,
LOC + QString(
"CAM: Menu Title: %1")
171 .arg(
menu->TitleText()));
172 if (
menu->SubTitleText() !=
nullptr)
173 LOG(VB_DVBCAM, LOG_INFO,
LOC + QString(
"CAM: Menu SubTitle: %1")
174 .arg(
menu->SubTitleText()));
175 if (
menu->BottomText() !=
nullptr)
176 LOG(VB_DVBCAM, LOG_INFO,
LOC + QString(
"CAM: Menu BottomText: %1")
177 .arg(
menu->BottomText()));
179 for (
int i=0; i<
menu->NumEntries(); i++)
181 if (
menu->Entry(i) !=
nullptr)
182 LOG(VB_DVBCAM, LOG_INFO,
LOC + QString(
"CAM: Menu Entry: %1")
183 .arg(
menu->Entry(i)));
186 if (
menu->Selectable())
188 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"CAM: Menu is selectable");
191 if (
menu->NumEntries() > 0)
193 LOG(VB_DVBCAM, LOG_INFO,
LOC +
"CAM: Selecting first entry");
198 LOG(VB_DVBCAM, LOG_INFO,
LOC +
"CAM: Cancelling menu");
210 QList<uint> unique_sids;
211 pmt_list_t::iterator it;
220 if (unique_sids.contains(serviceId))
223 LOG(VB_DVBCAM, LOG_DEBUG,
LOC + QString(
"Service [%1]%2 duplicate, removed from pmtList")
224 .arg(inputId).arg(serviceId));
228 unique_sids.append(serviceId);
230 LOG(VB_DVBCAM, LOG_DEBUG,
LOC + QString(
"Service [%1]%2 stays in pmtList")
231 .arg(inputId).arg(serviceId));
242 if (unique_sids.contains(serviceId))
245 LOG(VB_DVBCAM, LOG_DEBUG,
LOC + QString(
"Service [%1]%2 duplicate, removed from pmtAddList")
246 .arg(inputId).arg(serviceId));
250 unique_sids.append(serviceId);
252 LOG(VB_DVBCAM, LOG_DEBUG,
LOC + QString(
"Service [%1]%2 stays in pmtAddList")
253 .arg(inputId).arg(serviceId));
261 LOG(VB_DVBCAM, LOG_INFO,
LOC +
"CiHandler needs CA_PMT");
297 for (
auto *pmt : std::as_const(
m_pmtList))
300 cplm = (count + 1 == length) ?
CPLM_LAST : cplm;
315 LOG(VB_DVBCAM, LOG_INFO,
LOC +
"CI handler thread running");
339 LOG(VB_DVBCAM, LOG_INFO,
LOC +
"CiHandler thread stopped");
346 pmt_list_t::iterator it =
m_pmtList.find(chan);
382 static std::array<const std::string,6>
cplm_info
399 bool success =
false;
407 LOG(success ? VB_DVBCAM : VB_GENERAL, LOG_ERR,
408 LOC +
"CAM supports no CA systems! " +
409 QString(
"(Slot #%1)").arg(s));
413 LOG(VB_DVBCAM, LOG_INFO,
LOC +
414 QString(
"Creating CA_PMT, ServiceID = %1")
419 LOG(VB_DVBCAM, LOG_INFO,
LOC +
420 QString(
"Sending CA_PMT with %1 to CI slot #%2")
421 .arg(QString::fromStdString(
cplm_info[cplm])).arg(s));
425 LOG(success ? VB_DVBCAM : VB_GENERAL, LOG_ERR,
426 LOC +
"CA_PMT send failed!");
439 desc_list_t::const_iterator it;
440 for (it = desc.begin(); it != desc.end(); ++it)
443 for (
auto id : casids)
448 LOG(VB_DVBCAM, LOG_INFO, QString(
"DVBCam: Adding CA descriptor: "
449 "CASID(0x%2), ECM PID(0x%3)")
475 LOG(VB_DVBCAM, LOG_INFO,
476 QString(
"DVBCam: Adding elementary stream: %1, pid(0x%2)")
const unsigned char * ProgramInfo(void) const
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
#define ENO
This can be appended to the LOG args with "+".
void AddCaDescriptor(int ca_system_id, int ca_pid, int data_len, const uint8_t *data)
uint StreamCount(void) const
virtual bool SetCaPmt(cCiCaPmt &CaPmt, int Slot)=0
std::vector< uint16_t > dvbca_vector
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
const unsigned char * StreamInfo(uint i) const
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
virtual cCiEnquiry * GetEnquiry(void)=0
uint ProgramNumber(void) const
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static std::array< const std::string, 6 > cplm_info
virtual bool Process(void)=0
uint DataSize(void) const
void SetTimeOffset(double offset_in_seconds)
static void process_desc(cCiCaPmt &capmt, const dvbca_vector &casids, const desc_list_t &desc)
virtual void SetTimeOffset(double)
QString StreamDescription(uint i, const QString &sistandard) const
Returns a better (and more expensive) string representation of type at stream index i than StreamType...
const unsigned char * Data(void) const
Abstract class providing a generic interface to tuning hardware.
virtual int NumSlots(void)=0
uint SystemID(void) const
static MythThemedMenu * menu
virtual bool NeedCaPmt(void)=0
uint StreamType(uint i) const
std::vector< const unsigned char * > desc_list_t
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
QWaitCondition m_ciHandlerWait
virtual bool HasUserIO(void)=0
cCiCaPmt CreateCAPMT(const ProgramMapTable &, const dvbca_vector &, uint)
static QString GetDeviceName(dvb_dev_type_t type, const QString &device)
uint ProgramInfoLength(void) const
void RemoveDuplicateServices(void)
void SendPMT(const ProgramMapTable &pmt, uint cplm)
MThread * m_ciHandlerThread
This is a wrapper around QThread that does several additional things.
void SetPMT(const ChannelBase *chan, const ProgramMapTable *pmt)
virtual int GetInputID(void) const
static cCiHandler * CreateCiHandler(const char *FileName)
virtual cCiMenu * GetMenu(void)=0
virtual dvbca_vector GetCaSystemIds(int Slot)=0
uint StreamInfoLength(uint i) const
uint StreamPID(uint i) const
void AddElementaryStream(int type, int pid)