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

📄 tps.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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 <stdlib.h>#include <unistd.h>#include <string.h>#include <libsi/section.h>#include "viaccess.h"#include "log-viaccess.h"#include "tps.h"#include "opentv.h"#include "st20.h"#include "sc.h"#include "scsetup.h"#include "system-common.h"#include "filter.h"#include "misc.h"#include "helper.h"#define CHECK_TIME    5*60*1000#define LOADBIN_TIME 60*60*1000#define TPSAU_TIME   30*60*1000//#define TRUST_BOXTIME // should we trust the local time on this machine?//#define DUMP_TPSAU "/var/tmp"// -- cRC6 ---------------------------------------------------------------------/* * This code implements the RC6-32/20 block cipher. * * The algorithm is due to Ron Rivest and RSA Labs. This code is based on code * which was written by Martin Hinner <mhi@penguin.cz> in 1999, no copyright is * claimed. */#define RC6_WORDSIZE	32#define RC6_P32		0xB7E15163L#define RC6_Q32		0x9E3779B9Lunsigned int cRC6::rol(unsigned int v, unsigned int cnt){  cnt&=(RC6_WORDSIZE-1);  return (v<<cnt) | (v>>(RC6_WORDSIZE-cnt));}unsigned int cRC6::ror(unsigned int v, unsigned int cnt){  cnt&=(RC6_WORDSIZE-1);  return (v>>cnt) | (v<<(RC6_WORDSIZE-cnt));}void cRC6::SetKey(const unsigned char *Key, int len){  key[0]=RC6_P32;  for(int v=1; v<RC6_MAX; v++) key[v]=key[v-1]+RC6_Q32;  len/=4;  unsigned int a=0, b=0, l[len];  memcpy(l,Key,len*4);  for(int i=0,j=0,v=3*(len>RC6_MAX ? len : RC6_MAX) ; v>0; v--) {    a=key[i]=rol(key[i]+a+b,3);    b=  l[j]=rol(  l[j]+a+b,a+b);    i++; i%=RC6_MAX;    j++; j%=len;    }}void cRC6::Decrypt(unsigned char *data){  unsigned int *l=(unsigned int *)data;  unsigned int a, b, c, d;  a=l[0]-key[RC6_MAX-2];  b=l[1];  c=l[2]-key[RC6_MAX-1];  d=l[3];  for(int i=RC6_ROUNDS; i>0; i--) {    unsigned int t=a;    unsigned int u=b;    a=d; d=c; b=t; c=u;    u=rol((d*(2*d+1)),5);    t=rol((b*(2*b+1)),5);    c=ror(c-key[2*i+1],t)^u;    a=ror(a-key[2*i  ],u)^t;    }  l[0]=a;  l[1]=b-key[0];  l[2]=c;  l[3]=d-key[1];}// -- cTransponderTime ---------------------------------------------------------class cTransponderTime : public cSimpleItem {private:  time_t sattime;  cTimeMs reftime;  cMutex mutex;  cCondVar wait;  int source, transponder;  bool hasHandler;public:  cTransponderTime(int Source, int Transponder);  bool Is(int Source, int Transponder) const;  void Set(time_t st);  time_t Now(void);  void SetHasHandler(bool on) { hasHandler=on; }  bool HasHandler(void) const { return hasHandler; }  };cTransponderTime::cTransponderTime(int Source, int Transponder){  source=Source; transponder=Transponder;#ifdef TRUST_BOXTIME  sattime=time(0);#else  sattime=-1;#endif  hasHandler=false;}bool cTransponderTime::Is(int Source, int Transponder) const{  return source==Source && transponder==Transponder;}void cTransponderTime::Set(time_t st){  cMutexLock lock(&mutex);  if(sattime<0 || reftime.Elapsed()>5*1000) {    reftime.Set(-100);    sattime=st;    wait.Broadcast();    char str[32];    struct tm utm;    st=Now();    time_t now=time(0);    gmtime_r(&st,&utm); asctime_r(&utm,str); stripspace(str);    PRINTF(L_SYS_TIME,"%x:%x: %s (delta %ld)",source,transponder,str,st-now);    }}time_t cTransponderTime::Now(void){  cMutexLock lock(&mutex);  if(sattime<0) {    if(!wait.TimedWait(mutex,3*1000)) {      PRINTF(L_SYS_TIME,"%x:%x: unsuccessfull wait",source,transponder);      return -1;      }    }  return sattime+(reftime.Elapsed()/1000);}// -- cSatTimeHook -------------------------------------------------------------class cSatTimeHook : public cLogHook {private:  cTransponderTime *ttime;public:  cSatTimeHook(cTransponderTime *Ttime);  ~cSatTimeHook();  virtual void Process(int pid, unsigned char *data);  };cSatTimeHook::cSatTimeHook(cTransponderTime *Ttime):cLogHook(HOOK_SATTIME,"sattime"){  ttime=Ttime;  pids.AddPid(0x14,0x71,0xff,0x03);  ttime->SetHasHandler(true);}cSatTimeHook::~cSatTimeHook(){  ttime->SetHasHandler(false);}void cSatTimeHook::Process(int pid, unsigned char *data){  if(data && ttime) {    if(data[0]==0x70) { // TDT      SI::TDT tdt(data,false);      tdt.CheckParse();      ttime->Set(tdt.getTime());      }    else if(data[0]==0x73) { // TOT      SI::TOT tot(data,false);      if(!tot.CheckCRCAndParse()) return;      ttime->Set(tot.getTime());      }    }}// -- cSatTime -----------------------------------------------------------------class cSatTime {private:  static cMutex mutex;  static cSimpleList<cTransponderTime> list;  //  int cardNum;  cTransponderTime *ttime;  //  void CheckHandler(void);public:  cSatTime(int CardNum, int Source, int Transponder);  time_t Now(void);  };cMutex cSatTime::mutex;cSimpleList<cTransponderTime> cSatTime::list;cSatTime::cSatTime(int CardNum, int Source, int Transponder){  cardNum=CardNum;  cMutexLock lock(&mutex);  for(ttime=list.First(); ttime; ttime=list.Next(ttime))    if(ttime->Is(Source,Transponder)) break;  if(!ttime) {    ttime=new cTransponderTime(Source,Transponder);    if(ttime) list.Add(ttime);    PRINTF(L_SYS_TIME,"%x:%x: created new transpondertime",Source,Transponder);    }  else PRINTF(L_SYS_TIME,"%x:%x: using existing transpondertime",Source,Transponder);  CheckHandler();}time_t cSatTime::Now(void){  CheckHandler();  return ttime ? ttime->Now() : -1;}void cSatTime::CheckHandler(void){  if(ttime) {    if(!cSoftCAM::TriggerHook(cardNum,HOOK_SATTIME) && !ttime->HasHandler()) {      cSatTimeHook *hook=new cSatTimeHook(ttime);      cSoftCAM::AddHook(cardNum,hook);      PRINTF(L_SYS_TIME,"added hook");      }    }}// -- cOpenTVModule ------------------------------------------------------------class cOpenTVModule {private:  int id, modlen;  unsigned char *mem;  int received;  info_header_t info;  code_header_t code;  data_header_t data;  //  bool Decompress(void);  bool DoDecompress(unsigned char *out_ptr, const unsigned char *in_ptr, int dsize, int data_size, int usize);  bool ParseSections(void);  void Dump(void);public:  cOpenTVModule(const unsigned char *data);  ~cOpenTVModule();  int AddPart(const unsigned char *data, int len);  const info_header_t *InfoHdr(void) const { return &info; }  const code_header_t *CodeHdr(void) const { return &code; }  const data_header_t *DataHdr(void) const { return &data; }  //  inline static int Id(const unsigned char *data) { return UINT16_BE(&data[3]); }  inline static int Offset(const unsigned char *data) { return UINT32_BE(&data[16]); }  inline static int Length(const unsigned char *data) { return UINT32_BE(&data[20]); }  };cOpenTVModule::cOpenTVModule(const unsigned char *data){  id=Id(data); modlen=Length(data);  received=0;  mem=MALLOC(unsigned char,modlen);}cOpenTVModule::~cOpenTVModule(){  free(mem);}int cOpenTVModule::AddPart(const unsigned char *data, int slen){  if(Id(data)==id) {    int off=Offset(data);    int mlen=Length(data);    int rec=slen-28;    if(mlen!=modlen || (off+rec)>mlen || !mem) {      PRINTF(L_SYS_TPSAU,"length mismatch while adding to OpenTV module");      return -1;      }    memcpy(&mem[off],data+24,rec);    received+=rec;    if(received==mlen) {      if(!Decompress()) {        PRINTF(L_SYS_TPSAU,"failed to decompress OpenTV module");        return -1;        }      if(!ParseSections()) {        PRINTF(L_SYS_TPSAU,"DATA & CODE section not located in OpenTV module");        return -1;        }      Dump();      return 1;      }    }  return 0;}void cOpenTVModule::Dump(void){#ifdef DUMP_TPSAU#warning Dumping TPS AU data  {  char fname[32];  snprintf(fname,sizeof(fname),"%s/decomp.bin.%d.%x",DUMP_TPSAU,getpid(),(int)time(0));  int fd=open(fname,O_CREAT|O_TRUNC|O_WRONLY,DEFFILEMODE);  if(fd>=0) {    write(fd,mem,modlen);    close(fd);    PRINTF(L_SYS_TPSAU,"dumped to file '%s'",fname);    }  }#endif}bool cOpenTVModule::ParseSections(void){  int sections=0;  for(int idx=0; idx<modlen;) {    unsigned int hdr=UINT32_BE(mem+idx);    unsigned int s_len=UINT32_BE(mem+idx+4);    switch(hdr) {      case INFO_SECTION_HDR:	info.magic=hdr;	info.bsssize=UINT32_BE(mem+idx+8);	info.stacksize=UINT32_BE(mem+idx+12);        sections|=1;        break;      case CODE_SECTION_HDR:	code.magic=hdr;	code.size=s_len-8;	code.m_id=UINT32_BE(mem+idx+8);	code.entry_point=UINT16_BE(mem+idx+12);	code.end=UINT16_BE(mem+idx+14);	code.code=mem+idx+8;        sections|=2;        break;      case DATA_SECTION_HDR:	data.magic=hdr;	data.dlen=s_len-8;	data.data=mem+idx+8;        sections|=4;        break;      case SWAP_SECTION_HDR:      case GDBO_SECTION_HDR:        break;      case LAST_SECTION_HDR:      case 0:        idx=modlen;        break;      case COMP_SECTION_HDR:        PRINTF(L_GEN_DEBUG,"OpenTV module still compressed in ParseSections()");        return 0;      default:        PRINTF(L_SYS_TPSAU,"unknown section hdr %08x (%c%c%c%c) in OpenTV module",hdr,(hdr>>24)&0xFF,(hdr>>16)&0xFF,(hdr>>8)&0xFF,hdr&0xFF);        break;      }    idx+=s_len;

⌨️ 快捷键说明

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