/* * Copyright (C) 2010 Jiri Pittner * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include #include #include #include #include "keeloq.c" uint64_t keyloq_crypt=0x123456789abcdef0LL; int oversampling; #define MAXCODELEN 32 uint8_t incode[MAXCODELEN+1]; uint8_t incodelen=0; //0 indicates ready to receive, non-zero indicates ready to read it in main void process() { printf("Received %d: ",incodelen); int i; for(i=0; i<((incodelen+7)>>3); ++i) printf("%02x ",incode[i]); if(incodelen==65 || incodelen==66) { uint8_t buf[4]; //little endian assumed in conversion to uint32_t memcpy(buf,incode,4); decrypt((uint32_t *)buf,&keyloq_crypt); printf(" Decrypted: "); for(i=0; i<4; ++i) printf("%02x ",buf[i]); printf(" Counter = %d\n",buf[0]+buf[1]*256); } else printf("\n"); incodelen=0; } uint8_t bitcount=0, bytecount=0; //working counters typedef enum {noise,upmark,ready} STATE; //receive routine for the code-hopping Keeloq remote - PWM coded void receive_car2(uint32_t time1, uint32_t time0) { //fprintf(stderr,"TESTX %d %d\n",time1,time0); static STATE state=noise; static uint8_t headercount=0; //{char c[6]; print(itoa(time1,c,10)); print(":"); print(itoa(time0,c,10)); print("\n"); } switch(state) { case noise: if(abs(time1-time0)<=3*oversampling) headercount++; else headercount=0; if(headercount>6) {fprintf(stderr,"HEAD %d %d\n",time1,time0); state=upmark;} break; case upmark: if(time1>=2*oversampling && time1<=7*oversampling && time0>=15*oversampling&& time0<=70*oversampling) {fprintf(stderr,"START %d %d\n",time1,time0);state=ready; incode[0]=bitcount=bytecount=0;break;} if(time1>=2*oversampling && time1<=7*oversampling && time0>=2*oversampling && time0<=7*oversampling && abs(time1-time0)<=3*oversampling) headercount++; else {fprintf(stderr,"NOISE %d %d\n",time1,time0); state=noise; headercount=bitcount=bytecount=0;} break; case ready: //fprintf(stderr,"TESTY %d %d\n",time1,time0); if(time1==time0||time112*oversampling || time0time0?0:1)<60*oversampling || bytecount>=MAXCODELEN+1) {fprintf(stderr,"END %d %d\n",time1,time0);state=noise; incodelen=bitcount+(bytecount<<3)-1; process(); } //legal end of transmition break; } } void receive_car(uint8_t level,uint32_t time) { static uint32_t time1=0; //fprintf(stderr,"TEST %d %d\n",level,time); if(level) time1=time; else receive_car2(time1,time); } void receive(int fd, unsigned int sample_rate, float thres0) { fd_set readfds; float data; int state; int count[2]={0,0}; int laststate=0; float thres=thres0; oversampling = sample_rate/10000; while(1) { int retval ; /* not necessary, read blocks and waits for data from a fifo, returns zero only at the end of a regular file FD_ZERO(&readfds); FD_SET(fd, &readfds); retval = select(fd+1, &readfds, NULL, NULL, NULL); if(retval == -1) { perror("select"); exit(errno);} */ retval = read(fd,&data,sizeof(float)); if(retval!=sizeof(float)) return; //end of file state= data>thres?1:0; //@@@if(state==1 && .4*data>thres) thres=.4*data; //adjust to signal level of current pulse if(state==laststate) { if(++count[state]<=sample_rate/2) continue; else {thres=thres0; state=laststate=count[0]=count[1]=0; } //reset after half second without signal } //state!=laststate or same state for too long { uint8_t l; uint32_t t; t=count[l=laststate]; laststate=state; count[state]=1; count[l]=0; receive_car(l,t); } } } int main(int argc, char **argv) { if(argc!=4) {fprintf(stderr,"Usage: %s inputfile sample_rate threshold\n",argv[0]); exit(1);} int sr=480000; //sample rate sscanf(argv[2],"%d",&sr); float thr=0; sscanf(argv[3],"%f",&thr); //implement input of the keeloq password keyloq_crypt int fd ; fd=open(argv[1],O_RDONLY); if(fd<0) {perror("cannot open input file"); exit(errno);}; receive(fd, sr, thr); close(fd); }