31 #include <sys/ioctl.h>
33 #include "media/lirc.h"
35 #include "lirc/ir_remote.h"
36 #include "lirc/driver.h"
37 #include "lirc/release.h"
38 #include "lirc/lirc_log.h"
44 "__EOF",
LIRC_EOF, 1, NULL, NULL, NULL, 0
48 static const char*
const PACKET_EOF =
"0000000008000000 00 __EOF lirc\n";
51 static struct ir_remote lirc_internal_remote = {
"lirc" };
61 static int dyncodes = 0;
74 if (new_ncode == NULL)
76 memcpy(new_ncode, ncode,
sizeof(
struct ir_ncode));
77 new_ncode->
name = ncode->
name == NULL ? NULL : strdup(ncode->
name);
79 signal_size = ncode->
length *
sizeof(lirc_t);
80 new_ncode->
signals = (lirc_t*)malloc(signal_size);
87 node_ptr = &(new_ncode->
next);
88 for (node = ncode->
next; node != NULL; node = node->next) {
92 node_ptr = &(new_node->next);
108 while (node != NULL) {
122 dyncodes = use_dyncodes;
126 static lirc_t time_left(
struct timeval* current,
127 struct timeval* last,
130 unsigned long secs, diff;
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);
153 unsigned int* min_freq,
154 unsigned int* max_freq)
164 *min_freq = scan->
freq;
165 *max_freq = scan->
freq;
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;
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)
198 lirc_t min_pulse_length = 0, min_space_length = 0;
199 lirc_t max_pulse_length = 0, max_space_length = 0;
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;
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;
238 while (remotes != NULL) {
239 if (remotes == remote)
241 remotes = remotes->next;
254 if (strcmp(
name,
"lirc") == 0)
255 return &lirc_internal_remote;
257 if (strcasecmp(all->
name,
name) == 0)
294 all = (pre & gen_mask(pre_bits));
296 all |= (code & gen_mask(
bits));
298 all |= (post & gen_mask(post_bits));
302 ctx->
code = (all & gen_mask(remote->
bits));
303 all >>= remote->
bits;
327 const struct timeval* start,
328 const struct timeval* last,
329 lirc_t signal_length)
336 if (start->tv_sec - last->tv_sec >= 2) {
342 gap = time_elapsed(last, start);
355 if (is_const(remote)) {
358 if (min_gap(remote) > signal_length) {
365 if (max_gap(remote) > signal_length)
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",
385 log_trace(
"signal length: %lu", (uint32_t)signal_length);
387 log_trace(
"extim. remaining_gap: %lu %lu",
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)
413 void find_longest_match(
struct ir_remote* remote,
425 int sequence_match = 0;
427 search = codes->
next;
429 || (codes->
next != NULL && codes->
current == NULL)) {
433 while (search != codes->
current->next) {
436 while (next != codes->
current) {
437 if (get_ir_code(codes, prev)
438 != get_ir_code(codes, next)) {
442 prev = get_next_ir_code_node(codes, prev);
443 next = get_next_ir_code_node(codes, next);
446 *next_all = gen_ir_code(remote,
448 get_ir_code(codes, prev),
450 if (match_ir_code(remote, *next_all, all)) {
452 get_next_ir_code_node(codes, prev);
460 search = search->next;
472 ir_code* toggle_bit_mask_statep)
474 ir_code pre_mask, code_mask, post_mask, toggle_bit_mask_state, all;
475 int found_code, have_code;
479 pre_mask = code_mask = post_mask = 0;
481 if (has_toggle_bit_mask(remote)) {
487 if (has_ignore_mask(remote)) {
493 if (has_toggle_mask(remote) && remote->toggle_mask_state % 2) {
497 int bit, current_bit;
501 for (bit = current_bit = 0; bit < bit_count(remote);
502 bit++, current_bit++) {
512 (*affected) ^= (mask_bit << current_bit);
516 if (has_pre(remote)) {
517 if ((pre | pre_mask) != (remote->
pre_data | pre_mask)) {
525 if (has_post(remote)) {
526 if ((post | post_mask) != (remote->
post_data | post_mask)) {
534 all = gen_ir_code(remote, pre,
code, post);
536 if (*repeat_flag && has_repeat_mask(remote))
544 codes = remote->codes;
546 while (codes->
name != NULL) {
549 next_all = gen_ir_code(remote,
554 if (match_ir_code(remote, next_all, all) ||
556 has_repeat_mask(remote) &&
557 match_ir_code(remote,
561 if (codes->
next != NULL) {
574 find_longest_match(remote,
585 if (!found_code && dyncodes) {
594 if (found_code && found != NULL && has_toggle_mask(remote)) {
595 if (!(remote->toggle_mask_state % 2)) {
606 *toggle_bit_mask_statep = toggle_bit_mask_state;
611 static uint64_t set_code(
struct ir_remote* remote,
616 struct timeval current;
617 static struct ir_remote* last_decoded = NULL;
621 gettimeofday(¤t, NULL);
622 log_trace(
"%lx %lx %lx %d %d %d %d %d %d %d",
624 remote == last_decoded,
629 (!has_toggle_bit_mask(remote)
631 toggle_bit_mask_state ==
633 ->toggle_bit_mask_state));
638 "repeat indicated although release was detected before");
642 if (remote == last_decoded &&
644 || (found->
next != NULL && found->
current != NULL))
646 && time_elapsed(&remote->
last_send, ¤t) < 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) {
653 remote->toggle_mask_state = 2;
655 }
else if (found->
current == NULL) {
663 if (has_toggle_mask(remote)) {
664 remote->toggle_mask_state = 1;
667 if (has_toggle_bit_mask(remote))
668 remote->toggle_bit_mask_state = toggle_bit_mask_state;
671 last_decoded = remote;
679 if (has_pre(remote)) {
684 if (has_post(remote)) {
693 ctx->
code = reverse(ctx->
code, bit_count(remote));
711 const char* remote_name,
712 const char* button_name,
713 const char* button_suffix,
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 :
"",
740 decoding = remote = remotes;
744 ncode = get_code(remote,
747 &toggle_bit_mask_state);
752 if (ncode == &NCODE_EOF) {
755 PACKET_EOF,
sizeof(message));
758 ctx.
code = set_code(remote,
760 toggle_bit_mask_state,
762 if ((has_toggle_mask(remote)
763 && remote->toggle_mask_state % 2)
769 for (scan = decoding;
772 for (scan_ncode = scan->codes;
773 scan_ncode->
name != NULL;
779 reps = remote->reps - (ncode->
next ? 1 : 0);
781 if (reps <= remote->suppress_repeat) {
809 remote->toggle_mask_state = 0;
810 remote = remote->next;
814 log_trace(
"decoding failed for all remotes");
826 struct timeval current;
829 gettimeofday(¤t, NULL);
830 usecs = time_left(¤t,
852 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.
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_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.
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.
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 * is_in_remotes(const struct ir_remote *remotes, const struct ir_remote *remote)
Test if a given remote is in a list of remotes.
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)
struct ir_ncode * ncode_dup(struct ir_ncode *ncode)
Create a malloc'd, deep copy of ncode.
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)
char * decode_all(struct ir_remote *remotes)
Tries to decode current signal trying all known remotes.
const struct ir_remote * get_decoding(void)
Return pointer to currently decoded remote.
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.
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 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.
int(*const decode_func)(struct ir_remote *remote, struct decode_ctx_t *ctx)
TODO.
int(*const send_func)(struct ir_remote *remote, struct ir_ncode *code)
Send data to the remote.
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 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.
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