1 /* $Id: ir_remote.c,v 5.38 2008/06/03 17:21:29 lirc Exp $ */
3 /****************************************************************************
4 ** ir_remote.c *************************************************************
5 ****************************************************************************
7 * ir_remote.c - sends and decodes the signals from IR remotes
9 * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 * Copyright (C) 1998 Christoph Bartelmus (lirc@bartelmus.de)
23 #include <sys/ioctl.h>
25 #include "drivers/lirc.h"
28 #include "ir_remote.h"
32 struct ir_remote
*decoding
=NULL
;
34 struct ir_remote
*last_remote
=NULL
;
35 struct ir_remote
*repeat_remote
=NULL
;
36 struct ir_ncode
*repeat_code
;
38 extern struct hardware hw
;
40 static int match_ir_code(struct ir_remote
*remote
, ir_code a
, ir_code b
)
42 return ((remote
->ignore_mask
|a
) == (remote
->ignore_mask
|b
) ||
43 (remote
->ignore_mask
|a
) ==
44 (remote
->ignore_mask
|(b
^remote
->toggle_bit_mask
)));
47 void get_frequency_range(struct ir_remote
*remotes
,
48 unsigned int *min_freq
,unsigned int *max_freq
)
50 struct ir_remote
*scan
;
52 /* use remotes carefully, it may be changed on SIGHUP */
56 *min_freq
=DEFAULT_FREQ
;
57 *max_freq
=DEFAULT_FREQ
;
69 if(scan
->freq
>*max_freq
)
73 else if(scan
->freq
<*min_freq
)
82 struct ir_remote
*is_in_remotes(struct ir_remote
*remotes
,
83 struct ir_remote
*remote
)
85 while(remotes
!= NULL
)
91 remotes
= remotes
->next
;
96 struct ir_remote
*get_ir_remote(struct ir_remote
*remotes
,char *name
)
98 struct ir_remote
*all
;
100 /* use remotes carefully, it may be changed on SIGHUP */
104 if(strcasecmp(all
->name
,name
)==0)
113 int map_code(struct ir_remote
*remote
,
114 ir_code
*prep
,ir_code
*codep
,ir_code
*postp
,
115 int pre_bits
,ir_code pre
,
116 int bits
,ir_code code
,
117 int post_bits
,ir_code post
)
121 if(pre_bits
+bits
+post_bits
!=
122 remote
->pre_data_bits
+remote
->bits
+remote
->post_data_bits
)
126 all
=(pre
&gen_mask(pre_bits
));
128 all
|=(code
&gen_mask(bits
));
130 all
|=(post
&gen_mask(post_bits
));
132 *postp
=(all
&gen_mask(remote
->post_data_bits
));
133 all
>>=remote
->post_data_bits
;
134 *codep
=(all
&gen_mask(remote
->bits
));
136 *prep
=(all
&gen_mask(remote
->pre_data_bits
));
138 LOGPRINTF(1,"pre: %llx", (unsigned long long) *prep
);
139 LOGPRINTF(1,"code: %llx", (unsigned long long) *codep
);
140 LOGPRINTF(1,"post: %llx", (unsigned long long) *postp
);
141 LOGPRINTF(1, "code: %016llx\n", code
);
146 void map_gap(struct ir_remote
*remote
,
147 struct timeval
*start
, struct timeval
*last
,
148 lirc_t signal_length
,
150 lirc_t
*min_remaining_gapp
,
151 lirc_t
*max_remaining_gapp
)
153 // Time gap (us) between a keypress on the remote control and
157 // Check the time gap between the last keypress and this one.
158 if (start
->tv_sec
- last
->tv_sec
>= 2) {
159 // Gap of 2 or more seconds: this is not a repeated keypress.
163 // Calculate the time gap in microseconds.
164 gap
= time_elapsed(last
, start
);
165 if(expect_at_most(remote
, gap
, remote
->max_remaining_gap
))
167 // The gap is shorter than a standard gap
168 // (with relative or aboslute tolerance): this
169 // is a repeated keypress.
174 // Standard gap: this is a new keypress.
179 // Calculate extimated time gap remaining for the next code.
180 if (is_const(remote
)) {
181 // The sum (signal_length + gap) is always constant
182 // so the gap is shorter when the code is longer.
183 if (min_gap(remote
) > signal_length
) {
184 *min_remaining_gapp
= min_gap(remote
) - signal_length
;
185 *max_remaining_gapp
= max_gap(remote
) - signal_length
;
187 *min_remaining_gapp
= 0;
188 if(max_gap(remote
) > signal_length
)
190 *max_remaining_gapp
= max_gap(remote
) - signal_length
;
194 *max_remaining_gapp
= 0;
198 // The gap after the signal is always constant.
199 // This is the case of Kanam Accent serial remote.
200 *min_remaining_gapp
= min_gap(remote
);
201 *max_remaining_gapp
= max_gap(remote
);
204 LOGPRINTF(1, "repeat_flagp: %d", *repeat_flagp
);
205 LOGPRINTF(1, "is_const(remote): %d", is_const(remote
));
206 LOGPRINTF(1, "remote->gap range: %lu %lu",
207 (unsigned long) min_gap(remote
),
208 (unsigned long) max_gap(remote
));
209 LOGPRINTF(1, "remote->remaining_gap: %lu %lu",
210 (unsigned long) remote
->min_remaining_gap
,
211 (unsigned long) remote
->max_remaining_gap
);
212 LOGPRINTF(1, "signal length: %lu",
213 (unsigned long) signal_length
);
214 LOGPRINTF(1, "gap: %lu",
215 (unsigned long) gap
);
216 LOGPRINTF(1, "extim. remaining_gap: %lu %lu",
217 (unsigned long) *min_remaining_gapp
,
218 (unsigned long) *max_remaining_gapp
);
222 struct ir_ncode
*get_code_by_name(struct ir_remote
*remote
,char *name
)
224 struct ir_ncode
*all
;
227 while(all
->name
!=NULL
)
229 if(strcasecmp(all
->name
,name
)==0)
238 struct ir_ncode
*get_code(struct ir_remote
*remote
,
239 ir_code pre
,ir_code code
,ir_code post
,
240 ir_code
*toggle_bit_mask_statep
)
242 ir_code pre_mask
,code_mask
,post_mask
,toggle_bit_mask_state
,all
;
243 int found_code
, have_code
;
244 struct ir_ncode
*codes
,*found
;
246 pre_mask
=code_mask
=post_mask
=0;
248 if(has_toggle_bit_mask(remote
))
250 pre_mask
= remote
->toggle_bit_mask
>>
251 (remote
->bits
+ remote
->post_data_bits
);
252 post_mask
= remote
->toggle_bit_mask
&
253 gen_mask(remote
->post_data_bits
);
255 if(has_ignore_mask(remote
))
257 pre_mask
|= remote
->ignore_mask
>>
258 (remote
->bits
+ remote
->post_data_bits
);
259 post_mask
|= remote
->ignore_mask
&
260 gen_mask(remote
->post_data_bits
);
262 if(has_toggle_mask(remote
) && remote
->toggle_mask_state
%2)
264 ir_code
*affected
,mask
,mask_bit
;
268 mask
=remote
->toggle_mask
;
269 for(bit
=current_bit
=0;bit
<bit_count(remote
);bit
++,current_bit
++)
271 if(bit
==remote
->post_data_bits
)
276 if(bit
==remote
->post_data_bits
+remote
->bits
)
282 (*affected
)^=(mask_bit
<<current_bit
);
288 if((pre
|pre_mask
)!=(remote
->pre_data
|pre_mask
))
290 LOGPRINTF(1,"bad pre data");
292 LOGPRINTF(2,"%llx %llx",pre
,remote
->pre_data
);
294 LOGPRINTF(2,"%lx %lx",pre
,remote
->pre_data
);
303 if((post
|post_mask
)!=(remote
->post_data
|post_mask
))
305 LOGPRINTF(1,"bad post data");
307 LOGPRINTF(2,"%llx %llx",post
,remote
->post_data
);
309 LOGPRINTF(2,"%lx %lx",post
,remote
->post_data
);
316 all
= gen_ir_code(remote
, pre
, code
, post
);
318 toggle_bit_mask_state
= all
&remote
->toggle_bit_mask
;
326 while(codes
->name
!=NULL
)
330 next_all
= gen_ir_code(remote
, remote
->pre_data
,
331 get_ir_code(codes
, codes
->current
),
333 if(match_ir_code(remote
, next_all
, all
))
336 if(codes
->next
!=NULL
)
338 if(codes
->current
==NULL
)
340 codes
->current
=codes
->next
;
345 codes
->current
->next
;
351 if(codes
->current
==NULL
)
359 /* find longest matching sequence */
360 struct ir_code_node
*search
;
362 search
= codes
->next
;
364 (codes
->next
!= NULL
&& codes
->current
== NULL
))
370 int sequence_match
= 0;
372 while(search
!= codes
->current
->next
)
374 struct ir_code_node
*prev
, *next
;
377 prev
= NULL
; /* means codes->code */
379 while(next
!= codes
->current
)
381 if(get_ir_code(codes
, prev
) != get_ir_code(codes
, next
))
386 prev
= get_next_ir_code_node(codes
, prev
);
387 next
= get_next_ir_code_node(codes
, next
);
391 next_all
= gen_ir_code(remote
, remote
->pre_data
,
392 get_ir_code(codes
, prev
),
394 if(match_ir_code(remote
, next_all
, all
))
396 codes
->current
= get_next_ir_code_node(codes
, prev
);
401 search
= search
->next
;
403 if(!sequence_match
) codes
->current
= NULL
;
412 if(remote
->dyncodes
[remote
->dyncode
].code
!=code
)
417 remote
->dyncodes
[remote
->dyncode
].code
=code
;
418 found
=&(remote
->dyncodes
[remote
->dyncode
]);
422 if(found_code
&& found
!=NULL
&& has_toggle_mask(remote
))
424 if(!(remote
->toggle_mask_state
%2))
426 remote
->toggle_code
=found
;
427 LOGPRINTF(1,"toggle_mask_start");
431 if(found
!=remote
->toggle_code
)
433 remote
->toggle_code
=NULL
;
436 remote
->toggle_code
=NULL
;
439 *toggle_bit_mask_statep
=toggle_bit_mask_state
;
443 unsigned long long set_code(struct ir_remote
*remote
,struct ir_ncode
*found
,
444 ir_code toggle_bit_mask_state
,int repeat_flag
,
445 lirc_t min_remaining_gap
, lirc_t max_remaining_gap
)
447 unsigned long long code
;
448 struct timeval current
;
450 LOGPRINTF(1,"found: %s",found
->name
);
452 gettimeofday(¤t
,NULL
);
453 if(remote
==last_remote
&&
454 (found
==remote
->last_code
|| (found
->next
!=NULL
&& found
->current
!=NULL
)) &&
456 time_elapsed(&remote
->last_send
,¤t
)<1000000 &&
457 (!has_toggle_bit_mask(remote
) || toggle_bit_mask_state
==remote
->toggle_bit_mask_state
))
459 if(has_toggle_mask(remote
))
461 remote
->toggle_mask_state
++;
462 if(remote
->toggle_mask_state
==4)
465 remote
->toggle_mask_state
=2;
468 else if(found
->current
==NULL
)
475 if(found
->next
!=NULL
&& found
->current
==NULL
)
483 if(has_toggle_mask(remote
))
485 remote
->toggle_mask_state
=1;
486 remote
->toggle_code
=found
;
488 if(has_toggle_bit_mask(remote
))
490 remote
->toggle_bit_mask_state
=toggle_bit_mask_state
;
494 if(found
->current
==NULL
) remote
->last_code
=found
;
495 remote
->last_send
=current
;
496 remote
->min_remaining_gap
=min_remaining_gap
;
497 remote
->max_remaining_gap
=max_remaining_gap
;
502 code
|=remote
->pre_data
;
503 code
=code
<<remote
->bits
;
508 code
=code
<<remote
->post_data_bits
;
509 code
|=remote
->post_data
;
511 if(remote
->flags
&COMPAT_REVERSE
)
513 /* actually this is wrong: pre, code and post should
514 be rotated separately but we have to stay
515 compatible with older software
517 code
=reverse(code
,bit_count(remote
));
522 int write_message(char *buffer
, size_t size
, const char *remote_name
,
523 const char *button_name
, const char *button_suffix
,
524 ir_code code
, int reps
)
529 /* It seems you can't print 64-bit longs on glibc */
531 len
=snprintf(buffer
, size
,"%08lx%08lx %02x %s%s %s\n",
532 (unsigned long) (code
>>32),
533 (unsigned long) (code
&0xFFFFFFFF),
535 button_name
, button_suffix
,
538 len
=snprintf(buffer
, size
, "%016llx %02x %s%s %s\n",
541 button_name
, button_suffix
,
547 char *decode_all(struct ir_remote
*remotes
)
549 struct ir_remote
*remote
;
550 static char message
[PACKET_SIZE
+1];
551 ir_code pre
,code
,post
;
552 struct ir_ncode
*ncode
;
554 ir_code toggle_bit_mask_state
;
555 lirc_t min_remaining_gap
, max_remaining_gap
;
556 struct ir_remote
*scan
;
557 struct ir_ncode
*scan_ncode
;
559 /* use remotes carefully, it may be changed on SIGHUP */
560 decoding
=remote
=remotes
;
563 LOGPRINTF(1,"trying \"%s\" remote",remote
->name
);
565 if(hw
.decode_func(remote
,&pre
,&code
,&post
,&repeat_flag
,
566 &min_remaining_gap
, &max_remaining_gap
) &&
567 (ncode
=get_code(remote
,pre
,code
,post
,&toggle_bit_mask_state
)))
571 code
=set_code(remote
,ncode
,toggle_bit_mask_state
,
575 if((has_toggle_mask(remote
) &&
576 remote
->toggle_mask_state
%2) ||
577 ncode
->current
!=NULL
)
583 for(scan
= decoding
; scan
!= NULL
; scan
= scan
->next
)
585 for( scan_ncode
= scan
->codes
; scan_ncode
->name
!= NULL
; scan_ncode
++)
587 scan_ncode
->current
= NULL
;
590 register_button_press
591 (remote
, remote
->last_code
,
592 code
, remote
->reps
-(ncode
->next
? 1:0));
594 len
= write_message(message
, PACKET_SIZE
+1,
596 remote
->last_code
->name
, "", code
,
597 remote
->reps
-(ncode
->next
? 1:0));
599 if(len
>=PACKET_SIZE
+1)
601 logprintf(LOG_ERR
,"message buffer overflow");
611 LOGPRINTF(1,"failed \"%s\" remote",remote
->name
);
613 remote
->toggle_mask_state
=0;
618 LOGPRINTF(1,"decoding failed for all remotes");
622 int send_ir_ncode(struct ir_remote
*remote
,struct ir_ncode
*code
)
626 ret
= hw
.send_func(remote
, code
);
630 gettimeofday(&remote
->last_send
, NULL
);
631 remote
->last_code
= code
;