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