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