./ MultiCS.r82 / cli-radegast.c
void rdg_getsrvmsg();

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

int rdgd_connect_srv(struct server_data *srv, int fd)
{
	static char msg[]= "Connected";
	uint8_t buf[10];
	if ( recv_nonb(fd, buf, 10,0)==0 ) {
		static char msg[]= "Server not connected";
		srv->statmsg = msg;
		return -1;
	}
	debugf(getdbgflag(DBG_SERVER,0,srv->id)," radegast: connect to server (%s:%d)\n", srv->host->name, srv->port);
	srv->statmsg = msg;
	srv->connection.status = 1;
	srv->connection.time = GetTickCount();
	srv->keepalive.time = GetTickCount();
	srv->keepalive.status = 0;
	srv->busy = 0;
	srv->lastecmoktime = 0;
	srv->lastecmtime = 0;
	srv->lastdcwtime = 0;
	srv->chkrecvtime = 0;
	srv->handle = fd;
#ifdef EPOLL_ECM
	pipe_pointer( prg.pipe.ecm[1], PIPE_SRV_CONNECTED, srv );
#else
	pipe_cmd( prg.pipe.ecm[1], PIPE_SRV_CONNECTED );
#endif
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
//01 3E 020101 06083030303030303330 070430303036 080102 0A020100 0322 80 001F D4 AB B2 CD C6 9B B4 54 11 0E 82 74 41 21 3D DC 87 70 E9 3E A1 41 E1 FC 67 3E 01 7E 97 EA DC 
int rdgd_sendecm_srv(struct server_data *srv, ECM_DATA *ecm)
{
	unsigned char buf[CWS_NETMSGSIZE];
	buf[0] = 0x01;
	//buf[1] = len;
	int index = 2;
	//Caid Byte Entry
	buf[index]=2; buf[index+1]=1;
	buf[index+2] = ecm->caid>>8;
	index+=3;
	//ProvID Entry
	buf[index]=6; buf[index+1]=8;
	hex32(ecm->provid, (char*)&buf[index+2]);
	index+=10;
	//KeyNo Entry
	buf[index]=7; buf[index+1]=4;
	buf[index+2]=0x30; buf[index+3]=0x30; buf[index+4]=0x30; buf[index+5]=0x36;
	index+=6;
	//Ecm process pid entry
	buf[index]=8; buf[index+1]=1;
	buf[index+2] = 2;
	index+=3;
	//Caid entry
	buf[index]=0x0A; buf[index+1]=2;
	buf[index+2] = ecm->caid>>8; buf[index+3] = ecm->caid & 0xff;
	index+=4;
	//Ecm entry
	buf[index]=3; buf[index+1]=ecm->ecmlen;
	memcpy(&buf[index+2],ecm->ecm, ecm->ecmlen);
	index += 2+ecm->ecmlen;
	buf[1] = index-2;
	return rdgd_message_send(srv->handle, buf, index);
}	


///////////////////////////////////////////////////////////////////////////////

void rdgd_srv_recvmsg(struct 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(getdbgflag(DBG_SERVER,0,srv->id)," radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len);
			disconnect_srv(srv);
		}
		else if (len==-1) {
			if (!srv->chkrecvtime) srv->chkrecvtime = GetTickCount();
			else if ( (srv->chkrecvtime+300)<GetTickCount() ) {
				debugf(getdbgflag(DBG_SERVER,0,srv->id)," radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len);
				disconnect_srv(srv);
			}
		}
		else if (len>0) {
			srv->chkrecvtime = 0;
			len = rdgd_message_receive(srv->handle, buf, 3);
			if (len==0) {
				debugf(getdbgflag(DBG_SERVER,0,srv->id)," radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len);
				disconnect_srv(srv);
			}
			else if (len<0) {
				debugf(getdbgflag(DBG_SERVER,0,srv->id)," radegast: server (%s:%d) read failed %d(%d)\n", srv->host->name, srv->port, len, errno);
				disconnect_srv(srv);
			}
			else if (len>0) {
				switch ( buf[0] ) {
				case 0x02: // DCW
					srv->lastdcwtime = GetTickCount();
					if (!srv->busy) {
						debugf(getdbgflag(DBG_SERVER,0,srv->id)," [!] dcw error from server (%s:%d), unknown ecm request\n",srv->host->name,srv->port);
						break;
					}
					srv->busy = 0;
					pipe_cmd( prg.pipe.ecm[1], PIPE_SRV_AVAILABLE );

					pthread_mutex_lock(&prg.lockecm); //###

					ecm = srv->ecm.request;
					if (!ecm) {
						debugf(getdbgflag(DBG_SERVER,0,srv->id)," [!] 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->ecm.hash) {
						debugf(getdbgflag(DBG_SERVER,0,srv->id)," [!] 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->ecm.request, srv->id, ECM_SRV_REPLY_GOOD, &buf[4]);
						debugf(getdbgflag(DBG_SERVER,0,srv->id)," <= 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( 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(getdbgflag(DBG_SERVER,0,srv->id)," !!! different dcw from server (%s:%d)\n",srv->host->name,srv->port);
						}
#ifdef SID_FILTER
						// ADD IN SID LIST
						struct cardserver_data *cs=ecm->cs;
						if (cs) {
							cardsids_update( srv->busycard, ecm->provid, ecm->sid, 1);
							srv_cstatadd( srv, cs->id, 1 , srv->lastecmoktime);
						}
#endif
						pthread_mutex_unlock(&prg.lockecm); //###
					}
					else {
						struct cardserver_data *cs=ecm->cs;
						if ( cs && (ecm->dcwstatus!=STAT_DCW_SUCCESS) && (srv->retry<cs->option.retry.radegast) ) {
							if ( (GetTickCount()-ecm->recvtime) < (cs->option.server.timeout*ecm->period) )
							if (rdgd_sendecm_srv(srv, ecm)>0) {
								srv->retry++;
								ecm->lastsendtime = GetTickCount();
								debugf(getdbgflag(DBG_SERVER,0,srv->id)," (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->ecm.request, srv->id, ECM_SRV_REPLY_FAIL);
						debugf(getdbgflag(DBG_SERVER,0,srv->id)," <| 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);
#ifdef SID_FILTER
						// ADD IN SID LIST
						if (cs) {
							cardsids_update( srv->busycard, ecm->provid, ecm->sid, -1);
							srv_cstatadd( srv, cs->id, 0 , 0);
						}
#endif
						pthread_mutex_unlock(&prg.lockecm); //###
						wakeup_sendecm();
					}
					break;

				default:
					buf[0] = 0x81;
					buf[1] = 0;
					rdgd_message_send(srv->handle,buf,2);
				}
			}

		}
	}
}