LIRC libraries
Linux Infrared Remote Control
Loading...
Searching...
No Matches
receive.c
Go to the documentation of this file.
1/****************************************************************************
2 * receive.c ***************************************************************
3 ****************************************************************************
4 *
5 * functions that decode IR codes
6 *
7 * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de>
8 *
9 */
10
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20
21#include <errno.h>
22#include <limits.h>
23#include <poll.h>
24#include <stdint.h>
25
26#ifdef HAVE_KERNEL_LIRC_H
27#include <linux/lirc.h>
28#else
29#include "media/lirc.h"
30#endif
31
32#include "lirc/driver.h"
33#include "lirc/lirc_log.h"
34#include "lirc/receive.h"
35#include "lirc/ir_remote.h"
36
37#define RBUF_SIZE 512
38
39#define REC_SYNC 8
40
41static const logchannel_t logchannel = LOG_LIB;
42
46struct rbuf {
47 lirc_t data[RBUF_SIZE];
48 ir_code decoded;
49 int rptr;
50 int wptr;
51 int too_long;
52 int is_biphase;
53 lirc_t pendingp;
54 lirc_t pendings;
55 lirc_t sum;
56 struct timeval last_signal_time;
57 int at_eof;
58 FILE* input_log;
59};
60
61
65static struct rbuf rec_buffer;
66static int update_mode = 0;
67
68
69void rec_set_update_mode(int mode)
70{
71 update_mode = mode;
72}
73
74int (*lircd_waitfordata)(uint32_t timeout) = NULL;
75
76
77static lirc_t readdata(lirc_t timeout)
78{
79 lirc_t data;
80
81 data = curr_driver->readdata(timeout);
82 rec_buffer.at_eof = data & LIRC_EOF ? 1 : 0;
83 if (rec_buffer.at_eof)
84 log_debug("receive: Got EOF");
85 return data;
86}
87
88
89static lirc_t lirc_t_max(lirc_t a, lirc_t b)
90{
91 return a > b ? a : b;
92}
93
94static void set_pending_pulse(lirc_t deltap)
95{
96 log_trace2("pending pulse: %lu", deltap);
97 rec_buffer.pendingp = deltap;
98}
99
100static void set_pending_space(lirc_t deltas)
101{
102 log_trace2("pending space: %lu", deltas);
103 rec_buffer.pendings = deltas;
104}
105
106
107static void log_input(lirc_t data)
108{
109 fprintf(rec_buffer.input_log, "%s %u\n",
110 data & PULSE_BIT ? "pulse" : "space", data & PULSE_MASK);
111 fflush(rec_buffer.input_log);
112}
113
114
115static lirc_t get_next_rec_buffer_internal(lirc_t maxusec)
116{
117 if (rec_buffer.rptr < rec_buffer.wptr) {
118 log_trace2("<%c%lu", rec_buffer.data[rec_buffer.rptr] & PULSE_BIT ? 'p' : 's', (uint32_t)
119 rec_buffer.data[rec_buffer.rptr] & (PULSE_MASK));
120 rec_buffer.sum += rec_buffer.data[rec_buffer.rptr] & (PULSE_MASK);
121 return rec_buffer.data[rec_buffer.rptr++];
122 }
123 if (rec_buffer.wptr < RBUF_SIZE) {
124 lirc_t data = 0;
125 unsigned long elapsed = 0;
126
127 if (timerisset(&rec_buffer.last_signal_time)) {
128 struct timeval current;
129
130 gettimeofday(&current, NULL);
131 elapsed = time_elapsed(&rec_buffer.last_signal_time, &current);
132 }
133 if (elapsed < maxusec)
134 data = readdata(maxusec - elapsed);
135 if (!data) {
136 log_trace2("timeout: %u", maxusec);
137 return 0;
138 }
139 if (data & LIRC_EOF) {
140 log_debug("Receive: returning EOF");
141 return data;
142 }
143 if (LIRC_IS_TIMEOUT(data)) {
144 log_trace("timeout received: %lu", (uint32_t)LIRC_VALUE(data));
145 if (LIRC_VALUE(data) < maxusec)
146 return get_next_rec_buffer_internal(maxusec - LIRC_VALUE(data));
147 return 0;
148 }
149
150 rec_buffer.data[rec_buffer.wptr] = data;
151 if (rec_buffer.input_log != NULL)
152 log_input(data);
153 if (rec_buffer.data[rec_buffer.wptr] == 0)
154 return 0;
155 rec_buffer.sum += rec_buffer.data[rec_buffer.rptr]
156 & (PULSE_MASK);
157 rec_buffer.wptr++;
158 rec_buffer.rptr++;
159 log_trace2("+%c%lu", rec_buffer.data[rec_buffer.rptr - 1] & PULSE_BIT ? 'p' : 's', (uint32_t)
160 rec_buffer.data[rec_buffer.rptr - 1]
161 & (PULSE_MASK));
162 return rec_buffer.data[rec_buffer.rptr - 1];
163 }
164 rec_buffer.too_long = 1;
165 return 0;
166}
167
168
169void set_waitfordata_func(int(*func)(uint32_t maxusec))
170{
171 lircd_waitfordata = func;
172}
173
174
175int waitfordata(uint32_t maxusec)
176{
177 int ret;
178 struct pollfd pfd = {
179 .fd = curr_driver->fd, .events = POLLIN, .revents = 0 };
180
181 if (lircd_waitfordata != NULL)
182 return lircd_waitfordata(maxusec);
183
184 while (1) {
185 do {
186 do {
187 ret = curl_poll(&pfd, 1, (maxusec > 0) ? (maxusec / 1000) : -1);
188 if (maxusec > 0 && ret == 0)
189 return 0;
190 } while (ret == -1 && errno == EINTR);
191 if (ret == -1) {
192 log_perror_err("curl_poll() failed");
193 continue;
194 }
195 } while (ret == -1);
196
197 if (pfd.revents & POLLIN)
198 /* we will read later */
199 return 1;
200 }
201}
202
203
205{
206 if (rec_buffer.input_log != NULL)
207 fclose(rec_buffer.input_log);
208 rec_buffer.input_log = f;
209}
210
211
212static lirc_t get_next_rec_buffer(lirc_t maxusec)
213{
214 return get_next_rec_buffer_internal(receive_timeout(maxusec));
215}
216
218{
219 memset(&rec_buffer, 0, sizeof(rec_buffer));
220}
221
223{
224 rec_buffer.rptr = 0;
225 rec_buffer.too_long = 0;
226 set_pending_pulse(0);
227 set_pending_space(0);
228 rec_buffer.sum = 0;
229 rec_buffer.at_eof = 0;
230}
231
233{
234 rec_buffer.wptr = 0;
235}
236
238{
239 int move, i;
240
241 timerclear(&rec_buffer.last_signal_time);
242 if (curr_driver->rec_mode == LIRC_MODE_LIRCCODE) {
243 unsigned char buffer[curr_driver->code_length/CHAR_BIT + 1];
244 size_t count;
245
246 count = curr_driver->code_length / CHAR_BIT;
247 if (curr_driver->code_length % CHAR_BIT)
248 count++;
249
250 if (read(curr_driver->fd, buffer, count) != count) {
251 log_error("reading in mode LIRC_MODE_LIRCCODE failed");
252 return 0;
253 }
254 for (i = 0, rec_buffer.decoded = 0; i < count; i++)
255 rec_buffer.decoded = (rec_buffer.decoded << CHAR_BIT) + ((ir_code)buffer[i]);
256 } else {
257 lirc_t data;
258
259 move = rec_buffer.wptr - rec_buffer.rptr;
260 if (move > 0 && rec_buffer.rptr > 0) {
261 memmove(&rec_buffer.data[0], &rec_buffer.data[rec_buffer.rptr],
262 sizeof(rec_buffer.data[0]) * move);
263 rec_buffer.wptr -= rec_buffer.rptr;
264 } else {
265 rec_buffer.wptr = 0;
266 data = readdata(0);
267
268 log_trace2("c%lu", (uint32_t)data & (PULSE_MASK));
269
270 rec_buffer.data[rec_buffer.wptr] = data;
271 rec_buffer.wptr++;
272 }
273 }
274
276 rec_buffer.is_biphase = 0;
277
278 return 1;
279}
280
281static void unget_rec_buffer(int count)
282{
283 log_trace2("unget: %d", count);
284 if (count == 1 || count == 2) {
285 rec_buffer.rptr -= count;
286 rec_buffer.sum -= rec_buffer.data[rec_buffer.rptr] & (PULSE_MASK);
287 if (count == 2)
288 rec_buffer.sum -= rec_buffer.data[rec_buffer.rptr + 1]
289 & (PULSE_MASK);
290 }
291}
292
293static void unget_rec_buffer_delta(lirc_t delta)
294{
295 rec_buffer.rptr--;
296 rec_buffer.sum -= delta & (PULSE_MASK);
297 rec_buffer.data[rec_buffer.rptr] = delta;
298}
299
300static lirc_t get_next_pulse(lirc_t maxusec)
301{
302 lirc_t data;
303
304 data = get_next_rec_buffer(maxusec);
305 if (data == 0)
306 return 0;
307 if (!is_pulse(data)) {
308 log_trace1("pulse expected");
309 return 0;
310 }
311 return data & (PULSE_MASK);
312}
313
314static lirc_t get_next_space(lirc_t maxusec)
315{
316 lirc_t data;
317
318 data = get_next_rec_buffer(maxusec);
319 if (data == 0)
320 return 0;
321 if (!is_space(data)) {
322 log_trace1("space expected");
323 return 0;
324 }
325 return data;
326}
327
328static int sync_pending_pulse(struct ir_remote* remote)
329{
330 if (rec_buffer.pendingp > 0) {
331 lirc_t deltap;
332
333 deltap = get_next_pulse(rec_buffer.pendingp);
334 if (deltap == 0)
335 return 0;
336 if (!expect(remote, deltap, rec_buffer.pendingp))
337 return 0;
338 set_pending_pulse(0);
339 }
340 return 1;
341}
342
343static int sync_pending_space(struct ir_remote* remote)
344{
345 if (rec_buffer.pendings > 0) {
346 lirc_t deltas;
347
348 deltas = get_next_space(rec_buffer.pendings);
349 if (deltas == 0)
350 return 0;
351 if (!expect(remote, deltas, rec_buffer.pendings))
352 return 0;
353 set_pending_space(0);
354 }
355 return 1;
356}
357
358static int expectpulse(struct ir_remote* remote, int exdelta)
359{
360 lirc_t deltap;
361 int retval;
362
363 log_trace2("expecting pulse: %lu", exdelta);
364 if (!sync_pending_space(remote))
365 return 0;
366
367 deltap = get_next_pulse(rec_buffer.pendingp + exdelta);
368 if (deltap == 0)
369 return 0;
370 if (rec_buffer.pendingp > 0) {
371 if (rec_buffer.pendingp > deltap)
372 return 0;
373 retval = expect(remote, deltap - rec_buffer.pendingp, exdelta);
374 if (!retval)
375 return 0;
376 set_pending_pulse(0);
377 } else {
378 retval = expect(remote, deltap, exdelta);
379 }
380 return retval;
381}
382
383static int expectspace(struct ir_remote* remote, int exdelta)
384{
385 lirc_t deltas;
386 int retval;
387
388 log_trace2("expecting space: %lu", exdelta);
389 if (!sync_pending_pulse(remote))
390 return 0;
391
392 deltas = get_next_space(rec_buffer.pendings + exdelta);
393 if (deltas == 0)
394 return 0;
395 if (rec_buffer.pendings > 0) {
396 if (rec_buffer.pendings > deltas)
397 return 0;
398 retval = expect(remote, deltas - rec_buffer.pendings, exdelta);
399 if (!retval)
400 return 0;
401 set_pending_space(0);
402 } else {
403 retval = expect(remote, deltas, exdelta);
404 }
405 return retval;
406}
407
408static int expectone(struct ir_remote* remote, int bit)
409{
410 if (is_biphase(remote)) {
411 int all_bits = bit_count(remote);
412 ir_code mask;
413
414 mask = ((ir_code)1) << (all_bits - 1 - bit);
415 if (mask & remote->rc6_mask) {
416 if (remote->sone > 0 && !expectspace(remote, 2 * remote->sone)) {
417 unget_rec_buffer(1);
418 return 0;
419 }
420 set_pending_pulse(2 * remote->pone);
421 } else {
422 if (remote->sone > 0 && !expectspace(remote, remote->sone)) {
423 unget_rec_buffer(1);
424 return 0;
425 }
426 set_pending_pulse(remote->pone);
427 }
428 } else if (is_space_first(remote)) {
429 if (remote->sone > 0 && !expectspace(remote, remote->sone)) {
430 unget_rec_buffer(1);
431 return 0;
432 }
433 if (remote->pone > 0 && !expectpulse(remote, remote->pone)) {
434 unget_rec_buffer(2);
435 return 0;
436 }
437 } else {
438 if (remote->pone > 0 && !expectpulse(remote, remote->pone)) {
439 unget_rec_buffer(1);
440 return 0;
441 }
442 if (remote->ptrail > 0) {
443 if (remote->sone > 0 && !expectspace(remote, remote->sone)) {
444 unget_rec_buffer(2);
445 return 0;
446 }
447 } else {
448 set_pending_space(remote->sone);
449 }
450 }
451 return 1;
452}
453
454static int expectzero(struct ir_remote* remote, int bit)
455{
456 if (is_biphase(remote)) {
457 int all_bits = bit_count(remote);
458 ir_code mask;
459
460 mask = ((ir_code)1) << (all_bits - 1 - bit);
461 if (mask & remote->rc6_mask) {
462 if (!expectpulse(remote, 2 * remote->pzero)) {
463 unget_rec_buffer(1);
464 return 0;
465 }
466 set_pending_space(2 * remote->szero);
467 } else {
468 if (!expectpulse(remote, remote->pzero)) {
469 unget_rec_buffer(1);
470 return 0;
471 }
472 set_pending_space(remote->szero);
473 }
474 } else if (is_space_first(remote)) {
475 if (remote->szero > 0 && !expectspace(remote, remote->szero)) {
476 unget_rec_buffer(1);
477 return 0;
478 }
479 if (remote->pzero > 0 && !expectpulse(remote, remote->pzero)) {
480 unget_rec_buffer(2);
481 return 0;
482 }
483 } else {
484 if (!expectpulse(remote, remote->pzero)) {
485 unget_rec_buffer(1);
486 return 0;
487 }
488 if (remote->ptrail > 0) {
489 if (!expectspace(remote, remote->szero)) {
490 unget_rec_buffer(2);
491 return 0;
492 }
493 } else {
494 set_pending_space(remote->szero);
495 }
496 }
497 return 1;
498}
499
500static lirc_t sync_rec_buffer(struct ir_remote* remote)
501{
502 int count;
503 lirc_t deltas, deltap;
504
505 count = 0;
506 deltas = get_next_space(1000000);
507 if (deltas == 0)
508 return 0;
509
510 if (last_remote != NULL && !is_rcmm(remote)) {
511 while (!expect_at_least(last_remote, deltas, last_remote->min_remaining_gap)) {
512 deltap = get_next_pulse(1000000);
513 if (deltap == 0)
514 return 0;
515 deltas = get_next_space(1000000);
516 if (deltas == 0)
517 return 0;
518 count++;
519 if (count > REC_SYNC) /* no sync found,
520 * let's try a diffrent remote */
521 return 0;
522 }
523 if (has_toggle_mask(remote)) {
524 if (!expect_at_most(last_remote, deltas, last_remote->max_remaining_gap)) {
525 remote->toggle_mask_state = 0;
526 remote->toggle_code = NULL;
527 }
528 }
529 }
530 rec_buffer.sum = 0;
531 return deltas;
532}
533
534static int get_header(struct ir_remote* remote)
535{
536 if (is_rcmm(remote)) {
537 lirc_t deltap, deltas, sum;
538
539 deltap = get_next_pulse(remote->phead);
540 if (deltap == 0) {
541 unget_rec_buffer(1);
542 return 0;
543 }
544 deltas = get_next_space(remote->shead);
545 if (deltas == 0) {
546 unget_rec_buffer(2);
547 return 0;
548 }
549 sum = deltap + deltas;
550 if (expect(remote, sum, remote->phead + remote->shead))
551 return 1;
552 unget_rec_buffer(2);
553 return 0;
554 } else if (is_bo(remote)) {
555 if (expectpulse(remote, remote->pone) && expectspace(remote, remote->sone)
556 && expectpulse(remote, remote->pone) && expectspace(remote, remote->sone)
557 && expectpulse(remote, remote->phead) && expectspace(remote, remote->shead))
558 return 1;
559 return 0;
560 }
561 if (remote->shead == 0) {
562 if (!sync_pending_space(remote))
563 return 0;
564 set_pending_pulse(remote->phead);
565 return 1;
566 }
567 if (!expectpulse(remote, remote->phead)) {
568 unget_rec_buffer(1);
569 return 0;
570 }
571 /* if this flag is set I need a decision now if this is really
572 * a header */
573 if (remote->flags & NO_HEAD_REP) {
574 lirc_t deltas;
575
576 deltas = get_next_space(remote->shead);
577 if (deltas != 0) {
578 if (expect(remote, remote->shead, deltas))
579 return 1;
580 unget_rec_buffer(2);
581 return 0;
582 }
583 }
584
585 set_pending_space(remote->shead);
586 return 1;
587}
588
589static int get_foot(struct ir_remote* remote)
590{
591 if (!expectspace(remote, remote->sfoot))
592 return 0;
593 if (!expectpulse(remote, remote->pfoot))
594 return 0;
595 return 1;
596}
597
598static int get_lead(struct ir_remote* remote)
599{
600 if (remote->plead == 0)
601 return 1;
602 if (!sync_pending_space(remote))
603 return 0;
604 set_pending_pulse(remote->plead);
605 return 1;
606}
607
608static int get_trail(struct ir_remote* remote)
609{
610 if (remote->ptrail != 0)
611 if (!expectpulse(remote, remote->ptrail))
612 return 0;
613 if (rec_buffer.pendingp > 0)
614 if (!sync_pending_pulse(remote))
615 return 0;
616 return 1;
617}
618
619static int get_gap(struct ir_remote* remote, lirc_t gap)
620{
621 lirc_t data;
622
623 log_trace1("sum: %d", rec_buffer.sum);
624 data = get_next_rec_buffer(gap - gap * remote->eps / 100);
625 if (data == 0)
626 return 1;
627 if (!is_space(data)) {
628 log_trace1("space expected");
629 return 0;
630 }
631 unget_rec_buffer(1);
632 if (!expect_at_least(remote, data, gap)) {
633 log_trace("end of signal not found");
634 return 0;
635 }
636 return 1;
637}
638
639static int get_repeat(struct ir_remote* remote)
640{
641 if (!get_lead(remote))
642 return 0;
643 if (is_biphase(remote)) {
644 if (!expectspace(remote, remote->srepeat))
645 return 0;
646 if (!expectpulse(remote, remote->prepeat))
647 return 0;
648 } else {
649 if (!expectpulse(remote, remote->prepeat))
650 return 0;
651 set_pending_space(remote->srepeat);
652 }
653 if (!get_trail(remote))
654 return 0;
655 if (!get_gap
656 (remote,
657 is_const(remote) ? (min_gap(remote) >
658 rec_buffer.sum ?
659 min_gap(remote) - rec_buffer.sum : 0) :
660 (has_repeat_gap(remote) ? remote->repeat_gap : min_gap(remote))
661 ))
662 return 0;
663 return 1;
664}
665
666static ir_code get_data(struct ir_remote* remote, int bits, int done)
667{
668 ir_code code;
669 int i;
670
671 code = 0;
672
673 if (is_rcmm(remote)) {
674 lirc_t deltap, deltas, sum;
675
676 if (bits % 2 || done % 2) {
677 log_error("invalid bit number.");
678 return (ir_code) -1;
679 }
680 if (!sync_pending_space(remote))
681 return 0;
682 for (i = 0; i < bits; i += 2) {
683 code <<= 2;
684 deltap = get_next_pulse(remote->pzero + remote->pone + remote->ptwo + remote->pthree);
685 deltas = get_next_space(remote->szero + remote->sone + remote->stwo + remote->sthree);
686 if (deltap == 0 || deltas == 0) {
687 log_error("failed on bit %d", done + i + 1);
688 return (ir_code) -1;
689 }
690 sum = deltap + deltas;
691 log_trace2("rcmm: sum %ld", (uint32_t)sum);
692 if (expect(remote, sum, remote->pzero + remote->szero)) {
693 code |= 0;
694 log_trace1("00");
695 } else if (expect(remote, sum, remote->pone + remote->sone)) {
696 code |= 1;
697 log_trace1("01");
698 } else if (expect(remote, sum, remote->ptwo + remote->stwo)) {
699 code |= 2;
700 log_trace1("10");
701 } else if (expect(remote, sum, remote->pthree + remote->sthree)) {
702 code |= 3;
703 log_trace1("11");
704 } else {
705 log_trace1("no match for %d+%d=%d", deltap, deltas, sum);
706 return (ir_code) -1;
707 }
708 }
709 return code;
710 } else if (is_grundig(remote)) {
711 lirc_t deltap, deltas, sum;
712 int state, laststate;
713
714 if (bits % 2 || done % 2) {
715 log_error("invalid bit number.");
716 return (ir_code) -1;
717 }
718 if (!sync_pending_pulse(remote))
719 return (ir_code) -1;
720 for (laststate = state = -1, i = 0; i < bits; ) {
721 deltas = get_next_space(remote->szero + remote->sone + remote->stwo + remote->sthree);
722 deltap = get_next_pulse(remote->pzero + remote->pone + remote->ptwo + remote->pthree);
723 if (deltas == 0 || deltap == 0) {
724 log_error("failed on bit %d", done + i + 1);
725 return (ir_code) -1;
726 }
727 sum = deltas + deltap;
728 log_trace2("grundig: sum %ld", (uint32_t)sum);
729 if (expect(remote, sum, remote->szero + remote->pzero)) {
730 state = 0;
731 log_trace1("2T");
732 } else if (expect(remote, sum, remote->sone + remote->pone)) {
733 state = 1;
734 log_trace1("3T");
735 } else if (expect(remote, sum, remote->stwo + remote->ptwo)) {
736 state = 2;
737 log_trace1("4T");
738 } else if (expect(remote, sum, remote->sthree + remote->pthree)) {
739 state = 3;
740 log_trace2("6T");
741 } else {
742 log_trace1("no match for %d+%d=%d", deltas, deltap, sum);
743 return (ir_code) -1;
744 }
745 if (state == 3) { /* 6T */
746 i += 2;
747 code <<= 2;
748 state = -1;
749 code |= 0;
750 } else if (laststate == 2 && state == 0) { /* 4T2T */
751 i += 2;
752 code <<= 2;
753 state = -1;
754 code |= 1;
755 } else if (laststate == 1 && state == 1) { /* 3T3T */
756 i += 2;
757 code <<= 2;
758 state = -1;
759 code |= 2;
760 } else if (laststate == 0 && state == 2) { /* 2T4T */
761 i += 2;
762 code <<= 2;
763 state = -1;
764 code |= 3;
765 } else if (laststate == -1) {
766 /* 1st bit */
767 } else {
768 log_error("invalid state %d:%d", laststate, state);
769 return (ir_code) -1;
770 }
771 laststate = state;
772 }
773 return code;
774 } else if (is_serial(remote)) {
775 int received;
776 int space, stop_bit, parity_bit;
777 int parity;
778 lirc_t delta, origdelta, pending, expecting, gap_delta;
779 lirc_t base, stop;
780 lirc_t max_space, max_pulse;
781
782 base = 1000000 / remote->baud;
783
784 /* start bit */
785 set_pending_pulse(base);
786
787 received = 0;
788 space = (rec_buffer.pendingp == 0); /* expecting space ? */
789 stop_bit = 0;
790 parity_bit = 0;
791 delta = origdelta = 0;
792 stop = base * remote->stop_bits / 2;
793 parity = 0;
794 gap_delta = 0;
795
796 max_space = remote->sone * remote->bits_in_byte + stop;
797 max_pulse = remote->pzero * (1 + remote->bits_in_byte);
798 if (remote->parity != IR_PARITY_NONE) {
799 parity_bit = 1;
800 max_space += remote->sone;
801 max_pulse += remote->pzero;
802 bits += bits / remote->bits_in_byte;
803 }
804
805 while (received < bits || stop_bit) {
806 if (delta == 0) {
807 delta = space ? get_next_space(max_space) : get_next_pulse(max_pulse);
808 if (delta == 0 && space && received + remote->bits_in_byte + parity_bit >= bits)
809 /* open end */
810 delta = max_space;
811 origdelta = delta;
812 }
813 if (delta == 0) {
814 log_trace("failed before bit %d", received + 1);
815 return (ir_code) -1;
816 }
817 pending = (space ? rec_buffer.pendings : rec_buffer.pendingp);
818 if (expect(remote, delta, pending)) {
819 delta = 0;
820 } else if (delta > pending) {
821 delta -= pending;
822 } else {
823 log_trace("failed before bit %d", received + 1);
824 return (ir_code) -1;
825 }
826 if (pending > 0) {
827 if (stop_bit) {
828 log_trace2("delta: %lu", delta);
829 gap_delta = delta;
830 delta = 0;
831 set_pending_pulse(base);
832 set_pending_space(0);
833 stop_bit = 0;
834 space = 0;
835 log_trace2("stop bit found");
836 } else {
837 log_trace2("pending bit found");
838 set_pending_pulse(0);
839 set_pending_space(0);
840 if (delta == 0)
841 space = (space ? 0 : 1);
842 }
843 continue;
844 }
845 expecting = (space ? remote->sone : remote->pzero);
846 if (delta > expecting || expect(remote, delta, expecting)) {
847 delta -= (expecting > delta ? delta : expecting);
848 received++;
849 code <<= 1;
850 code |= space;
851 parity ^= space;
852 log_trace1("adding %d", space);
853 if (received % (remote->bits_in_byte + parity_bit) == 0) {
854 ir_code temp;
855
856 if ((remote->parity == IR_PARITY_EVEN && parity)
857 || (remote->parity == IR_PARITY_ODD && !parity)) {
858 log_trace("parity error after %d bits", received + 1);
859 return (ir_code) -1;
860 }
861 parity = 0;
862
863 /* parity bit is filtered out */
864 temp = code >> (remote->bits_in_byte + parity_bit);
865 code =
866 temp << remote->bits_in_byte | reverse(code >> parity_bit,
867 remote->bits_in_byte);
868
869 if (space && delta == 0) {
870 log_trace("failed at stop bit after %d bits", received + 1);
871 return (ir_code) -1;
872 }
873 log_trace2("awaiting stop bit");
874 set_pending_space(stop);
875 stop_bit = 1;
876 }
877 } else {
878 if (delta == origdelta) {
879 log_trace("framing error after %d bits", received + 1);
880 return (ir_code) -1;
881 }
882 delta = 0;
883 }
884 if (delta == 0)
885 space = (space ? 0 : 1);
886 }
887 if (gap_delta)
888 unget_rec_buffer_delta(gap_delta);
889 set_pending_pulse(0);
890 set_pending_space(0);
891 return code;
892 } else if (is_bo(remote)) {
893 int lastbit = 1;
894 lirc_t deltap, deltas;
895 lirc_t pzero, szero;
896 lirc_t pone, sone;
897
898 for (i = 0; i < bits; i++) {
899 code <<= 1;
900 deltap = get_next_pulse(remote->pzero + remote->pone + remote->ptwo + remote->pthree);
901 deltas = get_next_space(remote->szero + remote->sone + remote->stwo + remote->sthree);
902 if (deltap == 0 || deltas == 0) {
903 log_error("failed on bit %d", done + i + 1);
904 return (ir_code) -1;
905 }
906 if (lastbit == 1) {
907 pzero = remote->pone;
908 szero = remote->sone;
909 pone = remote->ptwo;
910 sone = remote->stwo;
911 } else {
912 pzero = remote->ptwo;
913 szero = remote->stwo;
914 pone = remote->pthree;
915 sone = remote->sthree;
916 }
917 log_trace2("%lu %lu %lu %lu", pzero, szero, pone, sone);
918 if (expect(remote, deltap, pzero)) {
919 if (expect(remote, deltas, szero)) {
920 code |= 0;
921 lastbit = 0;
922 log_trace1("0");
923 continue;
924 }
925 }
926
927 if (expect(remote, deltap, pone)) {
928 if (expect(remote, deltas, sone)) {
929 code |= 1;
930 lastbit = 1;
931 log_trace1("1");
932 continue;
933 }
934 }
935 log_error("failed on bit %d", done + i + 1);
936 return (ir_code) -1;
937 }
938 return code;
939 } else if (is_xmp(remote)) {
940 lirc_t deltap, deltas, sum;
941 ir_code n;
942
943 if (bits % 4 || done % 4) {
944 log_error("invalid bit number.");
945 return (ir_code) -1;
946 }
947 if (!sync_pending_space(remote))
948 return 0;
949 for (i = 0; i < bits; i += 4) {
950 code <<= 4;
951 deltap = get_next_pulse(remote->pzero);
952 deltas = get_next_space(remote->szero + 16 * remote->sone);
953 if (deltap == 0 || deltas == 0) {
954 log_error("failed on bit %d", done + i + 1);
955 return (ir_code) -1;
956 }
957 sum = deltap + deltas;
958
959 sum -= remote->pzero + remote->szero;
960 n = (sum + remote->sone / 2) / remote->sone;
961 if (n >= 16) {
962 log_error("failed on bit %d", done + i + 1);
963 return (ir_code) -1;
964 }
965 log_trace("%d: %lx", i, n);
966 code |= n;
967 }
968 return code;
969 }
970
971 for (i = 0; i < bits; i++) {
972 code = code << 1;
973 if (is_goldstar(remote)) {
974 if ((done + i) % 2) {
975 log_trace1("$1");
976 remote->pone = remote->ptwo;
977 remote->sone = remote->stwo;
978 } else {
979 log_trace1("$2");
980 remote->pone = remote->pthree;
981 remote->sone = remote->sthree;
982 }
983 }
984
985 if (expectone(remote, done + i)) {
986 log_trace1("1");
987 code |= 1;
988 } else if (expectzero(remote, done + i)) {
989 log_trace1("0");
990 code |= 0;
991 } else {
992 log_trace("failed on bit %d", done + i + 1);
993 return (ir_code) -1;
994 }
995 }
996 return code;
997}
998
999static ir_code get_pre(struct ir_remote* remote)
1000{
1001 ir_code pre;
1002 ir_code remote_pre;
1003 ir_code match_pre;
1004 ir_code toggle_mask;
1005
1006 pre = get_data(remote, remote->pre_data_bits, 0);
1007
1008 if (pre == (ir_code) -1) {
1009 log_trace("Failed on pre_data: cannot get it");
1010 return (ir_code) -1;
1011 }
1012 if (update_mode) {
1013 /*
1014 * toggle_bit_mask is applied to the concatenated
1015 * pre_data - data - post_data. We dont check post data, but
1016 * adjusts for the length.
1017 */
1018 toggle_mask =
1019 remote->toggle_bit_mask >> remote->post_data_bits;
1020 remote_pre = remote->pre_data & ~toggle_mask;
1021 match_pre = pre & ~toggle_mask;
1022 if (remote->pre_data != 0 && remote_pre != match_pre) {
1023 log_trace("Failed on pre_data: bad data: %x", pre);
1024 return (ir_code) -1;
1025 }
1026 }
1027 if (remote->pre_p > 0 && remote->pre_s > 0) {
1028 if (!expectpulse(remote, remote->pre_p))
1029 return (ir_code) -1;
1030 set_pending_space(remote->pre_s);
1031 }
1032 return pre;
1033}
1034
1035static ir_code get_post(struct ir_remote* remote)
1036{
1037 ir_code post;
1038
1039 if (remote->post_p > 0 && remote->post_s > 0) {
1040 if (!expectpulse(remote, remote->post_p))
1041 return (ir_code) -1;
1042 set_pending_space(remote->post_s);
1043 }
1044
1045 post = get_data(remote, remote->post_data_bits, remote->pre_data_bits + remote->bits);
1046
1047 if (post == (ir_code) -1) {
1048 log_trace("failed on post_data");
1049 return (ir_code) -1;
1050 }
1051 return post;
1052}
1053
1054int receive_decode(struct ir_remote* remote, struct decode_ctx_t* ctx)
1055{
1056 lirc_t sync;
1057 int header;
1058 struct timeval current;
1059
1060 sync = 0; /* make compiler happy */
1061 memset(ctx, 0, sizeof(struct decode_ctx_t));
1062 ctx->code = ctx->pre = ctx->post = 0;
1063 header = 0;
1064
1065 if (rec_buffer.at_eof && rec_buffer.wptr - rec_buffer.rptr <= 1) {
1066 log_debug("Decode: found EOF");
1067 ctx->code = LIRC_EOF;
1068 rec_buffer.at_eof = 0;
1069 return 1;
1070 }
1071 if (curr_driver->rec_mode == LIRC_MODE_MODE2 ||
1072 curr_driver->rec_mode == LIRC_MODE_PULSE ||
1073 curr_driver->rec_mode == LIRC_MODE_RAW) {
1075 rec_buffer.is_biphase = is_biphase(remote) ? 1 : 0;
1076
1077 /* we should get a long space first */
1078 sync = sync_rec_buffer(remote);
1079 if (!sync) {
1080 log_trace("failed on sync");
1081 return 0;
1082 }
1083 log_trace("sync");
1084
1085 if (has_repeat(remote) && last_remote == remote) {
1086 if (remote->flags & REPEAT_HEADER && has_header(remote)) {
1087 if (!get_header(remote)) {
1088 log_trace("failed on repeat header");
1089 return 0;
1090 }
1091 log_trace("repeat header");
1092 }
1093 if (get_repeat(remote)) {
1094 if (remote->last_code == NULL) {
1095 log_notice("repeat code without last_code received");
1096 return 0;
1097 }
1098
1099 ctx->pre = remote->pre_data;
1100 ctx->code = remote->last_code->code;
1101 ctx->post = remote->post_data;
1102 ctx->repeat_flag = 1;
1103
1104 ctx->min_remaining_gap =
1105 is_const(remote) ? (min_gap(remote) >
1106 rec_buffer.sum ? min_gap(remote) -
1107 rec_buffer.sum : 0) : (has_repeat_gap(remote) ? remote->
1108 repeat_gap : min_gap(remote));
1109 ctx->max_remaining_gap =
1110 is_const(remote) ? (max_gap(remote) >
1111 rec_buffer.sum ? max_gap(remote) -
1112 rec_buffer.sum : 0) : (has_repeat_gap(remote) ? remote->
1113 repeat_gap : max_gap(remote));
1114 return 1;
1115 }
1116 log_trace("no repeat");
1118 sync_rec_buffer(remote);
1119 }
1120
1121 if (has_header(remote)) {
1122 header = 1;
1123 if (!get_header(remote)) {
1124 header = 0;
1125 if (!(remote->flags & NO_HEAD_REP && expect_at_most(remote, sync, max_gap(remote)))) {
1126 log_trace("failed on header");
1127 return 0;
1128 }
1129 }
1130 log_trace("header");
1131 }
1132 }
1133
1134 if (is_raw(remote)) {
1135 struct ir_ncode* codes;
1136 struct ir_ncode* found;
1137 int i;
1138
1139 if (curr_driver->rec_mode == LIRC_MODE_LIRCCODE)
1140 return 0;
1141
1142 codes = remote->codes;
1143 found = NULL;
1144 while (codes->name != NULL && found == NULL) {
1145 found = codes;
1146 for (i = 0; i < codes->length; ) {
1147 if (!expectpulse(remote, codes->signals[i++])) {
1148 found = NULL;
1150 sync_rec_buffer(remote);
1151 break;
1152 }
1153 if (i < codes->length && !expectspace(remote, codes->signals[i++])) {
1154 found = NULL;
1156 sync_rec_buffer(remote);
1157 break;
1158 }
1159 }
1160 codes++;
1161 if (found != NULL) {
1162 if (!get_gap
1163 (remote, is_const(remote) ?
1164 min_gap(remote) - rec_buffer.sum :
1165 min_gap(remote)))
1166 found = NULL;
1167 }
1168 }
1169 if (found == NULL)
1170 return 0;
1171 ctx->code = found->code;
1172 } else {
1173 if (curr_driver->rec_mode == LIRC_MODE_LIRCCODE) {
1174 lirc_t sum;
1175 ir_code decoded = rec_buffer.decoded;
1176
1177 log_trace("decoded: %llx", decoded);
1178 if (curr_driver->rec_mode == LIRC_MODE_LIRCCODE
1179 && curr_driver->code_length != bit_count(remote))
1180 return 0;
1181
1182 ctx->post = decoded & gen_mask(remote->post_data_bits);
1183 decoded >>= remote->post_data_bits;
1184 ctx->code = decoded & gen_mask(remote->bits);
1185 ctx->pre = decoded >> remote->bits;
1186
1187 gettimeofday(&current, NULL);
1188 sum = remote->phead + remote->shead +
1189 lirc_t_max(remote->pone + remote->sone,
1190 remote->pzero + remote->szero) * bit_count(remote) + remote->plead +
1191 remote->ptrail + remote->pfoot + remote->sfoot + remote->pre_p + remote->pre_s +
1192 remote->post_p + remote->post_s;
1193
1194 rec_buffer.sum = sum >= remote->gap ? remote->gap - 1 : sum;
1195 sync = time_elapsed(&remote->last_send, &current) - rec_buffer.sum;
1196 } else {
1197 if (!get_lead(remote)) {
1198 log_trace("failed on leading pulse");
1199 return 0;
1200 }
1201
1202 if (has_pre(remote)) {
1203 ctx->pre = get_pre(remote);
1204 if (ctx->pre == (ir_code) -1) {
1205 log_trace("failed on pre");
1206 return 0;
1207 }
1208 log_trace("pre: %llx", ctx->pre);
1209 }
1210
1211 ctx->code = get_data(remote, remote->bits, remote->pre_data_bits);
1212 if (ctx->code == (ir_code) -1) {
1213 log_trace("failed on code");
1214 return 0;
1215 }
1216 log_trace("code: %llx", ctx->code);
1217
1218 if (has_post(remote)) {
1219 ctx->post = get_post(remote);
1220 if (ctx->post == (ir_code) -1) {
1221 log_trace("failed on post");
1222 return 0;
1223 }
1224 log_trace("post: %llx", ctx->post);
1225 }
1226 if (!get_trail(remote)) {
1227 log_trace("failed on trailing pulse");
1228 return 0;
1229 }
1230 if (has_foot(remote)) {
1231 if (!get_foot(remote)) {
1232 log_trace("failed on foot");
1233 return 0;
1234 }
1235 }
1236 if (header == 1 && is_const(remote) && (remote->flags & NO_HEAD_REP))
1237 rec_buffer.sum -= remote->phead + remote->shead;
1238 if (is_rcmm(remote)) {
1239 if (!get_gap(remote, 1000))
1240 return 0;
1241 } else if (is_const(remote)) {
1242 if (!get_gap(remote, min_gap(remote) > rec_buffer.sum ?
1243 min_gap(remote) - rec_buffer.sum :
1244 0))
1245 return 0;
1246 } else {
1247 if (!get_gap(remote, min_gap(remote)))
1248 return 0;
1249 }
1250 } /* end of mode specific code */
1251 }
1252 if ((!has_repeat(remote) || remote->reps < remote->min_code_repeat)
1253 && expect_at_most(remote, sync, remote->max_remaining_gap))
1254 ctx->repeat_flag = 1;
1255 else
1256 ctx->repeat_flag = 0;
1257 if (curr_driver->rec_mode == LIRC_MODE_LIRCCODE) {
1258 /* Most TV cards don't pass each signal to the
1259 * driver. This heuristic should fix repeat in such
1260 * cases. */
1261 if (time_elapsed(&remote->last_send, &current) < 325000)
1262 ctx->repeat_flag = 1;
1263 }
1264 if (is_const(remote)) {
1265 ctx->min_remaining_gap = min_gap(remote) > rec_buffer.sum ? min_gap(remote) - rec_buffer.sum : 0;
1266 ctx->max_remaining_gap = max_gap(remote) > rec_buffer.sum ? max_gap(remote) - rec_buffer.sum : 0;
1267 } else {
1268 ctx->min_remaining_gap = min_gap(remote);
1269 ctx->max_remaining_gap = max_gap(remote);
1270 }
1271 return 1;
1272}
const struct driver *const curr_driver
Read-only access to drv for client code.
Definition driver.c:34
void rec_buffer_set_logfile(FILE *f)
Set a file logging input from driver in same format as mode2(1).
Definition receive.c:204
int waitfordata(uint32_t maxusec)
If set_waitfordata(func) is called, invoke and return function set this way.
Definition receive.c:175
void set_waitfordata_func(int(*func)(uint32_t maxusec))
Set the function used by waitfordata().
Definition receive.c:169
void rec_buffer_rewind(void)
Reset the modules's internal fifo's read state to initial values where the nothing is read.
Definition receive.c:222
struct ir_remote * last_remote
TODO.
Definition ir_remote.c:59
void rec_buffer_reset_wptr(void)
Reset internal fifo's write pointer.
Definition receive.c:232
void rec_set_update_mode(int mode)
Set update mode, where recorded pre_data is verified to match the template pre_data.
Definition receive.c:69
void rec_buffer_init(void)
Clear internal buffer to pristine state.
Definition receive.c:217
int receive_decode(struct ir_remote *remote, struct decode_ctx_t *ctx)
Decode data from remote.
Definition receive.c:1054
int rec_buffer_clear(void)
Flush the internal fifo and store a single code read from the driver in it.
Definition receive.c:237
#define REPEAT_HEADER
header is also sent before repeat code
uint64_t ir_code
Denotes an internal coded representation for an IR transmission.
#define NO_HEAD_REP
no header for key repeats
#define LIRC_EOF
Bit manipulator in lirc_t, see lirc.h .
Definition lirc_config.h:90
#define log_trace(fmt,...)
Log a trace message.
Definition lirc_log.h:129
#define log_notice(fmt,...)
Log a notice message.
Definition lirc_log.h:119
#define log_debug(fmt,...)
Log a debug message.
Definition lirc_log.h:124
#define log_perror_err(fmt,...)
perror wrapper logging with level LIRC_ERROR.
Definition lirc_log.h:89
#define log_trace2(fmt,...)
Log a trace2 message.
Definition lirc_log.h:139
#define log_error(fmt,...)
Log an error message.
Definition lirc_log.h:104
#define log_trace1(fmt,...)
Log a trace1 message.
Definition lirc_log.h:134
logchannel_t
Log channels used to filter messages.
Definition lirc_log.h:53
State describing code, pre, post + gap and repeat state.
ir_code code
Code part, matched to code defintion.
int repeat_flag
True if code is a repeated one.
ir_code post
post data, sent after code.
lirc_t min_remaining_gap
Estimated min time of trailing gap.
lirc_t max_remaining_gap
Estimated max time of trailing gap.
ir_code pre
pre data, before code.
int fd
Set by the driver after init().
Definition driver.h:146
const uint32_t code_length
Length in bits of the code.
Definition driver.h:164
lirc_t(*const readdata)(lirc_t timeout)
Get length of next pulse/space from hardware.
Definition driver.h:222
uint32_t rec_mode
Possible values are: LIRC_MODE_RAW, LIRC_MODE_PULSE, LIRC_MODE_MODE2, LIRC_MODE_LIRCCODE.
Definition driver.h:161
IR Command, corresponding to one (command defining) line of the configuration file.
ir_code code
The first code of the command.
int length
(private)
lirc_t * signals
(private)
struct ir_code_node * current
Should point at the ir_code currently being transmitted, or NULL if none.
char * name
Name of command.
One remote as represented in the configuration file.
uint32_t repeat_gap
time between two repeat codes if different from gap
lirc_t stwo
2 (only used for RC-MM)
unsigned int stop_bits
mapping: 1->2 1.5->3 2->4
unsigned int bits_in_byte
default: 8
lirc_t sfoot
foot
ir_code rc6_mask
RC-6 doubles signal length of some bits.
lirc_t max_remaining_gap
gap range
lirc_t ptrail
trailing pulse
lirc_t srepeat
indicate repeating
ir_code pre_data
data which the remote sends before actual keycode
int bits
bits (length of code)
int post_data_bits
length of post_data
lirc_t plead
leading pulse
lirc_t sthree
3 (only used for RC-MM)
lirc_t shead
header
struct timeval last_send
time last_code was received or sent
ir_code post_data
data which the remote sends after actual keycode
int flags
flags
unsigned int baud
can be overridden by [p|s]zero, [p|s]one
lirc_t post_s
signal between keycode and post_code
lirc_t pre_s
signal between pre_data and keycode
uint32_t gap
time between signals in usecs
int eps
eps (relative tolerance)
struct ir_ncode * last_code
code received or sent last
struct ir_ncode * toggle_code
toggle code received or sent last
unsigned int min_code_repeat
meaningful only if remote sends a repeat code: in this case this value indicates how often the real c...
ir_code toggle_bit_mask
previously only one bit called toggle_bit
unsigned int parity
currently unsupported
int pre_data_bits
length of pre_data
lirc_t min_remaining_gap
remember gap for CONST_LENGTH remotes