📄 irrecord.c
字号:
fprintf(stderr,"%s: no data for 10 secs," " aborting\n",progname); retval=EXIT_FAILURE; break; } data=remote.gap; } if(count==0) { if(!is_space(data) || data<remote.gap-remote.gap*remote.eps/100) { printf("Sorry, something " "went wrong.\n"); sleep(3); printf("Try again.\n"); flushhw(); count=0; continue; } } else { if(is_space(data) && (is_const(&remote) ? data>(remote.gap>sum ? (remote.gap-sum)*(100-remote.eps)/100:0) : data>remote.gap*(100-remote.eps)/100)) { printf("Got it.\n"); printf("Signal length is %d\n", count-1); if(count%2) { printf("That's weird because " "the signal length " "must be odd!\n"); sleep(3); printf("Try again.\n"); flushhw(); count=0; continue; } else { ncode.name=buffer; ncode.length=count-1; ncode.signals=signals; fprint_remote_signal(fout, &remote, &ncode); break; } } signals[count-1]=data&PULSE_MASK; sum+=data&PULSE_MASK; } count++; } if(count==MAX_SIGNALS) { printf("Signal is too long.\n"); } if(retval==EXIT_FAILURE) break; continue; } retries=RETRIES; while(retries>0) { int flag; if(!waitfordata(10000000)) { fprintf(stderr,"%s: no data for 10 secs," " aborting\n",progname); retval=EXIT_FAILURE; break; } last_remote=NULL; flag=0; sleep(1); while(availabledata()) { hw.rec_func(NULL); if(hw.decode_func(&remote,&pre,&code,&post, &repeat_flag,&remaining_gap)) { flag=1; break; } } if(flag) { ncode.name=buffer; ncode.code=code; fprint_remote_signal(fout,&remote,&ncode); break; } else { printf("Something went wrong. "); if(retries>1) { fflush(stdout);sleep(3); if(!resethw()) { fprintf(stderr,"%s: Could not reset " "hardware.\n",progname); retval=EXIT_FAILURE; break; } flushhw(); printf("Please try again. " "(%d retries left)\n",retries-1); } else { printf("\n"); printf("Try using the -f option.\n"); } retries--; continue; } } if(retries==0) retval=EXIT_FAILURE; if(retval==EXIT_FAILURE) break; } fprint_remote_signal_foot(fout,&remote); fprint_remote_foot(fout,&remote); fclose(fout); if(retval==EXIT_FAILURE) { if(hw.deinit_func) hw.deinit_func(); exit(EXIT_FAILURE); } if(remote.flags&RAW_CODES) { return(EXIT_SUCCESS); } if(!resethw()) { fprintf(stderr,"%s: could not reset hardware.\n",progname); exit(EXIT_FAILURE); } fin=fopen(filename,"r"); if(fin==NULL) { fprintf(stderr,"%s: could not reopen config file\n",progname); if(hw.deinit_func) hw.deinit_func(); exit(EXIT_FAILURE); } remotes=read_config(fin); fclose(fin); if(remotes==NULL) { fprintf(stderr,"%s: config file contains no valid " "remote control definition\n",progname); fprintf(stderr,"%s: this shouldn't ever happen!\n",progname); if(hw.deinit_func) hw.deinit_func(); exit(EXIT_FAILURE); } if(remotes==(void *) -1) { fprintf(stderr,"%s: reading of config file failed\n", progname); fprintf(stderr,"%s: this shouldn't ever happen!\n",progname); if(hw.deinit_func) hw.deinit_func(); exit(EXIT_FAILURE); } if(remotes->toggle_bit==0) { get_toggle_bit(remotes); } else { set_toggle_bit(remotes, 1<<(remotes->bits-remotes->toggle_bit)); } if(hw.deinit_func) hw.deinit_func(); get_pre_data(remotes); get_post_data(remotes); /* write final config file */ fout=fopen(filename,"w"); if(fout==NULL) { fprintf(stderr,"%s: could not open file \"%s\"\n",progname, filename); perror(progname); free_config(remotes); return(EXIT_FAILURE); } fprint_copyright(fout); fprint_remotes(fout,remotes); free_config(remotes); printf("Successfully written config file.\n"); return(EXIT_SUCCESS);}void flushhw(void){ size_t size=1; char buffer[sizeof(ir_code)]; switch(hw.rec_mode) { case LIRC_MODE_MODE2: size=sizeof(lirc_t); break; case LIRC_MODE_CODE: size=sizeof(unsigned char); break; case LIRC_MODE_LIRCCODE: size=hw.code_length/CHAR_BIT; if(hw.code_length%CHAR_BIT) size++; break; } while(read(hw.fd,buffer,size)==size);}int resethw(void){ int flags; if(hw.deinit_func) hw.deinit_func(); if(hw.init_func) { if(!hw.init_func()) return(0); } flags=fcntl(hw.fd,F_GETFL,0); if(flags==-1 || fcntl(hw.fd,F_SETFL,flags|O_NONBLOCK)==-1) { if(hw.deinit_func) hw.deinit_func(); return(0); } return(1);}int waitfordata(unsigned long maxusec){ fd_set fds; int ret; struct timeval tv; while(1) { FD_ZERO(&fds); FD_SET(hw.fd,&fds); do{ do{ if(maxusec>0) { tv.tv_sec=maxusec/1000000; tv.tv_usec=maxusec%1000000; ret=select(hw.fd+1,&fds,NULL,NULL,&tv); if(ret==0) return(0); } else { ret=select(hw.fd+1,&fds,NULL,NULL,NULL); } } while(ret==-1 && errno==EINTR); if(ret==-1) { logprintf(LOG_ERR,"select() failed\n"); logperror(LOG_ERR,NULL); continue; } } while(ret==-1); if(FD_ISSET(hw.fd,&fds)) { /* we will read later */ return(1); } }}int availabledata(void){ fd_set fds; int ret; struct timeval tv; FD_ZERO(&fds); FD_SET(hw.fd,&fds); do{ do{ tv.tv_sec=0; tv.tv_usec=0; ret=select(hw.fd+1,&fds,NULL,NULL,&tv); } while(ret==-1 && errno==EINTR); if(ret==-1) { logprintf(LOG_ERR,"select() failed\n"); logperror(LOG_ERR,NULL); continue; } } while(ret==-1); if(FD_ISSET(hw.fd,&fds)) { return(1); } return(0);}int get_toggle_bit(struct ir_remote *remote){ ir_code pre,code,post; int repeat_flag; lirc_t remaining_gap; int retval=EXIT_SUCCESS; int retries,flag,success; ir_code first; int seq,repeats; int found; printf("Checking for toggle bit.\n"); printf("Please press an arbitrary button repeatedly as fast as possible (don't hold\n""it down!).\n"); retries=30;flag=success=0;first=0; seq=repeats=0;found=0; while(availabledata()) { hw.rec_func(NULL); } while(retval==EXIT_SUCCESS && retries>0) { if(!waitfordata(10000000)) { printf("%s: no data for 10 secs, aborting\n", progname); retval=EXIT_FAILURE; break; } hw.rec_func(remote); if(is_rc6(remote)) { for(remote->toggle_bit=1; remote->toggle_bit<=remote->bits; remote->toggle_bit++) { success=hw.decode_func(remote,&pre,&code,&post, &repeat_flag, &remaining_gap); if(success) { remote->remaining_gap=remaining_gap; break; } } if(success==0) remote->toggle_bit=0; } else { success=hw.decode_func(remote,&pre,&code,&post, &repeat_flag,&remaining_gap); if(success) { remote->remaining_gap=remaining_gap; } } if(success) { if(flag==0) { flag=1; first=code; } else if(!repeat_flag) { seq++; if(!found && (is_rc6(remote) || first^code)) { if(!is_rc6(remote)) { set_toggle_bit(remote,first^code); } found=1; } printf(".");fflush(stdout); retries--; } else { repeats++; } } } if(!found) { printf("\nNo toggle bit found.\n"); } else { if(remote->toggle_bit>0) { printf("\nToggle bit is %d.\n",remote->toggle_bit); } else if(remote->toggle_mask!=0) { printf("\nToggle mask found.\n"); } else { printf("\nInvalid toggle bit.\n"); } } if(seq>0) remote->min_repeat=repeats/seq;# ifdef DEBUG printf("min_repeat=%d\n",remote->min_repeat);# endif return(found);}void set_toggle_bit(struct ir_remote *remote,ir_code xor){ ir_code mask; int toggle_bit; struct ir_ncode *codes; int bits; if(!remote->codes) return; bits=remote->bits+remote->pre_data_bits+remote->post_data_bits; mask=((ir_code) 1)<<(bits-1); toggle_bit=1; while(mask) { if(mask==xor) break; mask=mask>>1; toggle_bit++; } if(mask) { remote->toggle_bit=toggle_bit; codes=remote->codes; while(codes->name!=NULL) { codes->code&=~mask; codes++; } } else { /* Sharp, Denon and some others use a toggle_mask */ if(bits==15 && xor==0x3ff) { remote->toggle_mask=xor; } }}void get_pre_data(struct ir_remote *remote){ struct ir_ncode *codes; ir_code mask,last; int count,i; if(remote->bits==0) return; mask=(-1); codes=remote->codes; if(codes->name==NULL) return; /* at least 2 codes needed */ last=codes->code; codes++; if(codes->name==NULL) return; /* at least 2 codes needed */ while(codes->name!=NULL) { mask&=~(last^codes->code); last=codes->code; codes++; } count=0;#ifdef LONG_IR_CODE while(mask&0x8000000000000000LL)#else while(mask&0x80000000L)#endif { count++; mask=mask<<1; } count-=sizeof(ir_code)*CHAR_BIT-remote->bits; /* only "even" numbers should go to pre/post data */ if(count%8 && (remote->bits-count)%8) { count-=count%8; } if(count>0) { mask=0; for(i=0;i<count;i++) { mask=mask<<1; mask|=1; } remote->bits-=count; mask=mask<<(remote->bits); remote->pre_data_bits=count; remote->pre_data=(last&mask)>>(remote->bits); codes=remote->codes; while(codes->name!=NULL) { codes->code&=~mask; codes++; } }}void get_post_data(struct ir_remote *remote){ struct ir_ncode *codes; ir_code mask,last; int count,i; if(remote->bits==0) return; mask=(-1); codes=remote->codes; if(codes->name==NULL) return; /* at least 2 codes needed */ last=codes->code; codes++; if(codes->name==NULL) return; /* at least 2 codes needed */ while(codes->name!=NULL) { mask&=~(last^codes->code); last=codes->code; codes++; } count=0; while(mask&0x1) { count++; mask=mask>>1; } /* only "even" numbers should go to pre/post data */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -