diff -Nrubw -x '*.pot' -x '*.po' -x .svn -x '*.o' -x .dependencies -x '*.so' -x '*~' sc-1cc3497be31c/device.c sc-1cc3497be31c.mcli/device.c --- sc-1cc3497be31c/device.c 2010-04-13 02:55:20.000000000 +0100 +++ sc-1cc3497be31c.mcli/device.c 2010-06-14 09:47:03.275991610 +0100 @@ -30,7 +30,9 @@ #include #include #ifndef SASC +#if APIVERSNUM >= 10500 #include +#endif #include "FFdecsa/FFdecsa.h" #endif //SASC @@ -49,7 +51,7 @@ #ifdef VDR_MAXCAID #define MAX_CI_SLOT_CAIDS VDR_MAXCAID #else -#define MAX_CI_SLOT_CAIDS 16 +#define MAX_CI_SLOT_CAIDS 64 #endif // -- cCaDescr ----------------------------------------------------------------- @@ -196,7 +198,7 @@ // --- cChannelCaids ----------------------------------------------------------- #ifndef SASC - +#if APIVERSNUM >= 10500 class cChannelCaids : public cSimpleItem { private: int prg, source, transponder; @@ -496,7 +498,7 @@ int version[MAX_CI_SLOTS]; caid_t caids[MAX_CI_SLOTS][MAX_CI_SLOT_CAIDS+1]; int tcid; - bool rebuildcaids; + bool rebuildcaids, firstTime; // cTimeMs readTimer, writeTimer; // @@ -765,6 +767,11 @@ } */ BuildCaids(true); +#ifdef MCLI_ENABLED + firstTime=true; // First time GetCaids() is called rebuild the cache +#else + firstTime=false; +#endif slots[0]=new cScCamSlot(this,cardIndex,0); Start(); } @@ -796,7 +803,8 @@ int cScCiAdapter::GetCaids(int slot, unsigned short *Caids, int max) { - BuildCaids(false); + BuildCaids(firstTime ? true :false); + firstTime=false; cMutexLock lock(&ciMutex); if(Caids) { int i; @@ -973,6 +981,7 @@ { return Device ? (Device==device) : true; } +#endif //APIVERSNUM >= 10500 // -- cDeCSA ------------------------------------------------------------------- @@ -1326,7 +1335,7 @@ bool cScDeviceProbe::Probe(int Adapter, int Frontend) { PRINTF(L_GEN_DEBUG,"capturing device %d/%d",Adapter,Frontend); - new cScDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); + new cScDvbDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); return true; } #endif @@ -1413,7 +1422,7 @@ if(f>=0) { close(f); PRINTF(L_GEN_DEBUG,"capturing device %d",i); - new cScDevice(i,0,cScDevices::DvbOpen(DEV_DVB_CA,i,0,O_RDWR)); + new cScDvbDevice(i,0,cScDevices::DvbOpen(DEV_DVB_CA,i,0,O_RDWR)); found++; } else { @@ -1483,7 +1492,7 @@ #define DVB_DEV_SPEC CardIndex(),0 #endif -cScDevice::cScDevice(int Adapter, int Frontend, int cafd) +cScDvbDevice::cScDvbDevice(int Adapter, int Frontend, int cafd) #if APIVERSNUM >= 10711 :cDvbDevice(Adapter,Frontend) #else @@ -1492,7 +1501,11 @@ { #ifndef SASC decsa=0; tsBuffer=0; cam=0; fullts=false; +#if APIVERSNUM >= 10500 ciadapter=0; hwciadapter=0; +#else + memset(lrucaid,0,sizeof(lrucaid)); +#endif fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1; softcsa=(fd_ca<0); #else @@ -1501,7 +1514,7 @@ #endif // !SASC } -cScDevice::~cScDevice() +cScDvbDevice::~cScDvbDevice() { #ifndef SASC DetachAllReceivers(); @@ -1509,7 +1522,9 @@ EarlyShutdown(); delete decsa; if(fd_ca>=0) close(fd_ca); +#if APIVERSNUM >= 10500 if(fd_ca2>=0) close(fd_ca2); +#endif #else delete cam; #endif // !SASC @@ -1517,16 +1532,18 @@ #ifndef SASC -void cScDevice::EarlyShutdown(void) +void cScDvbDevice::EarlyShutdown(void) { +#if APIVERSNUM >= 10500 SetCamSlot(0); delete ciadapter; ciadapter=0; delete hwciadapter; hwciadapter=0; +#endif if(cam) cam->Stop(); delete cam; cam=0; } -void cScDevice::LateInit(void) +void cScDvbDevice::LateInit(void) { int n=CardIndex(); if(DeviceNumber()!=n) @@ -1539,9 +1556,18 @@ softcsa=true; } +#if APIVERSNUM >= 10500 if(fd_ca2>=0) hwciadapter=cDvbCiAdapter::CreateCiAdapter(this,fd_ca2); cam=new cCam(this,n); ciadapter=new cScCiAdapter(this,n,cam); +#else + if(fd_ca2>=0) { + ciHandler=cCiHandler::CreateCiHandler(fd_ca2); + if(!ciHandler) close(fd_ca2); + } + cam=ScSetup.CapCheck(n) ? new cCam(this,n):0; +#endif + if(softcsa) { decsa=new cDeCSA(n); if(IsPrimaryDevice() && HasDecoder()) { @@ -1552,18 +1578,22 @@ } } -bool cScDevice::HasCi(void) +#if APIVERSNUM >= 10501 +bool cScDvbDevice::HasCi(void) { return ciadapter || hwciadapter; } +#endif -bool cScDevice::Ready(void) +#if APIVERSNUM >= 10500 +bool cScDvbDevice::Ready(void) { return (ciadapter ? ciadapter->Ready():true) && (hwciadapter ? hwciadapter->Ready():true); } +#endif -bool cScDevice::SetPid(cPidHandle *Handle, int Type, bool On) +bool cScDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) { if(cam) cam->SetPid(Type,Handle->pid,On); tsMutex.Lock(); @@ -1572,20 +1602,119 @@ return cDvbDevice::SetPid(Handle,Type,On); } -bool cScDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) +bool cScDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { +#if APIVERSNUM < 10500 + SetChannelLRU(Channel); +#endif if(cam) cam->Tune(Channel); bool ret=cDvbDevice::SetChannelDevice(Channel,LiveView); if(ret && cam) cam->PostTune(); return ret; } -bool cScDevice::ScActive(void) +#if APIVERSNUM < 10500 +int cScDvbDevice::ProvidesCa(const cChannel *Channel) const +{ + if(cam && Channel->Ca()>=CA_ENCRYPTED_MIN) { + int caid; + for(int j=0; (caid=Channel->Ca(j)); j++) + if(!overrides.Ignore(Channel->Source(),Channel->Transponder(),caid)) { + int n=cSystems::CanHandle(caid,!softcsa); + if(n<0) break; + if(n>0) return 2; + } + } + return cDvbDevice::ProvidesCa(Channel); +} + +bool cScDvbDevice::CiAllowConcurrent(void) const +{ + return softcsa || ScSetup.ConcurrentFF>0; +} + +bool cScDvbDevice::GetPrgCaids(int source, int transponder, int prg, caid_t *c) +{ + cMutexLock lock(&lruMutex); + int i=FindLRUPrg(source,transponder,prg); + if(i>=0) { + for(int j=0; jSource(),Channel->Transponder(),Channel->Sid()); + if(i<0) i=MAX_LRU_CAID-1; + if(i>0) memmove(&lrucaid[1],&lrucaid[0],sizeof(struct LruCaid)*i); + for(i=0; i<=MAXCAIDS; i++) if((lrucaid[0].caids[i]=Channel->Ca(i))==0) break; + lrucaid[0].src=Channel->Source(); + lrucaid[0].tr=Channel->Transponder(); + lrucaid[0].prg=Channel->Sid(); + lruMutex.Unlock(); +} + +void cScDvbDevice::CiStartDecrypting(void) { + if(cam) { + cSimpleList prgList; + for(cCiCaProgramData *p=ciProgramList.First(); p; p=ciProgramList.Next(p)) { + if(p->modified) { + cPrg *prg=new cPrg(p->programNumber,cam->HasPrg(p->programNumber)); + if(prg) { + bool haspid=false; + for(cCiCaPidData *q=p->pidList.First(); q; q=p->pidList.Next(q)) { + if(q->active) { + prg->pids.Add(new cPrgPid(q->streamType,q->pid)); + haspid=true; + } + } + if(haspid) { + caid_t casys[MAXCAIDS+1]; + if(GetPrgCaids(ciSource,ciTransponder,p->programNumber,casys)) { + unsigned char buff[2048]; + bool streamflag; + int len=GetCaDescriptors(ciSource,ciTransponder,p->programNumber,casys,sizeof(buff),buff,streamflag); + if(len>0) prg->caDescr.Set(buff,len); + } + } + prgList.Add(prg); + } + p->modified=false; + } + } + for(int loop=1; loop<=2; loop++) // first delete, then add + for(cPrg *prg=prgList.First(); prg; prg=prgList.Next(prg)) + if((loop==1)!=(prg->pids.Count()>0)) + cam->AddPrg(prg); + } + cDvbDevice::CiStartDecrypting(); +} +#endif //APIVERSNUM < 10500 + + +bool cScDvbDevice::ScActive(void) +{ +#if APIVERSNUM >= 10500 return dynamic_cast(CamSlot())!=0; +#else + return cam && softcsa; +#endif + } -bool cScDevice::OpenDvr(void) +bool cScDvbDevice::OpenDvr(void) { CloseDvr(); fd_dvr=cScDevices::DvbOpen(DEV_DVB_DVR,DVB_DEV_SPEC,O_RDONLY|O_NONBLOCK,true); @@ -1597,7 +1726,7 @@ return fd_dvr>=0; } -void cScDevice::CloseDvr(void) +void cScDvbDevice::CloseDvr(void) { tsMutex.Lock(); delete tsBuffer; tsBuffer=0; @@ -1605,7 +1734,7 @@ if(fd_dvr>=0) { close(fd_dvr); fd_dvr=-1; } } -bool cScDevice::GetTSPacket(uchar *&Data) +bool cScDvbDevice::GetTSPacket(uchar *&Data) { if(tsBuffer) { Data=tsBuffer->Get(); return true; } return false; @@ -1613,20 +1742,22 @@ #endif // !SASC -bool cScDevice::SoftCSA(bool live) +bool cScDvbDevice::SoftCSA(bool live) { return softcsa && (!fullts || !live); } -void cScDevice::CaidsChanged(void) +void cScDvbDevice::CaidsChanged(void) { #ifndef SASC +#if APIVERSNUM >= 10500 if(ciadapter) ciadapter->CaidsChanged(); PRINTF(L_CORE_CAIDS,"caid list rebuild triggered"); +#endif #endif // !SASC } -bool cScDevice::SetCaDescr(ca_descr_t *ca_descr, bool initial) +bool cScDvbDevice::SetCaDescr(ca_descr_t *ca_descr, bool initial) { #ifndef SASC if(!softcsa || (fullts && ca_descr->index==0)) { @@ -1638,7 +1769,7 @@ return false; } -bool cScDevice::SetCaPid(ca_pid_t *ca_pid) +bool cScDvbDevice::SetCaPid(ca_pid_t *ca_pid) { #ifndef SASC if(!softcsa || (fullts && ca_pid->index==0)) { @@ -1650,7 +1781,7 @@ return false; } -int cScDevice::FilterHandle(void) +int cScDvbDevice::FilterHandle(void) { return cScDevices::DvbOpen(DEV_DVB_DEMUX,DVB_DEV_SPEC,O_RDWR|O_NONBLOCK); } @@ -1675,7 +1806,7 @@ } #endif -void cScDevice::DumpAV7110(void) +void cScDvbDevice::DumpAV7110(void) { #ifndef SASC if(LOG(L_CORE_AV7110)) { @@ -1735,3 +1866,8 @@ } #endif // !SASC } + + +#ifdef MCLI_ENABLED +#include "mclidevice.c" +#endif diff -Nrubw -x '*.pot' -x '*.po' -x .svn -x '*.o' -x .dependencies -x '*.so' -x '*~' sc-1cc3497be31c/device.h sc-1cc3497be31c.mcli/device.h --- sc-1cc3497be31c/device.h 2010-04-13 02:55:20.000000000 +0100 +++ sc-1cc3497be31c.mcli/device.h 2010-04-25 22:56:46.188184810 +0100 @@ -23,9 +23,17 @@ #include #include #include +#ifdef MCLI_ENABLED +#include "../mcli/filter.h" +#include "../mcli/device.h" +#endif #include "misc.h" +#if APIVERSNUM >= 10500 typedef int caid_t; +#else +typedef unsigned short caid_t; +#endif class cCam; class cDeCSA; @@ -110,19 +118,42 @@ // ---------------------------------------------------------------- -class cScDevice : public cDvbDevice { +class cScDevice { +public: +#ifndef SASC + virtual void LateInit(void) {}; + virtual void EarlyShutdown(void) {}; + virtual bool ScActive(void) { return false; }; +#endif //SASC + virtual cCam *Cam(void) { return 0; }; + virtual bool SetCaDescr(ca_descr_t *ca_descr, bool initial) { return false; }; + virtual bool SetCaPid(ca_pid_t *ca_pid) { return false; }; + virtual bool SoftCSA(bool live) { return false; } + virtual void CaidsChanged(void) {}; + virtual void DumpAV7110(void) {}; + virtual int FilterHandle(void) { return -1; }; + cScDevice() {}; + virtual ~cScDevice() {}; +}; + + +class cScDvbDevice : public cDvbDevice, cScDevice { friend class cScDevices; private: cDeCSA *decsa; cDeCsaTSBuffer *tsBuffer; cMutex tsMutex; +#if APIVERSNUM >= 10500 cScCiAdapter *ciadapter; cCiAdapter *hwciadapter; +#endif cCam *cam; int fd_dvr, fd_ca, fd_ca2; bool softcsa, fullts; cMutex cafdMutex; cTimeMs lastDump; + + // #ifndef SASC void LateInit(void); @@ -130,28 +161,137 @@ bool ScActive(void); #endif //SASC // +#if APIVERSNUM < 10500 +#define MAX_LRU_CAID 10 + struct LruCaid { + int src, tr, prg; + caid_t caids[MAXCAIDS+1]; + } lrucaid[MAX_LRU_CAID]; + cMutex lruMutex; + // + int FindLRUPrg(int source, int transponder, int prg); + bool GetPrgCaids(int source, int transponder, int prg, caid_t *c); + void SetChannelLRU(const cChannel *Channel); +#endif + + + protected: #ifndef SASC +#if APIVERSNUM >= 10500 virtual bool Ready(void); +#else + virtual void CiStartDecrypting(void); + virtual bool CiAllowConcurrent(void) const; +#endif virtual bool SetPid(cPidHandle *Handle, int Type, bool On); virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); virtual bool OpenDvr(void); virtual void CloseDvr(void); virtual bool GetTSPacket(uchar *&Data); +#ifdef GET_TS_PACKETS + virtual int GetTSPackets (uchar *, int); +#endif #endif //SASC public: - cScDevice(int Adapter, int Frontend, int cafd); - ~cScDevice(); + cScDvbDevice(int Adapter, int Frontend, int cafd); + ~cScDvbDevice(); #ifndef SASC +#if APIVERSNUM >= 10501 virtual bool HasCi(void); +#endif +#if APIVERSNUM < 10500 + virtual int ProvidesCa(const cChannel *Channel) const; +#endif #endif //SASC virtual bool SetCaDescr(ca_descr_t *ca_descr, bool initial); virtual bool SetCaPid(ca_pid_t *ca_pid); - int FilterHandle(void); + virtual int FilterHandle(void); void DumpAV7110(void); cCam *Cam(void) { return cam; } bool SoftCSA(bool live); void CaidsChanged(void); }; +#ifdef MCLI_ENABLED +class cScMcliDevice : public cScDevice, public cMcliDevice { +private: + cRingBufferLinear *ringBuffer; + cDeCSA *decsa; + cDeCsaTSBuffer *tsBuffer; + cMutex tsMutex; +#if APIVERSNUM >= 10500 + cScCiAdapter *ciadapter; +#endif + cCam *cam; + bool softcsa; + cTimeMs lastDump; + bool delivered; + bool scActive; +#ifdef HW_MINI + static int rbm_fd; + rbm_dmx_pids dmx_pids; +#endif + // +#ifndef SASC + virtual void EarlyShutdown(void); + virtual bool ScActive(void); +#endif //SASC + // +#if APIVERSNUM < 10500 +#define MAX_LRU_CAID 10 + struct LruCaid { + int src, tr, prg; + caid_t caids[MAXCAIDS+1]; + } lrucaid[MAX_LRU_CAID]; + cMutex lruMutex; + // + int FindLRUPrg(int source, int transponder, int prg); + bool GetPrgCaids(int source, int transponder, int prg, caid_t *c); +#endif +protected: +#ifndef SASC +#if APIVERSNUM >= 10500 + virtual bool Ready(void); +#else + virtual void CiStartDecrypting(void); + virtual bool CiAllowConcurrent(void) const; +#endif + virtual bool SetPid(cPidHandle *Handle, int Type, bool On); + virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); + virtual bool GetTSPacket(uchar *&Data); +#ifdef GET_TS_PACKETS + virtual int GetTSPackets (uchar *, int); +#endif + +#endif //SASC +public: + cScMcliDevice(); + ~cScMcliDevice(); +#ifndef SASC +#if APIVERSNUM >= 10501 + virtual bool HasCi(void); +#endif +#if APIVERSNUM < 10500 + virtual int ProvidesCa(const cChannel *Channel) const; +#endif +#endif //SASC + static void Shutdown(void); + virtual bool SetCaDescr(ca_descr_t *ca_descr, bool initial); + virtual bool SetCaPid(ca_pid_t *ca_pid); + virtual void DumpAV7110(void); + virtual cCam *Cam(void) { return cam; } + virtual bool SoftCSA(bool live); + virtual void CaidsChanged(void); + + // Override from pi-mcli + virtual int HandleTsData (unsigned char *buffer, size_t len); + + virtual bool HasInternalCam (void) { return false; } + + }; +#endif + + + #endif // ___DEVICE_H diff -Nrubw -x '*.pot' -x '*.po' -x .svn -x '*.o' -x .dependencies -x '*.so' -x '*~' sc-1cc3497be31c/FFdecsa/FFdecsa.c sc-1cc3497be31c.mcli/FFdecsa/FFdecsa.c --- sc-1cc3497be31c/FFdecsa/FFdecsa.c 2010-04-13 02:55:20.000000000 +0100 +++ sc-1cc3497be31c.mcli/FFdecsa/FFdecsa.c 2010-04-25 22:34:39.963185678 +0100 @@ -839,7 +839,12 @@ // alive packets: decrypt data for(g=0;g +#include #include #include "filter.h" @@ -38,6 +40,20 @@ cPidFilter::cPidFilter(const char *Id, int Num, int DvbNum, unsigned int IdleTime) { + device = 0; +#ifdef MCLI_ENABLED + for ( int i = 0; i < MAXDEVICES; i++ ) { + cDevice *d = cDevice::GetDevice(i); + if ( d && d->CardIndex() == DvbNum ) { + cScMcliDevice *scd = dynamic_cast(d); + if ( scd ) { + device = d; + break; + } + } + } +#endif + dvbNum=DvbNum; idleTime=IdleTime; id=0; fd=-1; active=false; forceRun=false; userData=0; @@ -48,9 +64,9 @@ cPidFilter::~cPidFilter() { cMutexLock lock(this); - if(fd>=0) { + if(fd>=0 || device) { Stop(); - close(fd); + if (device==0) close(fd); } PRINTF(L_CORE_ACTION,"filter '%s' on card %d removed",id,dvbNum); free(id); @@ -62,6 +78,7 @@ if(fd<0) { fd=cSoftCAM::FilterHandle(dvbNum); if(fd>=0) return true; + if (device) return true; // We'll set up the filter later... } return false; } @@ -78,8 +95,9 @@ void cPidFilter::Start(int Pid, int Section, int Mask, int Mode, bool Crc) { cMutexLock lock(this); - if(fd>=0) { + if(fd>=0 || device) { Stop(); + if (device==0) { struct dmx_sct_filter_params FilterParams; memset(&FilterParams,0,sizeof(FilterParams)); FilterParams.filter.filter[0]=Section; @@ -92,6 +110,14 @@ PRINTF(L_GEN_ERROR,"filter '%s': DMX_SET_FILTER failed: %s",id,strerror(errno)); return; } + }else{ + fd = device->OpenFilter(Pid, Section, Mask); + if ( fd < 0 ){ + PRINTF(L_GEN_ERROR,"filter '%s': Can't open filter on ScMcliDevice", id); + return; + } + } + pid=Pid; active=true; @@ -113,7 +139,12 @@ { cMutexLock lock(this); if(fd>=0) { + if (device) { + device->CloseFilter(fd); + fd = -1; + } else { CHECK(ioctl(fd,DMX_STOP)); + } active=false; } } @@ -123,10 +154,12 @@ cMutexLock lock(this); if(fd>=0) { Stop(); + if(device==0) { int s=max(BuffSize,8192); CHECK(ioctl(fd,DMX_SET_BUFFER_SIZE,s)); } } +} int cPidFilter::SetIdleTime(unsigned int IdleTime) { @@ -264,7 +297,7 @@ if(errno==EOVERFLOW) PRINTF(L_GEN_ERROR,"action %s read: Buffer overflow",filter->id); else PRINTF(L_GEN_ERROR,"action %s read: %s",filter->id,strerror(errno)); } - if(n>0) { + if(n>0 && n > 3) { filter->lastTime.Set(); filter->forceRun=false; Process(filter,buff,n); // don't make any assumption about data-structs here diff -Nrubw -x '*.pot' -x '*.po' -x .svn -x '*.o' -x .dependencies -x '*.so' -x '*~' sc-1cc3497be31c/filter.h sc-1cc3497be31c.mcli/filter.h --- sc-1cc3497be31c/filter.h 2010-04-13 02:55:20.000000000 +0100 +++ sc-1cc3497be31c.mcli/filter.h 2010-04-25 22:34:40.503189752 +0100 @@ -21,6 +21,7 @@ #define ___FILTER_H #include +#include "device.h" #include "misc.h" class cPidFilter; @@ -61,6 +62,7 @@ // bool Open(void); protected: + cDevice *device; char *id; int fd; int pid; diff -Nrubw -x '*.pot' -x '*.po' -x .svn -x '*.o' -x .dependencies -x '*.so' -x '*~' sc-1cc3497be31c/Make.config sc-1cc3497be31c.mcli/Make.config --- sc-1cc3497be31c/Make.config 1970-01-01 01:00:00.000000000 +0100 +++ sc-1cc3497be31c.mcli/Make.config 2010-04-26 21:42:05.383860812 +0100 @@ -0,0 +1,30 @@ + +APIVERSION := $(shell sed -ne '/define APIVERSION/ s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/include/vdr/config.h) + +# Magic for libvdr-mcli and ReelVDR configuration +# If we're running with Reelvdr then we do want the mcli compatibility +# enabled (unless it's explicitly disabled) +ifneq ($(REELVDR),) + DEFINES += -DREELVDR + MCLI_ENABLED ?= 1 +endif + +ifeq ($(MCLI_ENABLED),1) + MCLI_LIBRARY= $(PLUGINLIBDIR)/libvdr-mcli.so.$(APIVERSION) + ifeq ($(shell ls $(MCLI_LIBRARY) 2> /dev/null | wc -l ),1) + ifeq ($(shell ls ../mcli/device.h 2> /dev/null | wc -l ),1) + LIBS += $(MCLI_LIBRARY) + DEFINES += -DMCLI_ENABLED + INCLUDES += -I../mcli/ `xml2-config --cflags` + else + $(error The source code for the mcli plugin must be present at the same directory level as the sc plugin) + endif + else + $(error mcli support requested, but can't find $(MCLI_LIBRARY) - you may need to install the plugins before building sc) + endif +endif + + +ifdef RBMINI +CXXFLAGS += -DHW_MINI +endif diff -Nrubw -x '*.pot' -x '*.po' -x .svn -x '*.o' -x .dependencies -x '*.so' -x '*~' sc-1cc3497be31c/mclidevice.c sc-1cc3497be31c.mcli/mclidevice.c --- sc-1cc3497be31c/mclidevice.c 1970-01-01 01:00:00.000000000 +0100 +++ sc-1cc3497be31c.mcli/mclidevice.c 2010-04-26 21:00:54.164861079 +0100 @@ -0,0 +1,361 @@ + + + + + +cScMcliDevice::cScMcliDevice() +{ + //SetCaOverride(true); + decsa=0; tsBuffer=0; cam=0; +#if APIVERSNUM >= 10500 + ciadapter=0; +#else + memset(lrucaid,0,sizeof(lrucaid)); +#endif + softcsa=true; + int n=CardIndex(); + scActive=true; +#ifdef HW_MINI + if ( rbm_fd == -1 ) { + rbm_fd = open("/dev/rbm1", O_RDWR|O_NDELAY); + rbm_dmx_mode mode = RBM_DMX_MODE_TS; + int ret = ioctl(rbm_fd, RBMIO_SET_DMX_MODE, &mode); + printf("Set dmx mode %d\n",ret); + + } + dmx_pids.pid_count = 0; + printf("RBM fd is %d\n",rbm_fd); +#endif + ringBuffer=new cRingBufferLinear(MEGABYTE(2),TS_SIZE,true,"FFdecsa-TS"); + ringBuffer->SetTimeouts(100,100); + softcsa=true; + delivered = false; +#ifndef HW_MINI + decsa=new cDeCSA(CardIndex()); +#else + decsa = 0; +#endif +#if APIVERSNUM >= 10500 + printf("Creating ci adapter\n"); + cam=new cCam(this,n); + ciadapter=new cScCiAdapter(this,n,cam); +#else + //cam=ScSetup.CapCheck(n) ? new cCam(this,n):0; + cam=new cCam(this,n); +#endif + PRINTF(L_GEN_INFO,"Using software decryption on card %d",n); +} + +cScMcliDevice::~cScMcliDevice() +{ + DetachAllReceivers(); + Cancel(3); + EarlyShutdown(); + delete decsa; +} + +void cScMcliDevice::EarlyShutdown(void) +{ +#if APIVERSNUM >= 10500 + SetCamSlot(0); + delete ciadapter; ciadapter=0; +#endif + if (ringBuffer) { delete ringBuffer; ringBuffer = 0; } + if(cam) cam->Stop(); + delete cam; cam=0; +} + +void cScMcliDevice::Shutdown(void) +{ + for(int n=cDevice::NumDevices(); --n>=0;) { + cScMcliDevice *dev=dynamic_cast(cDevice::GetDevice(n)); + if(dev) dev->EarlyShutdown(); + } +} + + +#if APIVERSNUM >= 10501 +bool cScMcliDevice::HasCi(void) +{ + return ciadapter; +} +#endif + +#if APIVERSNUM >= 10500 +bool cScMcliDevice::Ready(void) +{ + bool ret = (ciadapter ? ciadapter->Ready():true); + printf("Ready %d\n",ret); + return ret; +} +#endif + +bool cScMcliDevice::SetPid(cPidHandle *Handle, int Type, bool On) +{ + if (cMcliDevice::HasInput() == false ) + return false; + +#ifdef HW_MINI + unsigned int i; + for ( i = 0; i < dmx_pids.pid_count; i++ ) { + if ( dmx_pids.pid[i] == Handle->pid ) { + break; + } + } + if ( i == dmx_pids.pid_count ) { + printf("Setting pid %d at position %d",Handle->pid, dmx_pids.pid_count); + dmx_pids.pid[dmx_pids.pid_count++] = Handle->pid; + int ret = ioctl(rbm_fd, RBMIO_SET_DMX_PIDS,&dmx_pids); + printf("SET_DMX_PIDS = %d",ret); + } +#endif + + if(cam) cam->SetPid(Type,Handle->pid,On); + //tsMutex.Lock(); + scActive = true; + if (decsa) { + decsa->SetActive(true); + } + //tsMutex.Unlock(); + return cMcliDevice::SetPid(Handle,Type,On); +} + +bool cScMcliDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) +{ + if (cMcliDevice::HasInput() == false ) + return false; +#if APIVERSNUM < 10500 + lruMutex.Lock(); + int i=FindLRUPrg(Channel->Source(),Channel->Transponder(),Channel->Sid()); + if(i<0) i=MAX_LRU_CAID-1; + if(i>0) memmove(&lrucaid[1],&lrucaid[0],sizeof(struct LruCaid)*i); + for(i=0; i<=MAXCAIDS; i++) if((lrucaid[0].caids[i]=Channel->Ca(i))==0) break; + lrucaid[0].src=Channel->Source(); + lrucaid[0].tr=Channel->Transponder(); + lrucaid[0].prg=Channel->Sid(); + lruMutex.Unlock(); +#endif + +#ifdef HW_MINI + rbm_av_flush flush; + memset(&flush, 0, sizeof(flush)); + flush.mode = RBMIO_FLUSH_CLEAR; + int res = ioctl(rbm_fd, RBMIO_FLUSH, &flush); + dmx_pids.pid_count = 0; +#endif + +#if APIVERSNUM < 10500 + SetCaOverride(cam ? ProvidesCa(Channel) : false); +#else + SetCaOverride(true); +#endif + + if(cam) cam->Tune(Channel); + bool ret=cMcliDevice::SetChannelDevice(Channel,LiveView); + if(ret && cam) cam->PostTune(); + return ret; +} + +#if APIVERSNUM < 10500 +int cScMcliDevice::ProvidesCa(const cChannel *Channel) const +{ + if(cam && Channel->Ca()>=CA_ENCRYPTED_MIN) { + int caid; + for(int j=0; (caid=Channel->Ca(j)); j++) + if(!overrides.Ignore(Channel->Source(),Channel->Transponder(),caid)) { + int n=cSystems::CanHandle(caid,!softcsa); + if(n<0) break; + if(n>0) return 2; + } + } + return 0; +} + +bool cScMcliDevice::CiAllowConcurrent(void) const +{ + return true; +} + +bool cScMcliDevice::GetPrgCaids(int source, int transponder, int prg, caid_t *c) +{ + cMutexLock lock(&lruMutex); + int i=FindLRUPrg(source,transponder,prg); + if(i>=0) { + for(int j=0; j prgList; + for(cCiCaProgramData *p=ciProgramList.First(); p; p=ciProgramList.Next(p)) { + if(p->modified) { + cPrg *prg=new cPrg(p->programNumber,cam->HasPrg(p->programNumber)); + if(prg) { + bool haspid=false; + for(cCiCaPidData *q=p->pidList.First(); q; q=p->pidList.Next(q)) { + if(q->active) { + prg->pids.Add(new cPrgPid(q->streamType,q->pid)); + haspid=true; + } + } + if(haspid) { + caid_t casys[MAXCAIDS+1]; + if(GetPrgCaids(ciSource,ciTransponder,p->programNumber,casys)) { + unsigned char buff[2048]; + bool streamflag; + int len=GetCaDescriptors(ciSource,ciTransponder,p->programNumber,casys,sizeof(buff),buff,streamflag); + if(len>0) prg->caDescr.Set(buff,len); + } + } + prgList.Add(prg); + } + p->modified=false; + } + } + for(int loop=1; loop<=2; loop++) // first delete, then add + for(cPrg *prg=prgList.First(); prg; prg=prgList.Next(prg)) + if((loop==1)!=(prg->pids.Count()>0)) + cam->AddPrg(prg); + } + cDevice::CiStartDecrypting(); +} +#endif //APIVERSNUM < 10500 + +bool cScMcliDevice::ScActive(void) +{ +#if APIVERSNUM >= 10500 + return dynamic_cast(CamSlot())!=0; +#else + return cam && softcsa; +#endif +} + +bool cScMcliDevice::GetTSPacket(uchar *&Data) +{ + int Count=0; + if(delivered) { ringBuffer->Del(TS_SIZE); delivered=false; } + uchar *p=ringBuffer->Get(Count); + if(p && Count>=TS_SIZE) { + if(*p!=TS_SYNC_BYTE) { + for(int i=1; iCount && p[i+TS_SIZE]==TS_SYNC_BYTE)) ) { Count=i; break; } + ringBuffer->Del(Count); + esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d",Count,CardIndex()); + return false; + } + if(scActive && (p[3]&0xC0)) { + if(decsa) { + if(!decsa->Decrypt(p,Count,false)) { + cCondWait::SleepMs(20); + return true; + } + } + } + + delivered=true; + Data = p; + return true; + } + return true; +} + +#ifdef GET_TS_PACKETS +int cScMcliDevice::GetTSPackets (uchar *Data, int count) +{ + int done = 0; + count=1; + while ( done < count ) { + uchar *temp = 0; + + GetTSPacket(temp); + + if (temp != 0 ) { + memcpy(Data + (done * TS_SIZE), temp, TS_SIZE); + done++; + } else break; + } + return done * TS_SIZE; +} +#endif + + +bool cScMcliDevice::SoftCSA(bool live) +{ + return true; +} + +void cScMcliDevice::CaidsChanged(void) +{ +#if APIVERSNUM >= 10500 + if(ciadapter) ciadapter->CaidsChanged(); + PRINTF(L_CORE_CAIDS,"caid list rebuild triggered"); +#endif +} + +bool cScMcliDevice::SetCaDescr(ca_descr_t *ca_descr, bool initial) +{ +#ifdef HW_MINI + bool ret = ioctl(rbm_fd,CA_SET_DESCR,ca_descr)>=0; + return ret; +#endif + + if(decsa) return decsa->SetDescr(ca_descr,initial); + return false; +} + +bool cScMcliDevice::SetCaPid(ca_pid_t *ca_pid) +{ +#ifdef HW_MINI + bool ret = ioctl(rbm_fd,CA_SET_DESCR,ca_descr)>=0; + return ret; +#endif + + if(decsa) return decsa->SetCaPid(ca_pid); + return false; +} + +void cScMcliDevice::DumpAV7110(void) +{ +} + +int cScMcliDevice::HandleTsData (unsigned char *buffer, size_t len) +{ + int olen=len; + if (cMcliDevice::HasInput() == false ) + return len; + cMcliDevice::HandleTsData(buffer,len); + tsMutex.Lock(); +#ifdef HW_MINI + if ( scActive ) { + WriteAllOrNothing(rbm_fd, buffer, len); + tsMutex.Unlock(); + return len; + } +#endif + if ( ringBuffer ) { + size_t avail = ringBuffer->Free(); + if ( avail < len ) { + len = avail; + } + if ( len ) { + ringBuffer->Put(buffer, len); + } + } + tsMutex.Unlock(); + return olen; +} + + diff -Nrubw -x '*.pot' -x '*.po' -x .svn -x '*.o' -x .dependencies -x '*.so' -x '*~' sc-1cc3497be31c/sc.c sc-1cc3497be31c.mcli/sc.c --- sc-1cc3497be31c/sc.c 2010-04-13 02:55:20.000000000 +0100 +++ sc-1cc3497be31c.mcli/sc.c 2010-06-13 22:39:39.833522982 +0100 @@ -52,11 +52,23 @@ #include "i18n.h" #include "log-core.h" #include "version.h" +#ifdef MCLI_ENABLED +#include "../mcli/mcli.h" +#endif +#ifndef REELVDR #define MIN_VERS 1 // required VDR version #define MIN_MAJOR 6 #define MIN_MINOR 0 #define MINAPIVERSNUM 10600 +#else +#define MIN_VERS 1 // required VDR version +#define MIN_MAJOR 4 +#define MIN_MINOR 5 +#define MINAPIVERSNUM 10405 +#endif + + // some sanity checks #ifdef HAVE_SOFTCSA @@ -1240,6 +1252,9 @@ virtual bool SetupParse(const char *Name, const char *Value); virtual const char **SVDRPHelpPages(void); virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode); +#ifdef MCLI_ENABLED + virtual bool Service(const char *Id, void *data); +#endif }; cScPlugin::cScPlugin(void) @@ -1282,8 +1297,15 @@ bool cScPlugin::Initialize(void) { + bool succ = false; PRINTF(L_GEN_INFO,"SC version %s initializing (VDR %s)",ScVersion,VDRVERSION); - return dllSuccess && cScDevices::Initialize(); + if (dllSuccess) { + succ=cScDevices::Initialize(); +#ifdef MCLI_ENABLED + succ=true; +#endif + } + return dllSuccess && succ; } bool cScPlugin::Start(void) @@ -1512,4 +1534,28 @@ return NULL; } +#ifdef MCLI_ENABLED +bool cScPlugin::Service(const char *Id, void *data) +{ + if ( Id && strcmp(Id, "OnNewMcliDevice-" MCLI_DEVICE_VERSION) == 0 ) { + cMcliDevice **dev_ptr = (cMcliDevice **) data; + cMcliDevice *dev = *dev_ptr; + if ( dev ) { + dev->SetEnable(false); + delete dev; + } + // Wait till sc has truly started + while ( keeper == 0 ) { + cCondWait::SleepMs(200); + } + cScMcliDevice *newdev = new cScMcliDevice(); + *dev_ptr = newdev; + return true; + } + return false; +} +#endif + + + VDRPLUGINCREATOR(cScPlugin); // Don't touch this!