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.