⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shl.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdio.h>#include <string.h>#include <errno.h>#include <malloc.h>#include <sys/ioctl.h>#include <sys/poll.h>#include <linux/dvb/dmx.h>#include <openssl/des.h>#include "system-common.h"#include "data.h"#include "filter.h"#include "misc.h"#include "log-sys.h"#define SYSTEM_SHL           0x4A60#define SYSTEM_NAME          "@SHL"#define SYSTEM_PRI           -10#define SYSTEM_CAN_HANDLE(x) ((x)==SYSTEM_SHL)#define L_SYS        15#define L_SYS_HOPPER LCLASS(L_SYS,L_SYS_LASTDEF<<1)#define L_SYS_HSTATS LCLASS(L_SYS,L_SYS_LASTDEF<<2)#define L_SYS_ALL    LALL(L_SYS_HSTATS)static const struct LogModule lm_sys = {  (LMOD_ENABLE|L_SYS_ALL)&LOPT_MASK,  (LMOD_ENABLE|L_SYS_DEFDEF)&LOPT_MASK,  "shl",  { L_SYS_DEFNAMES,"pidHopper","hopperStats" }  };ADD_MODULE(L_SYS,lm_sys)// evil hack, but it's not worth to put much effort in a dead system ...static cTimeMs __time;#define time_ms() ((int)__time.Elapsed())static cPlainKeyTypeReg<cPlainKeyStd,'Z',false> KeyReg;// -- cPesFilter ---------------------------------------------------------------class cPesFilter : public cPidFilter {public:  cPesFilter(const char *Id, int Num, int DvbNum, int IdleTime);  virtual void Start(int Pid, int Section, int Mask, int Mode, bool Crc);  };cPesFilter::cPesFilter(const char *Id, int Num, int DvbNum, int IdleTime):cPidFilter(Id,Num,DvbNum,IdleTime){}void cPesFilter::Start(int Pid, int Section, int Mask, int Mode, bool Crc){  if(fd>=0) {    Stop();    struct dmx_pes_filter_params FilterParams;    FilterParams.input=DMX_IN_FRONTEND;    FilterParams.output=DMX_OUT_TAP;    FilterParams.pes_type=DMX_PES_OTHER;    FilterParams.flags=DMX_IMMEDIATE_START;    FilterParams.pid=Pid;    CHECK(ioctl(fd,DMX_SET_PES_FILTER,&FilterParams));    pid=Pid;    active=true;    }}// -- cPidHopper ---------------------------------------------------------------struct FilterPacket {  struct FilterPacket *next;  int lastTime, dataLen;  unsigned char lastData[1];  };  struct FilterData {  cPidFilter *filter;  int lastTime, lastRead, createTime, readCount;  struct FilterPacket *first, *last;  };class cPidHopper : public cAction {private:  struct FilterData *d;  int numFilters;  cMutex sleepMutex;  cCondVar sleep;  //  void PurgeFilter(struct FilterData *dd);  void PurgePacket(struct FilterData *dd, struct FilterPacket *p);protected:  virtual void Process(cPidFilter *filter, unsigned char *data, int len);  virtual cPidFilter *CreateFilter(const char *Id, int Num, int DvbNum, int IdleTime);public:  cPidHopper(int DvbNum, int NumFilters);  virtual ~cPidHopper();  int Read(int pid, int & now, unsigned char *buff, int len, int timeout);  bool AddPid(int pid);  void CutOff(int now);  };cPidHopper::cPidHopper(int DvbNum, int NumFilters):cAction("pidhopper",DvbNum){  numFilters=NumFilters;  d=MALLOC(struct FilterData,NumFilters);  memset(d,0,sizeof(struct FilterData)*NumFilters);  PRINTF(L_SYS_HOPPER,"pid hopper started (%d filters)",numFilters);}cPidHopper::~cPidHopper(){  Lock();  int now=time_ms(), num=1;  PRINTF(L_SYS_HSTATS,"active pids: (now=%d)\n",now);  for(int i=0; i<numFilters; i++) {    struct FilterData *dd=&d[i];    if(dd->filter) {      if(dd->filter->Pid()>=0)        PRINTF(L_SYS_HSTATS,"%2d. pid %04x lastTime=%4d lastRead=%4d created=%4d count=%4d",                num++,                dd->filter->Pid(),                dd->lastTime>0 ? (now-dd->lastTime)/1000 : -1,                dd->lastRead>0 ? (now-dd->lastRead)/1000 : -1,                dd->createTime>0 ? (now-dd->createTime)/1000 : -1,                dd->readCount);      DelFilter(dd->filter);      dd->filter=0;      }    PurgeFilter(dd);    }  Unlock();  free(d);}void cPidHopper::PurgeFilter(struct FilterData *dd){  if(dd->first && dd->last) PurgePacket(dd,dd->last);}void cPidHopper::PurgePacket(struct FilterData *dd, struct FilterPacket *p){  while(dd->first) {    struct FilterPacket *del=dd->first;    dd->first=del->next;    if(dd->filter) PRINTF(L_SYS_HOPPER,"PID %04x purging packet %p (time=%d)",dd->filter->Pid(),del,del->lastTime);    free(del);    if(del==p) break;    }  if(!dd->first) dd->last=0;}void cPidHopper::CutOff(int now){  Lock();  PRINTF(L_SYS_HOPPER,"cutoff (now=%d)",now);  for(int i=0; i<numFilters; i++) {    struct FilterData *dd=&d[i];    struct FilterPacket *p=dd->first, *del=0;    while(p) {      if(p->lastTime>=now) break;      del=p;      p=p->next;      }    if(del) {      PurgePacket(dd,del);      dd->lastTime=dd->first ? dd->first->lastTime : -1;      }    }  Unlock();}cPidFilter *cPidHopper::CreateFilter(const char *Id, int Num, int DvbNum, int IdleTime){  cPidFilter *filter=new cPesFilter(Id,Num,DvbNum,IdleTime);  d[Num].filter=filter;  d[Num].lastTime=-1;  d[Num].lastRead=-1;  d[Num].createTime=time_ms();  d[Num].readCount=0;  d[Num].first=0;  d[Num].last=0;  return filter;}void cPidHopper::Process(cPidFilter *filter, unsigned char *data, int len){  if(data && len>0) {    int now=time_ms();    for(int i=0; i<numFilters; i++)      if(d[i].filter==filter) {        do {          int l=min(len,184);          struct FilterPacket *p=(struct FilterPacket *)malloc(sizeof(struct FilterPacket)+l-1);          if(p) {            p->next=0;            memcpy(p->lastData,data,l);            p->dataLen=l;            p->lastTime=now;            if(d[i].first)              d[i].last->next=p;            else {              d[i].first=p;              d[i].lastTime=now;              }            d[i].last=p;            PRINTF(L_SYS_HOPPER,"PID %04x queued packet %p (time=%d len=%d) (%s)",d[i].filter->Pid(),p,p->lastTime,l,d[i].first==p?"first":"queue");            }          len-=l; data+=l;          } while(len>0);        sleep.Broadcast();        break;        }    }}bool cPidHopper::AddPid(int pid){  cPidFilter *filter=NewFilter(0);  if(!filter) return false;  filter->Start(pid,0,0,0,false);  return true;}int cPidHopper::Read(int pid, int & now, unsigned char *buff, int len, int timeout){  Lock();  timeout+=time_ms();  PRINTF(L_SYS_HOPPER,"PID %04x read (now=%d)",pid,now);  int n=-1;  while(time_ms()<timeout) {    struct FilterData *dd=0, *old=0;    for(int i=0; i<numFilters; i++)      if(d[i].filter) {        if(d[i].filter->Pid()==pid) { dd=&d[i]; break; }        if(!old ||           (d[i].lastRead<0 && d[i].createTime<old->createTime) ||           (d[i].lastRead>=0 && d[i].lastRead<old->lastRead))          old=&d[i];        }    if(!dd) {      LBSTARTF(L_SYS_VERBOSE);      LBPUT("NEW ");      if(!AddPid(pid)) {        if(!old) break;        LBPUT("{0x%04x/%d/%d} ",old->filter->Pid(),old->lastRead>0 ? (time_ms()-old->lastRead)/1000:-1,old->lastTime>0 ? (time_ms()-old->lastTime)/1000:-1);        old->filter->Stop(); // purge LRU filter        PurgeFilter(old);        old->lastTime=-1;        old->lastRead=-1;        old->createTime=time_ms();        old->readCount=0;        old->filter->Start(pid,0,0,0,false);        }      LBEND();      continue;      }    for(struct FilterPacket *p=dd->first; p; p=p->next) {      if(p->lastTime>=now) {        n=min(len,p->dataLen);        memcpy(buff,p->lastData,n);        now=p->lastTime;        PRINTF(L_SYS_HOPPER,"PID %04x returning packet %p (time=%d)",dd->filter->Pid(),p,p->lastTime);        PurgePacket(dd,p);        dd->lastRead=time_ms();        dd->readCount++;        dd->lastTime=dd->first ? dd->first->lastTime : -1;        break;        }      else {        PRINTF(L_SYS_HOPPER,"PID %04x skipping packet %p (time=%d)",dd->filter->Pid(),p,p->lastTime);        if(!p->next) {          PRINTF(L_SYS_HOPPER,"PID %04x queue empty",dd->filter->Pid());          PurgePacket(dd,p);          break;          }        }      }    if(n>0) break;    Unlock();    sleepMutex.Lock();    sleep.TimedWait(sleepMutex,200);    sleepMutex.Unlock();    Lock();    }  Unlock();  return n;}// -- cShl ---------------------------------------------------------------------class cShl {private:  DES_key_schedule sched;public:  void SetKey( const unsigned char *key);  void Decode(unsigned char *data, int n);  };void cShl::SetKey(const unsigned char *key){  DES_key_sched((DES_cblock *)key,&sched);}void cShl::Decode(unsigned char *data, int n){  int r=n&7;  n-=r;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -