/** * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the * lircd userspace daemon for decoding. * @input_dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the lirc interfaces aren't wired up. */ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct lirc_codec *lirc = &dev->raw->lirc; int sample; if (!(dev->raw->enabled_protocols & RC_BIT_LIRC)) return 0; if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) return -EINVAL; /* Packet start */ if (ev.reset) return 0; /* Carrier reports */ if (ev.carrier_report) { sample = LIRC_FREQUENCY(ev.carrier); IR_dprintk(2, "carrier report (freq: %d)\n", sample); /* Packet end */ } else if (ev.timeout) { if (lirc->gap) return 0; lirc->gap_start = ktime_get(); lirc->gap = true; lirc->gap_duration = ev.duration; if (!lirc->send_timeout_reports) return 0; sample = LIRC_TIMEOUT(ev.duration / 1000); IR_dprintk(2, "timeout report (duration: %d)\n", sample); /* Normal sample */ } else { if (lirc->gap) { int gap_sample; lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), lirc->gap_start)); /* Convert to ms and cap by LIRC_VALUE_MASK */ do_div(lirc->gap_duration, 1000); lirc->gap_duration = min(lirc->gap_duration, (u64)LIRC_VALUE_MASK); gap_sample = LIRC_SPACE(lirc->gap_duration); lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &gap_sample); lirc->gap = false; } sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : LIRC_SPACE(ev.duration / 1000); IR_dprintk(2, "delivering %uus %s to lirc_dev\n", TO_US(ev.duration), TO_STR(ev.pulse)); } lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &sample); wake_up(&dev->raw->lirc.drv->rbuf->wait_poll); return 0; }
//This process reads data from the device and forwards to the hw pipe //as PULSE/SPACE data int child_process(int pipe_w,int oldprotocol) { alarm(0); signal(SIGTERM, SIG_DFL); signal(SIGPIPE, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGHUP, SIG_IGN); signal(SIGALRM, SIG_IGN); unsigned char tirabuffer[64]; int tirabuflen = 0; int readsize,tmp; lirc_t data,tdata; fd_set read_set; struct timeval tv,trailtime,currtime; unsigned long eusec; tv.tv_sec = 0; tv.tv_usec=1000; FD_ZERO(&read_set); trailtime.tv_sec = 0; trailtime.tv_usec = 0; while (1) { FD_SET(hw.fd, &read_set); tmp = select(hw.fd+1, &read_set, NULL, NULL, &tv); if (tmp == 0) continue; if (tmp < 0) { logprintf(LOG_ERR,"Error select()"); return 0; } if (!FD_ISSET(hw.fd, &read_set)) continue; readsize = read(hw.fd, &tirabuffer[tirabuflen], sizeof(tirabuffer)-tirabuflen); if (readsize <= 0) { logprintf(LOG_ERR, "Error reading from Tira"); logperror(LOG_ERR, NULL); return 0; } if (readsize == 0) continue; tirabuflen += readsize; tmp = 0; while (tmp < tirabuflen-1) { data = tirabuffer[tmp];data<<=8;data += tirabuffer[tmp+1]; if (!oldprotocol) data <<= 3;else data<<=5; if (data == 0) { if (tmp > tirabuflen-4) break; //we have to receive more data if (tirabuffer[tmp+3] != 0xB2) { logprintf(LOG_ERR,"Tira error 00 00 xx B2 trailing : missing 0xB2"); return 0; } if ((trailtime.tv_sec == 0) && (trailtime.tv_usec == 0)) gettimeofday (&trailtime, NULL); if (tmp > tirabuflen-6) break; //we have to receive more data tmp += 4; continue; } tmp += 2; if ((trailtime.tv_sec != 0) || (trailtime.tv_usec != 0)) { gettimeofday (&currtime, NULL); if (trailtime.tv_usec > currtime.tv_usec) { currtime.tv_usec += 1000000; currtime.tv_sec--; } eusec = time_elapsed(&trailtime, &currtime); if(eusec > LIRC_VALUE_MASK) eusec = LIRC_VALUE_MASK; trailtime.tv_sec = 0; trailtime.tv_usec = 0; if (eusec > data) { pulse_space = 1; tdata = LIRC_SPACE(eusec); if (write(pipe_w, &tdata, sizeof(tdata)) != sizeof(tdata)) { logprintf(LOG_ERR,"Error writing pipe"); return 0; } } } data = pulse_space ? LIRC_PULSE(data):LIRC_SPACE(data); pulse_space = 1-pulse_space; if (write(pipe_w, &data, sizeof(data)) != sizeof(data)) { logprintf(LOG_ERR,"Error writing pipe"); return 0; } } //Scroll buffer to next position if (tmp > 0) { memmove(tirabuffer, tirabuffer+tmp, tirabuflen-tmp); tirabuflen -= tmp; } } }