SASC-NG
DVBSoftCAM

cCardClientRadegast Class Reference

Inheritance diagram for cCardClientRadegast:

List of all members.

Public Member Functions

 cCardClientRadegast (const char *Name)
virtual bool Init (const char *config)
virtual bool Login (void)
virtual bool CanHandle (unsigned short SysId)
virtual bool ProcessECM (const cEcmInfo *ecm, const unsigned char *source, unsigned char *cw)
virtual bool ProcessEMM (int caSys, const unsigned char *data)

Detailed Description

Definition at line 31 of file radegast.c.


Constructor & Destructor Documentation

cCardClientRadegast::cCardClientRadegast ( const char *  Name)

Definition at line 59 of file radegast.c.

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

:cCardClient(Name)
{
  InitVars();
  so.SetRWTimeout(7*1000);
}

Member Function Documentation

bool cCardClientRadegast::CanHandle ( unsigned short  SysId) [virtual]

Reimplemented from cCardClient.

Definition at line 71 of file radegast.c.

References i.

Referenced by ProcessECM().

{
  cMutexLock lock(this);
  if(numCaids<=0) return cCardClient::CanHandle(SysId);
  for(int i=0; i<numCaids; i++) if(caids[i]==SysId) return true;
  return false;
}
bool cCardClientRadegast::Init ( const char *  config) [virtual]

Implements cCardClient.

Definition at line 79 of file radegast.c.

References cCardClient::Logout(), and cCardClient::ParseStdConfig().

{
  cMutexLock lock(this);
  Logout();
  return ParseStdConfig(config);
}
bool cCardClientRadegast::Login ( void  ) [virtual]

Implements cCardClient.

Definition at line 170 of file radegast.c.

References caid, cCardClient::CaidsChanged(), cNetSocket::Connect(), cCardClient::emmAllowed, cCardClient::hostname, i, L_CC_EMM, L_CC_LOGIN, L_CC_RDGD, LBEND, LBPUT, LBSTARTF, cCardClient::Logout(), MAXCAIDS, cCardClient::name, cCardClient::port, PRINTF, ScVersion, and cCardClient::so.

Referenced by ProcessECM().

{
  Logout();
  if(!so.Connect(hostname,port)) return false;
  PRINTF(L_CC_LOGIN,"%s: connected to %s:%d",name,hostname,port);

  InitVars();
  unsigned char buff[512];
  char hello[32];
  snprintf(hello,sizeof(hello),"rdgd/vdr-sc-%s",ScVersion);
  StartMsg(buff,0x90);                  // RDGD_MSG_CLIENT_HELLO
  AddNano(buff,1,strlen(hello),(unsigned char *)hello); // RDGD_NANO_DESCR
  if(!Send(buff) || Recv(buff,sizeof(buff))<0) return false;
  if(buff[0]==0x91) {
    PRINTF(L_CC_RDGD,"got server hello, assuming V4 mode");
    StartMsg(buff,0x94);                // RDGD_MSG_CLIENT_CAP_REQ;
    int n;
    if(!Send(buff) || (n=Recv(buff,sizeof(buff)))<0) return false;
    if(buff[0]==0x95) {
      LBSTARTF(L_CC_LOGIN);
      LBPUT("radegast: got caps");
      int caid;
      for(int l=GetNanoStart(buff); l<n; l+=buff[l+1]+2) {
        switch(buff[l]) {
          case 0xE2:
            LBPUT(" VERS %s",(char *)&buff[l+2]);
            break;
          case 0xE4: // CAP_NANO_CAID
            if(numCaids>=MAXCAIDS) { l=n; break; } //stop processing
            caid=(buff[l+2]<<8)+buff[l+3];
            LBPUT(" CAID %04X",caid);
            caids[numCaids++]=caid;
            // XXX we should have EMM processing setup here, but as we don't
            // XXX get any ua/sa we cannot filter EMM anyways
            break;
          case 0xE5: // CAP_NANO_PROVID
            for(int i=0; i<buff[l+1]; i+=3)
              LBPUT("/%02X%02X%02X",buff[l+2+i],buff[l+2+i+1],buff[l+2+i+2]);
            break;
          }
        }
      LBEND();
      }
    }
  else PRINTF(L_CC_RDGD,"no server hello, assuming old mode");
  if(emmProcessing && !emmAllowed) 
    PRINTF(L_CC_EMM,"%s: EMM disabled from config",name);
  CaidsChanged();
  return true;
}
bool cCardClientRadegast::ProcessECM ( const cEcmInfo *  ecm,
const unsigned char *  source,
unsigned char *  cw 
) [virtual]

Implements cCardClient.

