SASC-NG
DVBSoftCAM

cScCamSlot Class Reference

Inheritance diagram for cScCamSlot:

List of all members.

Public Member Functions

 cScCamSlot (cCam *Cam, const char *DevId, int Slot)
void Process (const unsigned char *data, int len)
eModuleStatus Status (void)
bool Reset (bool log=true)
cCiFrame * Frame (void)

Detailed Description

Definition at line 1745 of file cam.c.


Constructor & Destructor Documentation

cScCamSlot::cScCamSlot ( cCam *  Cam,
const char *  DevId,
int  Slot 
)

Definition at line 1771 of file cam.c.

References msReset, cCamSlot::Reset(), and cCiFrame::SetRb().

:cCamSlot(Cam)
,checkTimer(-SLOT_CAID_CHECK-1000)
,rb(KILOBYTE(4),5+LEN_OFF,false,"SC-CI slot answer")
{
  cam=Cam; devId=DevId; slot=Slot;
  version=0; caids[0]=0; doReply=false; lastStatus=msReset;
  frame.SetRb(&rb);
  Reset(false);
}

Member Function Documentation

cCiFrame* cScCamSlot::Frame ( void  ) [inline]

Definition at line 1768 of file cam.c.

Referenced by cCam::Write().

{ return &frame; }
void cScCamSlot::Process ( const unsigned char *  data,
int  len 
)

Definition at line 1870 of file cam.c.

References cSimpleListBase::Add(), cCam::AddPrg(), b, cPrgPid::caDescr, cPrg::caDescr, data, cCiFrame::GetBuff(), L_CORE_CI, LBEND, LBPUT, LBSTARTF, cPrg::pids, PRINTF, cCiFrame::Put(), cCaDescr::Set(), cPrg::SetPidCaDescr(), cPrg::sid, and cCam::Stop().

Referenced by cCam::Write().

{
  const unsigned char *save=data;
  data+=3;
  int dlen=GetLength(data);
  if(dlen>len-(data-save)) {
    PRINTF(L_CORE_CI,"%s.%d TDPU length exceeds data length",devId,slot);
    dlen=len-(data-save);
    }
  int tcid=data[0];

  if(Check()) CaInfo(tcid,0x01);

  if(dlen<8 || data[1]!=0x90) return;
  int cid=(data[3]<<8)+data[4];
  int tag=(data[5]<<16)+(data[6]<<8)+data[7];
  data+=8;
  dlen=GetLength(data);
  if(dlen>len-(data-save)) {
    PRINTF(L_CORE_CI,"%s.%d tag length exceeds data length",devId,slot);
    dlen=len-(data-save);
    }
  switch(tag) {
    case 0x9f8030: // AOT_CA_INFO_ENQ
      CaInfo(tcid,cid);
      break;

    case 0x9f8032: // AOT_CA_PMT
      if(dlen>=6) {
        int ca_lm=data[0];
        int ci_cmd=-1;
        cPrg *prg=new cPrg((data[1]<<8)+data[2],ca_lm==5);
        int ilen=(data[4]<<8)+data[5];
        LBSTARTF(L_CORE_CI);
        LBPUT("%s.%d CA_PMT decoding len=%x lm=%x prg=%d len=%x",devId,slot,dlen,ca_lm,(data[1]<<8)+data[2],ilen);
        data+=6; dlen-=6;
        LBPUT("/%x",dlen);
        if(ilen>0 && dlen>=ilen) {
          ci_cmd=data[0];
          if(ilen>1)
            prg->caDescr.Set(&data[1],ilen-1);
          LBPUT(" ci_cmd(G)=%02x",ci_cmd);
          }
        data+=ilen; dlen-=ilen;
        while(dlen>=5) {
          cPrgPid *pid=new cPrgPid(data[0],(data[1]<<8)+data[2]);
          prg->pids.Add(pid);
          ilen=(data[3]<<8)+data[4];
          LBPUT(" pid=%d,%x len=%x",data[0],(data[1]<<8)+data[2],ilen);
          data+=5; dlen-=5;
          LBPUT("/%x",dlen);
          if(ilen>0 && dlen>=ilen) {
            ci_cmd=data[0];
            if(ilen>1) {
              pid->caDescr.Set(&data[1],ilen-1);
              prg->SetPidCaDescr(true);
              }
            LBPUT(" ci_cmd(S)=%x",ci_cmd);
            }
          data+=ilen; dlen-=ilen;
          }
        LBEND();
        PRINTF(L_CORE_CI,"%s.%d got CA pmt ciCmd=%d caLm=%d",devId,slot,ci_cmd,ca_lm);
        if(doReply && (ci_cmd==0x03 || (ci_cmd==0x01 && ca_lm==0x03))) {
          unsigned char *b;
          if((b=frame.GetBuff(4+11))) {
            b[0]=0xa0; b[2]=tcid;
            b[3]=0x90;
            b[4]=0x02; b[5]=cid<<8; b[6]=cid&0xff;
            b[7]=0x9f; b[8]=0x80; b[9]=0x33; // AOT_CA_PMT_REPLY
            b[11]=prg->sid<<8;
            b[12]=prg->sid&0xff;
            b[13]=0x00;
            b[14]=0x81;         // CA_ENABLE
            b[10]=4; b[1]=4+9;
            frame.Put();
            PRINTF(L_CORE_CI,"%s.%d answer to query",devId,slot);
            }
          }
        if(prg->sid!=0) {
          if(ci_cmd==0x04 || (ci_cmd==-1 && ca_lm==0x03)) {
            PRINTF(L_CORE_CI,"%s.%d stop decrypt",devId,slot);
            cam->Stop();
            }
          if(ci_cmd==0x01 || (ci_cmd==-1 && (ca_lm==0x04 || ca_lm==0x05))) {
            PRINTF(L_CORE_CI,"%s.%d set CAM decrypt (prg %d)",devId,slot,prg->sid);
            cam->AddPrg(prg);
            }
          }
        delete prg;
        }
      break;
    }
}
bool cScCamSlot::Reset ( bool  log = true)

Definition at line 1802 of file cam.c.

References L_CORE_CI, PRINTF, cTimeMs::Set(), and SLOT_RESET_TIME.

Referenced by cCam::Reset().

{
  reset=true; resetTimer.Set(SLOT_RESET_TIME);
  rb.Clear();
  if(log) PRINTF(L_CORE_CI,"%s.%d: reset",devId,slot);
  return true;
}
eModuleStatus cScCamSlot::Status ( void  )

Definition at line 1782 of file cam.c.

References L_CORE_CI, msPresent, msReady, msReset, PRINTF, and cTimeMs::TimedOut().

Referenced by cCam::ModuleStatus().

{
  eModuleStatus status;
  if(reset) {
    status=msReset;
    if(resetTimer.TimedOut()) reset=false;
    }
  else if(caids[0]) status=msReady;
  else {
    status=msPresent; //msNone;
    Check();
    }
  if(status!=lastStatus) {
    static const char *stext[] = { "none","reset","present","ready" };
    PRINTF(L_CORE_CI,"%s.%d: status '%s'",devId,slot,stext[status]);
    lastStatus=status;
    }
  return status;
}

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