./ MultiCS.r69 / th-ecm.c
#define MAXSRVTAB 255
struct srvtab_data
{
struct cs_server_data *srv;
struct cs_card_data *card; // selected card
uint32_t shareid; // Selected Card ShareID
int uphops;
int val; // sid value
unsigned int ecmtime; // Card Ecmtime
uint32 ecmperhr;
};
struct srvtab_data srvlist[MAXSRVTAB];
struct srvtab_data *psrvlist[MAXSRVTAB];
struct srvtab_data *srvtemp;
int srvtab_arrange(struct cardserver_data *cs, int ecmid, int bestone )
{
ECM_DATA *ecm = getecmbyid(ecmid);
int i,j;
int nbsrv = 0;
struct cs_server_data *srv;
memset( srvlist, 0 , sizeof(srvlist) );
nbsrv = 0;
// MULTICARD Servers Selection (Newcamd,CCcam,Mgcamd...) ;)
unsigned int ticks = GetTickCount();
srv = cfg.server;
while ( srv && (nbsrv<MAXSRVTAB) ) {
if ( !IS_DISABLED(srv->flags)&&(srv->handle>0) )
if (
( cs->option.fallownewcamd&&(srv->type==TYPE_NEWCAMD) )
|| ( cs->option.fallowcccam&&(srv->type==TYPE_CCCAM) )
|| ( cs->option.fallowradegast&&(srv->type==TYPE_RADEGAST) )
)
// Remove Circular request: check for client ip & srv ip
if ( (srv->host->ip==0x0100007F) || !ecm_checkip(ecmid, srv->host->ip) )
{
// Check for CS PORTS
for(i=0; i<MAX_CSPORTS; i++ ) {
if (!srv->csport[i]) break;
if (srv->csport[i]==cs->newcamd.port) {
i=0;
break;
}
}
if (i==0) { // ADD TO PROFILE
//Check for used servers, dont reuse
for (i=0; i<20;i++) {
if (!ecm->server[i].srvid) break;
if (ecm->server[i].srvid==srv->id) break;
}
if ( (i>=20)||(ecm->server[i].srvid!=srv->id) ) {
// Check for ECM TIMEOUT
if ( (srv->busy)&&((srv->lastecmtime+20000)<ticks) ) { // timeout
debugf(getdbgflag(DBG_SERVER,0,srv->id)," ??? server (%s:%d) doesnt send ecm answer\n", srv->host->name,srv->port);
srv->ecmtimeout++;
srv->busy = 0;
if (srv->type==TYPE_CCCAM) cc_disconnect_srv(srv);
else if (srv->type==TYPE_NEWCAMD) cs_disconnect_srv(srv);
}
else {
// Check for newcamd server sids
i = 0;
if ( srv->sids && (srv->type==TYPE_NEWCAMD) ) {
struct sid_chid_data *sid = srv->sids;
for(i=0; i<MAX_SIDS; i++,sid++) {
if ( sid->sid==0 ) break;
if (sid->sid==ecm->sid)
if (!sid->chid || (sid->chid==ecm->chid) ) { i=0; break; }
}
}
if (i==0) {
// check for any card to decode
pthread_mutex_lock(&srv->lock);
struct cs_card_data *pcard = srv_findcard( srv, cs, ecm->caid, ecm->provid ); // check if isthere any available card
if ( pcard ) {
srvlist[nbsrv].srv = srv;
srvlist[nbsrv].card = pcard; // default card
srvlist[nbsrv].shareid = pcard->shareid; // default card
srvlist[nbsrv].uphops = pcard->uphops;
srvlist[nbsrv].val = 0;
psrvlist[nbsrv] = &srvlist[nbsrv];
nbsrv++;
}
pthread_mutex_unlock(&srv->lock);
}
}
}
}
}
srv = srv->next;
}
// ARRANGE BY SID/TIME FILTER
#ifdef SID_FILTER
//Check FAILED SIDS
struct cs_card_data *card=NULL;
i=0;
for(j=0; j<nbsrv; j++) {
pthread_mutex_lock(&psrvlist[j]->srv->lock);
// best card to decode is selected, it may there is only worst one but is returned
psrvlist[j]->val = sidata_getval( psrvlist[j]->srv, cs, ecm->caid, ecm->provid, ecm->sid, &card);
// if ( psrvlist[j]->val > -100 )
if ( !cs->option.maxfailedecm || (psrvlist[j]->val > -cs->option.maxfailedecm) ) { // available card+sid : block card that have decode failed on sid
if (card) {
psrvlist[j]->card = card;
psrvlist[j]->shareid = card->shareid;
psrvlist[j]->uphops = card->uphops;
if (psrvlist[j]->srv->type==TYPE_CCCAM)
if (card->ecmok>10) psrvlist[j]->ecmtime = card->ecmoktime/card->ecmok; else psrvlist[j]->ecmtime = 0;
else
if (psrvlist[j]->srv->ecmok>10) psrvlist[j]->ecmtime = psrvlist[j]->srv->ecmoktime/psrvlist[j]->srv->ecmok; else psrvlist[j]->ecmtime = 0;
if ( !cs->option.server.validecmtime || (psrvlist[j]->ecmtime<cs->option.server.validecmtime) ) {
if (psrvlist[j]->srv->type==TYPE_CCCAM) {
if (card) {
if (i<j) psrvlist[i] = psrvlist[j];
i++;
}
}
else {
if (i<j) psrvlist[i] = psrvlist[j];
i++;
}
}
}
}
pthread_mutex_unlock(&psrvlist[j]->srv->lock);
}
psrvlist[i] = NULL;
nbsrv = i;
#endif
//Remove Cardservers with delay time
if (cs->option.server.timeperecm) {
i=0;
for(j=0; j<nbsrv; j++) {
//if ( (psrvlist[j]->srv->host->ip!=0x0100007F)&&(psrvlist[j]->srv->type==TYPE_NEWCAMD) )
if ( (psrvlist[j]->srv->type==TYPE_NEWCAMD) ) {
unsigned int msperecm = ( (ticks-psrvlist[j]->srv->connected) + psrvlist[j]->srv->uptime ) / (psrvlist[j]->srv->ecmnb+1);
unsigned int tim;
if ( msperecm > (2*cs->option.server.timeperecm) ) tim = 0;
else if ( msperecm > cs->option.server.timeperecm ) tim = (2*cs->option.server.timeperecm)-msperecm;
else tim = cs->option.server.timeperecm;
if ( (psrvlist[j]->srv->lastecmtime+tim)<=ticks ) {
if (i<j) psrvlist[i] = psrvlist[j];
i++;
}
}
else {
if (i<j) psrvlist[i] = psrvlist[j];
i++;
}
}
psrvlist[i] = NULL;
nbsrv = i;
}
//debugf(" srvtab_arrange(%04x:%06x:%04x) %d\n", ecm->caid, ecm->provid, ecm->sid, nbsrv);
if (!nbsrv) return -1;
// Remove Busy Servers
i=0;
for(j=0; j<nbsrv; j++) {
if (!psrvlist[j]->srv->busy) {
if (i<j) psrvlist[i] = psrvlist[j];
i++;
}
}
psrvlist[i] = NULL;
nbsrv = i;
//// ARRANGE
// Arrange by ECM LAST SENT TIME
for(i=0; i<nbsrv-1; i++)
for(j=i+1; j<nbsrv; j++)
if ( psrvlist[i]->srv->lastecmtime > psrvlist[j]->srv->lastecmtime ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
#ifdef SID_FILTER
ticks=GetTickCount();
for(i=0; i<nbsrv; i++)
psrvlist[i]->ecmperhr = (psrvlist[i]->srv->ecmnb*3600*1000) / ( 1+ (ticks-psrvlist[i]->srv->connected)+psrvlist[i]->srv->uptime );
if (!bestone)
// Arrange by ECM LAST SENT TIME && unbusy state & sid ok
for(i=0; i<nbsrv-1; i++)
for(j=i+1; j<nbsrv; j++)
if (psrvlist[i]->srv->busy == psrvlist[j]->srv->busy ) {
if ( (psrvlist[j]->val>=0)&&(psrvlist[j]->srv->priority==1)&&(psrvlist[i]->srv->priority==0) ) { // check if using local card
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
else if (psrvlist[i]->val>=0) {
if (psrvlist[j]->val>=0) {
// Check for card uphops
if (psrvlist[i]->uphops > psrvlist[j]->uphops) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
else if ( psrvlist[i]->ecmperhr > psrvlist[j]->ecmperhr ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
}
else if (psrvlist[i]->val==-1) {
if (psrvlist[j]->val>=0) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
else if (psrvlist[j]->val==-1) {
if ( psrvlist[i]->ecmperhr > psrvlist[j]->ecmperhr ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
}
else {
if (psrvlist[j]->val>=-1) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
else {
if ( psrvlist[i]->ecmperhr > psrvlist[j]->ecmperhr ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
}
}
else {
if ( psrvlist[i]->srv->busy ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
else
for(i=0; i<nbsrv-1; i++)
for(j=i+1; j<nbsrv; j++)
if (psrvlist[i]->srv->busy == psrvlist[j]->srv->busy ) {
if (psrvlist[i]->val>0) {
if (psrvlist[j]->val>0) {
if ( ( psrvlist[i]->ecmperhr > psrvlist[j]->ecmperhr ) ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
}
else if (psrvlist[i]->val==0) {
if (psrvlist[j]->val>0) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
else if (psrvlist[j]->val==0) {
if ( ( psrvlist[i]->ecmperhr > psrvlist[j]->ecmperhr ) ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
}
else {
if (psrvlist[j]->val>=0) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
else {
if ( psrvlist[i]->val < psrvlist[j]->val ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
}
}
else {
if ( psrvlist[i]->srv->busy ) {
srvtemp = psrvlist[i];
psrvlist[i] = psrvlist[j];
psrvlist[j] = srvtemp;
}
}
#endif
return nbsrv;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// SELECT & SEND ECM TO servers
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Check sending ecm to servers
///////////////////////////////////////////////////////////////////////////////
uint32 check_sendecm()
{
// Send priority
// 1.Send to all ecm's that wasnt send yet
// 2.Send to all ecm's that having send only once
// 3.Send to all ecm's that having send only twice
//XXX ...
uint restime = GetTickCount() + 10000;
uint ecmtime = restime;
struct cs_server_data *newsrv;
int lastecmid = nextecmid(srvmsgid);
int ecmid = lastecmid;
while ( (ecmid=prevecmid(ecmid)) != lastecmid ) {
ECM_DATA *ecm = getecmbyid(ecmid);
uint32 ticks = GetTickCount();
ecm->checktime = 0;
// CACHE(fallowcache = 1)
if (ecm->dcwstatus==STAT_DCW_WAITCACHE) {
struct cardserver_data *cs = getcsbyid( ecm->csid );
if (!cs) {
ecm->statusmsg = "Invalid profile id";
ecm->dcwstatus = STAT_DCW_FAILED;
continue;
}
if (cs->option.fallowcache) {
if (!ecm->waitcache) { // Not done
//debugf(" send pipe cache\n");
if (cs->option.fallowcache && pipe_send_cache_find( ecm, cs)) {
ecm->waitcache = 1;
ecmtime = ecm->recvtime+cs->option.cachetimeout;
ecm->checktime = ecm->recvtime+cs->option.cachetimeout;
}
else ecm->dcwstatus = STAT_DCW_WAIT;
}
else {
if ( ( (ecm->recvtime+cs->option.cachetimeout)<=ticks ) ) ecm->dcwstatus = STAT_DCW_WAIT;
else {
//debugf(" Wait for cache\n");
ecmtime = ecm->recvtime+cs->option.cachetimeout;
ecm->checktime = ecm->recvtime+cs->option.cachetimeout;
}
}
} else ecm->dcwstatus = STAT_DCW_WAIT;
if (restime>ecmtime) restime = ecmtime;
}
// SEND ECM
if ( (ecm->dcwstatus==STAT_DCW_WAIT) ) {
// Check Profile
struct cardserver_data *cs = getcsbyid( ecm->csid );
if (!cs) {
ecm->statusmsg = "Invalid profile id";
ecm->dcwstatus = STAT_DCW_FAILED;
cs_dcw_check_time=0;
#ifdef MGCAMD_SRV
mg_dcw_check_time = 0;
#endif
#ifdef CCCAM_SRV
cc_dcw_check_time = 0;
#endif
#ifdef FREECCCAM_SRV
frcc_dcw_check_time = 0;
#endif
#ifdef RADEGAST_SRV
rdgd_dcw_check_time = 0;
#endif
continue;
}
//check for decode failed
int nbservers = ecm_nbsentsrv(ecm);
int waitsrv = ecm_nbwaitsrv(ecm);
// Check for Max used Servers
if ( (cs->option.server.max>0) && (nbservers>=cs->option.server.max) ) {
if (!waitsrv) {
ecm->statusmsg = "Decode failed, max servers is reached and no more servers to wait";
ecm->dcwstatus = STAT_DCW_FAILED;
cs_dcw_check_time=0;
#ifdef MGCAMD_SRV
mg_dcw_check_time = 0;
#endif
#ifdef CCCAM_SRV
cc_dcw_check_time = 0;
#endif
#ifdef FREECCCAM_SRV
frcc_dcw_check_time = 0;
#endif
#ifdef RADEGAST_SRV
rdgd_dcw_check_time = 0;
#endif
// Send DCW to Cache if not sent
if ( cs->option.fallowcache && cs->option.cachesendrep && (ecm->cachestatus!=ECM_CACHE_REP) ) {
//pipe_send_cache_reply(ecm,cs); // Send failed Cache Reply
ecm->cachestatus = ECM_CACHE_REP;
}
}
}
// Check for ECM TimeOut
else if ( (ticks-ecm->recvtime) >= cs->option.dcw.timeout ) {
if (!waitsrv) {
ecm->statusmsg = "Decode failed, dcw timeout";
ecm->dcwstatus = STAT_DCW_FAILED;
cs_dcw_check_time=0;
#ifdef MGCAMD_SRV
mg_dcw_check_time = 0;
#endif
#ifdef CCCAM_SRV
cc_dcw_check_time = 0;
#endif
#ifdef FREECCCAM_SRV
frcc_dcw_check_time = 0;
#endif
#ifdef RADEGAST_SRV
rdgd_dcw_check_time = 0;
#endif
// Send DCW to Cache if not sent
if ( cs->option.fallowcache && cs->option.cachesendrep && (ecm->cachestatus!=ECM_CACHE_REP) ) {
//pipe_send_cache_reply(ecm,cs); // Send failed Cache Reply
ecm->cachestatus = ECM_CACHE_REP;
}
}
}
// Check for ECM sending
else if ((ticks-ecm->recvtime)<=cs->option.server.timeout) { // ~ cfg.cardserver.option.dcw.timeout*2/3 is the cardserver timeout
// check for decode failed with no remaining server to wait, send to new cardserver
if ( !waitsrv
|| (cs->option.server.first>nbservers)
|| ((ticks-ecm->lastsendtime)>=cs->option.server.interval)
) {
//debugf(" check_sendecm(): ECM -> CardServer '%s' ch %04x:%06x:%04x\n", cs->name,ecm->caid,ecm->provid,ecm->sid);
newsrv = NULL;
if ( srvtab_arrange(cs, ecmid, nbservers > 0 )==-1 ) { // No more servers to decode
//debugf(" sendecm: no servers found to decode\n");
if (!waitsrv) {
ecm->statusmsg = "Decode failed, No servers found to decode";
ecm->dcwstatus = STAT_DCW_FAILED;
cs_dcw_check_time=0;
#ifdef MGCAMD_SRV
mg_dcw_check_time = 0;
#endif
#ifdef CCCAM_SRV
cc_dcw_check_time = 0;
#endif
#ifdef FREECCCAM_SRV
frcc_dcw_check_time = 0;
#endif
#ifdef RADEGAST_SRV
rdgd_dcw_check_time = 0;
#endif
// Send DCW to Cache if not sent
if ( cs->option.fallowcache && cs->option.cachesendrep && (ecm->cachestatus!=ECM_CACHE_REP) ) {
//pipe_send_cache_reply(ecm,cs); //Send Failed Cache Reply
ecm->cachestatus=ECM_CACHE_REP;
}
}
else {
ecm->checktime = ecm->lastrecvtime+cs->option.server.timeout;
ecmtime = ecm->lastrecvtime+cs->option.server.timeout;
if (restime>ecmtime) restime = ecmtime;
}
continue;
}
else if (psrvlist[0] && psrvlist[0]->srv) {
newsrv = psrvlist[0]->srv;
newsrv->busycard = psrvlist[0]->card; // dont save pointers!!!
newsrv->busycardid = psrvlist[0]->shareid;
}
else {
ecm->statusmsg = "Wait for available servers";
#ifdef BUSY_SERVER
if (!waitsrv && !nbservers) {
ecm->statusmsg = "Decode failed, no free server";
ecm->dcwstatus = STAT_DCW_FAILED;
cs_dcw_check_time=0;
#ifdef MGCAMD_SRV
mg_dcw_check_time = 0;
#endif
#ifdef CCCAM_SRV
cc_dcw_check_time = 0;
#endif
#ifdef FREECCCAM_SRV
frcc_dcw_check_time = 0;
#endif
#ifdef RADEGAST_SRV
rdgd_dcw_check_time = 0;
#endif
cs->ecmbusysrv++;
}
#endif
continue;
}
// SEND ECM
if ( newsrv && !newsrv->busy ) {// time to send ecm
if ((ticks-ecm->lastrecvtime+cs->option.server.interval)<cs->option.server.timeout) {
ecm->checktime = ecm->lastsendtime+cs->option.server.interval;
ecmtime = ecm->lastsendtime+cs->option.server.interval;
}
else {
ecm->checktime = ecm->lastrecvtime+cs->option.dcw.timeout;
ecmtime = ecm->lastrecvtime+cs->option.dcw.timeout;
}
//debugf(" sendecm: selected server to decode (%s:%d)\n", newsrv->host->name, newsrv->port);
if (newsrv->type==TYPE_NEWCAMD) {
if (cs_sendecm_srv(cs, newsrv, ecm)>0) {
ecm->lastsendtime = GetTickCount();
debugf(getdbgflagpro(DBG_SERVER,0,newsrv->id,cs->id)," -> ecm to server%d (%s:%d) ch %04x:%06x:%04x\n",nbservers,newsrv->host->name,newsrv->port,ecm->caid,ecm->provid,ecm->sid);
newsrv->lastecmtime = GetTickCount();
newsrv->ecmnb++;
newsrv->busy=1;
newsrv->busyecmid = ecmid;
newsrv->busyecmhash = ecm->hash;
newsrv->retry=0;
ecm_addsrv(ecm, newsrv->id);
if ( cs->option.fallowcache && cs->option.cachesendreq && !nbservers && (ecm->cachestatus==ECM_CACHE_NONE) ) pipe_send_cache_request(ecm,cs);
ecm->cachestatus = ECM_CACHE_REQ;
}
}
#ifdef CCCAM_CLI
else if (newsrv->type==TYPE_CCCAM) {
if (cc_sendecm_srv(newsrv, ecm)>0) {
ecm->lastsendtime = GetTickCount();
debugf(getdbgflagpro(DBG_SERVER,0,newsrv->id,cs->id)," -> ecm to CCcam server%d (%s:%d) ch %04x:%06x:%04x\n",nbservers,newsrv->host->name,newsrv->port,ecm->caid,ecm->provid,ecm->sid);
newsrv->lastecmtime = GetTickCount();
newsrv->ecmnb++;
struct cs_card_data *card = cc_getcardbyid( newsrv, newsrv->busycardid );
if (card) card->ecmnb++;
newsrv->busy=1;
newsrv->busyecmid = ecmid;
newsrv->busyecmhash = ecm->hash;
newsrv->retry=0;
ecm_addsrv(ecm, newsrv->id);
if ( cs->option.fallowcache && cs->option.cachesendreq && !nbservers && (ecm->cachestatus==ECM_CACHE_NONE) ) pipe_send_cache_request(ecm,cs);
ecm->cachestatus = ECM_CACHE_REQ;
}
}
#endif
#ifdef RADEGAST_CLI
else if (newsrv->type==TYPE_RADEGAST) {
if (rdgd_sendecm_srv(newsrv, ecm)>0) {
ecm->lastsendtime = GetTickCount();
debugf(getdbgflagpro(DBG_SERVER,0,newsrv->id,cs->id)," -> ecm to Radegast server%d (%s:%d) ch %04x:%06x:%04x\n",nbservers,newsrv->host->name,newsrv->port,ecm->caid,ecm->provid,ecm->sid);
newsrv->lastecmtime = GetTickCount();
newsrv->ecmnb++;
newsrv->busy=1;
newsrv->busyecmid = ecmid;
newsrv->busyecmhash = ecm->hash;
newsrv->retry=0;
ecm_addsrv(ecm, newsrv->id);
if ( cs->option.fallowcache && cs->option.cachesendreq && !nbservers && (ecm->cachestatus==ECM_CACHE_NONE) ) pipe_send_cache_request(ecm,cs);
ecm->cachestatus = ECM_CACHE_REQ;
}
}
#endif
ecm->statusmsg = "Waiting for servers...";
if (restime>ecmtime) restime = ecmtime;
}
}
}
else if (!waitsrv) {
ecm->statusmsg = "Decode failed, no server open this channel";
ecm->dcwstatus = STAT_DCW_FAILED;
cs_dcw_check_time=0;
#ifdef MGCAMD_SRV
mg_dcw_check_time = 0;
#endif
#ifdef CCCAM_SRV
cc_dcw_check_time = 0;
#endif
#ifdef FREECCCAM_SRV
frcc_dcw_check_time = 0;
#endif
#ifdef RADEGAST_SRV
rdgd_dcw_check_time = 0;
#endif
// Send DCW to Cache if not sent
if ( cs->option.fallowcache && cs->option.cachesendrep && (ecm->cachestatus!=ECM_CACHE_REP) ) {
//pipe_send_cache_reply(ecm,cs); //Send Failed Cache Reply
ecm->cachestatus = ECM_CACHE_REP;
}
}
}
}
return (restime+1);
}
///////////////////////////////////////////////////////////////////////////////
// SEND ECM THREAD
///////////////////////////////////////////////////////////////////////////////
void recv_ecm_pipe()
{
uint16 sid;
uint16 caid;
uint32 hash;
uchar buf[1024];
int ecmid;
struct pollfd pfd[2];
do {
int len = pipe_recv( srvsocks[0], buf);
if (len>0) {
switch(buf[0]) {
case PIPE_LOCK:
pthread_mutex_lock(&prg.lockmain);
pthread_mutex_unlock(&prg.lockmain);
break;
case PIPE_CACHE_FIND_FAILED:
//debugf(" ecm check PIPE_CACHE_FIND_FAILED\n");
//Search for ecm
sid = (buf[3]<<8) | buf[4];
caid = (buf[7]<<8) | buf[8];
hash = (buf[9]<<24) | (buf[10]<<16) | (buf[11]<<8) | (buf[12]);
pthread_mutex_lock(&prg.lockecm); //###
ecmid = search_ecmdata_byhash( hash );
if (ecmid!=-1) {
ECM_DATA *ecm = getecmbyid(ecmid);
if ( (ecm->caid==caid)&&(ecm->hash==hash)&&(ecm->sid==sid)&&(ecm->dcwstatus==STAT_DCW_WAITCACHE) ) {
ecm->dcwstatus = STAT_DCW_WAIT;
}
} // else debugf(" pipe: ecm not found (%08X)\n",hash);
pthread_mutex_unlock(&prg.lockecm); //###
break;
case PIPE_CACHE_FIND_SUCCESS: // SET DCW
//Search for ecm
sid = (buf[3]<<8) | buf[4];
caid = (buf[7]<<8) | buf[8];
hash = (buf[9]<<24) | (buf[10]<<16) | (buf[11]<<8) | (buf[12]);
int peerid = (buf[13]<<8) | buf[14];
//debugf(" ecm check PIPE_CACHE_FIND_SUCCESS %04x:%04x:%08x\n",caid, sid, hash); debughex(buf,len);
pthread_mutex_lock(&prg.lockecm); //###
int ecmid = search_ecmdata_byhash( hash );
if (ecmid!=-1) {
ECM_DATA *ecm = getecmbyid(ecmid);
if ( (ecm->caid==caid)&&(ecm->hash==hash)&&(ecm->sid==sid)&&(ecm->dcwstatus!= STAT_DCW_SUCCESS) ) {
struct cardserver_data *cs = getcsbyid(ecm->csid);
struct cachepeer_data *peer = getpeerbyid(peerid);
if (cs&&peer) if (cs->option.fallowcache) ecm_setdcw( cs, ecm, buf+15, DCW_SOURCE_CACHE, peer->id);
}
} // else debugf(" pipe: ecm not found (%08X)\n",hash);
pthread_mutex_unlock(&prg.lockecm); //###
break;
}
}
pfd[0].fd = srvsocks[0];
pfd[0].events = POLLIN | POLLPRI;
} while (poll(pfd, 1, 0)>0);
}
char *src2string(int srctype, int srcid, char *ret)
{
static char ss1[] = "server";
static char ss2[] = "cache peer";
static char ss3[] = "newcamd client";
if (srctype==DCW_SOURCE_SERVER) {
struct cs_server_data *srv = getsrvbyid(srcid);
if (srv)
sprintf( ret,"server (%s:%d)", srv->host->name, srv->port);
else
sprintf( ret,"Unknow server (id=%d)", srcid);
return ss1;
}
else if (srctype==DCW_SOURCE_CACHE) {
struct cachepeer_data *peer = getpeerbyid(srcid);
if (peer)
sprintf( ret,"cache peer (%s:%d)", peer->host->name, peer->port);
else
sprintf( ret,"Unknown cache peer (id=%d)", srcid);
return ss2;
}
#ifdef SRV_CSCACHE
else if (srctype==DCW_SOURCE_CSCLIENT) {
// srcid = (csid<<16)|cliid;
struct cardserver_data *cs = getcsbyid( srcid>>16 );
if (cs) {
struct cs_client_data *cli = getnewcamdclientbyid( srcid&0xffff );
if (cli) {
sprintf( ret,"newcamd client '%s'", cli->user);
return ss3;
}
}
sprintf( ret,"Unknown newcamd client (id=%x)", srcid);
return ss3;
}
else if (srctype==DCW_SOURCE_MGCLIENT) {
// srcid = (csid<<16)|cliid;
struct mg_client_data *cli = getmgcamdclientbyid( srcid );
if (cli)
sprintf( ret,"mgcamd client '%s'", cli->user);
else
sprintf( ret,"Unknown mgcamd client (id=%d)", srcid);
return ss3;
}
#endif
else {
sprintf( ret,"Unknown Source (%d/%d)", srctype, srcid);
}
return NULL;
}
void ecm_setdcw( struct cardserver_data *cs, ECM_DATA *ecm, uchar dcw[16], int srctype, int srcid)
{
pthread_mutex_lock(&prg.lockdcw);
if (ecm->dcwstatus!=STAT_DCW_SUCCESS) {
// Search for SAME DCW
int ecmid = search_ecmdata_bycw( dcw, ecm->hash, ecm->sid, ecm->caid, ecm->provid);
if (ecmid==-1) {
#ifdef CHECK_NEXTDCW
if (cs && cs->option.dcw.check)
if ( !checkfreeze_setdcw(ecm->srvmsgid,dcw) ) {
pthread_mutex_unlock(&prg.lockdcw);
return;
}
#endif
ecm->statusmsg = "Decode Success";
int instant = (ecm->dcwstatus==STAT_DCW_WAITCACHE);
ecm->dcwsrctype = srctype;
ecm->dcwsrcid = srcid;
ecm->dcwstatus = STAT_DCW_SUCCESS;
memcpy( ecm->cw, dcw, 16 );
if (cs) {
uint ecmtime = GetTickCount()-ecm->recvtime;
if (ecmtime<cs->option.dcw.timeout) {
cs->ecmok++;
cs->ecmoktime += ecmtime;
int time = (ecmtime+50)/100;
if (time<100) cs->ttime[time]++; else cs->ttime[100]++;
if (srctype==DCW_SOURCE_CACHE) {
struct cachepeer_data *peer = getpeerbyid(srcid);
if (peer) {
// setup peer last used cache
peer->lastcaid = ecm->caid;
peer->lastprov = ecm->provid;
peer->lastsid = ecm->sid;
peer->lastdecodetime = ecmtime;
peer->hitnb++;
cs->cachehits++;
cfg.cache.hits++;
if (instant) {
peer->ihitnb++;
cs->cacheihits++;
cfg.cache.ihits++;
}
}
if (time<100) cs->ttimecache[time]++; else cs->ttimecache[100]++;
}
else if (srctype==DCW_SOURCE_SERVER) {
if (time<100) cs->ttimecards[time]++; else cs->ttimecards[100]++;
}
#ifdef SRV_CSCACHE
else if (srctype==DCW_SOURCE_CSCLIENT) {
// srcid = (csid<<16)|cliid;
struct cardserver_data *cs = getcsbyid( srcid>>16 );
if (cs) {
struct cs_client_data *cli = getnewcamdclientbyid( srcid&0xffff );
if (cli) cli->cachedcw++;
}
//
if (time<100) cs->ttimeclients[time]++; else cs->ttimeclients[100]++;
}
else if (srctype==DCW_SOURCE_MGCLIENT) {
struct mg_client_data *cli = getmgcamdclientbyid(srcid);
if (cli) cli->cachedcw++;
if (time<100) cs->ttimeclients[time]++; else cs->ttimeclients[100]++;
}
#endif
// Send DCW to Cache if not sent
if ( cs->option.fallowcache && cs->option.cachesendrep && ecm->cachestatus!=ECM_CACHE_REP ) {
pipe_send_cache_reply(ecm,cs); //Send Good Cache Reply
ecm->cachestatus = ECM_CACHE_REP;
}
}
}
// Send DCW to clients
cs_dcw_check_time=0;
#ifdef MGCAMD_SRV
mg_dcw_check_time = 0;
#endif
#ifdef CCCAM_SRV
cc_dcw_check_time = 0;
#endif
#ifdef FREECCCAM_SRV
frcc_dcw_check_time = 0;
#endif
#ifdef RADEGAST_SRV
rdgd_dcw_check_time = 0;
#endif
#ifdef CLI_CSCACHE
// Send to Newcamd Cached Servers
int i;
for( i=0; i<20; i++ ) {
if (!ecm->server[i].srvid) break;
if (ecm->server[i].flag==ECM_SRV_REQUEST) {
struct cs_server_data *srv = getsrvbyid(ecm->server[i].srvid);
if (!srv) continue;
if (!srv->busy) continue;
if ( (srv->type==TYPE_NEWCAMD)&&(srv->cscached) ) { // Send DCW to server
struct cs_custom_data srvcd;
unsigned char buf[32];
srvcd.msgid = srv->busyecmid;
srvcd.caid = ecm->caid;
srvcd.sid = ecm->sid;
srvcd.provid = ecm->provid;
buf[0] = ecm->ecm[0] | 0x40; // 0xC0 | 0xC1
buf[2] = 0x10;
memcpy(&buf[3], &ecm->cw,16);
cs_message_send( srv->handle, &srvcd, buf, 19, srv->sessionkey);
}
}
}
#endif
}
}
pthread_mutex_unlock(&prg.lockdcw);
}
#ifdef MSGTHREAD
#define TYPE_SERVER 1
#define TYPE_CLIENT_NEWCAMD 2
#define TYPE_CLIENT_CCCAM 3
#define TYPE_CLIENT_MGCAMD 4
struct recvmsg_data {
int type;
union {
struct cs_server_data *srv;
struct cc_client_data *cccli;
struct mg_client_data *mgcli;
struct cs_client_data *cscli;
};
struct cardserver_data *cs;
pthread_t lastthreadid;
};
void *recv_msg(struct recvmsg_data *data)
{
if (data->type==TYPE_SERVER) {
if (data->srv->type==TYPE_NEWCAMD) cs_srv_recvmsg(data->srv);
#ifdef CCCAM_CLI
else if (data->srv->type==TYPE_CCCAM) cc_srv_recvmsg(data->srv);
#endif
#ifdef RADEGAST_CLI
else if (data->srv->type==TYPE_RADEGAST) rdgd_srv_recvmsg(data->srv);
#endif
}
else if (data->type==TYPE_CLIENT_CCCAM) {
cc_cli_recvmsg(data->cccli);
}
else if (data->type==TYPE_CLIENT_MGCAMD) {
mg_cli_recvmsg(data->mgcli);
}
else if (data->type==TYPE_CLIENT_NEWCAMD) {
cs_cli_recvmsg(data->cscli,data->cs);
}
if ( !pthread_equal(data->lastthreadid, prg.tid_msg) ) {
pthread_join(data->lastthreadid, NULL);
}
free( data );
return NULL;
}
#endif
///////////////////////////////////////////////////////////////////////////////
// RECEIVE MESSAGES THREAD
///////////////////////////////////////////////////////////////////////////////
struct pollfd pfd[4000];
int pfdcount = 0;
void *recv_msg_thread(void *param)
{
prg.pid_msg = syscall(SYS_gettid);
prg.tid_msg = pthread_self();
uint32 katicks = GetTickCount()+ 20000; // KeepAlive for servers
while(1) {
pthread_t lastthreadid = pthread_self();
// getmintime
uint32 mintime = cs_dcw_check_time;
#ifdef MGCAMD_SRV
if (mintime>mg_dcw_check_time) mintime=mg_dcw_check_time;
#endif
#ifdef CCCAM_SRV
if (mintime>cc_dcw_check_time) mintime=cc_dcw_check_time;
#endif
#ifdef FREECCCAM_SRV
if (mintime>frcc_dcw_check_time) mintime=frcc_dcw_check_time;
#endif
#ifdef RADEGAST_SRV
if (mintime>rdgd_dcw_check_time) mintime=rdgd_dcw_check_time;
#endif
if (mintime>ecm_check_time) mintime=ecm_check_time;
uint ticks = GetTickCount();
uint ms;
if (mintime>(ticks+3)) ms = mintime-ticks; else ms = 3;
pfdcount = 0;
// PIPE
pfd[pfdcount].fd = srvsocks[0];
pfd[pfdcount++].events = POLLIN | POLLPRI;
//Servers
struct cs_server_data *srv = cfg.server;
while (srv) {
if ( !IS_DISABLED(srv->flags)&&(srv->handle>0) ) {
srv->ipoll = pfdcount;
pfd[pfdcount].fd = srv->handle;
pfd[pfdcount++].events = POLLIN | POLLPRI;
} else srv->ipoll = -1;
srv = srv->next;
}
// Check KA for newcamd Servers
if (katicks<ticks) {
struct cs_server_data *srv = cfg.server;
while (srv) {
if ( !IS_DISABLED(srv->flags)&&(srv->handle>0)&&(srv->type==TYPE_NEWCAMD) ) cs_check_keepalive(srv);
srv = srv->next;
}
katicks = ticks + 10000;
}
#ifdef CCCAM_SRV
struct cccamserver_data *cccam = cfg.cccam.server;
while (cccam) {
if ( !IS_DISABLED(cccam->flags)&&(cccam->handle>0) ) {
struct cc_client_data *cccli = cccam->client;
while (cccli) {
if ( !IS_DISABLED(cccli->flags)&&(cccli->handle>0) ) {
cccli->ipoll = pfdcount;
pfd[pfdcount].fd = cccli->handle;
pfd[pfdcount++].events = POLLIN | POLLPRI;
} else cccli->ipoll = -1;
cccli = cccli->next;
}
}
cccam = cccam->next;
}
#endif
#ifdef FREECCCAM_SRV
// srv-cccam
if ( !IS_DISABLED(cfg.freecccam.server.flags)&&(cfg.freecccam.server.handle>0) ) {
struct cc_client_data *fcccli = cfg.freecccam.server.client;
while (fcccli) {
if ( !IS_DISABLED(fcccli->flags)&&(fcccli->handle>0) ) {
fcccli->ipoll = pfdcount;
pfd[pfdcount].fd = fcccli->handle;
pfd[pfdcount++].events = POLLIN | POLLPRI;
} else fcccli->ipoll = -1;
fcccli = fcccli->next;
}
}
#endif
#ifdef MGCAMD_SRV
struct mgcamdserver_data *mgcamd = cfg.mgcamd.server;
while (mgcamd) {
if ( !IS_DISABLED(mgcamd->flags)&&(mgcamd->handle>0) ) {
struct mg_client_data *cli = mgcamd->client;
while (cli) {
if ( !IS_DISABLED(cli->flags)&&(cli->handle>0) ) {
cli->ipoll = pfdcount;
pfd[pfdcount].fd = cli->handle;
pfd[pfdcount++].events = POLLIN | POLLPRI;
} else cli->ipoll = -1;
cli = cli->next;
}
}
mgcamd = mgcamd->next;
}
#endif
struct cs_client_data *cscli;
struct cardserver_data *cs = cfg.cardserver;
while (cs) {
if ( !IS_DISABLED(cs->newcamd.flags)&&(cs->newcamd.handle>0) ) {
cscli = cs->newcamd.client;
while (cscli) {
if ( !IS_DISABLED(cscli->flags)&&(cscli->handle>0) ) {
cscli->ipoll = pfdcount;
pfd[pfdcount].fd = cscli->handle;
pfd[pfdcount++].events = POLLIN | POLLPRI;
} else cscli->ipoll = -1;
cscli = cscli->next;
}
}
cs = cs->next;
}
#ifdef RADEGAST_SRV
cs = cfg.cardserver;
while (cs) {
if ( !IS_DISABLED(cs->flags)&&(cs->rdgd.handle>0) ) {
pthread_mutex_lock(&prg.lockrdgdcli);
struct rdgd_client_data *rdgdcli = cs->rdgd.client;
while (rdgdcli) {
if ( !IS_DISABLED(rdgdcli->flags)&&(rdgdcli->handle>0) ) {
rdgdcli->ipoll = pfdcount;
pfd[pfdcount].fd = rdgdcli->handle;
pfd[pfdcount++].events = POLLIN | POLLPRI;
} else rdgdcli->ipoll = -1;
rdgdcli = rdgdcli->next;
}
pthread_mutex_unlock(&prg.lockrdgdcli);
}
cs = cs->next;
}
#endif
int retval = poll(pfd, pfdcount, ms);
if ( retval>0 ) {
usleep(1000);
/// SERVERS
pthread_mutex_lock(&prg.locksrv);
struct cs_server_data *srv = cfg.server;
while (srv) {
if ( !IS_DISABLED(srv->flags)&&(srv->handle>0)&&(srv->ipoll>=0)&&(srv->handle==pfd[srv->ipoll].fd) ) {
if ( pfd[srv->ipoll].revents & (POLLHUP|POLLNVAL) ) {
if (srv->type==TYPE_NEWCAMD) cs_disconnect_srv(srv);
#ifdef CCCAM_CLI
else if (srv->type==TYPE_CCCAM) cc_disconnect_srv(srv);
#endif
#ifdef RADEGAST_CLI
else if (srv->type==TYPE_RADEGAST) rdgd_disconnect_srv(srv);
#endif
}
else if ( pfd[srv->ipoll].revents & (POLLIN|POLLPRI) ) {
#ifdef MSGTHREAD
struct recvmsg_data *data = malloc( sizeof(struct recvmsg_data) );
data->type = TYPE_SERVER;
data->cs = NULL;
data->srv = srv;
data->lastthreadid = lastthreadid;
pthread_create(&lastthreadid , NULL, (threadfn)recv_msg, data);//recv_msg (data);
#else
if (srv->type==TYPE_NEWCAMD) cs_srv_recvmsg(srv);
#ifdef CCCAM_CLI
else if (srv->type==TYPE_CCCAM) cc_srv_recvmsg(srv);
#endif
#ifdef RADEGAST_CLI
else if (srv->type==TYPE_RADEGAST) rdgd_srv_recvmsg(srv);
#endif
#endif
}
}
srv = srv->next;
}
pthread_mutex_unlock(&prg.locksrv);
/// CLIENTS
// Newcamd Clients
cs = cfg.cardserver;
while (cs) {
if ( !IS_DISABLED(cs->newcamd.flags)&&(cs->newcamd.handle>0) ) {
pthread_mutex_lock(&prg.lockcli);
cscli = cs->newcamd.client;
while (cscli) {
if ( !IS_DISABLED(cscli->flags)&&(cscli->handle>0) && (cscli->ipoll>=0) && (cscli->handle==pfd[cscli->ipoll].fd) ) {
if ( pfd[cscli->ipoll].revents & (POLLHUP|POLLNVAL) ) cs_disconnect_cli(cscli);
else if ( pfd[cscli->ipoll].revents & (POLLIN|POLLPRI) ) {
#ifdef MSGTHREAD
struct recvmsg_data *data = malloc( sizeof(struct recvmsg_data) );
data->type = TYPE_CLIENT_NEWCAMD;
data->cs = cs;
data->cscli = cscli;
data->lastthreadid = lastthreadid;
pthread_create(&lastthreadid , NULL, (threadfn)recv_msg, data);//recv_msg (data);
#else
cs_cli_recvmsg(cscli,cs);
#endif
}
//else if ( (GetTickCount()-cscli->lastactivity) > 600000 ) cs_disconnect_cli(cscli);
}
cscli = cscli->next;
}
pthread_mutex_unlock(&prg.lockcli);
}
cs = cs->next;
}
#ifdef RADEGAST_SRV
// Radegast Clients
cs = cfg.cardserver;
while (cs) {
if ( !IS_DISABLED(cs->flags)&&(cs->rdgd.handle>0) ) {
pthread_mutex_lock(&prg.lockrdgdcli);
struct rdgd_client_data *rdgdcli = cs->rdgd.client;
while (rdgdcli) {
if ( !IS_DISABLED(rdgdcli->flags)&&(rdgdcli->handle>0)&&(rdgdcli->ipoll>=0)&&(rdgdcli->handle==pfd[rdgdcli->ipoll].fd) ) {
if ( pfd[rdgdcli->ipoll].revents & (POLLHUP|POLLNVAL) ) rdgd_disconnect_cli(cs,rdgdcli);
else if ( pfd[rdgdcli->ipoll].revents & (POLLIN|POLLPRI) ) rdgd_cli_recvmsg(rdgdcli,cs);
}
rdgdcli = rdgdcli->next;
}
pthread_mutex_unlock(&prg.lockrdgdcli);
}
cs = cs->next;
}
#endif
#ifdef MGCAMD_SRV
// CCcam Clients
struct mgcamdserver_data *mgcamd = cfg.mgcamd.server;
while (mgcamd) {
if ( !IS_DISABLED(mgcamd->flags)&&(mgcamd->handle>0) ) {
pthread_mutex_lock(&prg.lockclimg);
struct mg_client_data *mgcli = mgcamd->client;
while (mgcli) {
if ( !IS_DISABLED(mgcli->flags)&&(mgcli->handle>0)&&(mgcli->ipoll>=0)&&(mgcli->handle==pfd[mgcli->ipoll].fd) ) {
if ( pfd[mgcli->ipoll].revents & (POLLHUP|POLLNVAL) ) mg_disconnect_cli(mgcli);
else if ( pfd[mgcli->ipoll].revents & (POLLIN|POLLPRI) ) {
#ifdef MSGTHREAD
struct recvmsg_data *data = malloc( sizeof(struct recvmsg_data) );
data->type = TYPE_CLIENT_MGCAMD;
data->cs = NULL;
data->mgcli = mgcli;
data->lastthreadid = lastthreadid;
pthread_create(&lastthreadid , NULL, (threadfn)recv_msg, data);//recv_msg (data);
#else
mg_cli_recvmsg(mgcli);
#endif
}
///else if ( (GetTickCount()-mgcli->lastactivity) > 600000 ) mg_disconnect_cli(mgcli);
}
mgcli = mgcli->next;
}
pthread_mutex_unlock(&prg.lockclimg);
}
mgcamd = mgcamd->next;
}
#endif
#ifdef CCCAM_SRV
// CCcam Clients
struct cccamserver_data *cccam = cfg.cccam.server;
while (cccam) {
if ( !IS_DISABLED(cccam->flags)&&(cccam->handle>0) ) {
pthread_mutex_lock(&prg.lockcccli);
struct cc_client_data *cccli = cccam->client;
while (cccli) {
if ( !IS_DISABLED(cccli->flags)&&(cccli->handle>0)&&(cccli->ipoll>=0)&&(cccli->handle==pfd[cccli->ipoll].fd) ) {
if ( pfd[cccli->ipoll].revents & (POLLHUP|POLLNVAL) ) cc_disconnect_cli(cccli);
else if ( pfd[cccli->ipoll].revents & (POLLIN|POLLPRI) ) {
#ifdef MSGTHREAD
struct recvmsg_data *data = malloc( sizeof(struct recvmsg_data) );
data->type = TYPE_CLIENT_CCCAM;
data->cs = NULL;
data->cccli = cccli;
data->lastthreadid = lastthreadid;
pthread_create(&lastthreadid , NULL, (threadfn)recv_msg, data);//recv_msg (data);
#else
cc_cli_recvmsg(cccli);
#endif
}
///else if ( (GetTickCount()-cccli->lastactivity) > 600000 ) cc_disconnect_cli(cccli);
}
cccli = cccli->next;
}
pthread_mutex_unlock(&prg.lockcccli);
}
cccam = cccam->next;
}
#endif
#ifdef FREECCCAM_SRV
// FreeCCcam Clients
if ( !IS_DISABLED(cfg.freecccam.server.flags)&&(cfg.freecccam.server.handle>0) ) {
pthread_mutex_lock(&prg.lockfreecccli);
struct cc_client_data *fcccli = cfg.freecccam.server.client;
while (fcccli) {
if ( (fcccli->handle>0)&&(fcccli->ipoll>=0)&&(fcccli->handle==pfd[fcccli->ipoll].fd) ) {
if ( pfd[fcccli->ipoll].revents & (POLLHUP|POLLNVAL) ) cc_disconnect_cli(fcccli);
else if ( pfd[fcccli->ipoll].revents & (POLLIN|POLLPRI) ) freecc_cli_recvmsg(fcccli);
}
fcccli = fcccli->next;
}
pthread_mutex_unlock(&prg.lockfreecccli);
}
#endif
//
if ( pfd[0].revents & (POLLIN|POLLPRI) ) recv_ecm_pipe();
}
else if ( retval<0 ) {
debugf(0," thread receive messages: poll error %d(errno=%d)\n", retval, errno);
}
if ( !pthread_equal(lastthreadid, prg.tid_msg) ) {
// debugf(" Wait for thread...\n");
pthread_join(lastthreadid, NULL);
}
/////
// CHECK SEND ECM/DCW
/////
ticks = GetTickCount()+3;
/// SERVERS
if (ecm_check_time<ticks) {
pthread_mutex_lock(&prg.locksrv);
ecm_check_time = check_sendecm();
pthread_mutex_unlock(&prg.locksrv);
}
/// CLIENTS
// Newcamd Clients
if (cs_dcw_check_time<ticks) {
pthread_mutex_lock(&prg.lockcli);
cs_dcw_check_time = cs_check_sendcw();
//debugf(" cs_dcw_check_time = %dms\n",cs_dcw_check_time-ticks);
pthread_mutex_unlock(&prg.lockcli);
}
#ifdef RADEGAST_SRV
// Radegast Clients
if (rdgd_dcw_check_time<ticks) {
pthread_mutex_lock(&prg.lockrdgdcli);
rdgd_dcw_check_time = rdgd_check_sendcw();
pthread_mutex_unlock(&prg.lockrdgdcli);
}
#endif
#ifdef MGCAMD_SRV
if (mg_dcw_check_time<ticks) {
if (cfg.mgcamd.server) {
pthread_mutex_lock(&prg.lockclimg);
mg_dcw_check_time = mg_check_sendcw();
pthread_mutex_unlock(&prg.lockclimg);
} else mg_dcw_check_time = 0xffffffff;
}
#endif
#ifdef CCCAM_SRV
// CCcam Clients
if (cc_dcw_check_time<ticks) {
if (cfg.cccam.server) {
pthread_mutex_lock(&prg.lockcccli);
cc_dcw_check_time = cc_check_sendcw();
pthread_mutex_unlock(&prg.lockcccli);
} else cc_dcw_check_time = 0xffffffff;
}
#endif
#ifdef FREECCCAM_SRV
// FreeCCcam Clients
if (frcc_dcw_check_time<ticks) {
if (cfg.freecccam.server.handle>0) {
pthread_mutex_lock(&prg.lockfreecccli);
frcc_dcw_check_time = freecc_check_sendcw();
pthread_mutex_unlock(&prg.lockfreecccli);
} else frcc_dcw_check_time = 0xffffffff;
}
#endif
}
}
int start_thread_recv_msg()
{
create_prio_thread(&prg.tid_msg, (threadfn)recv_msg_thread,NULL, 50);
return 0;
}