Definition at line 221 of file radegast.c.

References cEcmInfo::caId, CanHandle(), CheckNull(), cNetSocket::Connected(), cNetSocket::Flush(), cParseViaccess::KeyNr(), cParseSeca::KeyNr(), L_CC_ECM, L_CC_RDGD, Login(), cCardClient::name, PRINTF, cEcmInfo::provId, SCT_LEN, and cCardClient::so.

{
  cMutexLock lock(this);
  if((!so.Connected() && !Login()) || !CanHandle(ecm->caId)) return false;
  so.Flush();
  int len=SCT_LEN(source);
  int keynr=-1;
  switch(ecm->caId>>8) {
    case 0x01: // Seca
      keynr=cParseSeca::KeyNr(source)&0x0F; break;
    case 0x05: // Viaccess
      keynr=cParseViaccess::KeyNr(source); break;
    case 0x18: // Nagra2
      if(ecm->caId>=0x1801) keynr=(source[7]&0x10) | 0x86;
      break;
    }
  unsigned char buff[512], tmp[10];
  StartMsg(buff,1);                     // CMD_ECM_KEY_ASK
  AddNano(buff,2,1,ecm->caId>>8);       // ECM_NANO_CAID_INDEX (old)
  AddNano(buff,10,2,ecm->caId);         // ECM_NANO_CAID
  sprintf((char *)tmp,"%08X",ecm->provId);
  AddNano(buff,6,8,tmp);                // ECM_NANO_PROVIDER
  if(keynr>=0) {
    sprintf((char *)tmp,"%04X",keynr);
    AddNano(buff,7,4,tmp);              // ECM_NANO_KEYNO
    }
  if(!CheckLength(buff,len)) return false;
  AddNano(buff,3,len,source);           // ECM_NANO_PACKET

  if(!Send(buff) || (len=Recv(buff,sizeof(buff)))<0) return false;
  if(buff[0]==2) {
    for(int l=GetNanoStart(buff); l<len; l+=buff[l+1]+2) {
      switch(buff[l]) {
        case 0x05:
          if(buff[l+1]==16) {
            // check for zero cw, as someone may not send both cw's every time
            if(!CheckNull(buff+l+ 2,8)) memcpy(cw+0,buff+l+ 2,8);
            if(!CheckNull(buff+l+10,8)) memcpy(cw+8,buff+l+10,8);
            return true;
            }
          else PRINTF(L_CC_RDGD,"wrong cw length %d from server",buff[l+1]);
          break;
        case 0x04:
          PRINTF(L_CC_ECM,"%s: key not available from server",name);
          break;
        default:
          PRINTF(L_CC_RDGD,"unknown nano %02x in ECM response",buff[l]);
          break;
        }
      }
    }
  else PRINTF(L_CC_RDGD,"bad ECM response from server %02x != 02",buff[0]);
  return false;
}
bool cCardClientRadegast::ProcessEMM ( int  caSys,
const unsigned char *  data 
) [virtual]

Reimplemented from cCardClient.

Definition at line 276 of file radegast.c.

References cAssembleData::Assembled(), cMsgCache::Cache(), cCardClient::emmAllowed, cMsgCache::Get(), cIdSet::MatchAndAssemble(), cCardClient::msEMM, cProvider::ProvId(), and SCT_LEN.

{
  if(emmProcessing && emmAllowed) {
    cMutexLock lock(this);
    int upd;
    cProvider *p;
    cAssembleData ad(data);
    if(MatchAndAssemble(&ad,&upd,&p)) {
      while((data=ad.Assembled())) {
        int len=SCT_LEN(data);
        int id=msEMM.Get(data,len,0);
        if(id>0 || emmAllowed>1) {
          unsigned char buff[512];
          StartMsg(buff,0x41);                  //
          AddNano(buff,0x42,2,caSys);           // EMM_CAID
          if(p) {
            unsigned char tmp[10];
            sprintf((char *)tmp,"%08X",(int)p->ProvId());
            AddNano(buff,0x46,8,tmp);           // EMM_PROVID
            }
/*
          if(upd==2 || upd==3) {
            AddNano(buff,0x44,2,(unsigned char *)"aa"); // EMM_ADDR_VAL
            }
*/
          AddNano(buff,0x45,1,upd==3 ? 0x11 : (upd==2 ? 0x12 : 0x13)); // EMM_ADDR_TYPE
          if(CheckLength(buff,len)) {
            AddNano(buff,0x43,len,data);        // EMM_CA_DATA
            Send(buff);
            }
          msEMM.Cache(id,true,0);
          }
        }
      return true;
      }
    }
  return false;
}

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