SASC
DVBSoftCAM

cCardClientCCcam Class Reference

Inheritance diagram for cCardClientCCcam:

List of all members.

Public Member Functions

 cCardClientCCcam (const char *Name)
 ~cCardClientCCcam ()
virtual bool Init (const char *CfgDir)
virtual bool Login (void)
virtual bool ProcessECM (const cEcmInfo *ecm, const unsigned char *data, unsigned char *Cw)
 cCardClientCCcam (const char *Name)
 ~cCardClientCCcam ()
virtual bool Init (const char *CfgDir)
virtual bool Login (void)
virtual bool ProcessECM (const cEcmInfo *ecm, const unsigned char *data, unsigned char *Cw)

Protected Member Functions

virtual void Action (void)
virtual void Action (void)

Detailed Description

Definition at line 164 of file cccam.c.


Constructor & Destructor Documentation

cCardClientCCcam::cCardClientCCcam ( const char *  Name)

Definition at line 182 of file cccam.c.

References cNetSocket::SetRWTimeout(), cNetSocket::SetUDP(), and cCardClient::so.

:cCardClient(Name)
,cThread("CCcam listener")
{
  pmtversion=0; socketpath=0;
  so.SetRWTimeout(2*1000);
  so.SetUDP(true);
}
cCardClientCCcam::~cCardClientCCcam ( )

Definition at line 191 of file cccam.c.

References cThread::Cancel(), and free.

{
  Cancel(3);
  free(socketpath);
}
cCardClientCCcam::cCardClientCCcam ( const char *  Name)
cCardClientCCcam::~cCardClientCCcam ( )

Member Function Documentation

void cCardClientCCcam::Action ( void  ) [protected, virtual]

A derived cThread class must implement the code it wants to execute as a separate thread in this function. If this is a loop, it must check Running() repeatedly to see whether it's time to stop.

Implements cThread.

Definition at line 315 of file cccam.c.

References cw, L_CC_CCCAM, LDUMP, cCCcamCard::NewCw(), cNetSocket::Read(), cThread::Running(), and cCardClient::so.

{
  unsigned char cw[18];
  while(Running()) {
    if(so.Read(cw,sizeof(cw))>0) {
      LDUMP(L_CC_CCCAM,cw+2,16,"got: %02x%02x ",cw[0],cw[1]);
      if(cw[1]==0x0f && cw[0]<4)
        card[cw[0]].NewCw(cw+2);
      }
    }
}
virtual void cCardClientCCcam::Action ( void  ) [protected, virtual]

A derived cThread class must implement the code it wants to execute as a separate thread in this function. If this is a loop, it must check Running() repeatedly to see whether it's time to stop.

Implements cThread.

bool cCardClientCCcam::Init ( const char *  CfgDir) [virtual]

Implements cCardClient.

Definition at line 197 of file cccam.c.

References i, L_CC_CORE, cCardClient::Logout(), cCardClient::name, cCardClient::ParseStdConfig(), PRINTF, and Setup.

{
  cMutexLock lock(this);
  int num=0;
  char path[256];
  Logout();
  if(!ParseStdConfig(config,&num)
     || sscanf(&config[num],":%255[^:]",path)!=1) return false;
  PRINTF(L_CC_CORE,"%s: socket=%s",name,path);
  socketpath=strdup(path);
  for(int i=0; i<4; i++) card[i].Setup(i,socketpath);
  return true;
}
virtual bool cCardClientCCcam::Init ( const char *  CfgDir) [virtual]

Implements cCardClient.

virtual bool cCardClientCCcam::Login ( void  ) [virtual]

Implements cCardClient.

bool cCardClientCCcam::Login ( void  ) [virtual]

Implements cCardClient.

Definition at line 211 of file cccam.c.

References cNetSocket::Bind(), L_CC_CCCAM, cCardClient::Logout(), cCardClient::port, PRINTF, cNetSocket::SetQuietLog(), cCardClient::so, and cThread::Start().

Referenced by ProcessECM().

{
  Logout();
  if(!so.Bind("127.0.0.1",port)) return false;
  so.SetQuietLog(true);
  PRINTF(L_CC_CCCAM,"Bound to port %d, starting UDP listener",port);
  Start();
  return true;
}
bool cCardClientCCcam::ProcessECM ( const cEcmInfo *  ecm,
const unsigned char *  data,
unsigned char *  Cw 
) [virtual]

Implements cCardClient.

Definition at line 221 of file cccam.c.

References AUTOMEM, cEcmInfo::caId, cCardClient::CanHandle(), cCCcamCard::Connected(), cNetSocket::Connected(), cCCcamCard::Disconnect(), DMX_POS, cEcmInfo::dvbAdapter, cEcmInfo::dvbFrontend, cEcmInfo::ecm_pid, cEcmInfo::GetCaDescr(), cCCcamCard::GetCw(), HEXDUMP, L_CC_CCCAM, LEN_POS, Login(), cCCcamCard::NewCaPmt(), cCCcamCard::Pid(), PID_POS, PRG_POS, cEcmInfo::prgId, PRINTF, PRIV_POS, cEcmInfo::provId, cCardClient::so, cEcmInfo::transponder, VERS_POS, and cCCcamCard::WriteCaPmt().

