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