|
SASC-NG
DVBSoftCAM
|
Inheritance diagram for cCardClientCCcam: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) |
Protected Member Functions | |
| virtual void | Action (void) |
| 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 | ( | ) |
| 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.
| 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.
| 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;
}