{
  cMutexLock lock(this);
  if((!so.Connected() && !Login()) || !CanHandle(ecm->caId)) return false;

  if(ecm->dvbAdapter<0 || ecm->dvbFrontend!=0) {
    PRINTF(L_CC_CCCAM,"cannot handle DVB adapter %d, frontend %d",ecm->dvbAdapter,ecm->dvbFrontend);
    return false;
    }
  int cardnum=ecm->dvbAdapter;

  cCCcamCard *c=&card[cardnum];
  int timeout=3000;
  if(ecm->ecm_pid!=c->Pid() || !c->Connected()) { // channel change
    int n;
    const unsigned char *descr=ecm->GetCaDescr(&n);
    if(!descr) {
      PRINTF(L_CC_CCCAM,"%d: no CA descriptor for caid %04x sid %d prov %04x",cardnum,ecm->caId,ecm->prgId,ecm->provId);
      return false;
      }

    static const unsigned char pmt[] = {
      0x9f,0x80,0x32,0x82,0xFF,0xFF,
      0x01,
#define PRG_POS 7
      0xFF,0xFF,                                          // prg-nr
#define VERS_POS 9
      0xFF,                                               // version
#define LEN_POS 10
      0xFF,0xFF,                                          // prg-info-len
      0x01,                                               // ca pmt command
#define PRIV_POS 13
      0x81,0x08,0x00,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,  // private descr
#define DMX_POS 23
     0x82,0x02,0xFF,0xFF,                                // demuxer stuff
#define PID_POS 27
      0x84,0x02,0xFF,0xFF                                 // pmt pid
      };
    unsigned char *capmt=AUTOMEM(sizeof(pmt)+n+32);
    memcpy(capmt,pmt,sizeof(pmt));
    int wp=sizeof(pmt);
    int len=wp-LEN_POS-2;
    capmt[PRG_POS]=ecm->prgId>>8;
    capmt[PRG_POS+1]=ecm->prgId&0xff;
    capmt[VERS_POS]=pmtversion;
    pmtversion=(pmtversion+1)&0x1f;
    capmt[PRIV_POS+4]=cardnum;
    capmt[PRIV_POS+6]=ecm->transponder>>8;
    capmt[PRIV_POS+7]=ecm->transponder&0xFF;
    capmt[PRIV_POS+8]=ecm->provId>>8;
    capmt[PRIV_POS+9]=ecm->provId&0xFF;
    capmt[DMX_POS+2]=1<<cardnum ;
    capmt[DMX_POS+3]=cardnum ;
    capmt[PID_POS+2]=ecm->ecm_pid>>8;
    capmt[PID_POS+3]=ecm->ecm_pid&0xFF;
    memcpy(&capmt[wp],descr,n);
    len+=n; wp+=n;
    capmt[wp++]=0x01;
    capmt[wp++]=0x0f;
    capmt[wp++]=cardnum;   // cccam uses this one as PID to program ca0
    capmt[wp++]=0x00;      //es_length
    capmt[wp++]=0x06;      //es ca_pmt_cmd_id
    capmt[LEN_POS]=((len&0xf00)>>8);
    capmt[LEN_POS+1]=(len&0xff);
    capmt[4]=(wp-6)>>8;
    capmt[5]=(wp-6)&0xff;

    HEXDUMP(L_CC_CCCAM,capmt,wp,"%d: sending capmts for pid %04x",cardnum,ecm->ecm_pid);
    c->NewCaPmt(ecm->ecm_pid,capmt,wp);
    timeout=6000;
    }
  if(!c->GetCw(cw,timeout)) {
    PRINTF(L_CC_CCCAM,"%d: getting CW timedout, re-writing CAPMT",cardnum);
    // somethings up, so we will send capmt again.
    c->WriteCaPmt();
    if(!c->GetCw(cw,timeout)) {
      PRINTF(L_CC_CCCAM,"%d: getting CW timedout again, failed ECM",cardnum);
      c->Disconnect();
      failedcw++;
      if(failedcw>=10) {
        // CCcam is having problems lets mark it for a restart....
        PRINTF(L_CC_CCCAM,"%d: marked CCcam for restart",cardnum);
        FILE *f=fopen("/tmp/killCCcam","w+");
        fclose(f);
        failedcw=0;
        }
      return false;
      }
    }
  PRINTF(L_CC_CCCAM,"%d: got a CW",cardnum);
  failedcw=0;
  return true;
}
virtual bool cCardClientCCcam::ProcessECM ( const cEcmInfo *  ecm,
const unsigned char *  data,
unsigned char *  Cw 
) [virtual]

Implements cCardClient.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines