31 #include <sys/ioctl.h>
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
52 static const char*
const PACKET_EOF =
"0000000008000000 00 __EOF lirc\n";
55 static struct ir_remote lirc_internal_remote = {
"lirc" };
65 static 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;
130 static 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);
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;
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;
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)
298 all = (pre & gen_mask(pre_bits));
300 all |= (code & gen_mask(bits));
302 all |= (post & gen_mask(post_bits));
306 ctx->
code = (all & gen_mask(remote->
bits));
307 all >>= remote->
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);
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",
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)
417 void 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)) {
491 if (has_ignore_mask(remote)) {
497 if (has_toggle_mask(remote) && remote->toggle_mask_state % 2) {
501 int bit, current_bit;
505 for (bit = current_bit = 0; bit < bit_count(remote);
506 bit++, current_bit++) {
516 (*affected) ^= (mask_bit << current_bit);
520 if (has_pre(remote)) {
521 if ((pre | pre_mask) != (remote->
pre_data | pre_mask)) {
529 if (has_post(remote)) {
530 if ((post | post_mask) != (remote->
post_data | post_mask)) {
538 all = gen_ir_code(remote, pre, code, post);
540 if (*repeat_flag && has_repeat_mask(remote))
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,
565 if (codes->
next != NULL) {
578 find_longest_match(remote,
589 if (!found_code && dyncodes) {
598 if (found_code && found != NULL && has_toggle_mask(remote)) {
599 if (!(remote->toggle_mask_state % 2)) {
610 *toggle_bit_mask_statep = toggle_bit_mask_state;
615 static 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",
627 remote, last_remote, last_decoded,
628 remote == last_decoded,
633 (!has_toggle_bit_mask(remote)
635 toggle_bit_mask_state ==
637 ->toggle_bit_mask_state));
642 "repeat indicated although release was detected before");
646 if (remote == last_decoded &&
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;
671 if (has_toggle_bit_mask(remote))
672 remote->toggle_bit_mask_state = toggle_bit_mask_state;
674 last_remote = remote;
675 last_decoded = remote;
683 if (has_pre(remote)) {
688 if (has_post(remote)) {
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;
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;
783 reps = remote->reps - (ncode->
next ? 1 : 0);
785 if (reps <= remote->suppress_repeat) {
813 remote->toggle_mask_state = 0;
814 remote = remote->next;
818 log_trace(
"decoding failed for all remotes");
830 struct timeval current;
833 gettimeofday(¤t, NULL);
834 usecs = time_left(¤t,
838 if (repeat_remote == NULL || remote !=
856 return (
const struct ir_remote*)&decoding;
lirc_t min_remaining_gap
remember gap for CONST_LENGTH remotes
struct ir_remote * last_remote
TODO.
struct ir_ncode * repeat_code
Global pointer to the code currently repeating.
One remote as represented in the configuration file.
int bits
bits (length of code)
An ir_code for entering into (singly) linked lists, i.e.
unsigned int freq
modulation frequency
lirc_t max_gap_length
how long is the longest gap
void ir_remote_init(int use_dyncodes)
Initiate: define if dynamic codes should be used.
const struct driver *const curr_driver
Read-only access to drv for client code.
ir_code post_data
data which the remote sends after actual keycode
ir_code repeat_mask
mask defines which bits are inverted for repeats
struct ir_ncode * toggle_code
toggle code received or sent last
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)
#define log_debug(fmt,...)
Log a debug message.
int(*const decode_func)(struct ir_remote *remote, struct decode_ctx_t *ctx)
TODO.
struct ir_code_node * next
Linked list of the subsequent ir_code's, after the first one.
const char * name
name of remote control
lirc_t * signals
(private)
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.
#define COMPAT_REVERSE
compatibility mode for REVERSE flag
struct ir_ncode * last_code
code received or sent last
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.
ir_code pre
pre data, before code.
#define LIRC_EOF
Bit manipulator in lirc_t, see lirc.h .
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)
char * decode_all(struct ir_remote *remotes)
Tries to decode current signal trying all known remotes.
int pre_data_bits
length of pre_data
int(*const send_func)(struct ir_remote *remote, struct ir_ncode *code)
Send data to the remote.
#define PACKET_SIZE
IR transmission packet size.
logchannel_t
Log channels used to filter messages.
char * name
Name of command.
struct timeval last_send
time last_code was received or sent
struct ir_code_node * current
Should point at the ir_code currently being transmitted, or NULL if none.
int post_data_bits
length of post_data
ir_code toggle_mask
Sharp (?) error detection scheme.
#define log_error(fmt,...)
Log an error message.
#define log_trace1(fmt,...)
Log a trace1 message.
ir_code pre_data
data which the remote sends before actual keycode
ir_code post
post data, sent after code.
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.
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.
uint32_t gap
time between signals in usecs
#define log_trace(fmt,...)
Log a trace message.
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.
lirc_t max_remaining_gap
Estimated max time of trailing gap.
ir_code code
Code part, matched to code defintion.
const struct ir_remote * get_decoding(void)
Return pointer to currently decoded remote.
int dyncode
last received code
void ncode_free(struct ir_ncode *ncode)
Dispose an ir_ncode instance obtained from ncode_dup().
IR Command, corresponding to one (command defining) line of the configuration file.
State describing code, pre, post + gap and repeat state.
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)
int release_detected
set by release generator
lirc_t min_remaining_gap
Estimated min time of trailing gap.
struct ir_ncode * ncode_dup(struct ir_ncode *ncode)
Create a malloc'd, deep copy of ncode.
lirc_t max_remaining_gap
gap range
void get_frequency_range(const struct ir_remote *remotes, unsigned int *min_freq, unsigned int *max_freq)
int suppress_repeat
suppress unwanted repeats
ir_code code
The first code of the command.
struct ir_ncode dyncodes[2]
helper structs for unknown buttons
int repeat_flag
True if code is a repeated one.
struct ir_remote * repeat_remote
Global pointer to the remote that contains the code currently repeating.
ir_code toggle_bit_mask
previously only one bit called toggle_bit
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.
ir_code ignore_mask
mask defines which bits can be ignored when matching a code
uint64_t ir_code
Denotes an internal coded representation for an IR transmission.