Пример #1
0
/**
 * 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;
}
Пример #2
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;
		}	
 	}
}