Пример #1
0
// 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;
			}
		}
	}
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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);
}
Пример #6
0
// 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;
}
Пример #7
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);
				}
			}
		}
	}
}
Пример #8
0
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();
		}
	}
}
Пример #9
0
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);
				}
			}

			}
	}
}