LIRC libraries: /tmp/work/src/lirc-0.10.2/lib/irrecord.c Source File

LIRC libraries Linux Infrared Remote Control

Loading...
Searching...
No Matches
irrecord.c
Go to the documentation of this file.
1/***************************************************************************
2** irrecord.c **************************************************************
3****************************************************************************
4*
5* irrecord - library for recording IR-codes for usage with lircd
6*
7* Copyright (C) 1998,99 Christoph Bartelmus <lirc@bartelmus.de>
8*
9*/
10
16#define _GNU_SOURCE
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <stdint.h>
23#include <unistd.h>
24#include <poll.h>
25
26#include "lirc_private.h"
27#include "irrecord.h"
28
29/* -------------------------- C file -------------------------------- */
30
31static const logchannel_t logchannel = LOG_LIB;
32
33// forwards
34static lirc_t emulation_readdata(lirc_t timeout);
35
36// Constants
37static const struct driver hw_emulation = {
38 .name = "emulation",
39 .device = "/dev/null",
40 .features = LIRC_CAN_REC_MODE2,
41 .send_mode = 0,
42 .rec_mode = LIRC_MODE_MODE2,
43 .code_length = 0,
44 .init_func = NULL,
45 .deinit_func = NULL,
46 .send_func = NULL,
47 .rec_func = NULL,
48 .decode_func = NULL,
49 .drvctl_func = NULL,
50 .readdata = emulation_readdata,
51 .open_func = default_open,
52 .close_func = default_close,
53 .api_version = 2,
54 .driver_version = "0.10.2"
55};
56
57static const int IR_CODE_NODE_SIZE = sizeof(struct ir_code_node);
58
59// Globals
60
61struct ir_remote remote;
62 unsigned int eps = 30;
63lirc_t aeps = 100;
64
65// Static data
66
67static lirc_t signals[MAX_SIGNALS];
68static struct ir_remote* emulation_data;
69static struct ir_ncode* next_code = NULL;
70static struct ir_ncode* current_code = NULL;
71static int current_index = 0;
72static int current_rep = 0;
73
74static struct lengths* first_space = NULL;
75static struct lengths* first_pulse = NULL;
76static struct lengths* first_sum = NULL;
77static struct lengths* first_gap = NULL;
78static struct lengths* first_repeat_gap = NULL;
79static struct lengths* first_signal_length = NULL;
80static struct lengths* first_headerp = NULL;
81static struct lengths* first_headers = NULL;
82static struct lengths* first_1lead = NULL;
83static struct lengths* first_3lead = NULL;
84static struct lengths* first_trail = NULL;
85static struct lengths* first_repeatp = NULL;
86static struct lengths* first_repeats = NULL;
87
88static uint32_t lengths[MAX_SIGNALS];
89static uint32_t first_length, first_lengths, second_lengths;
90static unsigned int count, count_spaces, count_signals;
91static unsigned int count_3repeats, count_5repeats;
92
93
94// Functions
95
97 void btn_state_set_message(struct button_state* state, const char* fmt, ...)
98{
99 va_list ap;
100
101 va_start(ap, fmt);
102 vsnprintf(state->message, sizeof(state->message), fmt, ap);
103 va_end(ap);
104}
105
106
107static void fprint_copyright(FILE* fout)
108{
109 fprintf(fout, "\n"
110 "# Please take the time to finish this file as described in\n"
111 "# https://sourceforge.net/p/lirc-remotes/wiki/Checklist/\n"
112 "# and make it available to others by sending it to\n"
113 "# <lirc@bartelmus.de>\n");
114}
115
116
118 int availabledata(void)
119{
120 struct pollfd pfd = {
121 .fd = curr_driver->fd, .events = POLLIN, .revents = 0};
122 int ret;
123
124 do {
125 do {
126 ret = curl_poll(&pfd, 1, 0);
127 } while (ret == -1 && errno == EINTR);
128 if (ret == -1) {
129 log_perror_err("availabledata: curl_poll() failed");
130 continue;
131 }
132 } while (ret == -1);
133
134 return pfd.revents & POLLIN ? 1 : 0;
135}
136
137
139 void flushhw(void)
140{
141 size_t size = 1;
142 char buffer[PACKET_SIZE];
143
144 switch (curr_driver->rec_mode) {
145 case LIRC_MODE_MODE2:
146 while (availabledata())
147 curr_driver->readdata(0);
148 return;
149 case LIRC_MODE_LIRCCODE:
150 size = curr_driver->code_length / CHAR_BIT;
151 if (curr_driver->code_length % CHAR_BIT)
152 size++;
153 break;
154 }
155 while (read(curr_driver->fd, buffer, size) == size)
156 ;
157}
158
159
161 int resethw(int started_as_root)
162{
163 int flags;
164
165 if (started_as_root)
166 if (seteuid(0) == -1)
167 log_error("Cannot reset root uid");
168 if (curr_driver->deinit_func)
169 curr_driver->deinit_func();
170 if (curr_driver->init_func) {
171 if (!curr_driver->init_func()) {
172 drop_sudo_root(seteuid);
173 return 0;
174 }
175 }
176 flags = fcntl(curr_driver->fd, F_GETFL, 0);
177 if (flags == -1 ||
178 fcntl(curr_driver->fd, F_SETFL, flags | O_NONBLOCK) == -1) {
179 if (curr_driver->deinit_func)
180 curr_driver->deinit_func();
181 drop_sudo_root(seteuid);
182 return 0;
183 }
184 drop_sudo_root(seteuid);
185 return 1;
186}
187
188
189 void gap_state_init(struct gap_state* state)
190{
191 memset(state, 0, sizeof(struct gap_state));
192}
193
194
195 void lengths_state_init(struct lengths_state* state)
196{
197 count = 0;
198 count_spaces = 0;
199 count_3repeats = 0;
200 count_5repeats = 0;
201 count_signals = 0;
202 first_length = 0;
203 first_lengths = 0;
204 second_lengths = 0;
205 memset(state, 0, sizeof(struct lengths_state));
206 state->first_signal = -1;
207 state->retval = 1;
208}
209
210
211 void toggle_state_init(struct toggle_state* state)
212{
213 memset(state, 0, sizeof(struct toggle_state));
214 state->retries = 30;
215 state->retval = EXIT_SUCCESS;
216}
217
218
219 void button_state_init(struct button_state* state, int started_as_root)
220{
221 memset(state, 0, sizeof(struct button_state));
222 state->started_as_root = started_as_root;
223 state->retval = EXIT_SUCCESS;
224}
225
226
227static lirc_t calc_signal(struct lengths* len)
228{
229 if (len->count == 0)
230 return 0;
231 return (lirc_t)(len->sum / len->count);
232}
233
234
235static void set_toggle_bit_mask(struct ir_remote* remote, ir_code xor)
236{
237 ir_code mask;
238 struct ir_ncode* codes;
239 int bits;
240
241 if (!remote->codes)
242 return;
243
244 bits = bit_count(remote);
245 mask = ((ir_code)1) << (bits - 1);
246 while (mask) {
247 if (mask == xor)
248 break;
249 mask = mask >> 1;
250 }
251 if (mask) {
252 remote->toggle_bit_mask = xor;
253
254 codes = remote->codes;
255 while (codes->name != NULL) {
256 codes->code &= ~xor;
257 codes++;
258 }
259 }
260 /* Sharp, Denon and some others use a toggle_mask */
261 else if (bits == 15 && xor == 0x3ff) {
262 remote->toggle_mask = xor;
263 } else {
264 remote->toggle_bit_mask = xor;
265 }
266}
267
268
269 void get_pre_data(struct ir_remote* remote)
270{
271 struct ir_ncode* codes;
272 ir_code mask, last;
273 int count, i;
274 struct ir_code_node* n;
275
276 if (remote->bits == 0)
277 return;
278 mask = (-1);
279 codes = remote->codes;
280 if (codes->name == NULL)
281 return; /* at least 2 codes needed */
282 last = codes->code;
283 codes++;
284 if (codes->name == NULL)
285 return; /* at least 2 codes needed */
286 while (codes->name != NULL) {
287 mask &= ~(last ^ codes->code);
288 last = codes->code;
289 for (n = codes->next; n != NULL; n = n->next) {
290 mask &= ~(last ^ n->code);
291 last = n->code;
292 }
293 codes++;
294 }
295 count = 0;
296 while (mask & 0x8000000000000000LL) {
297 count++;
298 mask = mask << 1;
299 }
300 count -= sizeof(ir_code) * CHAR_BIT - remote->bits;
301
302 /* only "even" numbers should go to pre/post data */
303 if (count % 8 && (remote->bits - count) % 8)
304 count -= count % 8;
305 if (count > 0) {
306 mask = 0;
307 for (i = 0; i < count; i++) {
308 mask = mask << 1;
309 mask |= 1;
310 }
311 remote->bits -= count;
312 mask = mask << (remote->bits);
313 remote->pre_data_bits = count;
314 remote->pre_data = (last & mask) >> (remote->bits);
315
316 codes = remote->codes;
317 while (codes->name != NULL) {
318 codes->code &= ~mask;
319 for (n = codes->next; n != NULL; n = n->next)
320 n->code &= ~mask;
321 codes++;
322 }
323 }
324}
325
326
327 void get_post_data(struct ir_remote* remote)
328{
329 struct ir_ncode* codes;
330 ir_code mask, last;
331 int count, i;
332 struct ir_code_node* n;
333
334 if (remote->bits == 0)
335 return;
336
337 mask = (-1);
338 codes = remote->codes;
339 if (codes->name == NULL)
340 return; /* at least 2 codes needed */
341 last = codes->code;
342 codes++;
343 if (codes->name == NULL)
344 return; /* at least 2 codes needed */
345 while (codes->name != NULL) {
346 mask &= ~(last ^ codes->code);
347 last = codes->code;
348 for (n = codes->next; n != NULL; n = n->next) {
349 mask &= ~(last ^ n->code);
350 last = n->code;
351 }
352 codes++;
353 }
354 count = 0;
355 while (mask & 0x1) {
356 count++;
357 mask = mask >> 1;
358 }
359 /* only "even" numbers should go to pre/post data */
360 if (count % 8 && (remote->bits - count) % 8)
361 count -= count % 8;
362 if (count > 0) {
363 mask = 0;
364 for (i = 0; i < count; i++) {
365 mask = mask << 1;
366 mask |= 1;
367 }
368 remote->bits -= count;
369 remote->post_data_bits = count;
370 remote->post_data = last & mask;
371
372 codes = remote->codes;
373 while (codes->name != NULL) {
374 codes->code = codes->code >> count;
375 for (n = codes->next; n != NULL; n = n->next)
376 n->code = n->code >> count;
377 codes++;
378 }
379 }
380}
381
382
383 void remove_pre_data(struct ir_remote* remote)
384{
385 struct ir_ncode* codes;
386 struct ir_code_node* n;
387
388 if (remote->pre_data_bits == 0
389 || remote->pre_p != 0
390 || remote->pre_s != 0)
391 return;
392 for (codes = remote->codes; codes->name != NULL; codes++) {
393 codes->code |= remote->pre_data << remote->bits;
394 for (n = codes->next; n != NULL; n = n->next)
395 n->code |= remote->pre_data << remote->bits;
396 }
397 remote->bits += remote->pre_data_bits;
398 remote->pre_data = 0;
399 remote->pre_data_bits = 0;
400}
401
402
403 void remove_post_data(struct ir_remote* remote)
404{
405 struct ir_ncode* codes;
406 struct ir_code_node* n;
407
408 if (remote->post_data_bits == 0)
409 return;
410 for (codes = remote->codes; codes->name != NULL; codes++) {
411 codes->code <<= remote->post_data_bits;
412 codes->code |= remote->post_data;
413 for (n = codes->next; n != NULL; n = n->next) {
414 n->code <<= remote->post_data_bits;
415 n->code |= remote->post_data;
416 }
417 }
418 remote->bits += remote->post_data_bits;
419 remote->post_data = 0;
420 remote->post_data_bits = 0;
421}
422
423
424 void invert_data(struct ir_remote* remote)
425{
426 struct ir_ncode* codes;
427 ir_code mask;
428 lirc_t p, s;
429 struct ir_code_node* n;
430
431 /* swap one, zero */
432 p = remote->pone;
433 s = remote->sone;
434 remote->pone = remote->pzero;
435 remote->sone = remote->szero;
436 remote->pzero = p;
437 remote->szero = s;
438
439 /* invert pre_data */
440 if (has_pre(remote)) {
441 mask = gen_mask(remote->pre_data_bits);
442 remote->pre_data ^= mask;
443 }
444 /* invert post_data */
445 if (has_post(remote)) {
446 mask = gen_mask(remote->post_data_bits);
447 remote->post_data ^= mask;
448 }
449
450 if (remote->bits == 0)
451 return;
452
453 /* invert codes */
454 mask = gen_mask(remote->bits);
455 for (codes = remote->codes; codes->name != NULL; codes++) {
456 codes->code ^= mask;
457 for (n = codes->next; n != NULL; n = n->next)
458 n->code ^= mask;
459 }
460}
461
462
463 void remove_trail(struct ir_remote* remote)
464{
465 int extra_bit;
466
467 if (!is_space_enc(remote))
468 return;
469 if (remote->ptrail == 0)
470 return;
471 if (expect(remote, remote->pone, remote->pzero)
472 || expect(remote, remote->pzero, remote->pone))
473 return;
474 if (!(expect(remote, remote->sone, remote->szero)
475 && expect(remote, remote->szero, remote->sone)))
476 return;
477 if (expect(remote, remote->ptrail, remote->pone))
478 extra_bit = 1;
479 else if (expect(remote, remote->ptrail, remote->pzero))
480 extra_bit = 0;
481 else
482 return;
483
484 remote->post_data_bits++;
485 remote->post_data <<= 1;
486 remote->post_data |= extra_bit;
487 remote->ptrail = 0;
488}
489
490
491 void for_each_remote(struct ir_remote* remotes, remote_func func)
492{
493 struct ir_remote* remote;
494
495 remote = remotes;
496 while (remote != NULL) {
497 func(remote);
498 remote = remote->next;
499 }
500}
501
502
503static int mywaitfordata(uint32_t maxusec)
504{
505 int ret;
506 struct pollfd pfd = {
507 .fd = curr_driver->fd, .events = POLLIN, .revents = 0};
508
509 do {
510 ret = curl_poll(&pfd, 1, maxusec / 1000);
511 } while (ret == -1 && errno == EINTR);
512
513 if (ret == -1 && errno != EINTR)
514 log_perror_err("mywaitfordata: curl_poll() failed");
515 return (pfd.revents & POLLIN) != 0;
516}
517
518
519static lirc_t emulation_readdata(lirc_t timeout)
520{
521 static lirc_t sum = 0;
522 lirc_t data = 0;
523
524 if (current_code == NULL) {
525 data = 1000000;
526 if (next_code)
527 current_code = next_code;
528 else
529 current_code = emulation_data->codes;
530 current_rep = 0;
531 sum = 0;
532 } else {
533 if (current_code->name == NULL) {
534 log_warn("%s: no data found", emulation_data->name);
535 data = 0;
536 }
537 if (current_index >= current_code->length) {
538 if (next_code) {
539 current_code = next_code;
540 } else {
541 current_rep++;
542 if (current_rep > 2) {
543 current_code++;
544 current_rep = 0;
545 data = 1000000;
546 }
547 }
548 current_index = 0;
549 if (current_code->name == NULL) {
550 current_code = NULL;
551 return emulation_readdata(timeout);
552 }
553 if (data == 0) {
554 if (is_const(emulation_data))
555 data = emulation_data->gap - sum;
556 else
557 data = emulation_data->gap;
558 }
559
560 sum = 0;
561 } else {
562 data = current_code->signals[current_index];
563 if ((current_index % 2) == 0)
564 data |= PULSE_BIT;
565 current_index++;
566 sum += data & PULSE_MASK;
567 }
568 }
569 log_debug("delivering: %c%u\n",
570 data & PULSE_BIT ? 'p':'s', data & PULSE_MASK);
571 return data;
572}
573
574
575static struct lengths* new_length(lirc_t length)
576{
577 struct lengths* l;
578
579 l = malloc(sizeof(struct lengths));
580 if (l == NULL)
581 return NULL;
582 l->count = 1;
583 l->sum = length;
584 l->lower_bound = length / 100 * 100;
585 l->upper_bound = length / 100 * 100 + 99;
586 l->min = l->max = length;
587 l->next = NULL;
588 return l;
589}
590
591
592void unlink_length(struct lengths** first, struct lengths* remove)
593{
594 struct lengths* last;
595 struct lengths* scan;
596
597 if (remove == *first) {
598 *first = remove->next;
599 remove->next = NULL;
600 return;
601 }
602 scan = (*first)->next;
603 last = *first;
604 while (scan) {
605 if (scan == remove) {
606 last->next = remove->next;
607 remove->next = NULL;
608 return;
609 }
610 last = scan;
611 scan = scan->next;
612 }
613 log_error("unlink_length(): report this bug!");
614}
615
616
617int add_length(struct lengths** first, lirc_t length)
618{
619 struct lengths* l;
620 struct lengths* last;
621
622 if (*first == NULL) {
623 *first = new_length(length);
624 if (*first == NULL)
625 return 0;
626 return 1;
627 }
628 l = *first;
629 while (l != NULL) {
630 if (l->lower_bound <= length && length <= l->upper_bound) {
631 l->count++;
632 l->sum += length;
633 l->min = min(l->min, length);
634 l->max = max(l->max, length);
635 return 1;
636 }
637 last = l;
638 l = l->next;
639 }
640 last->next = new_length(length);
641 if (last->next == NULL)
642 return 0;
643 return 1;
644}
645
646
647void free_lengths(struct lengths** firstp)
648{
649 struct lengths* first;
650 struct lengths* next;
651
652 first = *firstp;
653 if (first == NULL)
654 return;
655 while (first != NULL) {
656 next = first->next;
657 free(first);
658 first = next;
659 }
660 *firstp = NULL;
661}
662
663
664 void free_all_lengths(void)
665{
666 free_lengths(&first_space);
667 free_lengths(&first_pulse);
668 free_lengths(&first_sum);
669 free_lengths(&first_gap);
670 free_lengths(&first_repeat_gap);
671 free_lengths(&first_signal_length);
672 free_lengths(&first_headerp);
673 free_lengths(&first_headers);
674 free_lengths(&first_1lead);
675 free_lengths(&first_3lead);
676 free_lengths(&first_trail);
677 free_lengths(&first_repeatp);
678 free_lengths(&first_repeats);
679}
680
681
682static void merge_lengths(struct lengths* first)
683{
684 struct lengths* l;
685 struct lengths* inner;
686 struct lengths* last;
687 uint32_t new_sum;
688 int new_count;
689
690 l = first;
691 while (l != NULL) {
692 last = l;
693 inner = l->next;
694 while (inner != NULL) {
695 new_sum = l->sum + inner->sum;
696 new_count = l->count + inner->count;
697
698 if ((l->max <= new_sum / new_count + aeps
699 && l->min + aeps >= new_sum / new_count
700 && inner->max <= new_sum / new_count + aeps
701 && inner->min + aeps >= new_sum / new_count)
702 || (l->max <= new_sum / new_count * (100 + eps)
703 && l->min >= new_sum / new_count * (100 - eps)
704 && inner->max <= new_sum / new_count *
705 (100 + eps)
706 && inner->min >= new_sum / new_count *
707 (100 - eps))) {
708 l->sum = new_sum;
709 l->count = new_count;
710 l->upper_bound = max(l->upper_bound,
711 inner->upper_bound);
712 l->lower_bound = min(l->lower_bound,
713 inner->lower_bound);
714 l->min = min(l->min, inner->min);
715 l->max = max(l->max, inner->max);
716
717 last->next = inner->next;
718 free(inner);
719 inner = last;
720 }
721 last = inner;
722 inner = inner->next;
723 }
724 l = l->next;
725 }
726 for (l = first; l != NULL; l = l->next) {
727 log_debug("%d x %u [%u,%u]",
728 l->count, (uint32_t)calc_signal(l),
729 (uint32_t)l->min, (uint32_t)l->max);
730 }
731}
732
733
739static struct lengths* get_max_length(struct lengths* first,
740 unsigned int* sump)
741{
742 unsigned int sum;
743 struct lengths* scan;
744 struct lengths* max_length;
745
746 if (first == NULL)
747 return NULL;
748 max_length = first;
749 sum = first->count;
750
751 if (first->count > 0)
752 log_debug("%u x %u", first->count,
753 (uint32_t)calc_signal(first));
754 scan = first->next;
755 while (scan) {
756 if (scan->count > max_length->count)
757 max_length = scan;
758 sum += scan->count;
759 log_debug(
760 "%u x %u",
761 scan->count,
762 (uint32_t)calc_signal(scan));
763 scan = scan->next;
764 }
765 if (sump != NULL)
766 *sump = sum;
767 return max_length;
768}
769
770
771int get_trail_length(struct ir_remote* remote, int interactive)
772{
773 unsigned int sum = 0, max_count;
774 struct lengths* max_length;
775
776 if (is_biphase(remote))
777 return 1;
778
779 max_length = get_max_length(first_trail, &sum);
780 max_count = max_length->count;
781 log_debug(
782 "get_trail_length(): sum: %u, max_count %u",
783 sum, max_count);
784 if (max_count >= sum * TH_TRAIL / 100) {
785 log_debug("Found trail pulse: %lu",
786 (uint32_t)calc_signal(max_length));
787 remote->ptrail = calc_signal(max_length);
788 return 1;
789 }
790 log_debug("No trail pulse found.");
791 return 1;
792}
793
794
795int get_lead_length(struct ir_remote* remote, int interactive)
796{
797 unsigned int sum = 0, max_count;
798 struct lengths* first_lead;
799 struct lengths* max_length;
800 struct lengths* max2_length;
801 lirc_t a, b, swap;
802
803 if (!is_biphase(remote) || has_header(remote))
804 return 1;
805 if (is_rc6(remote))
806 return 1;
807
808 first_lead = has_header(remote) ? first_3lead : first_1lead;
809 max_length = get_max_length(first_lead, &sum);
810 max_count = max_length->count;
811 log_debug(
812 "get_lead_length(): sum: %u, max_count %u",
813 sum, max_count);
814 if (max_count >= sum * TH_LEAD / 100) {
815 log_debug(
816 "Found lead pulse: %lu",
817 (uint32_t)calc_signal(max_length));
818 remote->plead = calc_signal(max_length);
819 return 1;
820 }
821 unlink_length(&first_lead, max_length);
822 max2_length = get_max_length(first_lead, &sum);
823 max_length->next = first_lead;
824 first_lead = max_length;
825
826 a = calc_signal(max_length);
827 b = calc_signal(max2_length);
828 if (a > b) {
829 swap = a;
830 a = b;
831 b = swap;
832 }
833 if (abs(2 * a - b) < b * eps / 100 || abs(2 * a - b) < aeps) {
834 log_debug(
835 "Found hidden lead pulse: %lu",
836 (uint32_t)a);
837 remote->plead = a;
838 return 1;
839 }
840 log_debug("No lead pulse found.");
841 return 1;
842}
843
844
845int get_header_length(struct ir_remote* remote, int interactive)
846{
847 unsigned int sum, max_count;
848 lirc_t headerp, headers;
849 struct lengths* max_plength;
850 struct lengths* max_slength;
851
852 if (first_headerp != NULL) {
853 max_plength = get_max_length(first_headerp, &sum);
854 max_count = max_plength->count;
855 } else {
856 log_debug("No header data.");
857 return 1;
858 }
859 log_debug(
860 "get_header_length(): sum: %u, max_count %u",
861 sum, max_count);
862
863 if (max_count >= sum * TH_HEADER / 100) {
864 max_slength = get_max_length(first_headers, &sum);
865 max_count = max_slength->count;
866 log_debug(
867 "get_header_length(): sum: %u, max_count %u",
868 sum, max_count);
869 if (max_count >= sum * TH_HEADER / 100) {
870 headerp = calc_signal(max_plength);
871 headers = calc_signal(max_slength);
872
873 log_debug(
874 "Found possible header: %lu %lu",
875 (uint32_t)headerp,
876 (uint32_t)headers);
877 remote->phead = headerp;
878 remote->shead = headers;
879 if (first_lengths < second_lengths) {
880 log_debug(
881 "Header is not being repeated.");
882 remote->flags |= NO_HEAD_REP;
883 }
884 return 1;
885 }
886 }
887 log_debug("No header found.");
888 return 1;
889}
890
891
892int get_repeat_length(struct ir_remote* remote, int interactive)
893{
894 unsigned int sum = 0, max_count;
895 lirc_t repeatp, repeats, repeat_gap;
896 struct lengths* max_plength;
897 struct lengths* max_slength;
898
899 if (!((count_3repeats > SAMPLES / 2 ? 1 : 0) ^
900 (count_5repeats > SAMPLES / 2 ? 1 : 0))) {
901 if (count_3repeats > SAMPLES / 2
902 || count_5repeats > SAMPLES / 2) {
903 log_warn("Repeat inconsistency.");
904 return 0;
905 }
906 log_debug("No repeat code found.");
907 return 1;
908 }
909
910 max_plength = get_max_length(first_repeatp, &sum);
911 max_count = max_plength->count;
912 log_debug(
913 "get_repeat_length(): sum: %u, max_count %u",
914 sum, max_count);
915 if (max_count >= sum * TH_REPEAT / 100) {
916 max_slength = get_max_length(first_repeats, &sum);
917 max_count = max_slength->count;
918 log_debug(
919 "get_repeat_length(): sum: %u, max_count %u",
920 sum, max_count);
921 if (max_count >= sum * TH_REPEAT / 100) {
922 if (count_5repeats > count_3repeats
923 && !has_header(remote)) {
924 log_warn(
925 "Repeat code has header,"
926 " but no header found!");
927 return 0;
928 }
929 if (count_5repeats > count_3repeats
930 && has_header(remote))
931 remote->flags |= REPEAT_HEADER;
932 repeatp = calc_signal(max_plength);
933 repeats = calc_signal(max_slength);
934
935 log_debug(
936 "Found repeat code: %lu %lu",
937 (uint32_t)repeatp,
938 (uint32_t)repeats);
939 remote->prepeat = repeatp;
940 remote->srepeat = repeats;
941 if (!(remote->flags & CONST_LENGTH)) {
942 max_slength = get_max_length(first_repeat_gap,
943 NULL);
944 repeat_gap = calc_signal(max_slength);
945 log_debug(
946 "Found repeat gap: %lu",
947 (uint32_t)repeat_gap);
948 remote->repeat_gap = repeat_gap;
949 }
950 return 1;
951 }
952 }
953 log_debug("No repeat header found.");
954 return 1;
955}
956
957
958void get_scheme(struct ir_remote* remote, int interactive)
959{
960 unsigned int i, length = 0, sum = 0;
961 struct lengths* maxp;
962 struct lengths* max2p;
963 struct lengths* maxs;
964 struct lengths* max2s;
965
966 for (i = 1; i < MAX_SIGNALS; i++) {
967 if (lengths[i] > lengths[length])
968 length = i;
969 sum += lengths[i];
970 if (lengths[i] > 0)
971 log_debug("%u: %u", i, lengths[i]);
972 }
973 log_debug("get_scheme(): sum: %u length: %u signals: %u"
974 " first_lengths: %u second_lengths: %u\n",
975 sum, length + 1, lengths[length],
976 first_lengths, second_lengths);
977 /* FIXME !!! this heuristic is too bad */
978 if (lengths[length] >= TH_SPACE_ENC * sum / 100) {
979 length++;
980 log_debug(
981 "Space/pulse encoded remote control found.");
982 log_debug("Signal length is %u.", length);
983 /* this is not yet the number of bits */
984 remote->bits = length;
985 set_protocol(remote, SPACE_ENC);
986 return;
987 }
988 maxp = get_max_length(first_pulse, NULL);
989 unlink_length(&first_pulse, maxp);
990 if (first_pulse == NULL)
991 first_pulse = maxp;
992 max2p = get_max_length(first_pulse, NULL);
993 maxp->next = first_pulse;
994 first_pulse = maxp;
995
996 maxs = get_max_length(first_space, NULL);
997 unlink_length(&first_space, maxs);
998 if (first_space == NULL) {
999 first_space = maxs;
1000 } else {
1001 max2s = get_max_length(first_space, NULL);
1002 maxs->next = first_space;
1003 first_space = maxs;
1004
1005 maxs = get_max_length(first_space, NULL);
1006
1007 if (length > 20
1008 && (calc_signal(maxp) < TH_RC6_SIGNAL
1009 || calc_signal(max2p) < TH_RC6_SIGNAL)
1010 && (calc_signal(maxs) < TH_RC6_SIGNAL
1011 || calc_signal(max2s) < TH_RC6_SIGNAL)) {
1012 log_debug("RC-6 remote control found.");
1013 set_protocol(remote, RC6);
1014 } else {
1015 log_debug("RC-5 remote control found.");
1016 set_protocol(remote, RC5);
1017 }
1018 return;
1019 }
1020 length++;
1021 log_debug("Suspicious data length: %u.", length);
1022 /* this is not yet the number of bits */
1023 remote->bits = length;
1024 set_protocol(remote, SPACE_ENC);
1025}
1026
1027
1028int get_data_length(struct ir_remote* remote, int interactive)
1029{
1030 unsigned int sum = 0, max_count;
1031 lirc_t p1, p2, s1, s2;
1032 struct lengths* max_plength;
1033 struct lengths* max_slength;
1034 struct lengths* max2_plength;
1035 struct lengths* max2_slength;
1036
1037 max_plength = get_max_length(first_pulse, &sum);
1038 max_count = max_plength->count;
1039 log_debug("get_data_length(): sum: %u, max_count %u",
1040 sum, max_count);
1041
1042 if (max_count >= sum * TH_IS_BIT / 100) {
1043 unlink_length(&first_pulse, max_plength);
1044
1045 max2_plength = get_max_length(first_pulse, NULL);
1046 if (max2_plength != NULL)
1047 if (max2_plength->count < max_count * TH_IS_BIT / 100)
1048 max2_plength = NULL;
1049 log_debug("Pulse candidates: ");
1050 log_debug("%u x %u", max_plength->count,
1051 (uint32_t)calc_signal(max_plength));
1052 if (max2_plength)
1053 log_debug(", %u x %u",
1054 max2_plength->count,
1055 (uint32_t)calc_signal(max2_plength));
1056
1057 max_slength = get_max_length(first_space, &sum);
1058 max_count = max_slength->count;
1059 log_debug(
1060 "get_data_length(): sum: %u, max_count %u",
1061 sum, max_count);
1062 if (max_count >= sum * TH_IS_BIT / 100) {
1063 unlink_length(&first_space, max_slength);
1064
1065 max2_slength = get_max_length(first_space, NULL);
1066 if (max2_slength != NULL)
1067 if (max2_slength->count <
1068 max_count * TH_IS_BIT / 100)
1069 max2_slength = NULL;
1070 if (max_count >= sum * TH_IS_BIT / 100) {
1071 log_debug("Space candidates: ");
1072 log_debug(
1073 "%u x %u",
1074 max_slength->count,
1075 (uint32_t)calc_signal(max_slength));
1076 if (max2_slength) {
1077 log_debug(
1078 "%u x %u",
1079 max2_slength->count,
1080 (uint32_t)calc_signal(max2_slength));
1081 }
1082 }
1083 remote->eps = eps;
1084 remote->aeps = aeps;
1085 if (is_biphase(remote)) {
1086 if (max2_plength == NULL
1087 || max2_slength == NULL) {
1088 log_notice(
1089 "Unknown encoding found.");
1090 return 0;
1091 }
1092 log_debug(
1093 "Signals are biphase encoded.");
1094 p1 = calc_signal(max_plength);
1095 p2 = calc_signal(max2_plength);
1096 s1 = calc_signal(max_slength);
1097 s2 = calc_signal(max2_slength);
1098
1099 remote->pone =
1100 (min(p1, p2) + max(p1, p2) / 2) / 2;
1101 remote->sone =
1102 (min(s1, s2) + max(s1, s2) / 2) / 2;
1103 remote->pzero = remote->pone;
1104 remote->szero = remote->sone;
1105 } else {
1106 if (max2_plength == NULL
1107 && max2_slength == NULL) {
1108 log_notice(
1109 "No encoding found");
1110 return 0;
1111 }
1112 if (max2_plength && max2_slength) {
1113 log_notice(
1114 "Unknown encoding found.");
1115 return 0;
1116 }
1117 p1 = calc_signal(max_plength);
1118 s1 = calc_signal(max_slength);
1119 if (max2_plength) {
1120 p2 = calc_signal(max2_plength);
1121 log_debug("Signals are pulse encoded.");
1122 remote->pone = max(p1, p2);
1123 remote->sone = s1;
1124 remote->pzero = min(p1, p2);
1125 remote->szero = s1;
1126 if (expect(remote, remote->ptrail, p1)
1127 || expect(remote, remote->ptrail,
1128 p2))
1129 remote->ptrail = 0;
1130 } else {
1131 s2 = calc_signal(max2_slength);
1132 log_debug("Signals are space encoded.");
1133 remote->pone = p1;
1134 remote->sone = max(s1, s2);
1135 remote->pzero = p1;
1136 remote->szero = min(s1, s2);
1137 }
1138 }
1139 if (has_header(remote)
1140 && (!has_repeat(remote)
1141 || remote->flags & NO_HEAD_REP)) {
1142 if (!is_biphase(remote)
1143 && ((expect(remote, remote->phead,
1144 remote->pone)
1145 && expect(remote,
1146 remote->shead,
1147 remote->sone))
1148 || (expect(remote,
1149 remote->phead,
1150 remote->pzero)
1151 && expect(remote,
1152 remote->shead,
1153 remote->szero)))) {
1154 remote->phead = remote->shead = 0;
1155 remote->flags &= ~NO_HEAD_REP;
1156 log_debug(
1157 "Removed header.");
1158 }
1159 if (is_biphase(remote)
1160 && expect(remote,
1161 remote->shead,
1162 remote->sone)) {
1163 remote->plead = remote->phead;
1164 remote->phead = remote->shead = 0;
1165 remote->flags &= ~NO_HEAD_REP;
1166 log_debug(
1167 "Removed header.");
1168 }
1169 }
1170 if (is_biphase(remote)) {
1171 struct lengths* signal_length;
1172 lirc_t data_length;
1173
1174 signal_length =
1175 get_max_length(first_signal_length,
1176 NULL);
1177 data_length =
1178 calc_signal(signal_length) -
1179 remote->plead - remote->phead -
1180 remote->shead +
1181 /* + 1/2 bit */
1182 (remote->pone + remote->sone) / 2;
1183 remote->bits = data_length / (remote->pone +
1184 remote->sone);
1185 if (is_rc6(remote))
1186 remote->bits--;
1187 } else {
1188 remote->bits =
1189 (remote->bits -
1190 (has_header(remote) ? 2 : 0) + 1 -
1191 (remote->ptrail > 0 ? 2 : 0)) / 2;
1192 }
1193 log_debug(
1194 "Signal length is %d",
1195 remote->bits);
1196 free_lengths(&max_plength);
1197 free_lengths(&max_slength);
1198 return 1;
1199 }
1200 free_lengths(&max_plength);
1201 }
1202 log_notice("Could not find data lengths.");
1203 return 0;
1204}
1205
1206
1207 enum get_gap_status get_gap_length(struct gap_state* state,
1208 struct ir_remote* remote)
1209{
1210 while (availabledata())
1211 curr_driver->rec_func(NULL);
1212 if (!mywaitfordata(10000000)) {
1213 free_lengths(&(state->gaps));
1214 return STS_GAP_TIMEOUT;
1215 }
1216 gettimeofday(&(state->start), NULL);
1217 while (availabledata())
1218 curr_driver->rec_func(NULL);
1219 gettimeofday(&(state->end), NULL);
1220 if (state->flag) {
1221 state->gap = time_elapsed(&(state->last), &(state->start));
1222 add_length(&(state->gaps), state->gap);
1223 merge_lengths(state->gaps);
1224 state->maxcount = 0;
1225 state->scan = state->gaps;
1226 while (state->scan) {
1227 state->maxcount = max(state->maxcount,
1228 state->scan->count);
1229 if (state->scan->count > SAMPLES) {
1230 remote->gap = calc_signal(state->scan);
1231 free_lengths(&(state->gaps));
1232 return STS_GAP_FOUND;
1233 }
1234 state->scan = state->scan->next;
1235 }
1236 if (state->maxcount > state->lastmaxcount) {
1237 state->lastmaxcount = state->maxcount;
1238 return STS_GAP_GOT_ONE_PRESS;
1239 }
1240 } else {
1241 state->flag = 1;
1242 }
1243 state->last = state->end;
1244 return STS_GAP_AGAIN;
1245}
1246
1247
1249 int needs_toggle_mask(struct ir_remote* remote)
1250{
1251 struct ir_ncode* codes;
1252
1253 if (!is_rc6(remote))
1254 return 0;
1255 if (remote->codes) {
1256 codes = remote->codes;
1257 while (codes->name != NULL) {
1258 if (codes->next)
1259 /* asume no toggle bit mask when key
1260 * sequences are used */
1261 return 0;
1262 codes++;
1263 }
1264 }
1265 return 1;
1266}
1267
1268
1269/* Compute lengths from four recorded signals. */
1270static void compute_lengths_4_signals(void)
1271{
1272 add_length(&first_repeatp, signals[0]);
1273 merge_lengths(first_repeatp);
1274 add_length(&first_repeats, signals[1]);
1275 merge_lengths(first_repeats);
1276 add_length(&first_trail, signals[2]);
1277 merge_lengths(first_trail);
1278 add_length(&first_repeat_gap, signals[3]);
1279 merge_lengths(first_repeat_gap);
1280}
1281
1282
1283/* Compute lengths from six recorded signals. */
1284static void compute_lengths_6_signals(void)
1285{
1286 add_length(&first_headerp, signals[0]);
1287 merge_lengths(first_headerp);
1288 add_length(&first_headers, signals[1]);
1289 merge_lengths(first_headers);
1290 add_length(&first_repeatp, signals[2]);
1291 merge_lengths(first_repeatp);
1292 add_length(&first_repeats, signals[3]);
1293 merge_lengths(first_repeats);
1294 add_length(&first_trail, signals[4]);
1295 merge_lengths(first_trail);
1296 add_length(&first_repeat_gap, signals[5]);
1297 merge_lengths(first_repeat_gap);
1298}
1299
1300/* Compute lengths from more than six recorded signals. */
1301static void compute_lengths_many_signals(struct lengths_state* state)
1302{
1303 int i;
1304
1305 add_length(&first_1lead, signals[0]);
1306 merge_lengths(first_1lead);
1307 for (i = 2; i < state->count - 2; i++) {
1308 if (i % 2) {
1309 add_length(&first_space, signals[i]);
1310 merge_lengths(first_space);
1311 } else {
1312 add_length(&first_pulse, signals[i]);
1313 merge_lengths(first_pulse);
1314 }
1315 }
1316 add_length(&first_trail, signals[state->count - 2]);
1317 merge_lengths(first_trail);
1318 lengths[state->count - 2]++;
1319 add_length(&first_signal_length, state->sum - state->data);
1320 merge_lengths(first_signal_length);
1321 if (state->first_signal == 1
1322 || (first_length > 2
1323 && first_length - 2 != state->count - 2)) {
1324 add_length(&first_3lead, signals[2]);
1325 merge_lengths(first_3lead);
1326 add_length(&first_headerp, signals[0]);
1327 merge_lengths(first_headerp);
1328 add_length(&first_headers, signals[1]);
1329 merge_lengths(first_headers);
1330 }
1331 if (state->first_signal == 1) {
1332 first_lengths++;
1333 first_length = state->count - 2;
1334 state->header = signals[0] + signals[1];
1335 } else if (state->first_signal == 0
1336 && first_length - 2 == state->count - 2) {
1337 lengths[state->count - 2]--;
1338 lengths[state->count - 2 + 2]++;
1339 second_lengths++;
1340 }
1341}
1342
1343
1344static struct lengths* scan_gap1(struct lengths_state* state,
1345 struct ir_remote* remote,
1346 int* maxcount,
1347 enum lengths_status* again)
1348{
1349 struct lengths* scan;
1350
1351 for (scan = first_sum; scan; scan = scan->next) {
1352 *maxcount = max(*maxcount, scan->count);
1353 if (scan->count > SAMPLES) {
1354 remote->gap = calc_signal(scan);
1355 remote->flags |= CONST_LENGTH;
1356 state->mode = MODE_HAVE_GAP;
1357 log_debug("Found gap: %u", remote->gap);
1358 *again = STS_LEN_AGAIN_INFO;
1359 break;
1360 }
1361 }
1362 return scan;
1363}
1364
1365
1366static struct lengths* scan_gap2(struct lengths_state* state,
1367 struct ir_remote* remote,
1368 int* maxcount,
1369 enum lengths_status* again)
1370{
1371 struct lengths* scan;
1372
1373 for (scan = first_gap; scan; scan = scan->next) {
1374 *maxcount = max(*maxcount, scan->count);
1375 if (scan->count > SAMPLES) {
1376 remote->gap = calc_signal(scan);
1377 state->mode = MODE_HAVE_GAP;
1378 log_debug("Found gap: %u", remote->gap);
1379 *again = STS_LEN_AGAIN_INFO;
1380 break;
1381 }
1382 }
1383 return scan;
1384}
1385
1386
1387 enum lengths_status get_lengths(struct lengths_state* state,
1388 struct ir_remote* remote,
1389 int force, int interactive)
1390{
1391 struct lengths* scan;
1392 int maxcount = 0;
1393 static int lastmaxcount = 0;
1394 enum lengths_status again = STS_LEN_AGAIN;
1395
1396 state->data = curr_driver->readdata(10000000);
1397 if (!state->data) {
1398 state->retval = 0;
1399 return STS_LEN_TIMEOUT;
1400 }
1401 if (is_timeout(state->data) || is_overflow(state->data)) {
1402 return STS_LEN_AGAIN;
1403 }
1404 state->count++;
1405 if (state->mode == MODE_GET_GAP) {
1406 if (state->sum != 0 || is_pulse(state->data)) {
1407 state->sum += state->data & PULSE_MASK;
1408 }else{
1409 return STS_LEN_AGAIN;
1410 }
1411 if (state->average == 0 && is_space(state->data)) {
1412 if (state->data > 100000) {
1413 state->sum = 0;
1414 return STS_LEN_AGAIN;
1415 }
1416 state->average = state->data;
1417 state->maxspace = state->data;
1418 } else if (is_space(state->data)) {
1419 if (state->data > MIN_GAP
1420 || state->data > 100 * state->average
1421 /* this MUST be a gap */
1422 || (state->data >= 5000 && count_spaces > 10
1423 && state->data > 5 * state->average)
1424 || (state->data < 5000 && count_spaces > 10
1425 && state->data > 5 * state->maxspace / 2)) {
1426 add_length(&first_sum, state->sum);
1427 merge_lengths(first_sum);
1428 add_length(&first_gap, state->data);
1429 merge_lengths(first_gap);
1430 state->sum = 0;
1431 count_spaces = 0;
1432 state->average = 0;
1433 state->maxspace = 0;
1434
1435 maxcount = 0;
1436 scan = scan_gap1(state,
1437 remote,
1438 &maxcount,
1439 &again);
1440 if (scan == NULL) {
1441 scan = scan_gap2(state,
1442 remote,
1443 &maxcount,
1444 &again);
1445 }
1446 if (scan != NULL) {
1447 state->mode = MODE_HAVE_GAP;
1448 state->sum = 0;
1449 state->count = 0;
1450 state->remaining_gap =
1451 is_const(remote) ?
1452 (remote->gap >
1453 state->data ?
1454 remote->gap - state->data : 0)
1455 : (has_repeat_gap(remote) ?
1456 remote->
1457 repeat_gap : remote->gap);
1458 if (force) {
1459 state->retval = 0;
1460 return STS_LEN_RAW_OK;
1461 }
1462 return STS_LEN_AGAIN_INFO;
1463 }
1464 lastmaxcount = maxcount;
1465 state->keypresses = lastmaxcount;
1466 return again;
1467 }
1468 state->average =
1469 (state->average * count_spaces + state->data)
1470 / (count_spaces + 1);
1471 count_spaces++;
1472 if (state->data > state->maxspace)
1473 state->maxspace = state->data;
1474 }
1475 if (state->count > SAMPLES * MAX_SIGNALS * 2) {
1476 state->retval = 0;
1477 return STS_LEN_NO_GAP_FOUND;
1478 }
1479 state->keypresses = lastmaxcount;
1480 return STS_LEN_AGAIN;
1481 } else if (state->mode == MODE_HAVE_GAP) {
1482 if (state->count==1 && is_space(state->data)) {
1483 state->count = 0;
1484 return STS_LEN_AGAIN;
1485 }
1486 if (state->count <= MAX_SIGNALS) {
1487 signals[state->count - 1] = state->data & PULSE_MASK;
1488 } else {
1489 state->retval = 0;
1490 return STS_LEN_TOO_LONG;
1491 }
1492 if (is_const(remote))
1493 state->remaining_gap =
1494 remote->gap > state->sum ?
1495 remote->gap - state->sum : 0;
1496 else
1497 state->remaining_gap = remote->gap;
1498 state->sum += state->data & PULSE_MASK;
1499
1500 if (state->count > 2
1501 && ((state->data & PULSE_MASK) >=
1502 state->remaining_gap * (100 - eps) / 100
1503 || (state->data & PULSE_MASK) >=
1504 state->remaining_gap - aeps)) {
1505 if (is_space(state->data)) {
1506 /* signal complete */
1507 state->keypresses += 1;
1508 if (state->count == 4) {
1509 count_3repeats++;
1510 compute_lengths_4_signals();
1511 } else if (state->count == 6) {
1512 count_5repeats++;
1513 compute_lengths_6_signals();
1514 } else if (state->count > 6) {
1515 count_signals++;
1516 compute_lengths_many_signals(state);
1517 }
1518 state->count = 0;
1519 state->sum = 0;
1520 }
1521 /* such long pulses may appear with
1522 * crappy hardware (receiver? / remote?)
1523 */
1524 else if(is_pulse(state->data)) {
1525 remote->gap = 0;
1526 return STS_LEN_NO_GAP_FOUND;
1527 }
1528
1529 if (count_signals >= SAMPLES) {
1530 get_scheme(remote, interactive);
1531 if (!get_header_length(remote, interactive)
1532 || !get_trail_length(remote, interactive)
1533 || !get_lead_length(remote, interactive)
1534 || !get_repeat_length(remote, interactive)
1535 || !get_data_length(remote, interactive))
1536 state->retval = 0;
1537 return state->retval ==
1538 0 ? STS_LEN_FAIL : STS_LEN_OK;
1539 }
1540 if ((state->data & PULSE_MASK) <=
1541 (state->remaining_gap + state->header) *
1542 (100 + eps) / 100
1543 || (state->data & PULSE_MASK) <=
1544 (state->remaining_gap + state->header) + aeps) {
1545 state->first_signal = 0;
1546 state->header = 0;
1547 } else {
1548 state->first_signal = 1;
1549 }
1550 }
1551 }
1552 return STS_LEN_AGAIN;
1553}
1554
1555
1556 enum toggle_status get_toggle_bit_mask(struct toggle_state* state,
1557 struct ir_remote* remote)
1558{
1559 struct decode_ctx_t decode_ctx = { 0 };
1560 int i;
1561 ir_code mask;
1562
1563 if (!state->inited) {
1564 sleep(1);
1565 while (availabledata())
1566 curr_driver->rec_func(NULL);
1567 state->inited = 1;
1568 }
1569 if (state->retries <= 0) {
1570 if (!state->found)
1571 return STS_TGL_NOT_FOUND;
1572 if (state->seq > 0) {
1573 remote->min_repeat = state->repeats / state->seq;
1574 log_debug("min_repeat=%d",
1575 remote->min_repeat);
1576 }
1577 return STS_TGL_FOUND;
1578 }
1579 if (!mywaitfordata(10000000))
1580 return STS_TGL_TIMEOUT;
1581 curr_driver->rec_func(remote);
1582 if (is_rc6(remote) && remote->rc6_mask == 0) {
1583 for (i = 0, mask = 1; i < remote->bits; i++, mask <<= 1) {
1584 remote->rc6_mask = mask;
1585 state->success =
1586 curr_driver->decode_func(remote, &decode_ctx);
1587 if (state->success) {
1588 remote->min_remaining_gap =
1589 decode_ctx.min_remaining_gap;
1590 remote->max_remaining_gap =
1591 decode_ctx.max_remaining_gap;
1592 break;
1593 }
1594 }
1595 if (!state->success)
1596 remote->rc6_mask = 0;
1597 } else {
1598 state->success =
1599 curr_driver->decode_func(remote, &decode_ctx);
1600 if (state->success) {
1601 remote->min_remaining_gap =
1602 decode_ctx.min_remaining_gap;
1603 remote->max_remaining_gap =
1604 decode_ctx.max_remaining_gap;
1605 }
1606 }
1607 if (state->success) {
1608 if (state->flag == 0) {
1609 state->flag = 1;
1610 state->first = decode_ctx.code;
1611 } else if (!decode_ctx.repeat_flag
1612 || decode_ctx.code != state->last) {
1613 state->seq++;
1614 mask = state->first ^ decode_ctx.code;
1615 if (!state->found && mask) {
1616 set_toggle_bit_mask(remote, mask);
1617 state->found = 1;
1618 if (state->seq > 0)
1619 remote->min_repeat =
1620 state->repeats / state->seq;
1621 }
1622 state->retries--;
1623 state->last = decode_ctx.code;
1624 return STS_TGL_GOT_ONE_PRESS;
1625 }
1626 state->repeats++;
1627 state->last = decode_ctx.code;
1628 } else {
1629 state->retries--;
1630 while (availabledata())
1631 curr_driver->rec_func(NULL);
1632 }
1633 return STS_TGL_AGAIN;
1634}
1635
1636
1638 int analyse_get_lengths(struct lengths_state* lengths_state)
1639{
1640 enum lengths_status status = STS_LEN_AGAIN;
1641
1642 while (status == STS_LEN_AGAIN) {
1643 status = get_lengths(lengths_state, &remote, 0, 0);
1644 switch (status) {
1645 case STS_LEN_AGAIN_INFO:
1646 status = STS_LEN_AGAIN;
1647 break;
1648 case STS_LEN_AGAIN:
1649 break;
1650 case STS_LEN_OK:
1651 break;
1652 case STS_LEN_FAIL:
1653 log_error("get_lengths() failure");
1654 return 0;
1655 case STS_LEN_RAW_OK:
1656 log_error("raw analyse result?!");
1657 return 0;
1658 case STS_LEN_TIMEOUT:
1659 log_error("analyse timeout?!");
1660 return 0;
1661 case STS_LEN_NO_GAP_FOUND:
1662 log_error("analyse, no gap?!");
1663 return 0;
1664 case STS_LEN_TOO_LONG:
1665 log_error("analyse, signal too long?!");
1666 return 0;
1667 default:
1668 log_error("Cannot read raw data (%d)",
1669 status);
1670 return 0;
1671 }
1672 }
1673 return 1;
1674}
1675
1676
1678 int analyse_remote(struct ir_remote* raw_data, const struct opts* opts)
1679{
1680 struct ir_ncode* codes;
1681 struct decode_ctx_t decode_ctx;
1682 struct lengths_state lengths_state;
1683 int code;
1684 int code2;
1685 struct ir_ncode* new_codes;
1686 size_t new_codes_count = 100;
1687 int new_index = 0;
1688 int ret;
1689
1690 if (!is_raw(raw_data)) {
1691 log_error("remote %s not in raw mode, ignoring",
1692 raw_data->name);
1693 return 0;
1694 }
1695 flushhw();
1696 aeps = raw_data->aeps;
1697 eps = raw_data->eps;
1698 emulation_data = raw_data;
1699 next_code = NULL;
1700 current_code = NULL;
1701 current_index = 0;
1702 memset(&remote, 0, sizeof(remote));
1703 lengths_state_init(&lengths_state);
1704 if (!analyse_get_lengths(&lengths_state))
1705 return 0;
1706
1707 if (is_rc6(&remote) && remote.bits >= 5)
1708 /* have to assume something as it's very difficult to
1709 * extract the rc6_mask from the data that we have */
1710 remote.rc6_mask = ((ir_code)0x1ll) << (remote.bits - 5);
1711
1712 remote.name = raw_data->name;
1713 remote.freq = raw_data->freq;
1714
1715 new_codes = malloc(new_codes_count * sizeof(*new_codes));
1716 if (new_codes == NULL) {
1717 log_error("Out of memory");
1718 return 0;
1719 }
1720 memset(new_codes, 0, new_codes_count * sizeof(*new_codes));
1721 codes = raw_data->codes;
1722 while (codes->name != NULL) {
1723 // printf("decoding %s\n", codes->name);
1724 current_code = NULL;
1725 current_index = 0;
1726 next_code = codes;
1727
1728 rec_buffer_init();
1729
1730 ret = receive_decode(&remote, &decode_ctx);
1731 if (!ret) {
1732 log_warn(
1733 "Decoding of %s failed", codes->name);
1734 } else {
1735 if (new_index + 1 >= new_codes_count) {
1736 struct ir_ncode* renew_codes;
1737
1738 new_codes_count *= 2;
1739 renew_codes =
1740 realloc(new_codes,
1741 new_codes_count *
1742 sizeof(*new_codes));
1743 if (renew_codes == NULL) {
1744 log_error("Out of memory");
1745 free(new_codes);
1746 return 0;
1747 }
1748 memset(&new_codes[new_codes_count / 2],
1749 0,
1750 new_codes_count / 2 *
1751 sizeof(*new_codes));
1752 new_codes = renew_codes;
1753 }
1754
1755 rec_buffer_clear();
1756 code = decode_ctx.code;
1757 ret = receive_decode(&remote, &decode_ctx);
1758 code2 = decode_ctx.code;
1759 decode_ctx.code = code;
1760 if (ret && code2 != decode_ctx.code) {
1761 new_codes[new_index].next =
1762 malloc(IR_CODE_NODE_SIZE);
1763 if (new_codes[new_index].next) {
1764 memset(new_codes[new_index].next,
1765 0,
1766 IR_CODE_NODE_SIZE);
1767 new_codes[new_index].next->code =
1768 code2;
1769 }
1770 }
1771 new_codes[new_index].name = codes->name;
1772 new_codes[new_index].code = decode_ctx.code;
1773 new_index++;
1774 }
1775 codes++;
1776 }
1777 new_codes[new_index].name = NULL;
1778 remote.codes = new_codes;
1779 fprint_remotes(stdout, &remote, opts->commandline);
1780 remote.codes = NULL;
1781 free(new_codes);
1782 return 1;
1783}
1784
1785
1787 int do_analyse(const struct opts* opts, struct main_state* state)
1788{
1789 FILE* f;
1790 struct ir_remote* r;
1791
1792 memcpy((void*)curr_driver, &hw_emulation, sizeof(struct driver));
1793 f = fopen(opts->filename, "r");
1794 if (f == NULL) {
1795 fprintf(stderr, "Cannot open file: %s\n", opts->filename);
1796 return 0;
1797 }
1798 r = read_config(f, opts->filename);
1799 if (r == NULL) {
1800 fprintf(stderr, "Cannot parse file: %s\n", opts->filename);
1801 return 0;
1802 }
1803 for (; r != NULL; r = r->next) {
1804 if (!is_raw(r)) {
1805 log_error("remote %s not in raw mode, ignoring",
1806 r->name);
1807 continue;
1808 }
1809 analyse_remote(r, opts);
1810 }
1811 return 1;
1812}
1813
1814
1815ssize_t raw_read(void* buffer, size_t size, unsigned int timeout_us)
1816{
1817 if (!mywaitfordata(timeout_us))
1818 return 0;
1819 return read(curr_driver->fd, buffer, size);
1820}
1821
1822
1823static int raw_data_ok(struct button_state* btn_state)
1824{
1825 int r = 0;
1826 int ref;
1827
1828 if (is_pulse(btn_state->data)) {
1829 r = 0;
1830 } else if (is_space(btn_state->data)) {
1831 if (is_const(&remote)) {
1832 if (remote.gap > btn_state->sum) {
1833 ref = (remote.gap - btn_state->sum);
1834 ref *= (100 - remote.eps);
1835 ref /= 100;
1836 } else {
1837 ref = 0;
1838 }
1839 r = btn_state->data > ref;
1840 } else {
1841 r = btn_state->data > (remote.gap * (100 - remote.eps)) / 100;
1842 }
1843 }
1844 return r;
1845}
1846
1847
1848 enum button_status record_buttons(struct button_state* btn_state,
1849 enum button_status last_status,
1850 struct main_state* state,
1851 const struct opts* opts)
1852{
1853 const char* const MSG_BAD_LENGTH =
1854 "Signal length is %d\n"
1855 "That's weird because the signal length must be odd!\n";
1856 ir_code code2;
1857 int decode_ok;
1858 uint32_t timeout;
1859 int retries;
1860 struct ir_remote* my_remote;
1861 FILE* f;
1862 enum button_status sts;
1863
1864 if (btn_state->no_data) {
1865 btn_state->no_data = 0;
1866 return STS_BTN_TIMEOUT;
1867 }
1868 switch (last_status) {
1869 case STS_BTN_INIT:
1870 return STS_BTN_GET_NAME;
1871 case STS_BTN_GET_NAME:
1872 if (strchr(btn_state->buffer, ' ') != NULL) {
1873 btn_state_set_message(
1874 btn_state,
1875 "The name must not contain any whitespace.");
1876 return STS_BTN_SOFT_ERROR;
1877 }
1878 if (strchr(btn_state->buffer, '\t') != NULL) {
1879 btn_state_set_message(
1880 btn_state,
1881 "The name must not contain any whitespace.");
1882 return STS_BTN_SOFT_ERROR;
1883 }
1884 if (strcasecmp(btn_state->buffer, "begin") == 0) {
1885 btn_state_set_message(
1886 btn_state,
1887 "'%s' is not allowed as button name\n",
1888 btn_state->buffer);
1889 return STS_BTN_SOFT_ERROR;
1890 }
1891 if (strcasecmp(btn_state->buffer, "end") == 0) {
1892 btn_state_set_message(
1893 btn_state,
1894 "'%s' is not allowed as button name\n",
1895 btn_state->buffer);
1896 return STS_BTN_SOFT_ERROR;
1897 }
1898 if (strlen(btn_state->buffer) == 0)
1899 return STS_BTN_RECORD_DONE;
1900 if (!opts->disable_namespace
1901 && !is_in_namespace(btn_state->buffer)) {
1902 btn_state_set_message(
1903 btn_state,
1904 "'%s' is not in name space"
1905 " (use --disable-namespace to override)\n",
1906 btn_state->buffer);
1907 return STS_BTN_SOFT_ERROR;
1908 }
1909 return STS_BTN_INIT_DATA;
1910 case STS_BTN_INIT_DATA:
1911 if (opts->force)
1912 flushhw();
1913 else
1914 while (availabledata())
1915 curr_driver->rec_func(NULL);
1916 if (curr_driver->fd == -1)
1917 curr_driver->init_func();
1918 return opts->force ? STS_BTN_GET_RAW_DATA : STS_BTN_GET_DATA;
1919 case STS_BTN_GET_DATA:
1920 for (retries = RETRIES; retries > 0; ) {
1921 if (!mywaitfordata(10000000)) {
1922 btn_state->no_data = 1;
1923 return STS_BTN_TIMEOUT;
1924 }
1925 decode_ok = 0;
1926 last_remote = NULL;
1927 sleep(1);
1928 while (availabledata()) {
1929 curr_driver->rec_func(NULL);
1930 if (curr_driver->decode_func(
1931 &remote,
1932 &(state->decode_ctx))) {
1933 decode_ok = 1;
1934 break;
1935 }
1936 }
1937 if (!decode_ok) {
1938 if (!resethw(btn_state->started_as_root)) {
1939 btn_state_set_message(
1940 btn_state,
1941 "Could not reset hardware.\n");
1942 return STS_BTN_HARD_ERROR;
1943 }
1944 btn_state_set_message(btn_state,
1945 "Cannot decode data\n");
1946 flushhw();
1947 return STS_BTN_SOFT_ERROR;
1948 }
1949 btn_state->ncode.name = btn_state->buffer;
1950 btn_state->ncode.code = state->decode_ctx.code;
1951 curr_driver->rec_func(NULL);
1952 if (!curr_driver->decode_func(&remote,
1953 &(state->decode_ctx))) {
1954 code2 = state->decode_ctx.code;
1955 state->decode_ctx.code = btn_state->ncode.code;
1956 if (state->decode_ctx.code != code2) {
1957 btn_state->ncode.next =
1958 malloc(IR_CODE_NODE_SIZE);
1959 if (btn_state->ncode.next) {
1960 memset(btn_state->ncode.next,
1961 0,
1962 IR_CODE_NODE_SIZE);
1963 btn_state->ncode.next->code =
1964 code2;
1965 }
1966 }
1967 }
1968 break;
1969 }
1970 return STS_BTN_BUTTON_DONE;
1971 case STS_BTN_GET_RAW_DATA:
1972 btn_state->count = 0;
1973 btn_state->sum = 0;
1974 while (btn_state->count < MAX_SIGNALS) {
1975 if (btn_state->count == 0)
1976 timeout = 10000000;
1977 else
1978 timeout = remote.gap * 5;
1979 btn_state->data = curr_driver->readdata(timeout);
1980 if (!btn_state->data) {
1981 if (btn_state->count == 0)
1982 return STS_BTN_TIMEOUT;
1983 btn_state->data = remote.gap;
1984 }
1985 if (btn_state->count == 0) {
1986 if (is_pulse(btn_state->data)
1987 || btn_state->data <
1988 remote.gap - remote.gap * remote.eps /
1989 100) {
1990 sleep(3);
1991 flushhw();
1992 btn_state->count = 0;
1993 btn_state_set_message(
1994 btn_state,
1995 "Something went wrong.");
1996 return STS_BTN_SOFT_ERROR;
1997 }
1998 } else {
1999 if (raw_data_ok(btn_state)) {
2000 log_info("Got it.\n");
2001 log_info("Signal length is %d\n",
2002 btn_state->count - 1);
2003 if (btn_state->count % 2) {
2004 btn_state_set_message(
2005 btn_state,
2006 MSG_BAD_LENGTH,
2007 btn_state->count - 1);
2008 sleep(3);
2009 flushhw();
2010 btn_state->count = 0;
2011 return STS_BTN_SOFT_ERROR;
2012 }
2013 btn_state->ncode.name =
2014 btn_state->buffer;
2015 btn_state->ncode.length =
2016 btn_state->count - 1;
2017 btn_state->ncode.signals = signals;
2018 break;
2019 }
2020 signals[btn_state->count - 1] =
2021 btn_state->data & PULSE_MASK;
2022 btn_state->sum +=
2023 btn_state->data & PULSE_MASK;
2024 }
2025 btn_state->count++;
2026 }
2027 if (btn_state->count == MAX_SIGNALS) {
2028 btn_state_set_message(btn_state,
2029 "Signal is too long.\n");
2030 return STS_BTN_SOFT_ERROR;
2031 }
2032 return STS_BTN_BUTTON_DONE;
2033 case STS_BTN_RECORD_DONE:
2034 if (is_raw(&remote))
2035 return STS_BTN_ALL_DONE;
2036 if (!resethw(btn_state->started_as_root)) {
2037 btn_state_set_message(btn_state,
2038 "Could not reset hardware.");
2039 return STS_BTN_HARD_ERROR;
2040 }
2041 return STS_BTN_BUTTONS_DONE;
2042 case STS_BTN_BUTTONS_DONE:
2043 f = fopen(opts->tmpfile, "r");
2044 if (f == NULL) {
2045 btn_state_set_message(btn_state,
2046 "Could not reopen config file");
2047 return STS_BTN_HARD_ERROR;
2048 }
2049 my_remote = read_config(f, opts->filename);
2050 fclose(f);
2051 if (my_remote == NULL) {
2052 btn_state_set_message(
2053 btn_state,
2054 "Internal error: "
2055 "config file contains no valid remote");
2056 return STS_BTN_HARD_ERROR;
2057 }
2058 if (my_remote == (void*)-1) {
2059 btn_state_set_message(
2060 btn_state,
2061 "Internal error: "
2062 "Reading of config file failed");
2063 return STS_BTN_HARD_ERROR;
2064 }
2065 sts = STS_BTN_ALL_DONE;
2066 if (opts->force) {
2067 remote = *my_remote;
2068 return sts;
2069 }
2070 if (!has_toggle_bit_mask(my_remote)) {
2071 if (!opts->using_template
2072 && strcmp(curr_driver->name, "devinput") != 0) {
2073 remote = *(my_remote);
2074 sts = STS_BTN_GET_TOGGLE_BITS;
2075 }
2076 } else {
2077 set_toggle_bit_mask(my_remote,
2078 my_remote->toggle_bit_mask);
2079 if (curr_driver->deinit_func)
2080 curr_driver->deinit_func();
2081 }
2082 if (!opts->update) {
2083 get_pre_data(my_remote);
2084 get_post_data(my_remote);
2085 }
2086 remote = *my_remote;
2087 return sts;
2088 case STS_BTN_BUTTON_DONE:
2089 return STS_BTN_BUTTON_DONE;
2090 case STS_BTN_HARD_ERROR:
2091 return STS_BTN_HARD_ERROR;
2092 default:
2093 btn_state_set_message(btn_state,
2094 "record_buttons(): bad state: %d\n",
2095 last_status);
2096 return STS_BTN_HARD_ERROR;
2097 }
2098}
2099
2100
2102 void config_file_setup(struct main_state* state, const struct opts* opts)
2103{
2104 state->fout = fopen(opts->tmpfile, "w");
2105 if (state->fout == NULL) {
2106 log_error("Could not open new config file %s", tmpfile);
2107 log_perror_err("While opening temporary file for write");
2108 return;
2109 }
2110 fprint_copyright(state->fout);
2111 fprint_comment(state->fout, &remote, opts->commandline);
2112 fprint_remote_head(state->fout, &remote);
2113 fprint_remote_signal_head(state->fout, &remote);
2114}
2115
2116
2117
2119 int config_file_finish(struct main_state* state, const struct opts* opts)
2120{
2121 state->fout = fopen(opts->filename, "w");
2122 if (state->fout == NULL) {
2123 log_perror_err("While opening \"%s\" for write",
2124 opts->filename);
2125 return 0;
2126 }
2127 fprint_copyright(state->fout);
2128 fprint_remotes(state->fout, &remote, opts->commandline);
2129 return 1;
2130}
curr_driver
const struct driver *const curr_driver
Read-only access to drv for client code.
Definition: driver.c:34
last_remote
struct ir_remote * last_remote
TODO.
Definition: ir_remote.c:55
default_close
int default_close(void)
For now, a placeholder.
Definition: driver.c:52
rec_buffer_init
void rec_buffer_init(void)
Clear internal buffer to pristine state.
Definition: receive.c:213
default_open
int default_open(const char *path)
Stores path in drv.device if non-null.
Definition: driver.c:37
receive_decode
int receive_decode(struct ir_remote *remote, struct decode_ctx_t *ctx)
Decode data from remote.
Definition: receive.c:1038
rec_buffer_clear
int rec_buffer_clear(void)
Flush the internal fifo and store a single code read from the driver in it.
Definition: receive.c:233
read_config
struct ir_remote * read_config(FILE *f, const char *name)
Parse a lircd.conf config file.
Definition: config_file.c:833
drop_sudo_root
const char * drop_sudo_root(int(*set_some_uid)(uid_t))
Try to drop possible root privileges, returning new user or "" on error.
Definition: lirc-utils.c:28
RC6
#define RC6
IR data follows RC6 protocol.
Definition: ir_remote_types.h:107
REPEAT_HEADER
#define REPEAT_HEADER
header is also sent before repeat code
Definition: ir_remote_types.h:121
ir_code
uint64_t ir_code
Denotes an internal coded representation for an IR transmission.
Definition: ir_remote_types.h:43
SPACE_ENC
#define SPACE_ENC
IR data is space encoded.
Definition: ir_remote_types.h:109
RC5
#define RC5
IR data follows RC5 protocol.
Definition: ir_remote_types.h:101
NO_HEAD_REP
#define NO_HEAD_REP
no header for key repeats
Definition: ir_remote_types.h:118
CONST_LENGTH
#define CONST_LENGTH
signal length+gap is always constant
Definition: ir_remote_types.h:120
resethw
int resethw(int started_as_root)
Reset the hardware.
Definition: irrecord.c:161
eps
unsigned int eps
Shared list of remotes.
Definition: irrecord.c:62
flushhw
void flushhw(void)
Clear the driver input buffers.
Definition: irrecord.c:139
analyse_remote
int analyse_remote(struct ir_remote *raw_data, const struct opts *opts)
Implement the analyse task, return 1 for ok, 0 for errors.
Definition: irrecord.c:1678
get_lengths
enum lengths_status get_lengths(struct lengths_state *state, struct ir_remote *remote, int force, int interactive)
Try to find out pre/post etc.
Definition: irrecord.c:1387
analyse_get_lengths
int analyse_get_lengths(struct lengths_state *lengths_state)
analyse non-interactive get_lengths, returns boolean ok/fail.
Definition: irrecord.c:1638
record_buttons
enum button_status record_buttons(struct button_state *btn_state, enum button_status last_status, struct main_state *state, const struct opts *opts)
Try to record one button, returning button_status.
Definition: irrecord.c:1848
config_file_finish
int config_file_finish(struct main_state *state, const struct opts *opts)
Write the final config file.
Definition: irrecord.c:2119
needs_toggle_mask
int needs_toggle_mask(struct ir_remote *remote)
Return true if a given remote needs to compute toggle_mask.
Definition: irrecord.c:1249
get_toggle_bit_mask
enum toggle_status get_toggle_bit_mask(struct toggle_state *state, struct ir_remote *remote)
Try to find out toggle_bit_mask, returning toggle_status.
Definition: irrecord.c:1556
config_file_setup
void config_file_setup(struct main_state *state, const struct opts *opts)
Write the provisionary config file.
Definition: irrecord.c:2102
button_state_init
void button_state_init(struct button_state *state, int started_as_root)
Initiate a pristine button_state.
Definition: irrecord.c:219
raw_read
ssize_t raw_read(void *buffer, size_t size, unsigned int timeout_us)
Absolute error tolerance (us).
Definition: irrecord.c:1815
remove_pre_data
void remove_pre_data(struct ir_remote *remote)
Test hook: Move remote->pre_data into remote->bits.
Definition: irrecord.c:383
availabledata
int availabledata(void)
Return 1 if there is available after running poll(2), else 0.
Definition: irrecord.c:118
remove_post_data
void remove_post_data(struct ir_remote *remote)
Test hook: Move remote->post_data into remote->bits.
Definition: irrecord.c:403
invert_data
void invert_data(struct ir_remote *remote)
Test hook: Invert all data items in remote.
Definition: irrecord.c:424
get_gap_length
enum get_gap_status get_gap_length(struct gap_state *state, struct ir_remote *remote)
Try to find out gap length, returning gap_status.
Definition: irrecord.c:1207
free_all_lengths
void free_all_lengths(void)
Free heap data allocated by get_lengths().
Definition: irrecord.c:664
gap_state_init
void gap_state_init(struct gap_state *state)
Initiate a pristine gap_state.
Definition: irrecord.c:189
remove_trail
void remove_trail(struct ir_remote *remote)
Test hook: Move remote->trail into remote->bits.
Definition: irrecord.c:463
do_analyse
int do_analyse(const struct opts *opts, struct main_state *state)
The –analyse wrapper.
Definition: irrecord.c:1787
get_post_data
void get_post_data(struct ir_remote *remote)
Test hook: Extract remote->post_data and post_data_bits from bits.
Definition: irrecord.c:327
aeps
lirc_t aeps
Error tolerance in per cent.
Definition: irrecord.c:63
btn_state_set_message
void btn_state_set_message(struct button_state *state, const char *fmt,...)
snprintf-style message formatting into state->message.
Definition: irrecord.c:97
lengths_state_init
void lengths_state_init(struct lengths_state *state)
Initiate a pristine lengths_state.
Definition: irrecord.c:195
toggle_state_init
void toggle_state_init(struct toggle_state *state)
Initiate a pristine toggle_state.
Definition: irrecord.c:211
for_each_remote
void for_each_remote(struct ir_remote *remotes, remote_func func)
Unconditionally apply func(remote) for all items in remotes list.
Definition: irrecord.c:491
get_pre_data
void get_pre_data(struct ir_remote *remote)
Test hook: Extract remote->pre_data from remote->bits.
Definition: irrecord.c:269
irrecord.h
Library part of irrecord, functions to identify unknown remotes.
button_status
button_status
Return from one pass in record_buttons().
Definition: irrecord.h:124
lengths_status
lengths_status
Return from one attempt to determine lengths in get_lengths().
Definition: irrecord.h:91
get_gap_status
get_gap_status
Return form one attempt to get gap in get_gap().
Definition: irrecord.h:104
toggle_status
toggle_status
Return from one attempt in get_toggle_bit_mask().
Definition: irrecord.h:114
PACKET_SIZE
#define PACKET_SIZE
IR transmission packet size.
Definition: lirc_config.h:84
log_notice
#define log_notice(fmt,...)
Log a notice message.
Definition: lirc_log.h:119
log_debug
#define log_debug(fmt,...)
Log a debug message.
Definition: lirc_log.h:124
log_perror_err
#define log_perror_err(fmt,...)
perror wrapper logging with level LIRC_ERROR.
Definition: lirc_log.h:89
log_info
#define log_info(fmt,...)
Log an info message.
Definition: lirc_log.h:114
log_error
#define log_error(fmt,...)
Log an error message.
Definition: lirc_log.h:104
logchannel_t
logchannel_t
Log channels used to filter messages.
Definition: lirc_log.h:53
log_warn
#define log_warn(fmt,...)
Log a warning message.
Definition: lirc_log.h:109
lirc_private.h
Main include file for lirc applications.
button_state
State while recording buttons, privates besides commented.
Definition: irrecord.h:236
button_state::message
char message[128]
Error message, valid on STS_BTN_*_ERROR.
Definition: irrecord.h:240
button_state::ncode
struct ir_ncode ncode
Recorded button, valid on STS_BTN_BUTTON_DONE.
Definition: irrecord.h:238
decode_ctx_t
State describing code, pre, post + gap and repeat state.
Definition: ir_remote_types.h:137
decode_ctx_t::code
ir_code code
Code part, matched to code defintion.
Definition: ir_remote_types.h:138
decode_ctx_t::repeat_flag
int repeat_flag
True if code is a repeated one.
Definition: ir_remote_types.h:141
decode_ctx_t::min_remaining_gap
lirc_t min_remaining_gap
Estimated min time of trailing gap.
Definition: ir_remote_types.h:143
decode_ctx_t::max_remaining_gap
lirc_t max_remaining_gap
Estimated max time of trailing gap.
Definition: ir_remote_types.h:142
driver
The data the driver exports i.
Definition: driver.h:132
driver::fd
int fd
Set by the driver after init().
Definition: driver.h:142
driver::name
const char * name
Driver name, as listed by -H help and used as argument to i –driver.
Definition: driver.h:224
driver::code_length
const uint32_t code_length
Length in bits of the code.
Definition: driver.h:160
driver::decode_func
int(*const decode_func)(struct ir_remote *remote, struct decode_ctx_t *ctx)
TODO.
Definition: driver.h:202
driver::rec_func
char *(*const rec_func)(struct ir_remote *remotes)
Receive data from remote.
Definition: driver.h:197
driver::readdata
lirc_t(*const readdata)(lirc_t timeout)
Get length of next pulse/space from hardware.
Definition: driver.h:218
driver::deinit_func
int(*const deinit_func)(void)
Function called when transmitting/receiving stops.
Definition: driver.h:180
driver::init_func
int(*const init_func)(void)
Function called for initializing the driver and the hardware.
Definition: driver.h:174
driver::rec_mode
uint32_t rec_mode
Possible values are: LIRC_MODE_RAW, LIRC_MODE_PULSE, LIRC_MODE_MODE2, LIRC_MODE_LIRCCODE.
Definition: driver.h:157
gap_state
Private state in get_gap_length().
Definition: irrecord.h:185
ir_code_node
An ir_code for entering into (singly) linked lists, i.e.
Definition: ir_remote_types.h:49
ir_ncode
IR Command, corresponding to one (command defining) line of the configuration file.
Definition: ir_remote_types.h:60
ir_ncode::next
struct ir_code_node * next
Linked list of the subsequent ir_code's, after the first one.
Definition: ir_remote_types.h:75
ir_ncode::code
ir_code code
The first code of the command.
Definition: ir_remote_types.h:65
ir_ncode::length
int length
(private)
Definition: ir_remote_types.h:68
ir_ncode::signals
lirc_t * signals
(private)
Definition: ir_remote_types.h:71
ir_ncode::name
char * name
Name of command.
Definition: ir_remote_types.h:62
ir_remote
One remote as represented in the configuration file.
Definition: ir_remote_types.h:150
ir_remote::repeat_gap
uint32_t repeat_gap
time between two repeat codes if different from gap
Definition: ir_remote_types.h:188
ir_remote::freq
unsigned int freq
modulation frequency
Definition: ir_remote_types.h:203
ir_remote::aeps
unsigned int aeps
detecting very short pulses is difficult with relative tolerance for some remotes,...
Definition: ir_remote_types.h:157
ir_remote::rc6_mask
ir_code rc6_mask
RC-6 doubles signal length of some bits.
Definition: ir_remote_types.h:206
ir_remote::max_remaining_gap
lirc_t max_remaining_gap
gap range
Definition: ir_remote_types.h:228
ir_remote::ptrail
lirc_t ptrail
trailing pulse
Definition: ir_remote_types.h:175
ir_remote::srepeat
lirc_t srepeat
indicate repeating
Definition: ir_remote_types.h:177
ir_remote::pre_data
ir_code pre_data
data which the remote sends before actual keycode
Definition: ir_remote_types.h:180
ir_remote::bits
int bits
bits (length of code)
Definition: ir_remote_types.h:154
ir_remote::post_data_bits
int post_data_bits
length of post_data
Definition: ir_remote_types.h:181
ir_remote::plead
lirc_t plead
leading pulse
Definition: ir_remote_types.h:174
ir_remote::shead
lirc_t shead
header
Definition: ir_remote_types.h:169
ir_remote::szero
lirc_t szero
0
Definition: ir_remote_types.h:173
ir_remote::post_data
ir_code post_data
data which the remote sends after actual keycode
Definition: ir_remote_types.h:182
ir_remote::toggle_mask
ir_code toggle_mask
Sharp (?) error detection scheme.
Definition: ir_remote_types.h:205
ir_remote::flags
int flags
flags
Definition: ir_remote_types.h:155
ir_remote::min_repeat
int min_repeat
code is repeated at least x times code sent once -> min_repeat=0
Definition: ir_remote_types.h:194
ir_remote::pre_s
lirc_t pre_s
signal between pre_data and keycode
Definition: ir_remote_types.h:183
ir_remote::gap
uint32_t gap
time between signals in usecs
Definition: ir_remote_types.h:186
ir_remote::eps
int eps
eps (relative tolerance)
Definition: ir_remote_types.h:156
ir_remote::sone
lirc_t sone
1
Definition: ir_remote_types.h:172
ir_remote::name
const char * name
name of remote control
Definition: ir_remote_types.h:151
ir_remote::toggle_bit_mask
ir_code toggle_bit_mask
previously only one bit called toggle_bit
Definition: ir_remote_types.h:190
ir_remote::pre_data_bits
int pre_data_bits
length of pre_data
Definition: ir_remote_types.h:179
ir_remote::min_remaining_gap
lirc_t min_remaining_gap
remember gap for CONST_LENGTH remotes
Definition: ir_remote_types.h:227
lengths_state
State in get_lengths(), private besides commented.
Definition: irrecord.h:199
lengths_state::count
int count
Number of processed data items.
Definition: irrecord.h:206
lengths_state::keypresses
int keypresses
Number of counted button presses.
Definition: irrecord.h:203
lengths_state::sum
lirc_t sum
Number of bits accounted for in signal.
Definition: irrecord.h:211
lengths
Definition: irrecord.h:142
main_state
Overall state in main.
Definition: irrecord.h:177
opts
Parsed run-time options, reflects long_options and the command line, mostly a const object.
Definition: irrecord.h:153
toggle_state
Private state in get_togggle_bit_mask().
Definition: irrecord.h:220