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