./ MultiCS.r82 / ecmdata.h
#define MAX_ECM_DATA 9000
#define TIME_ECMALIVE 15000
#if __x86_64__ || __ppc64__
#define dcwcmp8(cw1, cw2) ( *((uint64_t*)(cw1))==*((uint64_t*)(cw2)) )
#define dcwcmp16(cw1, cw2) (( *((uint64_t*)(cw1))==*((uint64_t*)(cw2)) ) && ( *((uint64_t*)(cw1+8))==*((uint64_t*)(cw2+8)) ))
#else
#define dcwcmp8(cw1, cw2) (( *((uint32_t*)(cw1))==*((uint32_t*)(cw2)) ) && ( *((uint32_t*)(cw1+4))==*((uint32_t*)(cw2+4)) ))
#define dcwcmp16(cw1, cw2) (( *((uint32_t*)(cw1))==*((uint32_t*)(cw2)) ) && ( *((uint32_t*)(cw1+4))==*((uint32_t*)(cw2+4)) ) && ( *((uint32_t*)(cw1+8))==*((uint32_t*)(cw2+8)) ) && ( *((uint32_t*)(cw1+12))==*((uint32_t*)(cw2+12)) ))
#endif
#define ECM_SRV_REQUEST 0
#define ECM_SRV_REPLY_GOOD 1
#define ECM_SRV_REPLY_FAIL 2
#define ECM_SRV_EXCLUDE 3
// cachestatus
#define ECM_CACHE_NONE 0
#define ECM_CACHE_REQ 1
#define ECM_CACHE_REQ2 2
#define ECM_CACHE_REP 4
#define ECM_CACHE_CWC 8
typedef enum
{
STAT_DCW_FAILED, // decode failed
STAT_DCW_WAIT, // Wait servers answer
STAT_DCW_WAITCACHE, // Wait cached servers answer
STAT_DCW_SUCCESS // dcw returned
} dcwstatus_type;
#define DCW_SOURCE_NONE 0
#define DCW_SOURCE_CACHE 1
#define DCW_SOURCE_SERVER 2
#ifdef SRV_CSCACHE
#define DCW_SOURCE_CSCLIENT 3
#define DCW_SOURCE_MGCLIENT 4
#endif
#define DCW_SOURCE_CCCLIENT 6
struct ecm_request {
struct ecm_request *next;
struct ecm_request *prev;
struct ecm_request *csnext;
struct ecm_request *csprev;
struct cardserver_data *cs;
// Ecm Data
uint32_t recvtime; // First request time in ms received from client
uint32_t lastrecvtime; // Last request time received from client
uint32_t lastsendtime; // Last request Time sent to server
uint16_t sid; // Service id
uint16_t caid; // CA id
uint32_t provid; // Provider
uint16_t chid; // for irdeto
int ecmlen;
uint8_t ecm[MAX_ECM_SIZE];
uint32_t hash;
#ifdef CACHEEX
unsigned char ecmd5[16]; //MD5_DIGEST_LENGTH];
#endif
// DCW/Status
dcwstatus_type dcwstatus;
uint8_t cw[16];
// DCW SOURCE
int dcwsrctype;
int dcwsrcid;
//int peerid; // Cache PeerID sending dcw(0=nothing)
int cw1cycle; // 0x80 / 0x81
unsigned int checktime; // time when recheck the ecm.
unsigned int waitserver; // wait for available server.
unsigned char cachestatus;// 0:nothing sent;; 1:request sent;; 2:reply sent
unsigned char cacheexstatus;// 0:nothing sent;; 1:request sent;; 2:reply sent
char *statusmsg; // DCW status message
#ifdef CHECK_NEXTDCW
// Last Successive ECM/DCW
struct {
struct ecm_request *ecm; // NULL: nothing, else found last decode and checked
uint8_t dcw[16];
int error;
int ecmid;
int counter; // successif dcw counter * -1:error, 0: not found, 1: found and checked 1 time, 2: found and checked 2 times ...
int cwcycle; // 0: CW0 next to cycle; 1: CW1 next to cycle
uint32_t dcwchangetime;
} lastdecode; // maybe we have 3 different channels with same caid:provid:sid ???
#endif
// SERVERS that received ecm request
struct {
uint32_t srvid; // Server ID 0=nothing
int flag; // 0=request , 1=reply, 2: excluded(server disconnected, card removed...)
uint32_t sendtime; // ECM request sent time
uint32_t statustime; // Last Status Time
uint8_t dcw[16];
} server[20];
int server_totalsent;
int server_totalwait;
int waitcache; // 1: Wait for Cache; 0: dont wait
int period; // ==1, number of retries to decode ecm.
uint32_t iplist[20]; // Clients ip list: to Remove Circular request: check for client ip & srv ip
uint32_t srviplist[20]; // Clients ip list: to Remove Circular request: check for client ip & srv ip
};
typedef struct ecm_request ECM_DATA;
extern struct ecm_request *ecmdata;
extern int totalecm;
void init_ecmdata();
uint32_t ecm_crc( uint8_t *ecm, int ecmlen);
unsigned int hashCode( unsigned char *buf, int count);
uint8_t checkECMD5(uint8_t *ecmd5);
void ecm_addip( ECM_DATA *ecm, unsigned int ip);
int ecm_checkip(ECM_DATA *ecm, unsigned int ip);
uint32_t ecm_getprovid( uint8_t *ecm, uint16_t caid );
uint16_t ecm_getchid( uint8_t *ecm, uint16_t caid );
//struct ecm_request *store_ecmdata(struct cardserver_data *cs,uint8_t *ecm,int ecmlen, unsigned short sid, unsigned short caid, unsigned int provid);
struct ecm_request *search_ecmdata_dcw( uint8_t *ecm, int ecmlen, unsigned short sid);
struct ecm_request *search_ecmdata_any(struct cardserver_data *cs, uint8_t *ecm, int ecmlen, unsigned short sid, unsigned short caid);
struct ecm_request *search_ecmdata_byhash( uint16_t caid, uint16_t sid,uint32_t hash );
struct ecm_request *search_ecmdata_byecmd5( uint16_t caid, uint32_t provid, uint8_t ecmd5[16] );
int ecm_addsrv(ECM_DATA *ecm, unsigned srvid);
void ecm_addsrvip(ECM_DATA *ecm, unsigned int ip);
int ecm_checksrvip(ECM_DATA *ecm, unsigned int ip);
int ecm_nbsentsrv(ECM_DATA *ecm);
int ecm_nbwaitsrv(ECM_DATA *ecm);
int ecm_setsrvflag(ECM_DATA *ecm, unsigned int srvid, int flag);
int ecm_setsrvflagdcw(ECM_DATA *ecm, unsigned int srvid, int flag, uint8_t dcw[16]);
int ecm_getsrvflag(ECM_DATA *ecm, unsigned int srvid);
int ishalfnulledcw( uint8_t dcw[16] );
int ecmdata_check_cw( uint8_t tag, uint32_t hash, unsigned short caid, unsigned int provid , unsigned short sid, uint8_t cw[16], int cwpart );
#ifdef CHECK_NEXTDCW
void checkfreeze_storeECM(ECM_DATA *ecm);
void checkfreeze_checkECM( ECM_DATA *ecm, ECM_DATA *oldecm );
int checkfreeze_setdcw( ECM_DATA *ecm, uint8_t dcw[16] );
#endif