33#ifdef HAVE_KERNEL_LIRC_H
34#include <linux/lirc.h>
36#include "media/lirc.h"
39#include "lirc/ir_remote.h"
40#include "lirc/driver.h"
41#include "lirc/release.h"
42#include "lirc/lirc_log.h"
48 "__EOF",
LIRC_EOF, 1, NULL, NULL, NULL, 0
52static const char*
const PACKET_EOF =
"0000000008000000 00 __EOF lirc\n";
55static struct ir_remote lirc_internal_remote = {
"lirc" };
65static int dyncodes = 0;
78 if (new_ncode == NULL)
80 memcpy(new_ncode, ncode,
sizeof(
struct ir_ncode));
81 new_ncode->
name = ncode->
name == NULL ? NULL : strdup(ncode->
name);
83 signal_size = ncode->
length *
sizeof(lirc_t);
84 new_ncode->
signals = (lirc_t*)malloc(signal_size);
91 node_ptr = &(new_ncode->
next);
92 for (node = ncode->
next; node != NULL; node = node->next) {
96 node_ptr = &(new_node->next);
112 while (node != NULL) {
126 dyncodes = use_dyncodes;
130static lirc_t time_left(
struct timeval* current,
131 struct timeval* last,
134 unsigned long secs, diff;
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);
144 return (remote->ignore_mask | a) == (remote->ignore_mask | b)
145 || (remote->ignore_mask | a) ==
146 (remote->ignore_mask | (b ^ remote->toggle_bit_mask));
157 unsigned int* min_freq,
158 unsigned int* max_freq)
168 *min_freq = scan->
freq;
169 *max_freq = scan->
freq;
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;
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)
202 lirc_t min_pulse_length = 0, min_space_length = 0;
203 lirc_t max_pulse_length = 0, max_space_length = 0;
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;
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;
242 while (remotes != NULL) {
243 if (remotes == remote)
245 remotes = remotes->next;
258 if (strcmp(name,
"lirc") == 0)
259 return &lirc_internal_remote;
261 if (strcasecmp(all->
name, name) == 0)
295 if (pre_bits +
bits + post_bits != remote->pre_data_bits +
296 remote->bits + remote->post_data_bits)
298 all = (pre & gen_mask(pre_bits));
300 all |= (code & gen_mask(
bits));
302 all |= (post & gen_mask(post_bits));
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));
331 const struct timeval* start,
332 const struct timeval* last,
333 lirc_t signal_length)
340 if (start->tv_sec - last->tv_sec >= 2) {
346 gap = time_elapsed(last, start);
347 if (expect_at_most(remote,
gap, remote->max_remaining_gap)) {
359 if (is_const(remote)) {
362 if (min_gap(remote) > signal_length) {
369 if (max_gap(remote) > signal_length)
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);
391 log_trace(
"extim. remaining_gap: %lu %lu",
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)
417void find_longest_match(
struct ir_remote* remote,
429 int sequence_match = 0;
431 search = codes->
next;
433 || (codes->
next != NULL && codes->
current == NULL)) {
437 while (search != codes->
current->next) {
440 while (next != codes->
current) {
441 if (get_ir_code(codes, prev)
442 != get_ir_code(codes, next)) {
446 prev = get_next_ir_code_node(codes, prev);
447 next = get_next_ir_code_node(codes, next);
450 *next_all = gen_ir_code(remote,
452 get_ir_code(codes, prev),
454 if (match_ir_code(remote, *next_all, all)) {
456 get_next_ir_code_node(codes, prev);
464 search = search->next;
476 ir_code* toggle_bit_mask_statep)
478 ir_code pre_mask, code_mask, post_mask, toggle_bit_mask_state, all;
479 int found_code, have_code;
483 pre_mask = code_mask = post_mask = 0;
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);
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);
497 if (has_toggle_mask(remote) && remote->toggle_mask_state % 2) {
501 int bit, current_bit;
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) {
511 if (bit == remote->post_data_bits + remote->bits) {
516 (*affected) ^= (mask_bit << current_bit);
520 if (has_pre(remote)) {
521 if ((pre | pre_mask) != (remote->pre_data | pre_mask)) {
523 log_trace1(
"%llx %llx", pre, remote->pre_data);
529 if (has_post(remote)) {
530 if ((post | post_mask) != (remote->post_data | post_mask)) {
532 log_trace1(
"%llx %llx", post, remote->post_data);
538 all = gen_ir_code(remote, pre, code, post);
540 if (*repeat_flag && has_repeat_mask(remote))
541 all ^= remote->repeat_mask;
543 toggle_bit_mask_state = all & remote->toggle_bit_mask;
548 codes = remote->codes;
550 while (codes->
name != NULL) {
553 next_all = gen_ir_code(remote,
558 if (match_ir_code(remote, next_all, all) ||
560 has_repeat_mask(remote) &&
561 match_ir_code(remote,
563 all ^ remote->repeat_mask))) {
565 if (codes->
next != NULL) {
578 find_longest_match(remote,
589 if (!found_code && dyncodes) {
590 if (remote->dyncodes[remote->dyncode].code != code) {
592 remote->dyncode %= 2;
594 remote->dyncodes[remote->dyncode].code = code;
595 found = &(remote->dyncodes[remote->dyncode]);
598 if (found_code && found != NULL && has_toggle_mask(remote)) {
599 if (!(remote->toggle_mask_state % 2)) {
600 remote->toggle_code = found;
603 if (found != remote->toggle_code) {
604 remote->toggle_code = NULL;
607 remote->toggle_code = NULL;
610 *toggle_bit_mask_statep = toggle_bit_mask_state;
615static uint64_t set_code(
struct ir_remote* remote,
620 struct timeval current;
621 static struct ir_remote* last_decoded = NULL;
625 gettimeofday(¤t, NULL);
626 log_trace(
"%lx %lx %lx %d %d %d %d %d %d %d",
628 remote == last_decoded,
629 found == remote->last_code, found->
next != NULL,
631 time_elapsed(&remote->last_send,
633 (!has_toggle_bit_mask(remote)
635 toggle_bit_mask_state ==
637 ->toggle_bit_mask_state));
638 if (remote->release_detected) {
639 remote->release_detected = 0;
642 "repeat indicated although release was detected before");
646 if (remote == last_decoded &&
647 (found == remote->last_code
648 || (found->
next != NULL && found->
current != NULL))
650 && time_elapsed(&remote->last_send, ¤t) < 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) {
657 remote->toggle_mask_state = 2;
659 }
else if (found->
current == NULL) {
667 if (has_toggle_mask(remote)) {
668 remote->toggle_mask_state = 1;
669 remote->toggle_code = found;
671 if (has_toggle_bit_mask(remote))
672 remote->toggle_bit_mask_state = toggle_bit_mask_state;
675 last_decoded = remote;
678 remote->last_send = current;
683 if (has_pre(remote)) {
684 ctx->
code |= remote->pre_data;
685 ctx->
code = ctx->
code << remote->bits;
688 if (has_post(remote)) {
689 ctx->
code = ctx->
code << remote->post_data_bits;
690 ctx->
code |= remote->post_data;
697 ctx->
code = reverse(ctx->
code, bit_count(remote));
715 const char* remote_name,
716 const char* button_name,
717 const char* button_suffix,
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 :
"",
744 decoding = remote = remotes;
746 log_trace(
"trying \"%s\" remote", remote->name);
748 ncode = get_code(remote,
751 &toggle_bit_mask_state);
756 if (ncode == &NCODE_EOF) {
759 PACKET_EOF,
sizeof(message));
762 ctx.
code = set_code(remote,
764 toggle_bit_mask_state,
766 if ((has_toggle_mask(remote)
767 && remote->toggle_mask_state % 2)
773 for (scan = decoding;
776 for (scan_ncode = scan->codes;
777 scan_ncode->
name != NULL;
781 remote->last_code->current =
782 remote->last_code->next;
783 reps = remote->reps - (ncode->
next ? 1 : 0);
785 if (reps <= remote->suppress_repeat) {
789 reps -= remote->suppress_repeat;
797 remote->last_code->name,
813 remote->toggle_mask_state = 0;
814 remote = remote->next;
818 log_trace(
"decoding failed for all remotes");
829 if (remote->last_code != NULL) {
830 struct timeval current;
833 gettimeofday(¤t, NULL);
834 usecs = time_left(¤t,
836 remote->min_remaining_gap * 2);
840 || remote->last_code != code)
848 gettimeofday(&remote->last_send, NULL);
849 remote->last_code = code;
856 return (
const struct ir_remote*)&decoding;
const struct driver *const curr_driver
Read-only access to drv for client code.
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.
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.
void get_frequency_range(const struct ir_remote *remotes, unsigned int *min_freq, unsigned int *max_freq)
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)
struct ir_ncode * repeat_code
Global pointer to the code currently repeating.
void ncode_free(struct ir_ncode *ncode)
Dispose an ir_ncode instance obtained from ncode_dup().
struct ir_remote * last_remote
TODO.
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.
char * decode_all(struct ir_remote *remotes)
Tries to decode current signal trying all known remotes.
struct ir_remote * repeat_remote
Global pointer to the remote that contains the code currently repeating.
void ir_remote_init(int use_dyncodes)
Initiate: define if dynamic codes should be used.
const struct ir_remote * get_decoding(void)
Return pointer to currently decoded remote.
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.
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)
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)
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.
struct ir_ncode * ncode_dup(struct ir_ncode *ncode)
Create a malloc'd, deep copy of ncode.
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 .
#define PACKET_SIZE
IR transmission packet size.
#define log_trace(fmt,...)
Log a trace message.
#define log_debug(fmt,...)
Log a debug message.
#define log_error(fmt,...)
Log an error message.
#define log_trace1(fmt,...)
Log a trace1 message.
logchannel_t
Log channels used to filter messages.
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.
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.
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