inline int get_repeat(struct ir_remote *remote) { if (!get_lead(remote)) return (0); if (is_biphase(remote)) { if (!expectspace(remote, remote->srepeat)) return (0); if (!expectpulse(remote, remote->prepeat)) return (0); } else { if (!expectpulse(remote, remote->prepeat)) return (0); set_pending_space(remote->srepeat); } if (!get_trail(remote)) return (0); if (!get_gap (remote, is_const(remote) ? (min_gap(remote) > rec_buffer.sum ? min_gap(remote) - rec_buffer.sum : 0) : (has_repeat_gap(remote) ? remote->repeat_gap : min_gap(remote)) )) return (0); return (1); }
inline int expectone(struct ir_remote *remote,int bit) { if(is_biphase(remote)) { if(is_rc6(remote) && remote->toggle_bit>0 && bit==remote->toggle_bit-1) { if(remote->sone>0 && !expectspace(remote,2*remote->sone)) { unget_rec_buffer(1); return(0); } rec_buffer.pendingp=2*remote->pone; } else { if(remote->sone>0 && !expectspace(remote,remote->sone)) { unget_rec_buffer(1); return(0); } rec_buffer.pendingp=remote->pone; } } else { if(remote->pone>0 && !expectpulse(remote,remote->pone)) { unget_rec_buffer(1); return(0); } if(remote->ptrail>0) { if(remote->sone>0 && !expectspace(remote,remote->sone)) { unget_rec_buffer(2); return(0); } } else { rec_buffer.pendings=remote->sone; } } return(1); }
inline int expectzero(struct ir_remote *remote, int bit) { if (is_biphase(remote)) { int all_bits = bit_count(remote); ir_code mask; mask = ((ir_code) 1) << (all_bits - 1 - bit); if (mask & remote->rc6_mask) { if (!expectpulse(remote, 2 * remote->pzero)) { unget_rec_buffer(1); return (0); } set_pending_space(2 * remote->szero); } else { if (!expectpulse(remote, remote->pzero)) { unget_rec_buffer(1); return (0); } set_pending_space(remote->szero); } } else if (is_space_first(remote)) { if (remote->szero > 0 && !expectspace(remote, remote->szero)) { unget_rec_buffer(1); return (0); } if (remote->pzero > 0 && !expectpulse(remote, remote->pzero)) { unget_rec_buffer(2); return (0); } } else { if (!expectpulse(remote, remote->pzero)) { unget_rec_buffer(1); return (0); } if (remote->ptrail > 0) { if (!expectspace(remote, remote->szero)) { unget_rec_buffer(2); return (0); } } else { set_pending_space(remote->szero); } } return (1); }
int receive_decode(struct ir_remote *remote, ir_code *prep,ir_code *codep,ir_code *postp, int *repeat_flagp,lirc_t *remaining_gapp) { ir_code pre,code,post,code_mask=0,post_mask=0; lirc_t sync; int header; struct timeval current; sync=0; /* make compiler happy */ code=pre=post=0; header=0; if(hw.rec_mode==LIRC_MODE_MODE2 || hw.rec_mode==LIRC_MODE_PULSE || hw.rec_mode==LIRC_MODE_RAW) { rewind_rec_buffer(); rec_buffer.is_biphase=is_biphase(remote) ? 1:0; /* we should get a long space first */ if(!(sync=sync_rec_buffer(remote))) { LOGPRINTF(1,"failed on sync"); return(0); } LOGPRINTF(1,"sync"); if(has_repeat(remote) && last_remote==remote) { if(remote->flags&REPEAT_HEADER && has_header(remote)) { if(!get_header(remote)) { LOGPRINTF(1,"failed on repeat " "header"); return(0); } LOGPRINTF(1,"repeat header"); } if(get_repeat(remote)) { if(remote->last_code==NULL) { logprintf(LOG_NOTICE,"repeat code " "without last_code " "received"); return(0); } *prep=remote->pre_data; *codep=remote->last_code->code; *postp=remote->post_data; *repeat_flagp=1; *remaining_gapp= is_const(remote) ? (remote->gap>rec_buffer.sum ? remote->gap-rec_buffer.sum:0): (has_repeat_gap(remote) ? remote->repeat_gap:remote->gap); return(1); } else { LOGPRINTF(1,"no repeat"); rewind_rec_buffer(); sync_rec_buffer(remote); } } if(has_header(remote)) { header=1; if(!get_header(remote)) { header=0; if(!(remote->flags&NO_HEAD_REP && (sync<=remote->gap+remote->gap*remote->eps/100 || sync<=remote->gap+remote->aeps))) { LOGPRINTF(1,"failed on header"); return(0); } } LOGPRINTF(1,"header"); } } if(is_raw(remote)) { struct ir_ncode *codes,*found; int i; if(hw.rec_mode==LIRC_MODE_CODE || hw.rec_mode==LIRC_MODE_LIRCCODE) return(0); codes=remote->codes; found=NULL; while(codes->name!=NULL && found==NULL) { found=codes; for(i=0;i<codes->length;) { if(!expectpulse(remote,codes->signals[i++])) { found=NULL; rewind_rec_buffer(); sync_rec_buffer(remote); break; } if(i<codes->length && !expectspace(remote,codes->signals[i++])) { found=NULL; rewind_rec_buffer(); sync_rec_buffer(remote); break; } } codes++; } if(found!=NULL) { if(!get_gap(remote, is_const(remote) ? remote->gap-rec_buffer.sum: remote->gap)) found=NULL; } if(found==NULL) return(0); code=found->code; } else { if(hw.rec_mode==LIRC_MODE_CODE || hw.rec_mode==LIRC_MODE_LIRCCODE) { int i; lirc_t sum; # ifdef LONG_IR_CODE LOGPRINTF(1,"decoded: %llx",rec_buffer.decoded); # else LOGPRINTF(1,"decoded: %lx",rec_buffer.decoded); # endif if((hw.rec_mode==LIRC_MODE_CODE && hw.code_length<remote->pre_data_bits +remote->bits+remote->post_data_bits) || (hw.rec_mode==LIRC_MODE_LIRCCODE && hw.code_length!=remote->pre_data_bits +remote->bits+remote->post_data_bits)) { return(0); } for(i=0;i<remote->post_data_bits;i++) { post_mask=(post_mask<<1)+1; } post=rec_buffer.decoded&post_mask; post_mask=0; rec_buffer.decoded= rec_buffer.decoded>>remote->post_data_bits; for(i=0;i<remote->bits;i++) { code_mask=(code_mask<<1)+1; } code=rec_buffer.decoded&code_mask; code_mask=0; pre=rec_buffer.decoded>>remote->bits; gettimeofday(¤t,NULL); sum=remote->phead+remote->shead+ lirc_t_max(remote->pone+remote->sone, remote->pzero+remote->szero)* (remote->bits+ remote->pre_data_bits+ remote->post_data_bits)+ remote->plead+ remote->ptrail+ remote->pfoot+remote->sfoot+ remote->pre_p+remote->pre_s+ remote->post_p+remote->post_s; rec_buffer.sum=sum>=remote->gap ? remote->gap-1:sum; sync=time_elapsed(&remote->last_send,¤t)- rec_buffer.sum; } else { if(!get_lead(remote))
int init_send(struct ir_remote *remote,struct ir_ncode *code) { int i, repeat=0; if(is_grundig(remote) || is_goldstar(remote) || is_serial(remote) || is_bo(remote)) { logprintf(LOG_ERR,"sorry, can't send this protocol yet"); return(0); } clear_send_buffer(); if(is_biphase(remote)) { send_buffer.is_biphase=1; } if(repeat_remote==NULL) { remote->repeat_countdown=remote->min_repeat; } else { repeat = 1; } init_send_loop: if(repeat && has_repeat(remote)) { if(remote->flags&REPEAT_HEADER && has_header(remote)) { send_header(remote); } send_repeat(remote); } else { if(!is_raw(remote)) { ir_code next_code; if(code->transmit_state == NULL) { next_code = code->code; } else { next_code = code->transmit_state->code; } send_code(remote, next_code, repeat); if(has_toggle_mask(remote)) { remote->toggle_mask_state++; if(remote->toggle_mask_state==4) { remote->toggle_mask_state=2; } } send_buffer.data=send_buffer._data; } else { if(code->signals==NULL) { logprintf(LOG_ERR, "no signals for raw send"); return 0; } if(send_buffer.wptr>0) { send_signals(code->signals, code->length); } else { send_buffer.data=code->signals; send_buffer.wptr=code->length; for(i=0; i<code->length; i++) { send_buffer.sum+=code->signals[i]; } } } } sync_send_buffer(); if(bad_send_buffer()) { logprintf(LOG_ERR,"buffer too small"); return(0); } if(has_repeat_gap(remote) && repeat && has_repeat(remote)) { remote->min_remaining_gap=remote->repeat_gap; remote->max_remaining_gap=remote->repeat_gap; } else if(is_const(remote)) { if(min_gap(remote)>send_buffer.sum) { remote->min_remaining_gap=min_gap(remote)-send_buffer.sum; remote->max_remaining_gap=max_gap(remote)-send_buffer.sum; } else { logprintf(LOG_ERR,"too short gap: %u",remote->gap); remote->min_remaining_gap=min_gap(remote); remote->max_remaining_gap=max_gap(remote); return(0); } } else { remote->min_remaining_gap=min_gap(remote); remote->max_remaining_gap=max_gap(remote); } /* update transmit state */ if(code->next != NULL) { if(code->transmit_state == NULL) { code->transmit_state = code->next; } else { code->transmit_state = code->transmit_state->next; } } if((remote->repeat_countdown>0 || code->transmit_state != NULL) && remote->min_remaining_gap<LIRCD_EXACT_GAP_THRESHOLD) { if(send_buffer.data!=send_buffer._data) { lirc_t *signals; int n; LOGPRINTF(1, "unrolling raw signal optimisation"); signals=send_buffer.data; n=send_buffer.wptr; send_buffer.data=send_buffer._data; send_buffer.wptr=0; send_signals(signals, n); } LOGPRINTF(1, "concatenating low gap signals"); if(code->next == NULL || code->transmit_state == NULL) { remote->repeat_countdown--; } send_space(remote->min_remaining_gap); flush_send_buffer(); send_buffer.sum=0; repeat = 1; goto init_send_loop; } LOGPRINTF(3, "transmit buffer ready"); return(1); }
inline void send_data(struct ir_remote *remote,ir_code data,int bits,int done) { int i; int all_bits = bit_count(remote); ir_code mask; if(is_rcmm(remote)) { data=reverse(data,bits); mask=1<<(all_bits-1-done); if(bits%2 || done%2) { logprintf(LOG_ERR,"invalid bit number."); return; } for(i=0;i<bits;i+=2,mask>>=2) { switch(data&3) { case 0: send_pulse(remote->pzero); send_space(remote->szero); break; /* 2 and 1 swapped due to reverse() */ case 2: send_pulse(remote->pone); send_space(remote->sone); break; case 1: send_pulse(remote->ptwo); send_space(remote->stwo); break; case 3: send_pulse(remote->pthree); send_space(remote->sthree); break; } data=data>>2; } return; } data=reverse(data,bits); mask=((ir_code) 1)<<(all_bits-1-done); for(i=0;i<bits;i++,mask>>=1) { if(has_toggle_bit_mask(remote) && mask&remote->toggle_bit_mask) { data &= ~((ir_code) 1); if(remote->toggle_bit_mask_state&mask) { data |= (ir_code) 1; } } if(has_toggle_mask(remote) && mask&remote->toggle_mask && remote->toggle_mask_state%2) { data ^= 1; } if(data&1) { if(is_biphase(remote)) { if(mask&remote->rc6_mask) { send_space(2*remote->sone); send_pulse(2*remote->pone); } else { send_space(remote->sone); send_pulse(remote->pone); } } else if(is_space_first(remote)) { send_space(remote->sone); send_pulse(remote->pone); } else { send_pulse(remote->pone); send_space(remote->sone); } } else { if(mask&remote->rc6_mask) { send_pulse(2*remote->pzero); send_space(2*remote->szero); } else if(is_space_first(remote)) { send_space(remote->szero); send_pulse(remote->pzero); } else { send_pulse(remote->pzero); send_space(remote->szero); } } data=data>>1; } }