1 /* $Id: ir_remote.c,v 5.49 2010/05/13 16:24:29 lirc Exp $ */
2
3 /****************************************************************************
4 ** ir_remote.c *************************************************************
5 ****************************************************************************
6 *
7 * ir_remote.c - sends and decodes the signals from IR remotes
8 *
9 * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 * Copyright (C) 1998 Christoph Bartelmus (lirc@bartelmus.de)
11 *
12 */
13
14 #ifdef HAVE_CONFIG_H
15 # include <config.h>
16 #endif
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <fcntl.h>
21 #include <limits.h>
22
23 #include <sys/ioctl.h>
24
25 #include "drivers/lirc.h"
26
27 #include "lircd.h"
28 #include "ir_remote.h"
29 #include "hardware.h"
30 #include "release.h"
31
32 struct ir_remote *decoding = NULL;
33
34 struct ir_remote *last_remote = NULL;
35 struct ir_remote *repeat_remote = NULL;
36 struct ir_ncode *repeat_code;
37
38 extern struct hardware hw;
39
time_left(struct timeval * current,struct timeval * last,lirc_t gap)40 static inline lirc_t time_left(struct timeval *current, struct timeval *last, lirc_t gap)
41 {
42 unsigned long secs, diff;
43
44 secs = current->tv_sec - last->tv_sec;
45
46 diff = 1000000 * secs + current->tv_usec - last->tv_usec;
47
48 return ((lirc_t) (diff < gap ? gap - diff : 0));
49 }
50
match_ir_code(struct ir_remote * remote,ir_code a,ir_code b)51 static int match_ir_code(struct ir_remote *remote, ir_code a, ir_code b)
52 {
53 return ((remote->ignore_mask | a) == (remote->ignore_mask | b)
54 || (remote->ignore_mask | a) == (remote->ignore_mask | (b ^ remote->toggle_bit_mask)));
55 }
56
get_frequency_range(struct ir_remote * remotes,unsigned int * min_freq,unsigned int * max_freq)57 void get_frequency_range(struct ir_remote *remotes, unsigned int *min_freq, unsigned int *max_freq)
58 {
59 struct ir_remote *scan;
60
61 /* use remotes carefully, it may be changed on SIGHUP */
62 scan = remotes;
63 if (scan == NULL) {
64 *min_freq = 0;
65 *max_freq = 0;
66 } else {
67 *min_freq = scan->freq;
68 *max_freq = scan->freq;
69 scan = scan->next;
70 }
71 while (scan) {
72 if (scan->freq != 0) {
73 if (scan->freq > *max_freq) {
74 *max_freq = scan->freq;
75 } else if (scan->freq < *min_freq) {
76 *min_freq = scan->freq;
77 }
78 }
79 scan = scan->next;
80 }
81 }
82
get_filter_parameters(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)83 void get_filter_parameters(struct ir_remote *remotes, lirc_t * max_gap_lengthp, lirc_t * min_pulse_lengthp,
84 lirc_t * min_space_lengthp, lirc_t * max_pulse_lengthp, lirc_t * max_space_lengthp)
85 {
86 struct ir_remote *scan = remotes;
87 lirc_t max_gap_length = 0;
88 lirc_t min_pulse_length = 0, min_space_length = 0;
89 lirc_t max_pulse_length = 0, max_space_length = 0;
90
91 while (scan) {
92 lirc_t val;
93 val = upper_limit(scan, scan->max_gap_length);
94 if (val > max_gap_length) {
95 max_gap_length = val;
96 }
97 val = lower_limit(scan, scan->min_pulse_length);
98 if (min_pulse_length == 0 || val < min_pulse_length) {
99 min_pulse_length = val;
100 }
101 val = lower_limit(scan, scan->min_space_length);
102 if (min_space_length == 0 || val > min_space_length) {
103 min_space_length = val;
104 }
105 val = upper_limit(scan, scan->max_pulse_length);
106 if (val > max_pulse_length) {
107 max_pulse_length = val;
108 }
109 val = upper_limit(scan, scan->max_space_length);
110 if (val > max_space_length) {
111 max_space_length = val;
112 }
113 scan = scan->next;
114 }
115 *max_gap_lengthp = max_gap_length;
116 *min_pulse_lengthp = min_pulse_length;
117 *min_space_lengthp = min_space_length;
118 *max_pulse_lengthp = max_pulse_length;
119 *max_space_lengthp = max_space_length;
120 }
121
is_in_remotes(struct ir_remote * remotes,struct ir_remote * remote)122 struct ir_remote *is_in_remotes(struct ir_remote *remotes, struct ir_remote *remote)
123 {
124 while (remotes != NULL) {
125 if (remotes == remote) {
126 return remote;
127 }
128 remotes = remotes->next;
129 }
130 return NULL;
131 }
132
get_ir_remote(struct ir_remote * remotes,char * name)133 struct ir_remote *get_ir_remote(struct ir_remote *remotes, char *name)
134 {
135 struct ir_remote *all;
136
137 /* use remotes carefully, it may be changed on SIGHUP */
138 all = remotes;
139 while (all) {
140 if (strcasecmp(all->name, name) == 0) {
141 return (all);
142 }
143 all = all->next;
144 }
145 return (NULL);
146 }
147
map_code(struct ir_remote * remote,ir_code * prep,ir_code * codep,ir_code * postp,int pre_bits,ir_code pre,int bits,ir_code code,int post_bits,ir_code post)148 int map_code(struct ir_remote *remote, ir_code * prep, ir_code * codep, ir_code * postp, int pre_bits, ir_code pre,
149 int bits, ir_code code, int post_bits, ir_code post)
150 {
151 ir_code all;
152
153 if (pre_bits + bits + post_bits != remote->pre_data_bits + remote->bits + remote->post_data_bits) {
154 return (0);
155 }
156 all = (pre & gen_mask(pre_bits));
157 all <<= bits;
158 all |= (code & gen_mask(bits));
159 all <<= post_bits;
160 all |= (post & gen_mask(post_bits));
161
162 *postp = (all & gen_mask(remote->post_data_bits));
163 all >>= remote->post_data_bits;
164 *codep = (all & gen_mask(remote->bits));
165 all >>= remote->bits;
166 *prep = (all & gen_mask(remote->pre_data_bits));
167
168 LOGPRINTF(1, "pre: %llx", (__u64) * prep);
169 LOGPRINTF(1, "code: %llx", (__u64) * codep);
170 LOGPRINTF(1, "post: %llx", (__u64) * postp);
171 LOGPRINTF(1, "code: %016llx\n", code);
172
173 return (1);
174 }
175
map_gap(struct ir_remote * remote,struct timeval * start,struct timeval * last,lirc_t signal_length,int * repeat_flagp,lirc_t * min_remaining_gapp,lirc_t * max_remaining_gapp)176 void map_gap(struct ir_remote *remote, struct timeval *start, struct timeval *last, lirc_t signal_length,
177 int *repeat_flagp, lirc_t * min_remaining_gapp, lirc_t * max_remaining_gapp)
178 {
179 // Time gap (us) between a keypress on the remote control and
180 // the next one.
181 lirc_t gap;
182
183 // Check the time gap between the last keypress and this one.
184 if (start->tv_sec - last->tv_sec >= 2) {
185 // Gap of 2 or more seconds: this is not a repeated keypress.
186 *repeat_flagp = 0;
187 gap = 0;
188 } else {
189 // Calculate the time gap in microseconds.
190 gap = time_elapsed(last, start);
191 if (expect_at_most(remote, gap, remote->max_remaining_gap)) {
192 // The gap is shorter than a standard gap
193 // (with relative or aboslute tolerance): this
194 // is a repeated keypress.
195 *repeat_flagp = 1;
196 } else {
197 // Standard gap: this is a new keypress.
198 *repeat_flagp = 0;
199 }
200 }
201
202 // Calculate extimated time gap remaining for the next code.
203 if (is_const(remote)) {
204 // The sum (signal_length + gap) is always constant
205 // so the gap is shorter when the code is longer.
206 if (min_gap(remote) > signal_length) {
207 *min_remaining_gapp = min_gap(remote) - signal_length;
208 *max_remaining_gapp = max_gap(remote) - signal_length;
209 } else {
210 *min_remaining_gapp = 0;
211 if (max_gap(remote) > signal_length) {
212 *max_remaining_gapp = max_gap(remote) - signal_length;
213 } else {
214 *max_remaining_gapp = 0;
215 }
216 }
217 } else {
218 // The gap after the signal is always constant.
219 // This is the case of Kanam Accent serial remote.
220 *min_remaining_gapp = min_gap(remote);
221 *max_remaining_gapp = max_gap(remote);
222 }
223
224 LOGPRINTF(1, "repeat_flagp: %d", *repeat_flagp);
225 LOGPRINTF(1, "is_const(remote): %d", is_const(remote));
226 LOGPRINTF(1, "remote->gap range: %lu %lu", (__u32) min_gap(remote), (__u32) max_gap(remote));
227 LOGPRINTF(1, "remote->remaining_gap: %lu %lu", (__u32) remote->min_remaining_gap,
228 (__u32) remote->max_remaining_gap);
229 LOGPRINTF(1, "signal length: %lu", (__u32) signal_length);
230 LOGPRINTF(1, "gap: %lu", (__u32) gap);
231 LOGPRINTF(1, "extim. remaining_gap: %lu %lu", (__u32) * min_remaining_gapp, (__u32) * max_remaining_gapp);
232
233 }
234
get_code_by_name(struct ir_remote * remote,char * name)235 struct ir_ncode *get_code_by_name(struct ir_remote *remote, char *name)
236 {
237 struct ir_ncode *all;
238
239 all = remote->codes;
240 while (all->name != NULL) {
241 if (strcasecmp(all->name, name) == 0) {
242 return (all);
243 }
244 all++;
245 }
246 return (0);
247 }
248
get_code(struct ir_remote * remote,ir_code pre,ir_code code,ir_code post,ir_code * toggle_bit_mask_statep)249 struct ir_ncode *get_code(struct ir_remote *remote, ir_code pre, ir_code code, ir_code post,
250 ir_code * toggle_bit_mask_statep)
251 {
252 ir_code pre_mask, code_mask, post_mask, toggle_bit_mask_state, all;
253 int found_code, have_code;
254 struct ir_ncode *codes, *found;
255
256 pre_mask = code_mask = post_mask = 0;
257
258 if (has_toggle_bit_mask(remote)) {
259 pre_mask = remote->toggle_bit_mask >> (remote->bits + remote->post_data_bits);
260 post_mask = remote->toggle_bit_mask & gen_mask(remote->post_data_bits);
261 }
262 if (has_ignore_mask(remote)) {
263 pre_mask |= remote->ignore_mask >> (remote->bits + remote->post_data_bits);
264 post_mask |= remote->ignore_mask & gen_mask(remote->post_data_bits);
265 }
266 if (has_toggle_mask(remote) && remote->toggle_mask_state % 2) {
267 ir_code *affected, mask, mask_bit;
268 int bit, current_bit;
269
270 affected = &post;
271 mask = remote->toggle_mask;
272 for (bit = current_bit = 0; bit < bit_count(remote); bit++, current_bit++) {
273 if (bit == remote->post_data_bits) {
274 affected = &code;
275 current_bit = 0;
276 }
277 if (bit == remote->post_data_bits + remote->bits) {
278 affected = ⪯
279 current_bit = 0;
280 }
281 mask_bit = mask & 1;
282 (*affected) ^= (mask_bit << current_bit);
283 mask >>= 1;
284 }
285 }
286 if (has_pre(remote)) {
287 if ((pre | pre_mask) != (remote->pre_data | pre_mask)) {
288 LOGPRINTF(1, "bad pre data");
289 LOGPRINTF(2, "%llx %llx", pre, remote->pre_data);
290 return (0);
291 }
292 LOGPRINTF(1, "pre");
293 }
294
295 if (has_post(remote)) {
296 if ((post | post_mask) != (remote->post_data | post_mask)) {
297 LOGPRINTF(1, "bad post data");
298 LOGPRINTF(2, "%llx %llx", post, remote->post_data);
299 return (0);
300 }
301 LOGPRINTF(1, "post");
302 }
303
304 all = gen_ir_code(remote, pre, code, post);
305
306 toggle_bit_mask_state = all & remote->toggle_bit_mask;
307
308 found = NULL;
309 found_code = 0;
310 have_code = 0;
311 codes = remote->codes;
312 if (codes != NULL) {
313 while (codes->name != NULL) {
314 ir_code next_all;
315
316 next_all =
317 gen_ir_code(remote, remote->pre_data, get_ir_code(codes, codes->current),
318 remote->post_data);
319 if (match_ir_code(remote, next_all, all)) {
320 found_code = 1;
321 if (codes->next != NULL) {
322 if (codes->current == NULL) {
323 codes->current = codes->next;
324 } else {
325 codes->current = codes->current->next;
326 }
327 }
328 if (!have_code) {
329 found = codes;
330 if (codes->current == NULL) {
331 have_code = 1;
332 }
333 }
334 } else {
335 /* find longest matching sequence */
336 struct ir_code_node *search;
337
338 search = codes->next;
339 if (search == NULL || (codes->next != NULL && codes->current == NULL)) {
340 codes->current = NULL;
341 } else {
342 int sequence_match = 0;
343
344 while (search != codes->current->next) {
345 struct ir_code_node *prev, *next;
346 int flag = 1;
347
348 prev = NULL; /* means codes->code */
349 next = search;
350 while (next != codes->current) {
351 if (get_ir_code(codes, prev) != get_ir_code(codes, next)) {
352 flag = 0;
353 break;
354 }
355 prev = get_next_ir_code_node(codes, prev);
356 next = get_next_ir_code_node(codes, next);
357 }
358 if (flag == 1) {
359 next_all =
360 gen_ir_code(remote, remote->pre_data,
361 get_ir_code(codes, prev), remote->post_data);
362 if (match_ir_code(remote, next_all, all)) {
363 codes->current = get_next_ir_code_node(codes, prev);
364 sequence_match = 1;
365 found_code = 1;
366 if (!have_code) {
367 found = codes;
368 }
369 break;
370 }
371 }
372 search = search->next;
373 }
374 if (!sequence_match)
375 codes->current = NULL;
376 }
377 }
378 codes++;
379 }
380 }
381 # ifdef DYNCODES
382 if (!found_code) {
383 if (remote->dyncodes[remote->dyncode].code != code) {
384 remote->dyncode++;
385 remote->dyncode %= 2;
386 }
387 remote->dyncodes[remote->dyncode].code = code;
388 found = &(remote->dyncodes[remote->dyncode]);
389 found_code = 1;
390 }
391 # endif
392 if (found_code && found != NULL && has_toggle_mask(remote)) {
393 if (!(remote->toggle_mask_state % 2)) {
394 remote->toggle_code = found;
395 LOGPRINTF(1, "toggle_mask_start");
396 } else {
397 if (found != remote->toggle_code) {
398 remote->toggle_code = NULL;
399 return (NULL);
400 }
401 remote->toggle_code = NULL;
402 }
403 }
404 *toggle_bit_mask_statep = toggle_bit_mask_state;
405 return (found);
406 }
407
set_code(struct ir_remote * remote,struct ir_ncode * found,ir_code toggle_bit_mask_state,int repeat_flag,lirc_t min_remaining_gap,lirc_t max_remaining_gap)408 __u64 set_code(struct ir_remote * remote, struct ir_ncode * found, ir_code toggle_bit_mask_state, int repeat_flag,
409 lirc_t min_remaining_gap, lirc_t max_remaining_gap)
410 {
411 __u64 code;
412 struct timeval current;
413 static struct ir_remote *last_decoded = NULL;
414
415 LOGPRINTF(1, "found: %s", found->name);
416
417 gettimeofday(¤t, NULL);
418 LOGPRINTF(1, "%lx %lx %lx %d %d %d %d %d %d %d",
419 remote, last_remote, last_decoded,
420 remote == last_decoded,
421 found == remote->last_code, found->next != NULL, found->current != NULL, repeat_flag,
422 time_elapsed(&remote->last_send, ¤t) < 1000000, (!has_toggle_bit_mask(remote)
423 || toggle_bit_mask_state ==
424 remote->toggle_bit_mask_state));
425 if (remote->release_detected) {
426 remote->release_detected = 0;
427 if (repeat_flag) {
428 LOGPRINTF(0, "repeat indicated although release was detected before");
429 }
430 repeat_flag = 0;
431 }
432 if (remote == last_decoded &&
433 (found == remote->last_code || (found->next != NULL && found->current != NULL)) &&
434 repeat_flag && time_elapsed(&remote->last_send, ¤t) < 1000000 && (!has_toggle_bit_mask(remote)
435 || toggle_bit_mask_state ==
436 remote->toggle_bit_mask_state)) {
437 if (has_toggle_mask(remote)) {
438 remote->toggle_mask_state++;
439 if (remote->toggle_mask_state == 4) {
440 remote->reps++;
441 remote->toggle_mask_state = 2;
442 }
443 } else if (found->current == NULL) {
444 remote->reps++;
445 }
446 } else {
447 if (found->next != NULL && found->current == NULL) {
448 remote->reps = 1;
449 } else {
450 remote->reps = 0;
451 }
452 if (has_toggle_mask(remote)) {
453 remote->toggle_mask_state = 1;
454 remote->toggle_code = found;
455 }
456 if (has_toggle_bit_mask(remote)) {
457 remote->toggle_bit_mask_state = toggle_bit_mask_state;
458 }
459 }
460 last_remote = remote;
461 last_decoded = remote;
462 if (found->current == NULL)
463 remote->last_code = found;
464 remote->last_send = current;
465 remote->min_remaining_gap = min_remaining_gap;
466 remote->max_remaining_gap = max_remaining_gap;
467
468 code = 0;
469 if (has_pre(remote)) {
470 code |= remote->pre_data;
471 code = code << remote->bits;
472 }
473 code |= found->code;
474 if (has_post(remote)) {
475 code = code << remote->post_data_bits;
476 code |= remote->post_data;
477 }
478 if (remote->flags & COMPAT_REVERSE) {
479 /* actually this is wrong: pre, code and post should
480 be rotated separately but we have to stay
481 compatible with older software
482 */
483 code = reverse(code, bit_count(remote));
484 }
485 return (code);
486 }
487
write_message(char * buffer,size_t size,const char * remote_name,const char * button_name,const char * button_suffix,ir_code code,int reps)488 int write_message(char *buffer, size_t size, const char *remote_name, const char *button_name,
489 const char *button_suffix, ir_code code, int reps)
490 {
491 int len;
492
493 len = snprintf(buffer, size, "%016llx %02x %s%s %s\n", (unsigned long long)code, reps, button_name, button_suffix, remote_name);
494
495 return len;
496 }
497
decode_all(struct ir_remote * remotes)498 char *decode_all(struct ir_remote *remotes)
499 {
500 struct ir_remote *remote;
501 static char message[PACKET_SIZE + 1];
502 ir_code pre, code, post;
503 struct ir_ncode *ncode;
504 int repeat_flag;
505 ir_code toggle_bit_mask_state;
506 lirc_t min_remaining_gap, max_remaining_gap;
507 struct ir_remote *scan;
508 struct ir_ncode *scan_ncode;
509
510 /* use remotes carefully, it may be changed on SIGHUP */
511 decoding = remote = remotes;
512 while (remote) {
513 LOGPRINTF(1, "trying \"%s\" remote", remote->name);
514
515 if (hw.decode_func(remote, &pre, &code, &post, &repeat_flag, &min_remaining_gap, &max_remaining_gap)
516 && (ncode = get_code(remote, pre, code, post, &toggle_bit_mask_state))) {
517 int len;
518 int reps;
519
520 code =
521 set_code(remote, ncode, toggle_bit_mask_state, repeat_flag, min_remaining_gap,
522 max_remaining_gap);
523 if ((has_toggle_mask(remote) && remote->toggle_mask_state % 2) || ncode->current != NULL) {
524 decoding = NULL;
525 return (NULL);
526 }
527
528 for (scan = decoding; scan != NULL; scan = scan->next) {
529 for (scan_ncode = scan->codes; scan_ncode->name != NULL; scan_ncode++) {
530 scan_ncode->current = NULL;
531 }
532 }
533 if (is_xmp(remote)) {
534 remote->last_code->current = remote->last_code->next;
535 }
536 reps = remote->reps - (ncode->next ? 1 : 0);
537 if (reps > 0) {
538 if (reps <= remote->suppress_repeat) {
539 decoding = NULL;
540 return NULL;
541 } else {
542 reps -= remote->suppress_repeat;
543 }
544 }
545 register_button_press(remote, remote->last_code, code, reps);
546
547 len =
548 write_message(message, PACKET_SIZE + 1, remote->name, remote->last_code->name, "", code,
549 reps);
550 decoding = NULL;
551 if (len >= PACKET_SIZE + 1) {
552 logprintf(LOG_ERR, "message buffer overflow");
553 return (NULL);
554 } else {
555 return (message);
556 }
557 } else {
558 LOGPRINTF(1, "failed \"%s\" remote", remote->name);
559 }
560 remote->toggle_mask_state = 0;
561 remote = remote->next;
562 }
563 decoding = NULL;
564 last_remote = NULL;
565 LOGPRINTF(1, "decoding failed for all remotes");
566 return (NULL);
567 }
568
send_ir_ncode(struct ir_remote * remote,struct ir_ncode * code)569 int send_ir_ncode(struct ir_remote *remote, struct ir_ncode *code)
570 {
571 int ret;
572
573 #if !defined(SIM_SEND)
574 /* insert pause when needed: */
575 if (remote->last_code != NULL) {
576 struct timeval current;
577 unsigned long usecs;
578
579 gettimeofday(¤t, NULL);
580 usecs = time_left(¤t, &remote->last_send, remote->min_remaining_gap * 2);
581 if (usecs > 0) {
582 if (repeat_remote == NULL || remote != repeat_remote || remote->last_code != code) {
583 usleep(usecs);
584 }
585 }
586 }
587 #endif
588
589 ret = hw.send_func(remote, code);
590
591 if (ret) {
592 gettimeofday(&remote->last_send, NULL);
593 remote->last_code = code;
594 }
595
596 return ret;
597 }
598