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); }
ir_code get_data(struct ir_remote *remote,int bits,int done) { ir_code code; int i; code=0; if(is_rcmm(remote)) { lirc_t deltap,deltas,sum; if(bits%2 || done%2) { return((ir_code) -1); } if(!sync_pending_space(remote)) return 0; for(i=0;i<bits;i+=2) { code<<=2; deltap=get_next_pulse(remote->pzero+remote->pone+ remote->ptwo+remote->pthree); deltas=get_next_space(remote->szero+remote->sone+ remote->stwo+remote->sthree); if(deltap==0 || deltas==0) { return((ir_code) -1); } sum=deltap+deltas; //LOGPRINTF(3,"rcmm: sum %ld",(unsigned long) sum); if(expect(remote,sum,remote->pzero+remote->szero)) { code|=0; //LOGPRINTF(2,"00"); } else if(expect(remote,sum,remote->pone+remote->sone)) { code|=1; //LOGPRINTF(2,"01"); } else if(expect(remote,sum,remote->ptwo+remote->stwo)) { code|=2; //LOGPRINTF(2,"10"); } else if(expect(remote,sum,remote->pthree+remote->sthree)) { code|=3; //LOGPRINTF(2,"11"); } else { //LOGPRINTF(2,"no match for %d+%d=%d",deltap,deltas,sum); return((ir_code) -1); } } return(code); } else if(is_grundig(remote)) { lirc_t deltap,deltas,sum; int state,laststate; if(bits%2 || done%2) { return((ir_code) -1); } if(!sync_pending_pulse(remote)) return ((ir_code) -1); for(laststate=state=-1,i=0;i<bits;) { deltas=get_next_space(remote->szero+remote->sone+ remote->stwo+remote->sthree); deltap=get_next_pulse(remote->pzero+remote->pone+ remote->ptwo+remote->pthree); if(deltas==0 || deltap==0) { return((ir_code) -1); } sum=deltas+deltap; //LOGPRINTF(3,"grundig: sum %ld",(unsigned long) sum); if(expect(remote,sum,remote->szero+remote->pzero)) { state=0; //LOGPRINTF(2,"2T"); } else if(expect(remote,sum,remote->sone+remote->pone)) { state=1; //LOGPRINTF(2,"3T"); } else if(expect(remote,sum,remote->stwo+remote->ptwo)) { state=2; //LOGPRINTF(2,"4T"); } else if(expect(remote,sum,remote->sthree+remote->pthree)) { state=3; //LOGPRINTF(2,"6T"); } else { //LOGPRINTF(2,"no match for %d+%d=%d",deltas,deltap,sum); return((ir_code) -1); } if(state==3) /* 6T */ { i+=2;code<<=2;state=-1; code|=0; } else if(laststate==2 && state==0) /* 4T2T */ { i+=2;code<<=2;state=-1; code|=1; } else if(laststate==1 && state==1) /* 3T3T */ { i+=2;code<<=2;state=-1; code|=2; } else if(laststate==0 && state==2) /* 2T4T */ { i+=2;code<<=2;state=-1; code|=3; } else if(laststate==-1) { /* 1st bit */ } else { return((ir_code) -1); } laststate=state; } return(code); } else if(is_serial(remote)) { int received; int space, start_bit, stop_bit, parity_bit; int parity; lirc_t delta,origdelta,pending,expecting, gap_delta; lirc_t base, stop; lirc_t max_space, max_pulse; base=1000000/remote->baud; /* start bit */ set_pending_pulse(base); received=0; space=(rec_buffer.pendingp==0); /* expecting space ? */ start_bit=0; stop_bit=0; parity_bit=0; delta=origdelta=0; stop=base*remote->stop_bits/2; parity=0; gap_delta=0; max_space = remote->sone*remote->bits_in_byte+stop; max_pulse = remote->pzero*(1+remote->bits_in_byte); if(remote->parity != IR_PARITY_NONE) { parity_bit = 1; max_space += remote->sone; max_pulse += remote->pzero; bits += bits/remote->bits_in_byte; } while(received<bits || stop_bit) { if(delta==0) { delta=space ? get_next_space(max_space): get_next_pulse(max_pulse); if(delta==0 && space && received+remote->bits_in_byte+parity_bit>=bits) { /* open end */ delta=max_space; } origdelta=delta; } if(delta==0) { //LOGPRINTF(1,"failed before bit %d",received+1); return((ir_code) -1); } pending=(space ? rec_buffer.pendings:rec_buffer.pendingp); if(expect(remote, delta, pending)) { delta=0; } else if(delta>pending) { delta-=pending; } else { //LOGPRINTF(1,"failed before bit %d",received+1); return((ir_code) -1); } if(pending>0) { if(stop_bit) { //LOGPRINTF(5, "delta: %lu", delta); gap_delta = delta; delta=0; set_pending_pulse(base); set_pending_space(0); stop_bit=0; space=0; //LOGPRINTF(3,"stop bit found"); } else { //LOGPRINTF(3,"pending bit found"); set_pending_pulse(0); set_pending_space(0); if(delta==0) { space=(space ? 0:1); } } continue; } expecting=(space ? remote->sone:remote->pzero); if(delta>expecting || expect(remote,delta,expecting)) { delta-=(expecting>delta ? delta:expecting); received++; code<<=1; code|=space; parity^=space; //LOGPRINTF(2,"adding %d",space); if(received%(remote->bits_in_byte+parity_bit)==0) { ir_code temp; if((remote->parity == IR_PARITY_EVEN && parity) || (remote->parity == IR_PARITY_ODD && !parity)) { //LOGPRINTF(1, "parity error ""after %d bits",received+1); return((ir_code) -1); } parity = 0; /* parity bit is filtered out */ temp=code>>(remote->bits_in_byte+parity_bit); code=temp<<remote->bits_in_byte| reverse(code>>parity_bit, remote->bits_in_byte); if(space && delta==0) { //LOGPRINTF(1,"failed at stop ""bit after %d bits",received+1); return((ir_code) -1); } //LOGPRINTF(3,"awaiting stop bit"); set_pending_space(stop); stop_bit=1; } } else { if(delta==origdelta)
ir_code get_data(struct ir_remote * remote, int bits, int done) { ir_code code; int i; code = 0; if (is_rcmm(remote)) { lirc_t deltap, deltas, sum; if (bits % 2 || done % 2) { logprintf(LOG_ERR, "invalid bit number."); return ((ir_code) - 1); } if (!sync_pending_space(remote)) return 0; for (i = 0; i < bits; i += 2) { code <<= 2; deltap = get_next_pulse(remote->pzero + remote->pone + remote->ptwo + remote->pthree); deltas = get_next_space(remote->szero + remote->sone + remote->stwo + remote->sthree); if (deltap == 0 || deltas == 0) { logprintf(LOG_ERR, "failed on bit %d", done + i + 1); return ((ir_code) - 1); } sum = deltap + deltas; logprintf(3, "rcmm: sum %ld", (__u32) sum); if (expect(remote, sum, remote->pzero + remote->szero)) { code |= 0; logprintf(2, "00"); } else if (expect(remote, sum, remote->pone + remote->sone)) { code |= 1; logprintf(2, "01"); } else if (expect(remote, sum, remote->ptwo + remote->stwo)) { code |= 2; logprintf(2, "10"); } else if (expect(remote, sum, remote->pthree + remote->sthree)) { code |= 3; logprintf(2, "11"); } else { logprintf(2, "no match for %d+%d=%d", deltap, deltas, sum); return ((ir_code) - 1); } } return (code); } else if (is_grundig(remote)) { lirc_t deltap, deltas, sum; int state, laststate; if (bits % 2 || done % 2) { logprintf(LOG_ERR, "invalid bit number."); return ((ir_code) - 1); } if (!sync_pending_pulse(remote)) return ((ir_code) - 1); for (laststate = state = -1, i = 0; i < bits;) { deltas = get_next_space(remote->szero + remote->sone + remote->stwo + remote->sthree); deltap = get_next_pulse(remote->pzero + remote->pone + remote->ptwo + remote->pthree); if (deltas == 0 || deltap == 0) { logprintf(LOG_ERR, "failed on bit %d", done + i + 1); return ((ir_code) - 1); } sum = deltas + deltap; logprintf(3, "grundig: sum %ld", (__u32) sum); if (expect(remote, sum, remote->szero + remote->pzero)) { state = 0; logprintf(2, "2T"); } else if (expect(remote, sum, remote->sone + remote->pone)) { state = 1; logprintf(2, "3T"); } else if (expect(remote, sum, remote->stwo + remote->ptwo)) { state = 2; logprintf(2, "4T"); } else if (expect(remote, sum, remote->sthree + remote->pthree)) { state = 3; logprintf(2, "6T"); } else { logprintf(2, "no match for %d+%d=%d", deltas, deltap, sum); return ((ir_code) - 1); } if (state == 3) { /* 6T */ i += 2; code <<= 2; state = -1; code |= 0; } else if (laststate == 2 && state == 0) { /* 4T2T */ i += 2; code <<= 2; state = -1; code |= 1; } else if (laststate == 1 && state == 1) { /* 3T3T */ i += 2; code <<= 2; state = -1; code |= 2; } else if (laststate == 0 && state == 2) { /* 2T4T */ i += 2; code <<= 2; state = -1; code |= 3; } else if (laststate == -1) { /* 1st bit */ } else { logprintf(LOG_ERR, "invalid state %d:%d", laststate, state); return ((ir_code) - 1); } laststate = state; } return (code); } for (i = 0; i < bits; i++) { code = code << 1; if (is_goldstar(remote)) { if ((done + i) % 2) { logprintf(2, "$1"); remote->pone = remote->ptwo; remote->sone = remote->stwo; } else { logprintf(2, "$2"); remote->pone = remote->pthree; remote->sone = remote->sthree; } } if (expectone(remote, done + i)) { logprintf(2, "1"); code |= 1; } else if (expectzero(remote, done + i)) { logprintf(2, "0"); code |= 0; } else { logprintf(1, "failed on bit %d", done + i + 1); return ((ir_code) - 1); } } return (code); }