#include "override.h"
#include "misc.h"
#include "log-core.h"
+#ifndef SASC
#include "FFdecsa/FFdecsa.h"
+#endif
#define IDLE_SLEEP 0 // idleTime when sleeping
#define IDLE_GETCA 200 // idleTime when waiting for ca descriptors
// -- cCaDescr -----------------------------------------------------------------
-class cCaDescr {
-private:
- unsigned char *descr;
- int len;
-public:
- cCaDescr(void);
- cCaDescr(const cCaDescr &arg);
- ~cCaDescr();
- const unsigned char *Get(int &l) const;
- void Set(const cCaDescr *d);
- void Set(const unsigned char *de, int l);
- void Clear(void);
- bool operator== (const cCaDescr &arg) const;
- void Join(const cCaDescr *cd, bool rev=false);
- cString ToString(void);
- };
-
cCaDescr::cCaDescr(void)
{
descr=0; len=0;
return str;
}
-// -- cPrgPid ------------------------------------------------------------------
-
-class cPrgPid : public cSimpleItem {
-private:
- bool proc;
-public:
- int type, pid;
- cCaDescr caDescr;
- //
- cPrgPid(int Type, int Pid) { type=Type; pid=Pid; proc=false; }
- bool Proc(void) const { return proc; }
- void Proc(bool is) { proc=is; };
- };
-
// -- cPrg ---------------------------------------------------------------------
-class cPrg : public cSimpleItem {
-private:
- bool isUpdate, pidCaDescr;
- //
- void Setup(void);
-public:
- int sid, source, transponder;
- cSimpleList<cPrgPid> pids;
- cCaDescr caDescr;
- //
- cPrg(void);
- cPrg(int Sid, bool IsUpdate);
- bool IsUpdate(void) const { return isUpdate; }
- bool HasPidCaDescr(void) const { return pidCaDescr; }
- void SetPidCaDescr(bool val) { pidCaDescr=val; }
- bool SimplifyCaDescr(void);
- void DumpCaDescr(int c);
- };
-
cPrg::cPrg(void)
{
Setup();
bool cPrg::SimplifyCaDescr(void)
{
-//XXX
-PRINTF(L_CORE_PIDS,"SimplyCa entry pidCa=%d",HasPidCaDescr());
-DumpCaDescr(L_CORE_PIDS);
-//XXX
-
if(HasPidCaDescr()) {
bool equal=true;
if(pids.Count()>1) {
caDescr.Clear();
}
-//XXX
-PRINTF(L_CORE_PIDS,"SimplyCa exit pidCa=%d",HasPidCaDescr());
-DumpCaDescr(L_CORE_PIDS);
-//XXX
+ PRINTF(L_CORE_PIDS,"Ca descriptors after simplify (pidCa=%d)",HasPidCaDescr());
+ DumpCaDescr(L_CORE_PIDS);
return HasPidCaDescr();
}
}
}
-#endif //SASC
+#endif //!SASC
// -- cCams --------------------------------------------------------------------
// -- cCam ---------------------------------------------------------------
+#ifndef SASC
struct TPDU {
unsigned char slot;
unsigned char tcid;
unsigned char len;
unsigned char data[1];
};
+#endif
cCam::cCam(cDevice *Device, int Adapter, int Frontend, const char *DevId, int Cafd, bool SoftCSA, bool FullTS)
{
softcsa=SoftCSA; fullts=FullTS;
tcid=0; rebuildcaids=false;
memset(version,0,sizeof(version));
+#ifndef SASC
memset(slots,0,sizeof(slots));
SetDescription("SC-CI adapter on device %s",devId);
rb=new cRingBufferLinear(KILOBYTE(8),6+LEN_OFF,false,"SC-CI adapter read");
else PRINTF(L_GEN_ERROR,"failed to create ringbuffer for SC-CI adapter %s.",devId);
decsa=softcsa ? new cDeCSA(devId) : 0;
+#endif //!SASC
source=transponder=-1; liveVpid=liveApid=0; logger=0; hookman=0;
memset(lastCW,0,sizeof(lastCW));
handlerList.Clear();
delete hookman;
delete logger;
+#ifndef SASC
Cancel(3);
ciMutex.Lock();
delete rb; rb=0;
ciMutex.Unlock();
delete decsa; decsa=0;
+#endif //!SASC
}
+#ifndef SASC
bool cCam::OwnSlot(const cCamSlot *slot) const
{
if(slots[0]==slot) return true;
}
return version[slot];
}
+#endif //!SASC
void cCam::CaidsChanged(void)
{
rebuildcaids=true;
}
+#ifndef SASC
void cCam::BuildCaids(bool force)
{
if(caidTimer.TimedOut() || force || (rebuildcaids && triggerTimer.TimedOut())) {
{
return Device ? (Device==device) : true;
}
+#endif //!SASC
bool cCam::IsSoftCSA(bool live)
{
return ioctl(cafd,CA_SET_DESCR,ca_descr)>=0;
}
else if(decsa) return decsa->SetDescr(ca_descr,initial);
-#endif // !SASC
+#endif //!SASC
return false;
}
return ioctl(cafd,CA_SET_PID,ca_pid)>=0;
}
else if(decsa) return decsa->SetCaPid(ca_pid);
-#endif // !SASC
+#endif //!SASC
return false;
}
ioctl(fd,CA_GET_MSG,&arg);
return arg.index;
}
-#endif // !SASC
+#endif //!SASC
#if 0
static void av7110_write(int fd, unsigned int addr, unsigned int val)
}
}
}
-#endif // !SASC
+#endif //!SASC
}
int cCam::GetFreeIndex(void)
// -- cDeCSA -------------------------------------------------------------------
+#ifndef SASC
+
#define MAX_STALL_MS 70
#define MAX_REL_WAIT 100 // time to wait if key in used on set
}
return false;
}
+
+#endif //!SASC
class cHookManager;
class cLogHook;
class cScCamSlot;
-class cCiFrame;
class cDeCSA;
class cPrg;
// ----------------------------------------------------------------
+#ifndef SASC
class cCiFrame {
private:
cRingBufferLinear *rb;
void Del(void);
int Avail(void);
};
+#endif //!SASC
+
+// ----------------------------------------------------------------
+
+class cCaDescr {
+private:
+ unsigned char *descr;
+ int len;
+public:
+ cCaDescr(void);
+ cCaDescr(const cCaDescr &arg);
+ ~cCaDescr();
+ const unsigned char *Get(int &l) const;
+ void Set(const cCaDescr *d);
+ void Set(const unsigned char *de, int l);
+ void Clear(void);
+ bool operator== (const cCaDescr &arg) const;
+ void Join(const cCaDescr *cd, bool rev=false);
+ cString ToString(void);
+ };
+
+// ----------------------------------------------------------------
+
+class cPrgPid : public cSimpleItem {
+private:
+ bool proc;
+public:
+ int type, pid;
+ cCaDescr caDescr;
+ //
+ cPrgPid(int Type, int Pid) { type=Type; pid=Pid; proc=false; }
+ bool Proc(void) const { return proc; }
+ void Proc(bool is) { proc=is; };
+ };
+
+// ----------------------------------------------------------------
+
+class cPrg : public cSimpleItem {
+private:
+ bool isUpdate, pidCaDescr;
+ //
+ void Setup(void);
+public:
+ int sid, source, transponder;
+ cSimpleList<cPrgPid> pids;
+ cCaDescr caDescr;
+ //
+ cPrg(void);
+ cPrg(int Sid, bool IsUpdate);
+ bool IsUpdate(void) const { return isUpdate; }
+ bool HasPidCaDescr(void) const { return pidCaDescr; }
+ void SetPidCaDescr(bool val) { pidCaDescr=val; }
+ bool SimplifyCaDescr(void);
+ void DumpCaDescr(int c);
+ };
// ----------------------------------------------------------------
#define MAX_CW_IDX 16
#define MAX_SPLIT_SID 16
+#ifndef SASC
class cCam : public cCiAdapter, public cSimpleItem {
+#else
+class cCam : public cSimpleItem {
+#endif
private:
cDevice *device;
- cMutex ciMutex;
const char *devId;
int adapter, frontend;
+#ifndef SASC
+ cMutex ciMutex;
cRingBufferLinear *rb;
cScCamSlot *slots[MAX_CI_SLOTS];
cCiFrame frame;
//
cDeCSA *decsa;
+#endif
int cafd;
cMutex cafdMutex;
bool softcsa, fullts;
int GetFreeIndex(void);
void LogStartup(void);
protected:
+#ifndef SASC
virtual int Read(unsigned char *Buffer, int MaxLength);
virtual void Write(const unsigned char *Buffer, int Length);
virtual bool Reset(int Slot);
virtual eModuleStatus ModuleStatus(int Slot);
virtual bool Assign(cDevice *Device, bool Query=false);
+#endif
public:
cCam(cDevice *Device, int Adapter, int Frontend, const char *DevId, int Cafd, bool SoftCSA, bool FullTS);
virtual ~cCam();
void PostTune(void);
void SetPid(int type, int pid, bool on);
char *CurrentKeyStr(int num, const char **id);
+#ifndef SASC
bool OwnSlot(const cCamSlot *slot) const;
cDeCSA *DeCSA(void) const { return decsa; }
+#endif
};
void LogStatsDown(void);
// ----------------------------------------------------------------
+#ifndef SASC
+
#define MAX_CSA_PIDS 8192
#define MAX_CSA_IDX 16
bool SetCaPid(ca_pid_t *ca_pid);
void SetActive(bool on);
};
+#endif //!SASC
#endif // ___CAM_H
#define DEV_DVB_AUDIO "audio"
#define DEV_DVB_CA "ca"
+class cDvbName {
+private:
+ char buffer[PATH_MAX];
+public:
+ cDvbName(const char *Name, int n) {
+ snprintf(buffer, sizeof(buffer), "%s%d/%s%d", DEV_DVB_ADAPTER, n, Name, 0);
+ }
+ const char *operator*() { return buffer; }
+ };
+
// --- cDvbDevice ------------------------------------------------------------
int cDvbDevice::devVideoOffset = -1;
return fd_video;
}
-#include "include/vdr/plugin.h"
-#define SC_NAME "sc"
-#define SC_MAGIC { 0,'S','C',0xc4,0x5e,0xa1 }
-#define OP_PROVIDES 0
-#define OP_IGNORE 1
-
-struct ScLink {
- char magic[6];
- short op;
- const cDevice *dev;
- unsigned short *caids;
- const cChannel *channel;
- int num;
- };
-
cSpuDecoder *cDvbDevice::GetSpuDecoder(void)
{
return NULL;
int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
{
+ const char *FileName = *cDvbName(DEV_DVB_DEMUX, CardIndex());
+ int f = open(FileName, O_RDWR | O_NONBLOCK);
+ if (f >= 0) {
+ dmx_sct_filter_params sctFilterParams;
+ memset(&sctFilterParams, 0, sizeof(sctFilterParams));
+ sctFilterParams.pid = Pid;
+ sctFilterParams.timeout = 0;
+ sctFilterParams.flags = DMX_IMMEDIATE_START;
+ sctFilterParams.filter.filter[0] = Tid;
+ sctFilterParams.filter.mask[0] = Mask;
+ if (ioctl(f, DMX_SET_FILTER, &sctFilterParams) >= 0)
+ return f;
+ else {
+ esyslog("ERROR: can't set filter (pid=%d, tid=%02X, mask=%02X): %m", Pid, Tid, Mask);
+ close(f);
+ }
+ }
+ else
+ esyslog("ERROR: can't open filter handle on '%s'", FileName);
return -1;
}
+void cDvbDevice::CloseFilter(int Handle)
+{
+ close(Handle);
+}
+
bool cDvbDevice::ProvidesSource(int Source) const
{
return true;
///< Opens a file handle for the given filter data.
///< A derived device that provides section data must
///< implement this function.
+ virtual void CloseFilter(int Handle);
+ ///< Closes a file handle that has previously been opened
+ ///< by OpenFilter(). If this is as simple as calling close(Handle),
+ ///< a derived class need not implement this function, because this
+ ///< is done by the default implementation.
void AttachFilter(cFilter *Filter);
///< Attaches the given filter to this device.
void Detach(cFilter *Filter);
protected:
virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
+ virtual void CloseFilter(int Handle);
// Common Interface facilities:
#include "sasccam.h"
#include "scsetup.h"
+// -- cScDevice -------------------------------------------------------------
+
+#define SCDEVICE cScDevice
+#define DVBDEVICE cDvbDevice
+#include "device-tmpl.c"
+#undef SCDEVICE
+#undef DVBDEVICE
+
// -- cSascDvbDevice -------------------------------------------------------------
+
class cSascDvbDevice : public cScDevice {
private:
int cardidx;
class SCDEVICE : public DVBDEVICE {
private:
+#ifndef SASC
cDeCsaTSBuffer *tsBuffer;
cMutex tsMutex;
+#endif //!SASC
cCam *cam;
+#ifndef SASC
cCiAdapter *hwciadapter;
+#endif //!SASC
int fd_dvr, fd_ca, fd_ca2;
bool softcsa, fullts;
char devId[8];
//
#ifndef SASC
bool ScActive(void);
-#endif //SASC
+#endif //!SASC
protected:
#ifndef SASC
virtual bool Ready(void);
virtual bool OpenDvr(void);
virtual void CloseDvr(void);
virtual bool GetTSPacket(uchar *&Data);
-#endif //SASC
+#endif //!SASC
public:
SCDEVICE(int Adapter, int Frontend, int cafd);
~SCDEVICE();
virtual bool HasCi(void);
void LateInit(void);
void EarlyShutdown(void);
-#endif //SASC
+#else
+ cCam *Cam(void) { return cam; }
+#endif //!SASC
};
SCDEVICE::SCDEVICE(int Adapter, int Frontend, int cafd)
:DVBDEVICE(Adapter)
#endif
{
- tsBuffer=0; softcsa=fullts=false;
- cam=0; hwciadapter=0;
+#ifndef SASC
+ tsBuffer=0; hwciadapter=0;
+#endif
+ cam=0; softcsa=fullts=false;
fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1;
-#ifdef SASC
- cam=new cCam(this,Adapter);
-#endif // !SASC
#if APIVERSNUM >= 10711
snprintf(devId,sizeof(devId),"%d/%d",Adapter,Frontend);
#else
snprintf(devId,sizeof(devId),"%d",Adapter);
#endif
+#ifdef SASC
+ cam=new cCam(this,Adapter,0,devId,fd_ca,softcsa,fullts);
+#endif // !SASC
}
SCDEVICE::~SCDEVICE()
DetachAllReceivers();
Cancel(3);
EarlyShutdown();
+#endif
if(fd_ca>=0) close(fd_ca);
if(fd_ca2>=0) close(fd_ca2);
-#else
+#ifdef SASC
delete cam;
-#endif // !SASC
+#endif
}
#ifndef SASC
#include <vdr/ci.h>
#include <vdr/dvbdevice.h>
#include <vdr/thread.h>
+
#ifndef SASC
#include <vdr/dvbci.h>
-
#include "FFdecsa/FFdecsa.h"
-#endif //SASC
+#endif //!SASC
#include "device.h"
#include "cam.h"
// -- cDeCsaTSBuffer -----------------------------------------------------------
+#ifndef SASC
+
cDeCsaTSBuffer::cDeCsaTSBuffer(int File, int Size, int CardIndex, cDeCSA *DeCsa, bool ScActive)
{
SetDescription("TS buffer on device %d", CardIndex);
#endif //APIVERSNUM >= 10711
+#endif //!SASC
+
// -- cScDevices ---------------------------------------------------------------
int cScDevices::budget=0;
return budget && (budget&(1<<n));
}
-#else //SASC
+#else //!SASC
void cScDevices::OnPluginLoad(void) {}
void cScDevices::OnPluginUnload(void) {}
void cScDevices::SetForceBudget(int n) {}
bool cScDevices::ForceBudget(int n) { return true; }
-#endif //SASC
+#endif //!SASC
// ----------------------------------------------------------------
+#ifndef SASC
class cDeCsaTSBuffer : public cThread {
private:
int f;
uchar *Get(void);
void SetActive(bool ScActive);
};
+#endif
// ----------------------------------------------------------------
// ----------------------------------------------------------------
+#ifndef SASC
class cScDevicePlugin : public cSimpleItem {
public:
cScDevicePlugin(void);
virtual bool LateInit(cDevice *dev)=0;
virtual bool EarlyShutdown(cDevice *dev)=0;
};
+#endif //!SASC
#endif // ___DEVICE_H