LIRC libraries
Linux Infrared Remote Control
Loading...
Searching...
No Matches
ir_remote.c
Go to the documentation of this file.
1/****************************************************************************
2** ir_remote.c *************************************************************
3****************************************************************************
4*
5* ir_remote.c - sends and decodes the signals from IR remotes
6*
7* Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
8* Copyright (C) 1998 Christoph Bartelmus (lirc@bartelmus.de)
9*
10*/
11
21#ifdef HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <stdint.h>
28#include <fcntl.h>
29#include <limits.h>
30
31#include <sys/ioctl.h>
32
33#ifdef HAVE_KERNEL_LIRC_H
34#include <linux/lirc.h>
35#else
36#include "media/lirc.h"
37#endif
38
39#include "lirc/ir_remote.h"
40#include "lirc/driver.h"
41#include "lirc/release.h"
42#include "lirc/lirc_log.h"
43
44static const logchannel_t logchannel = LOG_LIB;
45
47static struct ir_ncode NCODE_EOF = {
48 "__EOF", LIRC_EOF, 1, NULL, NULL, NULL, 0
49};
50
52static const char* const PACKET_EOF = "0000000008000000 00 __EOF lirc\n";
53
55static struct ir_remote lirc_internal_remote = { "lirc" };
56
57struct ir_remote* decoding = NULL;
58
59struct ir_remote* last_remote = NULL;
60
61struct ir_remote* repeat_remote = NULL;
62
64
65static int dyncodes = 0;
66
67
69struct ir_ncode* ncode_dup(struct ir_ncode* ncode)
70{
71 struct ir_ncode* new_ncode;
72 size_t signal_size;
73 struct ir_code_node* node;
74 struct ir_code_node** node_ptr;
75 struct ir_code_node* new_node;
76
77 new_ncode = (struct ir_ncode*)malloc(sizeof(struct ir_ncode));
78 if (new_ncode == NULL)
79 return NULL;
80 memcpy(new_ncode, ncode, sizeof(struct ir_ncode));
81 new_ncode->name = ncode->name == NULL ? NULL : strdup(ncode->name);
82 if (ncode->length > 0) {
83 signal_size = ncode->length * sizeof(lirc_t);
84 new_ncode->signals = (lirc_t*)malloc(signal_size);
85 if (new_ncode->signals == NULL)
86 return NULL;
87 memcpy(new_ncode->signals, ncode->signals, signal_size);
88 } else {
89 new_ncode->signals = NULL;
90 }
91 node_ptr = &(new_ncode->next);
92 for (node = ncode->next; node != NULL; node = node->next) {
93 new_node = malloc(sizeof(struct ir_code_node));
94 memcpy(new_node, node, sizeof(struct ir_code_node));
95 *node_ptr = new_node;
96 node_ptr = &(new_node->next);
97 }
98 *node_ptr = NULL;
99 return new_ncode;
100}
101
102
104void ncode_free(struct ir_ncode* ncode)
105{
106 struct ir_code_node* node;
107 struct ir_code_node* next;
108
109 if (ncode == NULL)
110 return;
111 node = ncode->next;
112 while (node != NULL) {
113 next = node->next;
114 if (node != NULL)
115 free(node);
116 node = next;
117 }
118 if (ncode->signals != NULL)
119 free(ncode->signals);
120 free(ncode);
121}
122
123
124void ir_remote_init(int use_dyncodes)
125{
126 dyncodes = use_dyncodes;
127}
128
129
130static lirc_t time_left(struct timeval* current,
131 struct timeval* last,
132 lirc_t gap)
133{
134 unsigned long secs, diff;
135
136 secs = current->tv_sec - last->tv_sec;
137 diff = 1000000 * secs + current->tv_usec - last->tv_usec;
138 return (lirc_t)(diff < gap ? gap - diff : 0);
139}
140
141
142static int match_ir_code(struct ir_remote* remote, ir_code a, ir_code b)
143{
144 return (remote->ignore_mask | a) == (remote->ignore_mask | b)
145 || (remote->ignore_mask | a) ==
146 (remote->ignore_mask | (b ^ remote->toggle_bit_mask));
147}
148
149
156void get_frequency_range(const struct ir_remote* remotes,
157 unsigned int* min_freq,
158 unsigned int* max_freq)
159{
160 const struct ir_remote* scan;
161
162 /* use remotes carefully, it may be changed on SIGHUP */
163 scan = remotes;
164 if (scan == NULL) {
165 *min_freq = 0;
166 *max_freq = 0;
167 } else {
168 *min_freq = scan->freq;
169 *max_freq = scan->freq;
170 scan = scan->next;
171 }
172 while (scan) {
173 if (scan->freq != 0) {
174 if (scan->freq > *max_freq)
175 *max_freq = scan->freq;
176 else if (scan->freq < *min_freq)
177 *min_freq = scan->freq;
178 }
179 scan = scan->next;
180 }
181}
182
183
193void get_filter_parameters(const struct ir_remote* remotes,
194 lirc_t* max_gap_lengthp,
195 lirc_t* min_pulse_lengthp,
196 lirc_t* min_space_lengthp,
197 lirc_t* max_pulse_lengthp,
198 lirc_t* max_space_lengthp)
199{
200 const struct ir_remote* scan = remotes;
201 lirc_t max_gap_length = 0;
202 lirc_t min_pulse_length = 0, min_space_length = 0;
203 lirc_t max_pulse_length = 0, max_space_length = 0;
204
205 while (scan) {
206 lirc_t val;
207
208 val = upper_limit(scan, scan->max_gap_length);
209 if (val > max_gap_length)
210 max_gap_length = val;
211 val = lower_limit(scan, scan->min_pulse_length);
212 if (min_pulse_length == 0 || val < min_pulse_length)
213 min_pulse_length = val;
214 val = lower_limit(scan, scan->min_space_length);
215 if (min_space_length == 0 || val > min_space_length)
216 min_space_length = val;
217 val = upper_limit(scan, scan->max_pulse_length);
218 if (val > max_pulse_length)
219 max_pulse_length = val;
220 val = upper_limit(scan, scan->max_space_length);
221 if (val > max_space_length)
222 max_space_length = val;
223 scan = scan->next;
224 }
225 *max_gap_lengthp = max_gap_length;
226 *min_pulse_lengthp = min_pulse_length;
227 *min_space_lengthp = min_space_length;
228 *max_pulse_lengthp = max_pulse_length;
229 *max_space_lengthp = max_space_length;
230}
231
232
239const struct ir_remote* is_in_remotes(const struct ir_remote* remotes,
240 const struct ir_remote* remote)
241{
242 while (remotes != NULL) {
243 if (remotes == remote)
244 return remote;
245 remotes = remotes->next;
246 }
247 return NULL;
248}
249
250
251struct ir_remote* get_ir_remote(const struct ir_remote* remotes,
252 const char* name)
253{
254 const struct ir_remote* all;
255
256 /* use remotes carefully, it may be changed on SIGHUP */
257 all = remotes;
258 if (strcmp(name, "lirc") == 0)
259 return &lirc_internal_remote;
260 while (all) {
261 if (strcasecmp(all->name, name) == 0)
262 return (struct ir_remote*)all;
263 all = all->next;
264 }
265 return NULL;
266}
267
268
283int map_code(const struct ir_remote* remote,
284 struct decode_ctx_t* ctx,
285 int pre_bits,
286 ir_code pre,
287 int bits,
288 ir_code code,
289 int post_bits,
290 ir_code post)
291
292{
293 ir_code all;
294
295 if (pre_bits + bits + post_bits != remote->pre_data_bits +
296 remote->bits + remote->post_data_bits)
297 return 0;
298 all = (pre & gen_mask(pre_bits));
299 all <<= bits;
300 all |= (code & gen_mask(bits));
301 all <<= post_bits;
302 all |= (post & gen_mask(post_bits));
303
304 ctx->post = (all & gen_mask(remote->post_data_bits));
305 all >>= remote->post_data_bits;
306 ctx->code = (all & gen_mask(remote->bits));
307 all >>= remote->bits;
308 ctx->pre = (all & gen_mask(remote->pre_data_bits));
309
310 log_trace("pre: %llx", (uint64_t)(ctx->pre));
311 log_trace("code: %llx", (uint64_t)(ctx->code));
312 log_trace("post: %llx", (uint64_t)(ctx->post));
313 log_trace("code: %016llx\n", code);
314
315 return 1;
316}
317
318
329void map_gap(const struct ir_remote* remote,
330 struct decode_ctx_t* ctx,
331 const struct timeval* start,
332 const struct timeval* last,
333 lirc_t signal_length)
334{
335 // Time gap (us) between a keypress on the remote control and
336 // the next one.
337 lirc_t gap;
338
339 // Check the time gap between the last keypress and this one.
340 if (start->tv_sec - last->tv_sec >= 2) {
341 // Gap of 2 or more seconds: this is not a repeated keypress.
342 ctx->repeat_flag = 0;
343 gap = 0;
344 } else {
345 // Calculate the time gap in microseconds.
346 gap = time_elapsed(last, start);
347 if (expect_at_most(remote, gap, remote->max_remaining_gap)) {
348 // The gap is shorter than a standard gap
349 // (with relative or aboslute tolerance): this
350 // is a repeated keypress.
351 ctx->repeat_flag = 1;
352 } else {
353 // Standard gap: this is a new keypress.
354 ctx->repeat_flag = 0;
355 }
356 }
357
358 // Calculate extimated time gap remaining for the next code.
359 if (is_const(remote)) {
360 // The sum (signal_length + gap) is always constant
361 // so the gap is shorter when the code is longer.
362 if (min_gap(remote) > signal_length) {
363 ctx->min_remaining_gap = min_gap(remote) -
364 signal_length;
365 ctx->max_remaining_gap = max_gap(remote) -
366 signal_length;
367 } else {
368 ctx->min_remaining_gap = 0;
369 if (max_gap(remote) > signal_length)
370 ctx->max_remaining_gap = max_gap(remote) -
371 signal_length;
372 else
373 ctx->max_remaining_gap = 0;
374 }
375 } else {
376 // The gap after the signal is always constant.
377 // This is the case of Kanam Accent serial remote.
378 ctx->min_remaining_gap = min_gap(remote);
379 ctx->max_remaining_gap = max_gap(remote);
380 }
381
382 log_trace("repeat_flagp: %d", (ctx->repeat_flag));
383 log_trace("is_const(remote): %d", is_const(remote));
384 log_trace("remote->gap range: %lu %lu", (uint32_t)min_gap(
385 remote), (uint32_t)max_gap(remote));
386 log_trace("remote->remaining_gap: %lu %lu",
387 (uint32_t)remote->min_remaining_gap,
388 (uint32_t)remote->max_remaining_gap);
389 log_trace("signal length: %lu", (uint32_t)signal_length);
390 log_trace("gap: %lu", (uint32_t)gap);
391 log_trace("extim. remaining_gap: %lu %lu",
392 (uint32_t)(ctx->min_remaining_gap),
393 (uint32_t)(ctx->max_remaining_gap));
394}
395
396
397struct ir_ncode* get_code_by_name(const struct ir_remote* remote,
398 const char* name)
399{
400 const struct ir_ncode* all;
401
402 all = remote->codes;
403 if (all == NULL)
404 return NULL;
405 if (strcmp(remote->name, "lirc") == 0)
406 return strcmp(name, "__EOF") == 0 ? &NCODE_EOF : 0;
407 while (all->name != NULL) {
408 if (strcasecmp(all->name, name) == 0)
409 return (struct ir_ncode*)all;
410 all++;
411 }
412 return 0;
413}
414
415
416/* find longest matching sequence */
417void find_longest_match(struct ir_remote* remote,
418 struct ir_ncode* codes,
419 ir_code all,
420 ir_code* next_all,
421 int have_code,
422 struct ir_ncode** found,
423 int* found_code)
424{
425 struct ir_code_node* search;
426 struct ir_code_node* prev;
427 struct ir_code_node* next;
428 int flag = 1;
429 int sequence_match = 0;
430
431 search = codes->next;
432 if (search == NULL
433 || (codes->next != NULL && codes->current == NULL)) {
434 codes->current = NULL;
435 return;
436 }
437 while (search != codes->current->next) {
438 prev = NULL; /* means codes->code */
439 next = search;
440 while (next != codes->current) {
441 if (get_ir_code(codes, prev)
442 != get_ir_code(codes, next)) {
443 flag = 0;
444 break;
445 }
446 prev = get_next_ir_code_node(codes, prev);
447 next = get_next_ir_code_node(codes, next);
448 }
449 if (flag == 1) {
450 *next_all = gen_ir_code(remote,
451 remote->pre_data,
452 get_ir_code(codes, prev),
453 remote->post_data);
454 if (match_ir_code(remote, *next_all, all)) {
455 codes->current =
456 get_next_ir_code_node(codes, prev);
457 sequence_match = 1;
458 *found_code = 1;
459 if (!have_code)
460 *found = codes;
461 break;
462 }
463 }
464 search = search->next;
465 }
466 if (!sequence_match)
467 codes->current = NULL;
468}
469
470
471static struct ir_ncode* get_code(struct ir_remote* remote,
472 ir_code pre,
474 ir_code post,
475 int* repeat_flag,
476 ir_code* toggle_bit_mask_statep)
477{
478 ir_code pre_mask, code_mask, post_mask, toggle_bit_mask_state, all;
479 int found_code, have_code;
480 struct ir_ncode* codes;
481 struct ir_ncode* found;
482
483 pre_mask = code_mask = post_mask = 0;
484
485 if (has_toggle_bit_mask(remote)) {
486 pre_mask = remote->toggle_bit_mask >>
487 (remote->bits + remote->post_data_bits);
488 post_mask = remote->toggle_bit_mask & gen_mask(
489 remote->post_data_bits);
490 }
491 if (has_ignore_mask(remote)) {
492 pre_mask |= remote->ignore_mask >>
493 (remote->bits + remote->post_data_bits);
494 post_mask |= remote->ignore_mask & gen_mask(
495 remote->post_data_bits);
496 }
497 if (has_toggle_mask(remote) && remote->toggle_mask_state % 2) {
498 ir_code* affected;
499 ir_code mask;
500 ir_code mask_bit;
501 int bit, current_bit;
502
503 affected = &post;
504 mask = remote->toggle_mask;
505 for (bit = current_bit = 0; bit < bit_count(remote);
506 bit++, current_bit++) {
507 if (bit == remote->post_data_bits) {
508 affected = &code;
509 current_bit = 0;
510 }
511 if (bit == remote->post_data_bits + remote->bits) {
512 affected = &pre;
513 current_bit = 0;
514 }
515 mask_bit = mask & 1;
516 (*affected) ^= (mask_bit << current_bit);
517 mask >>= 1;
518 }
519 }
520 if (has_pre(remote)) {
521 if ((pre | pre_mask) != (remote->pre_data | pre_mask)) {
522 log_trace("bad pre data");
523 log_trace1("%llx %llx", pre, remote->pre_data);
524 return 0;
525 }
526 log_trace("pre");
527 }
528
529 if (has_post(remote)) {
530 if ((post | post_mask) != (remote->post_data | post_mask)) {
531 log_trace("bad post data");
532 log_trace1("%llx %llx", post, remote->post_data);
533 return 0;
534 }
535 log_trace("post");
536 }
537
538 all = gen_ir_code(remote, pre, code, post);
539
540 if (*repeat_flag && has_repeat_mask(remote))
541 all ^= remote->repeat_mask;
542
543 toggle_bit_mask_state = all & remote->toggle_bit_mask;
544
545 found = NULL;
546 found_code = 0;
547 have_code = 0;
548 codes = remote->codes;
549 if (codes != NULL) {
550 while (codes->name != NULL) {
551 ir_code next_all;
552
553 next_all = gen_ir_code(remote,
554 remote->pre_data,
555 get_ir_code(codes,
556 codes->current),
557 remote->post_data);
558 if (match_ir_code(remote, next_all, all) ||
559 (*repeat_flag &&
560 has_repeat_mask(remote) &&
561 match_ir_code(remote,
562 next_all,
563 all ^ remote->repeat_mask))) {
564 found_code = 1;
565 if (codes->next != NULL) {
566 if (codes->current == NULL)
567 codes->current = codes->next;
568 else
569 codes->current =
570 codes->current->next;
571 }
572 if (!have_code) {
573 found = codes;
574 if (codes->current == NULL)
575 have_code = 1;
576 }
577 } else {
578 find_longest_match(remote,
579 codes,
580 all,
581 &next_all,
582 have_code,
583 &found,
584 &found_code);
585 }
586 codes++;
587 }
588 }
589 if (!found_code && dyncodes) {
590 if (remote->dyncodes[remote->dyncode].code != code) {
591 remote->dyncode++;
592 remote->dyncode %= 2;
593 }
594 remote->dyncodes[remote->dyncode].code = code;
595 found = &(remote->dyncodes[remote->dyncode]);
596 found_code = 1;
597 }
598 if (found_code && found != NULL && has_toggle_mask(remote)) {
599 if (!(remote->toggle_mask_state % 2)) {
600 remote->toggle_code = found;
601 log_trace("toggle_mask_start");
602 } else {
603 if (found != remote->toggle_code) {
604 remote->toggle_code = NULL;
605 return NULL;
606 }
607 remote->toggle_code = NULL;
608 }
609 }
610 *toggle_bit_mask_statep = toggle_bit_mask_state;
611 return found;
612}
613
614
615static uint64_t set_code(struct ir_remote* remote,
616 struct ir_ncode* found,
617 ir_code toggle_bit_mask_state,
618 struct decode_ctx_t* ctx)
619{
620 struct timeval current;
621 static struct ir_remote* last_decoded = NULL;
622
623 log_trace("found: %s", found->name);
624
625 gettimeofday(&current, NULL);
626 log_trace("%lx %lx %lx %d %d %d %d %d %d %d",
627 remote, last_remote, last_decoded,
628 remote == last_decoded,
629 found == remote->last_code, found->next != NULL,
630 found->current != NULL, ctx->repeat_flag,
631 time_elapsed(&remote->last_send,
632 &current) < 1000000,
633 (!has_toggle_bit_mask(remote)
634 ||
635 toggle_bit_mask_state ==
636 remote
637 ->toggle_bit_mask_state));
638 if (remote->release_detected) {
639 remote->release_detected = 0;
640 if (ctx->repeat_flag)
641 log_trace(
642 "repeat indicated although release was detected before");
643
644 ctx->repeat_flag = 0;
645 }
646 if (remote == last_decoded &&
647 (found == remote->last_code
648 || (found->next != NULL && found->current != NULL))
649 && ctx->repeat_flag
650 && time_elapsed(&remote->last_send, &current) < 1000000
651 && (!has_toggle_bit_mask(remote)
652 || toggle_bit_mask_state == remote->toggle_bit_mask_state)) {
653 if (has_toggle_mask(remote)) {
654 remote->toggle_mask_state++;
655 if (remote->toggle_mask_state == 4) {
656 remote->reps++;
657 remote->toggle_mask_state = 2;
658 }
659 } else if (found->current == NULL) {
660 remote->reps++;
661 }
662 } else {
663 if (found->next != NULL && found->current == NULL)
664 remote->reps = 1;
665 else
666 remote->reps = 0;
667 if (has_toggle_mask(remote)) {
668 remote->toggle_mask_state = 1;
669 remote->toggle_code = found;
670 }
671 if (has_toggle_bit_mask(remote))
672 remote->toggle_bit_mask_state = toggle_bit_mask_state;
673 }
674 last_remote = remote;
675 last_decoded = remote;
676 if (found->current == NULL)
677 remote->last_code = found;
678 remote->last_send = current;
681
682 ctx->code = 0;
683 if (has_pre(remote)) {
684 ctx->code |= remote->pre_data;
685 ctx->code = ctx->code << remote->bits;
686 }
687 ctx->code |= found->code;
688 if (has_post(remote)) {
689 ctx->code = ctx->code << remote->post_data_bits;
690 ctx->code |= remote->post_data;
691 }
692 if (remote->flags & COMPAT_REVERSE)
693 /* actually this is wrong: pre, code and post should
694 * be rotated separately but we have to stay
695 * compatible with older software
696 */
697 ctx->code = reverse(ctx->code, bit_count(remote));
698 return ctx->code;
699}
700
701
713int write_message(char* buffer,
714 size_t size,
715 const char* remote_name,
716 const char* button_name,
717 const char* button_suffix,
718 ir_code code,
719 int reps)
720
721{
722 int len;
723
724 len = snprintf(buffer, size, "%016llx %02x %s%s %s\n",
725 (unsigned long long)code, reps, button_name,
726 button_suffix != NULL ? button_suffix : "",
727 remote_name);
728
729 return len;
730}
731
732
733char* decode_all(struct ir_remote* remotes)
734{
735 struct ir_remote* remote;
736 static char message[PACKET_SIZE + 1];
737 struct ir_ncode* ncode;
738 ir_code toggle_bit_mask_state;
739 struct ir_remote* scan;
740 struct ir_ncode* scan_ncode;
741 struct decode_ctx_t ctx;
742
743 /* use remotes carefully, it may be changed on SIGHUP */
744 decoding = remote = remotes;
745 while (remote) {
746 log_trace("trying \"%s\" remote", remote->name);
747 if (curr_driver->decode_func(remote, &ctx)) {
748 ncode = get_code(remote,
749 ctx.pre, ctx.code, ctx.post,
750 &ctx.repeat_flag,
751 &toggle_bit_mask_state);
752 if (ncode) {
753 int len;
754 int reps;
755
756 if (ncode == &NCODE_EOF) {
757 log_debug("decode all: returning EOF");
758 strncpy(message,
759 PACKET_EOF, sizeof(message));
760 return message;
761 }
762 ctx.code = set_code(remote,
763 ncode,
764 toggle_bit_mask_state,
765 &ctx);
766 if ((has_toggle_mask(remote)
767 && remote->toggle_mask_state % 2)
768 || ncode->current != NULL) {
769 decoding = NULL;
770 return NULL;
771 }
772
773 for (scan = decoding;
774 scan != NULL;
775 scan = scan->next)
776 for (scan_ncode = scan->codes;
777 scan_ncode->name != NULL;
778 scan_ncode++)
779 scan_ncode->current = NULL;
780 if (is_xmp(remote))
781 remote->last_code->current =
782 remote->last_code->next;
783 reps = remote->reps - (ncode->next ? 1 : 0);
784 if (reps > 0) {
785 if (reps <= remote->suppress_repeat) {
786 decoding = NULL;
787 return NULL;
788 }
789 reps -= remote->suppress_repeat;
790 }
792 remote->last_code,
793 ctx.code,
794 reps);
795 len = write_message(message, PACKET_SIZE + 1,
796 remote->name,
797 remote->last_code->name,
798 "",
799 ctx.code,
800 reps);
801 decoding = NULL;
802 if (len >= PACKET_SIZE + 1) {
803 log_error("message buffer overflow");
804 return NULL;
805 } else {
806 return message;
807 }
808 } else {
809 log_trace("failed \"%s\" remote",
810 remote->name);
811 }
812 }
813 remote->toggle_mask_state = 0;
814 remote = remote->next;
815 }
816 decoding = NULL;
817 last_remote = NULL;
818 log_trace("decoding failed for all remotes");
819 return NULL;
820}
821
822
823int send_ir_ncode(struct ir_remote* remote, struct ir_ncode* code, int delay)
824{
825 int ret;
826
827 if (delay) {
828 /* insert pause when needed: */
829 if (remote->last_code != NULL) {
830 struct timeval current;
831 unsigned long usecs;
832
833 gettimeofday(&current, NULL);
834 usecs = time_left(&current,
835 &remote->last_send,
836 remote->min_remaining_gap * 2);
837 if (usecs > 0) {
838 if (repeat_remote == NULL || remote !=
840 || remote->last_code != code)
841 usleep(usecs);
842 }
843 }
844 }
845 ret = curr_driver->send_func(remote, code);
846
847 if (ret) {
848 gettimeofday(&remote->last_send, NULL);
849 remote->last_code = code;
850 }
851 return ret;
852}
853
854const struct ir_remote* get_decoding(void)
855{
856 return (const struct ir_remote*)&decoding;
857}
const struct driver *const curr_driver
Read-only access to drv for client code.
Definition driver.c:34
int write_message(char *buffer, size_t size, const char *remote_name, const char *button_name, const char *button_suffix, ir_code code, int reps)
Formats the arguments into a readable string.
Definition ir_remote.c:713
struct ir_ncode * get_code_by_name(const struct ir_remote *remote, const char *name)
Return code with given name in remote's list of codes or NULL.
Definition ir_remote.c:397
void get_frequency_range(const struct ir_remote *remotes, unsigned int *min_freq, unsigned int *max_freq)
Definition ir_remote.c:156
void get_filter_parameters(const struct ir_remote *remotes, lirc_t *max_gap_lengthp, lirc_t *min_pulse_lengthp, lirc_t *min_space_lengthp, lirc_t *max_pulse_lengthp, lirc_t *max_space_lengthp)
Definition ir_remote.c:193
struct ir_ncode * repeat_code
Global pointer to the code currently repeating.
Definition ir_remote.c:63
void ncode_free(struct ir_ncode *ncode)
Dispose an ir_ncode instance obtained from ncode_dup().
Definition ir_remote.c:104
struct ir_remote * last_remote
TODO.
Definition ir_remote.c:59
int send_ir_ncode(struct ir_remote *remote, struct ir_ncode *code, int delay)
Transmits the actual code in the second argument by calling the current hardware driver.
Definition ir_remote.c:823
char * decode_all(struct ir_remote *remotes)
Tries to decode current signal trying all known remotes.
Definition ir_remote.c:733
struct ir_remote * repeat_remote
Global pointer to the remote that contains the code currently repeating.
Definition ir_remote.c:61
void ir_remote_init(int use_dyncodes)
Initiate: define if dynamic codes should be used.
Definition ir_remote.c:124
const struct ir_remote * get_decoding(void)
Return pointer to currently decoded remote.
Definition ir_remote.c:854
struct ir_remote * get_ir_remote(const struct ir_remote *remotes, const char *name)
Return ir_remote with given name in remotes list, or NULL if not found.
Definition ir_remote.c:251
int map_code(const struct ir_remote *remote, struct decode_ctx_t *ctx, int pre_bits, ir_code pre, int bits, ir_code code, int post_bits, ir_code post)
Definition ir_remote.c:283
void map_gap(const struct ir_remote *remote, struct decode_ctx_t *ctx, const struct timeval *start, const struct timeval *last, lirc_t signal_length)
Definition ir_remote.c:329
const struct ir_remote * is_in_remotes(const struct ir_remote *remotes, const struct ir_remote *remote)
Test if a given remote is in a list of remotes.
Definition ir_remote.c:239
struct ir_ncode * ncode_dup(struct ir_ncode *ncode)
Create a malloc'd, deep copy of ncode.
Definition ir_remote.c:69
uint64_t ir_code
Denotes an internal coded representation for an IR transmission.
#define COMPAT_REVERSE
compatibility mode for REVERSE flag
#define LIRC_EOF
Bit manipulator in lirc_t, see lirc.h .
Definition lirc_config.h:90
#define PACKET_SIZE
IR transmission packet size.
Definition lirc_config.h:84
#define log_trace(fmt,...)
Log a trace message.
Definition lirc_log.h:129
#define log_debug(fmt,...)
Log a debug message.
Definition lirc_log.h:124
#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
void register_button_press(struct ir_remote *remote, struct ir_ncode *ncode, ir_code code, int reps)
Set up pending release events for given button, including the release_gap.
Definition release.c:64
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(*const decode_func)(struct ir_remote *remote, struct decode_ctx_t *ctx)
TODO.
Definition driver.h:206
int(*const send_func)(struct ir_remote *remote, struct ir_ncode *code)
Send data to the remote.
Definition driver.h:192
An ir_code for entering into (singly) linked lists, i.e.
IR Command, corresponding to one (command defining) line of the configuration file.
struct ir_code_node * next
Linked list of the subsequent ir_code's, after the first one.
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.
unsigned int freq
modulation frequency
int suppress_repeat
suppress unwanted repeats
struct ir_ncode dyncodes[2]
helper structs for unknown buttons
lirc_t max_remaining_gap
gap range
ir_code repeat_mask
mask defines which bits are inverted for repeats
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
ir_code ignore_mask
mask defines which bits can be ignored when matching a code
int release_detected
set by release generator
struct timeval last_send
time last_code was received or sent
ir_code post_data
data which the remote sends after actual keycode
ir_code toggle_mask
Sharp (?) error detection scheme.
int flags
flags
uint32_t gap
time between signals in usecs
struct ir_ncode * last_code
code received or sent last
struct ir_ncode * toggle_code
toggle code received or sent last
const char * name
name of remote control
ir_code toggle_bit_mask
previously only one bit called toggle_bit
int pre_data_bits
length of pre_data
lirc_t max_gap_length
how long is the longest gap
int dyncode
last received code
lirc_t min_remaining_gap
remember gap for CONST_LENGTH remotes