./ MultiCS.r82 / setdcw.c
/////////////////////////////////////////////////////////////////////////////// // SETDCW /////////////////////////////////////////////////////////////////////////////// inline void peer_hitprofile( struct cachepeer_data *peer, int csid ) { int i; for(i=0; i<MAX_CSPORTS; i++) { if (!peer->csporthit[i].csid) { peer->csporthit[i].csid = csid; peer->csporthit[i].hits = 1; break; } else if (peer->csporthit[i].csid==csid) { peer->csporthit[i].hits++; break; } } } #ifdef CACHEEX inline void cacheex_cccam_hitprofile( struct cc_client_data *cli, int csid ) { int i; for(i=0; i<MAX_CSPORTS; i++) { if (!cli->csporthit[i].csid) { cli->csporthit[i].csid = csid; cli->csporthit[i].hits = 1; break; } else if (cli->csporthit[i].csid==csid) { cli->csporthit[i].hits++; break; } } } #ifdef CAMD35_SRV inline void cacheex_camd35_hitprofile( struct camd35_client_data *cli, int csid ) { int i; for(i=0; i<MAX_CSPORTS; i++) { if (!cli->csporthit[i].csid) { cli->csporthit[i].csid = csid; cli->csporthit[i].hits = 1; break; } else if (cli->csporthit[i].csid==csid) { cli->csporthit[i].hits++; break; } } } #endif #ifdef CS378X_SRV inline void cacheex_cs378x_hitprofile( struct camd35_client_data *cli, int csid ) { int i; for(i=0; i<MAX_CSPORTS; i++) { if (!cli->csporthit[i].csid) { cli->csporthit[i].csid = csid; cli->csporthit[i].hits = 1; break; } else if (cli->csporthit[i].csid==csid) { cli->csporthit[i].hits++; break; } } } #endif inline void cacheex_server_hitprofile( struct server_data *srv, int csid ) { int i; for(i=0; i<MAX_CSPORTS; i++) { if (!srv->csporthit[i].csid) { srv->csporthit[i].csid = csid; srv->csporthit[i].hits = 1; break; } else if (srv->csporthit[i].csid==csid) { srv->csporthit[i].hits++; break; } } } #endif inline int dcwcheck_nds( ECM_DATA *ecm, uint8_t dcw[16], int swap ) { char nullcw[8] = "\0\0\0\0\0\0\0\0"; //Must be halfnulled dcw //if ( memcmp(dcw,nullcw,3) && memcmp(dcw+8,nullcw,3) ) return 0; // get cwcycle int cwcycle = 0; if ( dcwcmp8(dcw,nullcw) ) cwcycle = 1; else if ( dcwcmp8(dcw+8,nullcw) ) cwcycle = 0; // //if (ecm->cw1cycle==0) return 1; if (0x81==ecm->ecm[0]) { if (cwcycle==1) return 1; #ifdef DCWSWAP else if (swap) { char tmp[8]; memcpy( tmp, dcw, 8); memcpy( dcw, dcw+8, 8); memcpy( dcw+8, tmp, 8); return 1; } #endif else return 0; } else { if (cwcycle==0) return 1; #ifdef DCWSWAP else if (swap) { char tmp[8]; memcpy( tmp, dcw, 8); memcpy( dcw, dcw+8, 8); memcpy( dcw+8, tmp, 8); return 1; } #endif else return 0; } } #ifndef THREAD_DCW void ecm_setdcw( ECM_DATA *ecm, uint8_t dcw[16], int srctype, int srcid ) { char nullcw[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; if ( dcwcmp16(dcw,nullcw) ) return; struct cardserver_data *cs = ecm->cs; if (!cs) return; if ( dcwcmp8(dcw,nullcw) && dcwcmp8(dcw+8,nullcw) ) return; if (!acceptDCW(dcw)) return; int cwpart = 2; if (ecm->cw1cycle) { if (ecm->ecm[0]==ecm->cw1cycle) cwpart = 1; else cwpart = 0; } else { if ( dcwcmp8(dcw,nullcw) ) cwpart = 1; else if ( dcwcmp8(dcw+8,nullcw) ) cwpart = 0; } if (ecm->dcwstatus==STAT_DCW_SUCCESS) { return; } /* if ( !ecmdata_check_cw( ecm->ecm[0], ecm->hash, ecm->caid, ecm->provid, ecm->sid, dcw, cwpart) ) { return; } */ if (srctype!=DCW_SOURCE_CACHE) { pthread_mutex_lock( &prg.lockcache ); int f = cache_check_cw( ecm->recvtime, ecm->ecm[0], ecm->caid, ecm->hash, ecm->sid, dcw, cwpart); pthread_mutex_unlock( &prg.lockcache ); if (!f) { return; } } // filter non-nds halfnulled cw if ( dcwcmp8(dcw,nullcw) || dcwcmp8(dcw+8,nullcw) ) { if ((ecm->caid>>8)!=9) { return; } int swap = 0; #ifdef DCWSWAP if (cs) if (cs->option.dcw.swap) swap = 1; #endif if ( !dcwcheck_nds( ecm, dcw, swap) ) { return; } } #ifdef CHECK_NEXTDCW if (cs->option.dcw.check && !cs->option.dcw.halfnulled) { int check = checkfreeze_setdcw(ecm,dcw); if (check==0) { ecm->lastdecode.error++; return; } else if (check==1) { ecm->lastdecode.counter = 0; ecm->lastdecode.cwcycle = 0; } else if (check&2) { ecm->lastdecode.counter++; if (check&4) ecm->lastdecode.cwcycle = '1'; else ecm->lastdecode.cwcycle = '0'; } } #endif #ifdef TESTCHANNEL int testchannel = ( (ecm->caid==cfg.testchn.caid) && (ecm->provid==cfg.testchn.provid) && (ecm->sid==cfg.testchn.sid) ); if (testchannel) { char dump[64]; array2hex( dcw, dump, 16); char temp[512]; src2string(srctype, srcid, temp); fdebugf(" =(setdcw)= from %s ch %04x:%06x:%04x/%02x:%08x => %s\n", temp, ecm->caid, ecm->provid, ecm->sid, ecm->ecm[0], ecm->hash, dump); } #endif ecm->statusmsg = "Decode Success"; int instant = (ecm->dcwstatus==STAT_DCW_WAITCACHE); ecm->dcwsrctype = srctype; ecm->dcwsrcid = srcid; ecm->dcwstatus = STAT_DCW_SUCCESS; ecm->checktime = 0; ecm->waitserver = 0; sid_newecm(ecm); memcpy( ecm->cw, dcw, 16 ); // Check timeout uint32_t ecmtime = GetTickCount()-ecm->recvtime; if ( ecmtime > cs->option.dcw.timeout*ecm->period ) return; // Send DCW to clients clients_check_sendcw(ecm); // Update Stat cs->ecmok++; cs->ecmoktime += ecmtime; int time = (ecmtime+50)/100; if (time<99) cs->ttime[time]++; else cs->ttime[99]++; if (srctype==DCW_SOURCE_CACHE) { if (srcid&PEER_CSP) { // Cache struct cachepeer_data *peer = getpeerbyid(srcid&0xffff); if (peer) { // setup peer last used cache peer->lastcaid = ecm->caid; peer->lastprov = ecm->provid; peer->lastsid = ecm->sid; peer->lastdecodetime = ecmtime; // add to profiles hits peer_hitprofile( peer, cs->id ); peer->hitnb++; cs->hits.csp++; cfg.cache.hits++; if (instant) { peer->ihitnb++; cs->hits.instant.csp++; cfg.cache.ihits++; } } if (time<99) cs->ttimecache[time]++; else cs->ttimecache[99]++; } #ifdef CACHEEX else if (srcid&PEER_CCCAM_CLIENT) { // Cacheex struct cc_client_data *cli = getcecccamclientbyid(srcid&0xffff); if (cli) { // setup client last used cache cli->cacheex.lastcaid = ecm->caid; cli->cacheex.lastprov = ecm->provid; cli->cacheex.lastsid = ecm->sid; cli->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_cccam_hitprofile( cli, cs->id ); cli->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; cli->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #ifdef CAMD35_SRV //PEERID_CAMD35 else if (srcid&PEER_CAMD35_CLIENT) { struct camd35_client_data *cli = getcamd35clientbyid(srcid&0xffff); if (cli) { // setup client last used cache cli->cacheex.lastcaid = ecm->caid; cli->cacheex.lastprov = ecm->provid; cli->cacheex.lastsid = ecm->sid; cli->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_camd35_hitprofile( cli, cs->id ); cli->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; cli->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #endif #ifdef CS378X_SRV //PEERID_CS378X else if (srcid&PEER_CS378X_CLIENT) { struct camd35_client_data *cli = getcs378xclientbyid(srcid&0xffff); if (cli) { // setup client last used cache cli->cacheex.lastcaid = ecm->caid; cli->cacheex.lastprov = ecm->provid; cli->cacheex.lastsid = ecm->sid; cli->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_cs378x_hitprofile( cli, cs->id ); cli->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; cli->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #endif else if (srcid&PEER_CACHEEX_SERVER) { struct server_data *srv = getcesrvbyid( srcid&0xffff ); if (srv) { // setup client last used cache srv->cacheex.lastcaid = ecm->caid; srv->cacheex.lastprov = ecm->provid; srv->cacheex.lastsid = ecm->sid; srv->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_server_hitprofile( srv, cs->id ); srv->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; srv->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #endif } else if (srctype==DCW_SOURCE_SERVER) { struct server_data *srv = getsrvbyid( srcid&0xffff ); if (srv) srv->hits++; if (time<99) cs->ttimecards[time]++; else cs->ttimecards[99]++; } #ifdef SRV_CSCACHE else if (srctype==DCW_SOURCE_CSCLIENT) { struct cs_client_data *cli = getnewcamdclientbyid( srcid&0xffff ); if (cli) cli->cachedcw++; if (time<99) cs->ttimeclients[time]++; else cs->ttimeclients[99]++; } else if (srctype==DCW_SOURCE_MGCLIENT) { struct mg_client_data *cli = getmgcamdclientbyid( srcid&0xffff ); if (cli) cli->cachedcw++; if (time<99) cs->ttimeclients[time]++; else cs->ttimeclients[99]++; } #endif #ifdef CACHEEX // Send DCW to CACHE-EX servers if ( cs->option.fallowcacheex ) if (ecmtime<cs->option.cacheexvalidtime) { // only for ecm with low time pipe_send_cacheex_push_out(ecm); } #endif // Send DCW to Cache if not sent if ( cs->option.fallowcache && cs->option.cachesendrep && !(ecm->cachestatus&ECM_CACHE_REP) ) { //if (ecm->from!=ECM_FROM_CACHEEX) pipe_cache_reply(ecm,cs); //Send Good Cache Reply ecm->cachestatus |= ECM_CACHE_REP; } #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 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->ecm.msgid; 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); if ( !cs_message_send( srv->handle, &srvcd, buf, 19, srv->sessionkey) ) disconnect_srv( srv ); } } } #endif } #endif #ifdef THREAD_DCW void ecm_setdcwdata( ECM_DATA *ecm, uint8_t dcw[16], int srctype, int srcid ) { char nullcw[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; if ( dcwcmp16(dcw,nullcw) ) return; struct cardserver_data *cs = ecm->cs; if (!cs) return; if ( dcwcmp8(dcw,nullcw) && dcwcmp8(dcw+8,nullcw) ) return; if (!acceptDCW(dcw)) return; int cwpart = 2; if (ecm->cw1cycle) { if (ecm->ecm[0]==ecm->cw1cycle) cwpart = 1; else cwpart = 0; } else { if ( dcwcmp8(dcw,nullcw) ) cwpart = 1; else if ( dcwcmp8(dcw+8,nullcw) ) cwpart = 0; } pthread_mutex_lock(&prg.lockecm); if (ecm->dcwstatus==STAT_DCW_SUCCESS) { pthread_mutex_unlock(&prg.lockecm); return; } /* if ( !ecmdata_check_cw( ecm->ecm[0], ecm->hash, ecm->caid, ecm->provid, ecm->sid, dcw, cwpart) ) { pthread_mutex_unlock(&prg.lockecm); return; } */ if (srctype!=DCW_SOURCE_CACHE) { pthread_mutex_lock( &prg.lockcache ); int f = cache_check_cw( ecm->recvtime, ecm->ecm[0], ecm->caid, ecm->hash, ecm->sid, dcw, cwpart); pthread_mutex_unlock( &prg.lockcache ); if (!f) { pthread_mutex_unlock(&prg.lockecm); return; } } // filter non-nds halfnulled cw if ( dcwcmp8(dcw,nullcw) || dcwcmp8(dcw+8,nullcw) ) { if ((ecm->caid>>8)!=9) { pthread_mutex_unlock(&prg.lockecm); return; } int swap = 0; #ifdef DCWSWAP if (cs) if (cs->option.dcw.swap) swap = 1; #endif if ( !dcwcheck_nds( ecm, dcw, swap) ) { pthread_mutex_unlock(&prg.lockecm); return; } } #ifdef CHECK_NEXTDCW if (cs->option.dcw.check && !cs->option.dcw.halfnulled) { int check = checkfreeze_setdcw(ecm,dcw); if (check==0) { ecm->lastdecode.error++; pthread_mutex_unlock(&prg.lockecm); return; } else if (check==1) { ecm->lastdecode.counter = 0; ecm->lastdecode.cwcycle = 0; } else if (check&2) { ecm->lastdecode.counter++; if (check&4) ecm->lastdecode.cwcycle = '1'; else ecm->lastdecode.cwcycle = '0'; } } #endif #ifdef TESTCHANNEL int testchannel = ( (ecm->caid==cfg.testchn.caid) && (ecm->provid==cfg.testchn.provid) && (ecm->sid==cfg.testchn.sid) ); if (testchannel) { char dump[64]; array2hex( dcw, dump, 16); char temp[512]; src2string(srctype, srcid, temp); fdebugf(" =(setdcw)= from %s ch %04x:%06x:%04x/%02x:%08x => %s\n", temp, ecm->caid, ecm->provid, ecm->sid, ecm->ecm[0], ecm->hash, dump); } #endif ecm->statusmsg = "Decode Success"; int instant = (ecm->dcwstatus==STAT_DCW_WAITCACHE); ecm->dcwsrctype = srctype; ecm->dcwsrcid = srcid; ecm->dcwstatus = STAT_DCW_SUCCESS; ecm->checktime = 0; ecm->waitserver = 0; sid_newecm(ecm); memcpy( ecm->cw, dcw, 16 ); pthread_mutex_unlock(&prg.lockecm); // Check timeout uint32_t ecmtime = GetTickCount()-ecm->recvtime; if ( ecmtime > cs->option.dcw.timeout*ecm->period ) return; // Send DCW to clients clients_check_sendcw(ecm); // Update Stat cs->ecmok++; cs->ecmoktime += ecmtime; int time = (ecmtime+50)/100; if (time<99) cs->ttime[time]++; else cs->ttime[99]++; if (srctype==DCW_SOURCE_CACHE) { if (srcid&PEER_CSP) { // Cache struct cachepeer_data *peer = getpeerbyid(srcid&0xffff); if (peer) { // setup peer last used cache peer->lastcaid = ecm->caid; peer->lastprov = ecm->provid; peer->lastsid = ecm->sid; peer->lastdecodetime = ecmtime; // add to profiles hits peer_hitprofile( peer, cs->id ); peer->hitnb++; cs->hits.csp++; cfg.cache.hits++; if (instant) { peer->ihitnb++; cs->hits.instant.csp++; cfg.cache.ihits++; } } if (time<99) cs->ttimecache[time]++; else cs->ttimecache[99]++; } #ifdef CACHEEX else if (srcid&PEER_CCCAM_CLIENT) { // Cacheex struct cc_client_data *cli = getcecccamclientbyid(srcid&0xffff); if (cli) { // setup client last used cache cli->cacheex.lastcaid = ecm->caid; cli->cacheex.lastprov = ecm->provid; cli->cacheex.lastsid = ecm->sid; cli->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_cccam_hitprofile( cli, cs->id ); cli->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; cli->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #ifdef CAMD35_SRV //PEERID_CAMD35 else if (srcid&PEER_CAMD35_CLIENT) { struct camd35_client_data *cli = getcamd35clientbyid(srcid&0xffff); if (cli) { // setup client last used cache cli->cacheex.lastcaid = ecm->caid; cli->cacheex.lastprov = ecm->provid; cli->cacheex.lastsid = ecm->sid; cli->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_camd35_hitprofile( cli, cs->id ); cli->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; cli->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #endif #ifdef CS378X_SRV //PEERID_CS378X else if (srcid&PEER_CS378X_CLIENT) { struct camd35_client_data *cli = getcs378xclientbyid(srcid&0xffff); if (cli) { // setup client last used cache cli->cacheex.lastcaid = ecm->caid; cli->cacheex.lastprov = ecm->provid; cli->cacheex.lastsid = ecm->sid; cli->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_cs378x_hitprofile( cli, cs->id ); cli->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; cli->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #endif else if (srcid&PEER_CACHEEX_SERVER) { struct server_data *srv = getcesrvbyid( srcid&0xffff ); if (srv) { // setup client last used cache srv->cacheex.lastcaid = ecm->caid; srv->cacheex.lastprov = ecm->provid; srv->cacheex.lastsid = ecm->sid; srv->cacheex.lastdecodetime = ecmtime; // add to profiles hits cacheex_server_hitprofile( srv, cs->id ); srv->cacheex.hits++; cs->hits.cacheex++; cfg.cacheex.hits++; if (instant) { cfg.cacheex.ihits++; cs->hits.instant.cacheex++; srv->cacheex.ihits++; } } if (time<99) cs->ttimecacheex[time]++; else cs->ttimecacheex[99]++; } #endif } else if (srctype==DCW_SOURCE_SERVER) { struct server_data *srv = getsrvbyid( srcid&0xffff ); if (srv) srv->hits++; if (time<99) cs->ttimecards[time]++; else cs->ttimecards[99]++; } #ifdef SRV_CSCACHE else if (srctype==DCW_SOURCE_CSCLIENT) { struct cs_client_data *cli = getnewcamdclientbyid( srcid&0xffff ); if (cli) cli->cachedcw++; if (time<99) cs->ttimeclients[time]++; else cs->ttimeclients[99]++; } else if (srctype==DCW_SOURCE_MGCLIENT) { struct mg_client_data *cli = getmgcamdclientbyid( srcid&0xffff ); if (cli) cli->cachedcw++; if (time<99) cs->ttimeclients[time]++; else cs->ttimeclients[99]++; } #endif #ifdef CACHEEX // Send DCW to CACHE-EX servers if ( cs->option.fallowcacheex ) if (ecmtime<cs->option.cacheexvalidtime) { // only for ecm with low time pipe_send_cacheex_push_out(ecm); } #endif // Send DCW to Cache if not sent if ( cs->option.fallowcache && cs->option.cachesendrep && !(ecm->cachestatus&ECM_CACHE_REP) ) { //if (ecm->from!=ECM_FROM_CACHEEX) pipe_cache_reply(ecm,cs); //Send Good Cache Reply ecm->cachestatus |= ECM_CACHE_REP; } #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 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->ecm.msgid; 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); if ( !cs_message_send( srv->handle, &srvcd, buf, 19, srv->sessionkey) ) disconnect_srv( srv ); } } } #endif } inline int get_setdcwdata(uint8_t *buf, void *ecm, uint8_t *dcw, int *srctype, int *srcid) { int index = 1; memcpy(srctype, buf+index, sizeof(int) ); index += sizeof(int); memcpy(srcid, buf+index, sizeof(int) ); index += sizeof(int); memcpy( ecm, buf+index, sizeof(void*) ); index += sizeof(void*); memcpy( dcw, buf+index, 16 ); index+=16; return index; } int put_setdcwdata(uint8_t *buf, ECM_DATA *ecm, uint8_t *dcw, int srctype, int srcid ) { buf[0] = 55; int index = 1; memcpy(buf+index, &srctype, sizeof(int) ); index += sizeof(int); memcpy(buf+index, &srcid, sizeof(int) ); index += sizeof(int); memcpy( buf+index, &ecm, sizeof(void*) ); index += sizeof(void*); memcpy( buf+index, dcw, 16 ); index+=16; return index; } void ecm_setdcw( ECM_DATA *ecm, uint8_t dcw[16], int srctype, int srcid ) { uint8_t buf[64]; int len = put_setdcwdata(buf, ecm, dcw, srctype, srcid ); pipe_send( dcwpipe[1], buf, len); } void *setdcw_thread(void *param) { prg.pid_setdcw = syscall(SYS_gettid); prg.tid_setdcw = pthread_self(); prctl(PR_SET_NAME,"Set DCW",0,0,0); struct pollfd pfd; while (1) { pfd.fd = dcwpipe[0]; pfd.events = POLLIN | POLLPRI; int retval = poll(&pfd, 1, 3000); if ( retval>0 ) { uint8_t buf[64]; int len = pipe_recv( dcwpipe[0], buf); if (len>0) { ECM_DATA *ecm; uint8_t dcw[16]; int srctype; int srcid; get_setdcwdata(buf, &ecm, dcw, &srctype, &srcid); ecm_setdcwdata( ecm, dcw, srctype, srcid ); } } } } #endif