1 /*      $Id: hw_uirt2_raw.c,v 5.16 2010/04/11 18:50:38 lirc Exp $   */
2 
3 /****************************************************************************
4  ** hw_uirt2_raw.c **********************************************************
5  ****************************************************************************
6  *
7  * Routines for UIRT2 receiver/transmitter.
8  * Receiving using the raw mode and transmitting using struc or raw mode,
9  * depending on code length.
10  *
11  * Copyright (C) 2003 Mikael Magnusson <mikma@users.sourceforge.net>
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU Library General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 //#define DEBUG
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <stdarg.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <limits.h>
39 #include <signal.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <sys/ioctl.h>
43 
44 #include "hardware.h"
45 #include "serial.h"
46 #include "ir_remote.h"
47 #include "lircd.h"
48 #include "receive.h"
49 #include "transmit.h"
50 #include "hw_uirt2_common.h"
51 
52 #define NUMBYTES 6
53 
54 //static int debug = 2;
55 
56 static uirt2_t *dev;
57 static lirc_t rec_buf[200];
58 static int rec_rptr;
59 static int rec_wptr;
60 static int rec_size;
61 
62 /* exported functions  */
63 static int uirt2_raw_init(void);
64 static int uirt2_raw_deinit(void);
65 static int uirt2_send(struct ir_remote *remote, struct ir_ncode *code);
66 static char *uirt2_raw_rec(struct ir_remote *remotes);
67 static int uirt2_raw_decode(struct ir_remote *remote, ir_code * prep, ir_code * codep, ir_code * postp,
68 			    int *repeat_flagp, lirc_t * min_remaining_gapp, lirc_t * max_remaining_gapp);
69 static lirc_t uirt2_raw_readdata(lirc_t timeout);
70 
71 /* forwards */
72 static int uirt2_send_mode2_raw(uirt2_t * dev, struct ir_remote *remote, lirc_t * buf, int length);
73 static int uirt2_send_mode2_struct1(uirt2_t * dev, struct ir_remote *remote, lirc_t * buf, int length);
74 
75 struct hardware hw_uirt2_raw = {
76 #ifndef LIRC_IRTTY
77 	"/dev/ttyS0",
78 #else
79 	LIRC_IRTTY,		/* default device */
80 #endif
81 	-1,			/* fd */
82 	LIRC_CAN_REC_MODE2 | LIRC_CAN_SEND_PULSE,	/* features */
83 	LIRC_MODE_PULSE,	/* send_mode */
84 	LIRC_MODE_MODE2,	/* rec_mode */
85 	0,			/* code_length */
86 	uirt2_raw_init,		/* init_func */
87 	uirt2_raw_deinit,	/* deinit_func */
88 	uirt2_send,		/* send_func */
89 	uirt2_raw_rec,		/* rec_func */
90 	uirt2_raw_decode,	/* decode_func */
91 	NULL,			/* ioctl_func */
92 	uirt2_raw_readdata,	/* readdata */
93 	"uirt2_raw"
94 };
95 
96 struct hardware hw_usb_uirt_raw = {
97 #ifndef LIRC_IRTTY
98 	"/dev/ttyUSB0",
99 #else
100 	LIRC_IRTTY,		/* default device */
101 #endif
102 	-1,			/* fd */
103 	LIRC_CAN_REC_MODE2 | LIRC_CAN_SEND_PULSE,	/* features */
104 	LIRC_MODE_PULSE,	/* send_mode */
105 	LIRC_MODE_MODE2,	/* rec_mode */
106 	0,			/* code_length */
107 	uirt2_raw_init,		/* init_func */
108 	uirt2_raw_deinit,	/* deinit_func */
109 	uirt2_send,		/* send_func */
110 	uirt2_raw_rec,		/* rec_func */
111 	uirt2_raw_decode,	/* decode_func */
112 	NULL,			/* ioctl_func */
113 	uirt2_raw_readdata,	/* readdata */
114 	"usb_uirt_raw"
115 };
116 
117 /*
118  * queue
119  */
queue_put(lirc_t data)120 static int queue_put(lirc_t data)
121 {
122 	int next = (rec_wptr + 1) % rec_size;
123 
124 	LOGPRINTF(3, "queue_put: %d", data);
125 
126 	if (next != rec_rptr) {
127 		rec_buf[rec_wptr] = data;
128 		rec_wptr = next;
129 		return 0;
130 	} else {
131 		logprintf(LOG_ERR, "uirt2_raw: queue full");
132 		return -1;
133 	}
134 }
135 
queue_get(lirc_t * pdata)136 static int queue_get(lirc_t * pdata)
137 {
138 	if (rec_wptr != rec_rptr) {
139 		*pdata = rec_buf[rec_rptr];
140 		rec_rptr = (rec_rptr + 1) % rec_size;
141 		LOGPRINTF(3, "queue_get: %d", *pdata);
142 
143 		return 0;
144 	} else {
145 		logprintf(LOG_ERR, "uirt2_raw: queue empty");
146 		return -1;
147 	}
148 }
149 
queue_is_empty()150 static int queue_is_empty()
151 {
152 	return rec_wptr == rec_rptr;
153 }
154 
queue_clear()155 static void queue_clear()
156 {
157 	rec_rptr = 0;
158 	rec_wptr = 0;
159 }
160 
uirt2_raw_decode(struct ir_remote * remote,ir_code * prep,ir_code * codep,ir_code * postp,int * repeat_flagp,lirc_t * min_remaining_gapp,lirc_t * max_remaining_gapp)161 static int uirt2_raw_decode(struct ir_remote *remote, ir_code * prep, ir_code * codep, ir_code * postp,
162 			    int *repeat_flagp, lirc_t * min_remaining_gapp, lirc_t * max_remaining_gapp)
163 {
164 	int res;
165 
166 	LOGPRINTF(1, "uirt2_raw_decode: enter");
167 
168 	res = receive_decode(remote, prep, codep, postp, repeat_flagp, min_remaining_gapp, max_remaining_gapp);
169 
170 	LOGPRINTF(1, "uirt2_raw_decode: %d", res);
171 
172 	return res;
173 }
174 
uirt2_raw_readdata(lirc_t timeout)175 static lirc_t uirt2_raw_readdata(lirc_t timeout)
176 {
177 	lirc_t data = 0;
178 
179 	if (queue_is_empty()) {
180 		lirc_t data = uirt2_read_raw(dev, timeout);
181 
182 		if (!data) {
183 			LOGPRINTF(1, "uirt2_raw_readdata failed");
184 			return 0;
185 		}
186 
187 		queue_put(data);
188 	}
189 
190 	queue_get(&data);
191 
192 	LOGPRINTF(1, "uirt2_raw_readdata %d %d", !!(data & PULSE_BIT), data & PULSE_MASK);
193 
194 	return (data);
195 }
196 
uirt2_raw_init(void)197 static int uirt2_raw_init(void)
198 {
199 	int version;
200 
201 	if (!tty_create_lock(hw.device)) {
202 		logprintf(LOG_ERR, "uirt2_raw: could not create lock files");
203 		return (0);
204 	}
205 
206 	if ((hw.fd = open(hw.device, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
207 		logprintf(LOG_ERR, "uirt2_raw: could not open %s", hw.device);
208 		tty_delete_lock();
209 		return (0);
210 	}
211 
212 	if (!tty_reset(hw.fd)) {
213 		logprintf(LOG_ERR, "uirt2_raw: could not reset tty");
214 		close(hw.fd);
215 		tty_delete_lock();
216 		return (0);
217 	}
218 
219 	/* Wait for UIRT device to power up */
220 	usleep(100 * 1000);
221 
222 	if (!tty_setbaud(hw.fd, 115200)) {
223 		logprintf(LOG_ERR, "uirt2_raw: could not set baud rate");
224 		close(hw.fd);
225 		tty_delete_lock();
226 		return (0);
227 	}
228 
229 	if (!tty_setcsize(hw.fd, 8)) {
230 		logprintf(LOG_ERR, "uirt2_raw: could not set csize");
231 		close(hw.fd);
232 		tty_delete_lock();
233 		return (0);
234 	}
235 
236 	if (!tty_setrtscts(hw.fd, 1)) {
237 		logprintf(LOG_ERR, "uirt2_raw: could not enable hardware flow");
238 		close(hw.fd);
239 		tty_delete_lock();
240 		return (0);
241 	}
242 
243 	if ((dev = uirt2_init(hw.fd)) == NULL) {
244 		logprintf(LOG_ERR, "uirt2_raw: No UIRT2 device found at %s", hw.device);
245 		close(hw.fd);
246 		tty_delete_lock();
247 		return (0);
248 	}
249 
250 	if (uirt2_setmoderaw(dev) < 0) {
251 		logprintf(LOG_ERR, "uirt2_raw: could not set raw mode");
252 		uirt2_raw_deinit();
253 		return (0);
254 	}
255 
256 	if (uirt2_getversion(dev, &version) < 0) {
257 		uirt2_raw_deinit();
258 		return (0);
259 	}
260 	if (version >= 0x0905) {
261 		if (!tty_setdtr(hw.fd, 0)) {
262 			logprintf(LOG_ERR, "uirt2_raw: could not set DTR");
263 			uirt2_raw_deinit();
264 			return (0);
265 		}
266 	}
267 
268 	init_rec_buffer();
269 	init_send_buffer();
270 
271 	rec_rptr = 0;
272 	rec_wptr = 0;
273 	rec_size = sizeof(rec_buf) / sizeof(rec_buf[0]);
274 
275 	return (1);
276 }
277 
uirt2_raw_deinit(void)278 static int uirt2_raw_deinit(void)
279 {
280 	int version;
281 
282 	if (uirt2_getversion(dev, &version) >= 0 && version >= 0x0905) {
283 		tty_setdtr(hw.fd, 1);
284 	}
285 	uirt2_uninit(dev);
286 	dev = NULL;
287 	close(hw.fd);
288 	hw.fd = -1;
289 	tty_delete_lock();
290 	return 1;
291 }
292 
uirt2_raw_rec(struct ir_remote * remotes)293 static char *uirt2_raw_rec(struct ir_remote *remotes)
294 {
295 	LOGPRINTF(1, "uirt2_raw_rec");
296 	LOGPRINTF(1, "uirt2_raw_rec: %p", remotes);
297 
298 	if (!clear_rec_buffer())
299 		return (NULL);
300 
301 	if (remotes) {
302 		char *res;
303 		res = decode_all(remotes);
304 
305 		return res;
306 	} else {
307 		lirc_t data;
308 
309 		queue_clear();
310 		data = uirt2_read_raw(dev, 1);
311 		if (data) {
312 			queue_put(data);
313 		}
314 
315 		return NULL;
316 	}
317 }
318 
uirt2_send(struct ir_remote * remote,struct ir_ncode * code)319 static int uirt2_send(struct ir_remote *remote, struct ir_ncode *code)
320 {
321 	int length;
322 	lirc_t *signals;
323 	int res = 0;
324 
325 	if (!init_send(remote, code)) {
326 		return 0;
327 	}
328 
329 	length = send_buffer.wptr;
330 	signals = send_buffer.data;
331 
332 	if (length <= 0 || signals == NULL) {
333 		LOGPRINTF(1, "nothing to send");
334 		return 0;
335 	}
336 
337 	LOGPRINTF(1, "Trying REMSTRUC1 transmission");
338 	res = uirt2_send_mode2_struct1(dev, remote, signals, length);
339 	if (!res && (length < 48)) {
340 		LOGPRINTF(1, "Using RAW transission");
341 		res = uirt2_send_mode2_raw(dev, remote, signals, length);
342 	}
343 
344 	if (!res) {
345 		logprintf(LOG_ERR, "uirt2_send: remote not supported");
346 	} else {
347 		LOGPRINTF(1, "uirt2_send: succeeded");
348 	}
349 
350 	return res;
351 }
352 
uirt2_send_mode2_raw(uirt2_t * dev,struct ir_remote * remote,lirc_t * buf,int length)353 static int uirt2_send_mode2_raw(uirt2_t * dev, struct ir_remote *remote, lirc_t * buf, int length)
354 {
355 	byte_t tmp[64];
356 	int i, dest;
357 	int ir_length = 0;
358 	int res;
359 	int repeats = 1;
360 
361 	LOGPRINTF(1, "uirt2_send_mode2_raw %d %p", length, buf);
362 
363 	tmp[0] = 0;
364 	tmp[1] = 0;
365 
366 	for (i = 0, dest = 2; i < length; i++) {
367 		int val = buf[i] / UIRT2_UNIT;
368 		while (val > 0) {
369 			if (val > UCHAR_MAX) {
370 				tmp[dest++] = UCHAR_MAX - 1;
371 				tmp[dest++] = 1;	/* 0 won't work */
372 				val -= UCHAR_MAX;
373 				length += 2;
374 			} else {
375 				tmp[dest++] = val;
376 				val = 0;
377 			}
378 			if (dest - 2 > 48) {
379 				logprintf(LOG_ERR, "uirt2_raw: too long RAW transmission %d > 48", dest - 2);
380 				return 0;
381 			}
382 		}
383 		ir_length += buf[i];
384 	}
385 
386 	tmp[dest++] = uirt2_calc_freq(remote->freq) + (repeats & 0x1f);
387 
388 	res = uirt2_send_raw(dev, tmp, dest);
389 
390 	if (!res) {
391 		return 0;
392 	}
393 
394 	LOGPRINTF(1, "uirt2_send_mode2_raw exit");
395 	return 1;
396 }
397 
set_data_bit(byte_t * dest,int offset,int bit)398 static void set_data_bit(byte_t * dest, int offset, int bit)
399 {
400 	int i = offset / 8;
401 	int j = offset % 8;
402 	int mask = 1 << j;
403 
404 	byte_t src = dest[i];
405 	byte_t dst;
406 
407 	if (bit) {
408 		dst = src | mask;
409 	} else {
410 		dst = src & ~mask;
411 	}
412 
413 	dest[i] = dst;
414 }
415 
calc_data_bit(struct ir_remote * remote,int table[],int table_len,int signal,int tUnit)416 static int calc_data_bit(struct ir_remote *remote, int table[], int table_len, int signal, int tUnit)
417 {
418 	int i;
419 
420 	for (i = 0; i < table_len; i++) {
421 		if (table[i] == 0) {
422 			table[i] = signal / tUnit;
423 
424 			LOGPRINTF(2, "table[%d] = %d\n", i, table[i]);
425 
426 			return i;
427 		}
428 
429 		if (expect(remote, signal, table[i] * tUnit)) {
430 			LOGPRINTF(2, "expect %d, table[%d] = %d\n", signal / tUnit, i, table[i]);
431 			return i;
432 		}
433 	}
434 
435 	LOGPRINTF(2, "Couldn't find %d\n", signal / tUnit);
436 
437 	return -1;
438 }
439 
uirt2_send_mode2_struct1(uirt2_t * dev,struct ir_remote * remote,lirc_t * buf,int length)440 static int uirt2_send_mode2_struct1(uirt2_t * dev, struct ir_remote *remote, lirc_t * buf, int length)
441 {
442 	const int TABLE_LEN = 2;
443 	remstruct1_data_t rem;
444 	int res;
445 	int table[2][TABLE_LEN];
446 	int bits = 0;
447 	int i, j;
448 	int tUnit;
449 	int freq;
450 	int bFrequency;
451 	int version;
452 	int repeats = 1;
453 
454 	memset(&rem, 0, sizeof(rem));
455 
456 	memset(table[0], 0, sizeof(table[0]));
457 	memset(table[1], 0, sizeof(table[1]));
458 
459 	res = uirt2_getversion(dev, &version);
460 	if (res < 0) {
461 		return res;
462 	}
463 	logprintf(LOG_INFO, "uirt2_raw: UIRT version %04x", version);
464 	freq = remote->freq;
465 	if (freq == 0)
466 		freq = DEFAULT_FREQ;
467 	if (version >= 0x0905) {
468 		if (((5000000 / freq) + 1) / 2 >= 0x80) {
469 			bFrequency = 0x80;
470 		} else {
471 			bFrequency = ((5000000 / freq) + 1) / 2;
472 		}
473 		tUnit = (bFrequency * 100) / 125;
474 	} else {
475 		tUnit = UIRT2_UNIT;
476 	}
477 	for (i = 0; i < length; i++) {
478 		int bit;
479 		int len = buf[i] / tUnit;
480 
481 		if (len > UCHAR_MAX) {
482 			LOGPRINTF(0, "signal too long for transmission %lu", (__u32) buf[i]);
483 			return 0;
484 		}
485 		if (i == 0) {
486 			rem.bHdr1 = len;
487 			continue;
488 		} else if (i == 1) {
489 			rem.bHdr0 = len;
490 			continue;
491 		}
492 
493 		bit = calc_data_bit(remote, table[i % 2], TABLE_LEN, buf[i], tUnit);
494 
495 		if (bit < 0) {
496 			int part_length = i + 1;
497 
498 			/* is this a repeated signal sequence? */
499 			if (!(i % 2 /* space */  && buf[i] == remote->min_remaining_gap)) {
500 				return 0;
501 			}
502 
503 			if ((length + 1) % part_length != 0) {
504 				return 0;
505 			}
506 
507 			repeats = (length + 1) / part_length;
508 
509 			for (j = 1; j < repeats; j++) {
510 				if (memcmp
511 				    (&buf[0], &buf[j * part_length],
512 				     (j + 1 == repeats ? part_length - 1 : part_length) * sizeof(*buf)) != 0) {
513 					return 0;
514 				}
515 			}
516 			break;
517 		}
518 
519 		if (i - 2 > UIRT2_MAX_BITS) {
520 			logprintf(LOG_ERR, "uirt2_raw: UIRT tried to send %d bits, max is %d", length - 2,
521 				  UIRT2_MAX_BITS);
522 
523 			return 0;
524 		}
525 
526 		set_data_bit(rem.bDatBits, i - 2, bit);
527 		bits++;
528 	}
529 
530 	LOGPRINTF(2, "bits %d", bits);
531 
532 	rem.bISDlyHi = remote->min_remaining_gap / tUnit / 256;
533 	rem.bISDlyLo = (remote->min_remaining_gap / tUnit) & 255;
534 	rem.bBits = bits;
535 	rem.bOff0 = table[1][0];
536 	rem.bOff1 = table[1][1];
537 	rem.bOn0 = table[0][0];
538 	rem.bOn1 = table[0][1];
539 
540 	res = uirt2_send_struct1(dev, freq, repeats, &rem);
541 
542 	return res;
543 }
544