./ MultiCS.r82 / twin.c
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int twin_init() { // Set up Serial Port if (serial_init(cfg.twin.serial.device,B115200 | CS8 | CLOCAL | CSTOPB | CREAD,&cfg.twin.serial.handle)==-1) { debugf(0, " Error initializing serial device '%s'\n", cfg.twin.serial.device); return -1; } else serial_purge(cfg.twin.serial.handle); debugf(0, " serial device '%s' opened.\n",cfg.twin.serial.device); return 0; } int twin_done() { serial_done(cfg.twin.serial.handle); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int twin_send(int chn, uint8_t* cw) { uint8_t wbuf[32]; // write uint8_t rbuf[32]; // read int rlen; memset( cw, 0, 16); wbuf[0] = 7; wbuf[1] = 6; wbuf[2] = cfg.twin.chninfo.data[chn].deg>>8; wbuf[3] = cfg.twin.chninfo.data[chn].deg&0xff; wbuf[4] = cfg.twin.chninfo.data[chn].freq>>8; wbuf[5] = cfg.twin.chninfo.data[chn].freq&0xfc; wbuf[6] = cfg.twin.chninfo.data[chn].sid>>8; wbuf[7] = cfg.twin.chninfo.data[chn].sid&0xff; wbuf[8] = wbuf[0]^wbuf[1]^wbuf[2]^wbuf[3]^wbuf[4]^wbuf[5]^wbuf[6]^wbuf[7]; serial_purge(cfg.twin.serial.handle); usleep(20000); serial_write(cfg.twin.serial.handle, wbuf, 9); usleep(20000); memset(rbuf,0,19); rlen = serial_readt(cfg.twin.serial.handle, 300, 1000, 19, rbuf); if ( (rlen!=19)||(rbuf[0]!=0xF7)||(rbuf[1]!=0x00)||(rbuf[2]!=0x16) ) { char str[512]; array2hex( rbuf, str, rlen); debugf(0, " ch %04x:%06x:%04x, Invalid packet from dongle (%s)\n", cfg.twin.chninfo.data[chn].caid, cfg.twin.chninfo.data[chn].prov, cfg.twin.chninfo.data[chn].sid, str ); return 0; } rbuf[6] = rbuf[3]+rbuf[4]+rbuf[5]; rbuf[10] = rbuf[7]+rbuf[8]+rbuf[9]; rbuf[14] = rbuf[11]+rbuf[12]+rbuf[13]; rbuf[18] = rbuf[15]+rbuf[16]+rbuf[17]; memcpy(cw, rbuf+3, 16); return 16; } /* struct channel_info_data *twin_getchannel(uint16_t caid, uint32_t prov, uint16_t sid) { int i; for(i=0; i<cfg.twin.chninfo.count; i++) if ( (cfg.twin.chninfo.data[i].caid==caid)&&(cfg.twin.chninfo.data[i].prov==prov)&&(cfg.twin.chninfo.data[i].sid==sid) ) return &(cfg.twin.chninfo.data[i]); } return NULL; } */ void *thread_twin() { int chn; uint8_t cw[16]; uint8_t nullcw[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; if ( twin_init()==-1 ) return NULL; while (1) { for(chn=0; chn<cfg.twin.chninfo.count; chn++) { uint32_t ticks = GetTickCount(); if ( !cfg.twin.chninfo.data[chn].ecm.rtime ) continue; if ( (cfg.twin.chninfo.data[chn].ecm.rtime+2500) > ticks ) continue; if ( (cfg.twin.chninfo.data[chn].ecm.rtime+8000) < ticks ) continue; if ( !twin_send(chn,cw) ) { if ( !twin_send(chn,cw) ) continue; } if ( !acceptcw(cw) ) { //cfg.twin.chninfo.data[chn].ecm.error++; //debugf(0, " ? chn %04x:%06x:%04x:%s invalid channel '%s'\n", cfg.twin.chninfo.data[chn].caid, cfg.twin.chninfo.data[chn].prov, cfg.twin.chninfo.data[chn].sid, cfg.twin.chninfo.data[chn].name); continue; } char str[512]; array2hex( cw, str, 16); //debugf(0, " chn %04x:%06x:%04x:%s\n", cfg.twin.chninfo.data[chn].caid, cfg.twin.chninfo.data[chn].prov, cfg.twin.chninfo.data[chn].sid, str); // pthread_mutex_lock(&cfg.lockchn); if (cfg.twin.chninfo.data[chn].ecm.rtime) { // maybe changed !!! if (cfg.twin.chninfo.data[chn].ecm.cwcycle==0x80) { if ( memcmp( cfg.twin.chninfo.data[chn].ecm.prevcw, cw, 8) && !memcmp( cfg.twin.chninfo.data[chn].ecm.prevcw+8, cw+8, 8) ) { debugf(0, " -> CW0 Cycle chn '%s' %04x:%06x:%04x:%s\n", cfg.twin.chninfo.data[chn].name, cfg.twin.chninfo.data[chn].caid, cfg.twin.chninfo.data[chn].prov, cfg.twin.chninfo.data[chn].sid, str); cfg.twin.chninfo.data[chn].ecm.rtime = 0; //cacheex_push( &cfg.twin.chninfo.data[chn], cw); memcpy( cfg.twin.chninfo.data[chn].ecm.cw, cw, 16); } } else if (cfg.twin.chninfo.data[chn].ecm.cwcycle==0x81) { if ( !memcmp( cfg.twin.chninfo.data[chn].ecm.prevcw, cw, 8) && memcmp( cfg.twin.chninfo.data[chn].ecm.prevcw+8, cw+8, 8) ) { debugf(0, " -> CW1 Cycle chn '%s' %04x:%06x:%04x:%s\n", cfg.twin.chninfo.data[chn].name, cfg.twin.chninfo.data[chn].caid, cfg.twin.chninfo.data[chn].prov, cfg.twin.chninfo.data[chn].sid, str); cfg.twin.chninfo.data[chn].ecm.rtime = 0; //cacheex_push( &cfg.twin.chninfo.data[chn], cw); memcpy( cfg.twin.chninfo.data[chn].ecm.cw, cw, 16); } } } // pthread_mutex_unlock(&cfg.lockchn); } } twin_done(); return NULL; }