// Get Last DCW for the same Channel void checkfreeze_storeECM(int ecmid) { // find after storing ecm ECM_DATA *ecm = getecmbyid(ecmid); if (!ecm) return; if (ecm->lastdecode.status<0) return; // error if (ecm->lastdecode.status>0) return; // already done!!! if ( (ecm->lastdecode.status==0)&&(ecm->dcwstatus!=STAT_DCW_SUCCESS) ) { //debugf(" \n[SROTE ECM] New (%04x:%06x:%04x/%08x)\n",ecm->caid, ecm->provid, ecm->sid, ecm->hash); int oldecmid = ecmid; while ( (oldecmid=prevecmid(oldecmid)) != ecmid ) { ECM_DATA *oldecm = getecmbyid(oldecmid); if (!oldecm) break; if ((ecm->recvtime-oldecm->recvtime)>60000) break; if ( (oldecm->dcwstatus==STAT_DCW_SUCCESS) &&(oldecm->ecmlen==ecm->ecmlen)&&(oldecm->ecm[0]!=ecm->ecm[0]) &&(oldecm->caid==ecm->caid)&&(oldecm->provid==ecm->provid)&&(oldecm->sid==ecm->sid) ) { /* char str1[512]; array2hex( oldecm->cw, str1, 16); debugf("Found (%04x:%06x:%04x/%08x) [%s] Stat:%d Cntr:%d Time:%d\n", oldecm->caid, oldecm->provid, oldecm->sid, oldecm->hash, str1, oldecm->lastdecode.status, oldecm->lastdecode.counter, oldecm->lastdecode.dcwchangetime); */ if ( (oldecm->lastdecode.status==1)&&(oldecm->lastdecode.counter>1) ) { if ((ecm->recvtime-oldecm->recvtime)<(oldecm->lastdecode.dcwchangetime*12/10)) { // found one (not sure) ecm->lastdecode.status = 1; ecm->lastdecode.counter = oldecm->lastdecode.counter; // get average of ecm change time ecm->lastdecode.dcwchangetime = (oldecm->lastdecode.dcwchangetime*oldecm->lastdecode.counter+(ecm->recvtime-oldecm->recvtime)) / (oldecm->lastdecode.counter+1); ecm->lastdecode.dcwchangetime = ((ecm->lastdecode.dcwchangetime+300)/1000)*1000; memcpy( ecm->lastdecode.dcw, oldecm->cw, 16); // Store latest DCW } } else { // maybe?? ecm->lastdecode.status = 1; ecm->lastdecode.counter = oldecm->lastdecode.counter; ecm->lastdecode.dcwchangetime = ecm->recvtime-oldecm->recvtime; memcpy( ecm->lastdecode.dcw, oldecm->cw, 16); // Store latest DCW } break; } } } }
int ecm_getreplysrvid(int ecmid) { int i; ECM_DATA *ecm = getecmbyid(ecmid); for(i=0; i<20; i++) if ( ecm->server[i].srvid && (ecm->server[i].flag==ECM_SRV_REPLY_GOOD) ) return ecm->server[i].srvid; for(i=0; i<20; i++) if ( ecm->server[i].srvid && (ecm->server[i].flag==ECM_SRV_REPLY_FAIL) ) return ecm->server[i].srvid; return 0; }
int ecm_getsrvflag(int ecmid, unsigned int srvid) { int i; ECM_DATA *ecm = getecmbyid(ecmid); for(i=0; i<20; i++) { if (ecm->server[i].srvid) { if (ecm->server[i].srvid==srvid) { return ecm->server[i].flag; } } else break; } return 0; }
int ecm_setsrvflag(int ecmid, unsigned int srvid, int flag) { int i; ECM_DATA *ecm = getecmbyid(ecmid); for(i=0; i<20; i++) { if (ecm->server[i].srvid) { if (ecm->server[i].srvid==srvid) { ecm->server[i].flag=flag; ecm->server[i].statustime = GetTickCount(); return 1; } } else break; } return 0; }
// Check sending cw to clients uint32 freecc_check_sendcw() { struct cc_client_data *cli = cfg.freecccam.client; uint ticks = GetTickCount(); uint restime = ticks + 10000; uint clitime = restime; while (cli) { if ( (cli->handle!=INVALID_SOCKET)&&(cli->ecm.busy) ) { //&&(cli->ecm.status==STAT_ECM_SENT) ) { pthread_mutex_lock(&prg.lockecm); //### // Check for DCW ANSWER ECM_DATA *ecm = getecmbyid(cli->ecm.id); if (ecm->hash!=cli->ecm.hash) cc_senddcw_cli( cli ); // Check for FAILED if (ecm->dcwstatus==STAT_DCW_FAILED) { static char msg[] = "decode failed"; cli->ecm.statmsg=msg; cc_senddcw_cli( cli ); } // Check for SUCCESS else if (ecm->dcwstatus==STAT_DCW_SUCCESS) { // check for client allowed cw time if ( (cli->ecm.recvtime+cli->ecm.dcwtime)<=ticks ) { static char msg[] = "good dcw"; cli->ecm.statmsg = msg; cc_senddcw_cli( cli ); } else clitime = cli->ecm.recvtime+cli->ecm.dcwtime; } // check for timeout / no server again else if (ecm->dcwstatus==STAT_DCW_WAIT){ uint32 timeout; struct cardserver_data *cs = getcsbyid( ecm->csid); if (cs) timeout = cs->dcwtimeout; else timeout = 5700; if ( (cli->ecm.recvtime+timeout) < ticks ) { static char msg[] = "dcw timeout"; cli->ecm.statmsg=msg; cc_senddcw_cli( cli ); } else clitime = cli->ecm.recvtime+timeout; } if (restime>clitime) restime = clitime; pthread_mutex_unlock(&prg.lockecm); //### } cli = cli->next; } return (restime+1); }
// return 0:wrong dcw, 1: good dcw int checkfreeze_setdcw( int ecmid, uchar dcw[16] ) { char nullcw[8] = "\0\0\0\0\0\0\0\0"; ECM_DATA *ecm = getecmbyid(ecmid); if (!ecm) return 1; if (ecm->lastdecode.status!=1) return 1; // no old successful decode /* char str1[512]; char str2[512]; array2hex( ecm->lastdecode.dcw, str1, 16); array2hex( dcw, str2, 16); debugf(" \n[SET DCW] (%04x:%06x:%04x/%08x) Cntr:%d\nOLD[%s] -- NEW[%s]\n",ecm->caid, ecm->provid, ecm->sid, ecm->hash, ecm->lastdecode.counter, str1, str2); */ if (ecm->lastdecode.counter<3) { // Check consecutif cw if ( memcmp(dcw,ecm->lastdecode.dcw,16) && ( !memcmp(dcw,ecm->lastdecode.dcw,8)||!memcmp(dcw+8,ecm->lastdecode.dcw+8,8) ) ) ecm->lastdecode.counter++; else ecm->lastdecode.counter = 0; //debugf("OK1 New Cntr:%d\n",ecm->lastdecode.counter); return 1; } else { // Check similar cws // or null cw1/cw2 ==> no more consec. if ( memcmp(dcw,ecm->lastdecode.dcw,16) ) { // must be not the same if ( (!memcmp(dcw,ecm->lastdecode.dcw,8)||!memcmp(dcw+8,ecm->lastdecode.dcw+8,8)) ) { ecm->lastdecode.counter++; //debugf("OK2 New Cntr:%d\n",ecm->lastdecode.counter); //if (ecm->lastdecode.error) fdebugf(" ***(GOOD%d)SET DCW (%04x:%06x:%04x/%08x) Cntr:%d\nOLD[%s] -- NEW[%s]\n",ecm->lastdecode.error, ecm->caid, ecm->provid, ecm->sid, ecm->hash, ecm->lastdecode.counter, str1, str2); return 1; } else if ( (!memcmp(dcw,nullcw,8)||!memcmp(dcw+8,nullcw,8)) ) { // Remove consec ecm->lastdecode.counter = 0; //debugf("OK3 New Cntr:%d\n",ecm->lastdecode.counter); return 1; } } } ecm->lastdecode.error++; //fdebugf(" (FAILED%d) SET DCW (%04x:%06x:%04x/%08x) Cntr:%d\nOLD[%s] -- NEW[%s]\n",ecm->lastdecode.error, ecm->caid, ecm->provid, ecm->sid, ecm->hash, ecm->lastdecode.counter, str1, str2); //debugf("FAILED\n"); return 0; }
// Receive messages from clients void freecc_cli_recvmsg(struct cc_client_data *cli) { unsigned char buf[CC_MAXMSGSIZE]; unsigned char data[CC_MAXMSGSIZE]; // for other use unsigned int cardid; int len; if (cli->handle>0) { len = cc_msg_chkrecv(cli->handle,&cli->recvblock); if (len==0) { debugf(" FreeCCcam: client(%s) read failed %d\n", cli->user,len); cc_disconnect_cli(cli); } else if (len==-1) { if (!cli->chkrecvtime) cli->chkrecvtime = GetTickCount(); else if ( (cli->chkrecvtime+500)<GetTickCount() ) { debugf(" FreeCCcam: client(%s) read failed %d\n", cli->user,len); cc_disconnect_cli(cli); } } else if (len>0) { cli->chkrecvtime = 0; len = cc_msg_recv( cli->handle, &cli->recvblock, buf, 3); if (len==0) { debugf(" FreeCCcam: client(%s) read failed %d\n", cli->user,len); cc_disconnect_cli(cli); } else if (len<0) { debugf(" FreeCCcam: client(%s) read failed %d(%d)\n", cli->user,len,errno); cc_disconnect_cli(cli); } else if (len>0) { switch (buf[1]) { case CC_MSG_ECM_REQUEST: // Check for length cli->lastecmtime = GetTickCount(); if (cli->ecm.busy) { // send decode failed debugf(" <|> decode failed to CCcam client(%s), too many ecm requests\n", cli->user); break; } //Check for card availability cardid = buf[10]<<24 | buf[11]<<16 | buf[12]<<8 | buf[13]; uint16 caid = buf[4]<<8 | buf[5]; uint32 provid = buf[6]<<24 | buf[7]<<16 | buf[8]<<8 | buf[9]; uint16 sid = buf[14]<<8 | buf[15]; // Check for Profile struct cardserver_data *cs=getcsbyid( cardid ); if (!cs) { cli->ecmdenied++; cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_ECM_NOK2, 0, NULL); debugf(" <|> decode failed to CCcam client(%s), card-id %x not found\n", cli->user, cardid); break; } // Check for sid if (!sid) { cs->ecmdenied++; cli->ecmdenied++; cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_ECM_NOK2, 0, NULL); debugf(" <|> decode failed to CCcam client(%s), Undefined SID\n", cli->user); break; } // Check for caid, accept caid=0 if ( !accept_caid(cs,caid) ) { cli->ecmdenied++; cs->ecmdenied++; // send decode failed cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_ECM_NOK2, 0, NULL); debugf(" <|> decode failed to CCcam client(%s) ch %04x:%06x:%04x Wrong CAID\n", cli->user,caid,provid,sid); break; } // Check for provid, accept provid==0 if ( !accept_prov(cs,provid) ) { cli->ecmdenied++; cs->ecmdenied++; // send decode failed cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_ECM_NOK2, 0, NULL); debugf(" <|> decode failed to CCcam client(%s) ch %04x:%06x:%04x Wrong PROVIDER\n", cli->user,caid,provid,sid); break; } // Check for Accepted sids if ( !accept_sid(cs,sid) ) { cli->ecmdenied++; cs->ecmdenied++; // send decode failed cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_ECM_NOK2, 0, NULL); debugf(" <|> decode failed to CCcam client(%s) ch %04x:%06x:%04x SID not accepted\n", cli->user,caid,provid,sid); break; } // Check ECM length if ( !accept_ecmlen(len) ) { cli->ecmdenied++; cs->ecmdenied++; buf[1] = 0; buf[2] = 0; cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_ECM_NOK2, 0, NULL); debugf(" <|> decode failed to CCcam client(%s) ch %04x:%06x:%04x, ecm length error(%d)\n", cli->user,caid,provid,sid,len); break; } // ACCEPTED memcpy( &data[0], &buf[17], len-17); pthread_mutex_lock(&prg.lockecm); // Search for ECM int ecmid = search_ecmdata_dcw( data, len-17, sid); // dont get failed ecm request from cache if ( ecmid!=-1 ) { ECM_DATA *ecm=getecmbyid(ecmid); ecm->lastrecvtime = GetTickCount(); //TODO: Add another card for sending ecm cc_store_ecmclient(ecmid, cli); debugf(" <- ecm from CCcam client(%s) ch %04x:%06x:%04x*\n", cli->user, caid, provid, sid); cli->ecm.busy=1; cli->ecm.hash = ecm->hash; cli->ecm.cardid = cs->id; } else { cs->ecmaccepted++; // Setup ECM Request for Server(s) ecmid = store_ecmdata(cs->id, &data[0], len-17, sid, caid, provid); ECM_DATA *ecm=getecmbyid(ecmid); cc_store_ecmclient(ecmid, cli); debugf(" <- ecm from CCcam client(%s) ch %04x:%06x:%04x (>%dms)\n", cli->user,caid,provid,sid, cli->ecm.dcwtime); cli->ecm.busy=1; cli->ecm.hash = ecm->hash; cli->ecm.cardid = cs->id; if (cs->usecache && cfg.cachepeer) { pipe_send_cache_find(ecm, cs); ecm->waitcache = 1; ecm->dcwstatus = STAT_DCW_WAITCACHE; } else ecm->dcwstatus = STAT_DCW_WAIT; } ecm_check_time = frcc_dcw_check_time = 0; pthread_mutex_unlock(&prg.lockecm); break; case CC_MSG_KEEPALIVE: //printf(" Keepalive from client '%s'\n",cli->user); cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_KEEPALIVE, 0, NULL); break; case CC_MSG_BAD_ECM: //debugf(" CCcam: cmd 0x05 ACK from client '%s'\n",cli->user); //if (cli->cardsent==0) { // cc_sendcards_cli(cli); // cli->cardsent=1; //} break; //default: debugf(" FreeCCcam: Unknown Packet ID : %02x from client(%s)\n", buf[1], cli->user); } } } } }
void cc_srv_recvmsg(struct cs_server_data *srv) { unsigned char buf[CC_MAXMSGSIZE]; struct cs_card_data *card; struct cardserver_data *cs; int i, len; ECM_DATA *ecm; if ( (srv->type==TYPE_CCCAM)&&(srv->handle>0) ) { len = cc_msg_chkrecv(srv->handle,&srv->recvblock); if (len==0) { debugf(" CCcam: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); cc_disconnect_srv(srv); } else if (len==-1) { if (!srv->chkrecvtime) srv->chkrecvtime = GetTickCount(); else if ( (srv->chkrecvtime+500)<GetTickCount() ) { debugf(" CCcam: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); cc_disconnect_srv(srv); } } else if (len>0) { srv->chkrecvtime = 0; len = cc_msg_recv(srv->handle, &srv->recvblock, buf, 3); if (len==0) { debugf(" CCcam: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); cc_disconnect_srv(srv); } else if (len<0) { debugf(" CCcam: server (%s:%d) read failed %d(%d)\n", srv->host->name, srv->port, len, errno); cc_disconnect_srv(srv); } else if (len>0) { switch (buf[1]) { case CC_MSG_CLI_INFO: debugf(" CCcam: Client data ACK from Server (%s:%d)\n", srv->host->name,srv->port); break; case CC_MSG_ECM_REQUEST: // Get CW if (!srv->busy) { debugf(" [!] dcw error from server (%s:%d), unknown ecm request\n",srv->host->name,srv->port); break; } uint8 dcw[16]; cc_crypt_cw( cfg.cccam.nodeid, srv->busycardid, &buf[4]); memcpy(dcw, &buf[4], 16); cc_decrypt(&srv->recvblock, buf+4, len-4); // additional crypto step srv->busy = 0; srv->lastdcwtime = GetTickCount(); pthread_mutex_lock(&prg.lockecm); //### ecm = getecmbyid(srv->busyecmid); if (!ecm) { debugf(" [!] error cw from server (%s:%d), ecm not found!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } // check for ECM??? if (ecm->hash!=srv->busyecmhash) { debugf(" [!] error cw from server (%s:%d), ecm deleted!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } cs = getcsbyid(ecm->csid); int cardcheck = istherecard( srv, srv->busycard ); // Check for DCW if (!acceptDCW(dcw)) { srv->ecmerrdcw ++; if (cs&&cardcheck) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, -1); srv_cstatadd( srv, cs->id, 0 , 0); } ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_REPLY_FAIL); pthread_mutex_unlock(&prg.lockecm); //### break; } // else { srv->lastecmoktime = GetTickCount()-srv->lastecmtime; srv->ecmoktime += srv->lastecmoktime; srv->ecmok++; ecm_setsrvflagdcw(srv->busyecmid, srv->id, ECM_SRV_REPLY_GOOD,dcw); if (cs&&cardcheck) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, 1); /// + Card nodeID srv_cstatadd( srv, cs->id, 1 , srv->lastecmoktime); } if (cardcheck) { srv->busycard->ecmoktime += GetTickCount()-srv->lastecmtime; srv->busycard->ecmok++; } if (ecm->dcwstatus!=STAT_DCW_SUCCESS) { static char msg[] = "Good dcw from CCcam server"; ecm->statusmsg = msg; ecm_setdcw( cs, ecm, dcw, DCW_SOURCE_SERVER, srv->id ); debugf(" <= cw from CCcam server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); } pthread_mutex_unlock(&prg.lockecm); //### break; case CC_MSG_ECM_NOK1: // EAGAIN, Retry /* if (!srv->busy) break; ecm = srv->busyecm; debugf(" <| decode1 failed from CCcam server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); if ( (GetTickCount()-srv->lastecmtime)<CC_ECMRETRY_TIMEOUT ) { if (srv->retry<CC_ECMRETRY_MAX) { srv->busy = 0; if (cc_sendecm_srv(srv, ecm)) { srv->lastecmtime = GetTickCount(); srv->busy = 1; srv->retry++; break; } } } if (srv->retry>=CC_ECMRETRY_MAX) { ecm_setsrvflag(ecm, srv->id, ECM_SRV_EXCLUDE); } srv->busy = 0; break; */ case CC_MSG_ECM_NOK2: // ecm decode failed if (!srv->busy) { debugf(" [!] dcw error from server (%s:%d), unknown ecm request\n",srv->host->name,srv->port); break; } pthread_mutex_lock(&prg.lockecm); //### ecm = getecmbyid(srv->busyecmid); if (!ecm) { debugf(" [!] dcw error from server (%s:%d), ecm not found!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } // check for ECM??? if (ecm->hash!=srv->busyecmhash) { debugf(" [!] dcw error from server (%s:%d), ecm deleted!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } debugf(" <| decode failed from CCcam server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); cs = getcsbyid(ecm->csid); if (ecm->dcwstatus!=STAT_DCW_SUCCESS) { if ( cs && (GetTickCount()-ecm->recvtime)<cs->cstimeout ) { if (srv->retry<cs->ccretry) { srv->busy = 0; if (cc_sendecm_srv(srv, ecm)) { srv->lastecmtime = GetTickCount(); srv->busy = 1; srv->retry++; debugf(" (RE%d) -> ecm to CCcam server (%s:%d) ch %04x:%06x:%04x\n",srv->retry,srv->host->name,srv->port,ecm->caid,ecm->provid,ecm->sid); pthread_mutex_unlock(&prg.lockecm); //### break; } } } } if (cs) { if ( istherecard( srv, srv->busycard ) ) cardsids_update( srv->busycard, ecm->provid, ecm->sid, -1); srv_cstatadd( srv, cs->id, 0 , 0); } ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_REPLY_FAIL); srv->busy = 0; pthread_mutex_unlock(&prg.lockecm); //### break; case CC_MSG_BAD_ECM: // Add Card cc_msg_send( srv->handle, &srv->sendblock, CC_MSG_BAD_ECM, 0, NULL); //debugf(" CCcam: cmd 0x05 from Server (%s:%d)\n",srv->host->name,srv->port); //currentecm.state = ECM_STATUS_FAILED; break; case CC_MSG_KEEPALIVE: srv->keepalivesent = 0; //debugf(" CCcam: Keepalive ACK from Server (%s:%d)\n",srv->host->name,srv->port); break; case CC_MSG_CARD_DEL: // Delete Card card = srv->card; uint32 k = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; struct cs_card_data *prevcard = NULL; while (card) { if (card->shareid==k) { debugf(" CCcam: server (%s:%d), remove share-id %d\n",srv->host->name,srv->port,k); if (prevcard) prevcard->next = card->next; else srv->card = card->next; //Free SIDs while (card->sids) { struct sid_data *sid = card->sids; card->sids = card->sids->next; free(sid); } free(card); // check for current ecm if (srv->busy && (srv->busycardid==k) ) ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_EXCLUDE); break; } prevcard = card; card = card->next; } break; case CC_MSG_CARD_ADD: // remove own cards -> same nodeid "cfg.cccam.nodeid" if ( (buf[14]<srv->uphops) && (buf[24]<=16) && memcmp(buf+26+buf[24]*7,cfg.cccam.nodeid,8) ) { // check Only the first 4 bytes // nodeid index = 26 + 7 * buf[24] struct cs_card_data *card = malloc( sizeof(struct cs_card_data) ); memset(card, 0, sizeof(struct cs_card_data) ); card->shareid = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; card->uphops = buf[14]+1; memcpy( card->nodeid, buf+26+buf[24]*7, 8); card->caid = (buf[12]<<8)+(buf[13]); card->nbprov = buf[24]; card->sids = NULL; i = 26+buf[24]*7; debugf(" CCcam: new card (%s:%d) %02x%02x%02x%02x%02x%02x%02x%02x_%x uphops %d caid %04x providers %d\n",srv->host->name,srv->port, buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7],card->shareid ,card->uphops, card->caid, card->nbprov); if (card->nbprov>CARD_MAXPROV) card->nbprov = CARD_MAXPROV; for (i=0;i<card->nbprov; i++) { card->prov[i] = (buf[25+i*7]<<16) | (buf[26+i*7]<<8) | (buf[27+i*7]); //debugf(" Provider %d = %06x\n",i, card->prov[i]); } card->next = srv->card; srv->card = card; } break; case CC_MSG_SRV_INFO: memcpy(srv->nodeid, buf+4, 8); memcpy(srv->version, buf+12, 31); for (i=12; i<53; i++) { if (!buf[i]) break; if ( (buf[i]<32)||(buf[i]>'z') ) { memset(srv->version, 0, 31); break; } } memcpy(srv->build, buf+44, 31); debugf(" CCcam: server (%s:%d), info: version %s build %s\n",srv->host->name,srv->port,buf+12, buf+44); break; //default: debugdump(buf,len," CCcam: unknown packet from server (%s:%d): ",srv->host->name,srv->port); } // switch } srv->keepalivetime = GetTickCount(); } } }
void rdgd_srv_recvmsg(struct cs_server_data *srv) { int len; ECM_DATA *ecm; unsigned char buf[CWS_NETMSGSIZE]; if (srv->handle>0) if (srv->type==TYPE_RADEGAST) { len = rdgd_check_message(srv->handle); if (len==0) { debugf(" radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); rdgd_disconnect_srv(srv); } else if (len==-1) { if (!srv->chkrecvtime) srv->chkrecvtime = GetTickCount(); else if ( (srv->chkrecvtime+300)<GetTickCount() ) { debugf(" radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); rdgd_disconnect_srv(srv); } } else if (len>0) { srv->chkrecvtime = 0; len = rdgd_message_receive(srv->handle, buf, 3); if (len==0) { debugf(" radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); rdgd_disconnect_srv(srv); } else if (len<0) { debugf(" radegast: server (%s:%d) read failed %d(%d)\n", srv->host->name, srv->port, len, errno); rdgd_disconnect_srv(srv); } else if (len>0) { switch ( buf[0] ) { case 0x02: // DCW srv->lastdcwtime = GetTickCount(); if (!srv->busy) { debugf(" [!] dcw error from server (%s:%d), unknown ecm request\n",srv->host->name,srv->port); break; } srv->busy = 0; pthread_mutex_lock(&prg.lockecm); //### ecm = getecmbyid(srv->busyecmid); if (!ecm) { debugf(" [!] dcw error from server (%s:%d), ecm not found!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### break; } // check for ECM??? if (ecm->hash!=srv->busyecmhash) { debugf(" [!] dcw error from server (%s:%d), ecm deleted!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### break; } if ( (buf[1]==0x12)&&(buf[2]==0x05)&&(buf[3]==0x10) ) { // Check for DCW if (!acceptDCW(&buf[4])) { srv->ecmerrdcw ++; pthread_mutex_unlock(&prg.lockecm); //### break; } srv->ecmok++; srv->ecmoktime += GetTickCount()-srv->lastecmtime; srv->lastecmoktime = GetTickCount()-srv->lastecmtime; ecm_setsrvflagdcw(srv->busyecmid, srv->id, ECM_SRV_REPLY_GOOD, &buf[4]); debugf(" <= cw from server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); if (ecm->dcwstatus!=STAT_DCW_SUCCESS) { static char msg[] = "Good dcw from Radegast server"; ecm->statusmsg = msg; // Store ECM Answer ecm_setdcw( getcsbyid(ecm->csid), ecm, &buf[4], DCW_SOURCE_SERVER, srv->id ); } else { //TODO: check same dcw between cards srv->ecmerrdcw ++; if ( memcmp(&ecm->cw, &buf[3],16) ) debugf(" !!! different dcw from server (%s:%d)\n",srv->host->name,srv->port); } // ADD IN SID LIST struct cardserver_data *cs=getcsbyid(ecm->csid); if (cs) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, 1); srv_cstatadd( srv, cs->id, 1 , srv->lastecmoktime); } } else { struct cardserver_data *cs=getcsbyid(ecm->csid); if ( cs && (ecm->dcwstatus!=STAT_DCW_SUCCESS) && (srv->retry<cs->rdgdretry) ) { if ( (GetTickCount()-ecm->recvtime)<cs->cstimeout ) if (rdgd_sendecm_srv(srv, ecm)>0) { srv->retry++; ecm->lastsendtime = GetTickCount(); debugf(" (RE) -> ecm to server (%s:%d) ch %04x:%06x:%04x\n",srv->host->name,srv->port,ecm->caid,ecm->provid,ecm->sid); srv->lastecmtime = GetTickCount(); srv->ecmnb++; srv->busy=1; //srv->busyecm = ecm; pthread_mutex_unlock(&prg.lockecm); //### break; } } ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_REPLY_FAIL); debugf(" <| decode failed from server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); // ADD IN SID LIST if (cs) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, -1); srv_cstatadd( srv, cs->id, 0 , 0); } ecm_check_time = 0; } pthread_mutex_unlock(&prg.lockecm); //### break; default: buf[0] = 0x81; buf[1] = 0; rdgd_message_send(srv->handle,buf,2); } } } } }