LIRC libraries LinuxInfraredRemoteControl

- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Examples

- File List
- Globals

config_file.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** config_file.c ***********************************************************
3 ****************************************************************************
4 *
5 *
6 * Copyright (C) 1998 Pablo d'Angelo <pablo@ag-trek.allgaeu.org>
7 *
8 */
9
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20
21 #include <dirent.h>
22 #include <errno.h>
23 #include <glob.h>
24 #include <limits.h>
25 #include <unistd.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <libgen.h>
30 #include <sys/socket.h>
31 #include <sys/un.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <fcntl.h>
35 #include <ctype.h>
36
37 #include "include/media/lirc.h"
38 #include "lirc/lirc_log.h"
39 #include "lirc/lirc_options.h"
40 #include "lirc/ir_remote.h"
41 #include "lirc/config_file.h"
42 #include "lirc/transmit.h"
43 #include "lirc/config_flags.h"
44
45
46 enum directive { ID_none, ID_remote, ID_codes, ID_raw_codes, ID_raw_name };
47
48 struct ptr_array {
49 void** ptr;
50 size_t nr_items;
51 size_t chunk_size;
52 };
53
54 struct void_array {
55 void* ptr;
56 size_t item_size;
57 size_t nr_items;
58 size_t chunk_size;
59 };
60
61
63 typedef void* (*array_guest_func)(void* item, void* arg);
64
65
66 #define LINE_LEN 1024
67 #define MAX_INCLUDES 10
68
69 const char* whitespace = " \t";
70
71 static int line;
72 static int parse_error;
73
74 static struct ir_remote* read_config_recursive(FILE* f, const char* name, int depth);
75 static void calculate_signal_lengths(struct ir_remote* remote);
76
77 void** init_void_array(struct void_array* ar, size_t chunk_size, size_t item_size)
78 {
79 ar->chunk_size = chunk_size;
80 ar->item_size = item_size;
81 ar->nr_items = 0;
82 ar->ptr = calloc(chunk_size, ar->item_size);
83 if (!ar->ptr) {
84 logprintf(LIRC_ERROR, "out of memory");
85 parse_error = 1;
86 return NULL;
87 }
88 return ar->ptr;
89 }
90
91 const struct flaglist all_flags[] = {
92 { "RAW_CODES", RAW_CODES },
93 { "RC5", RC5 },
94 { "SHIFT_ENC", SHIFT_ENC }, /* obsolete */
95 { "RC6", RC6 },
96 { "RCMM", RCMM },
97 { "SPACE_ENC", SPACE_ENC },
98 { "SPACE_FIRST", SPACE_FIRST },
99 { "GOLDSTAR", GOLDSTAR },
100 { "GRUNDIG", GRUNDIG },
101 { "BO", BO },
102 { "SERIAL", SERIAL },
103 { "XMP", XMP },
104
105 { "REVERSE", REVERSE },
106 { "NO_HEAD_REP", NO_HEAD_REP },
107 { "NO_FOOT_REP", NO_FOOT_REP },
108 { "CONST_LENGTH", CONST_LENGTH }, /* remember to adapt warning
109 * message when changing this */
110 { "REPEAT_HEADER", REPEAT_HEADER },
111 { NULL, 0 },
112 };
113
114
116 int add_void_array(struct void_array* ar, void* dataptr)
117 {
118 void* ptr;
119
120 if ((ar->nr_items % ar->chunk_size) == (ar->chunk_size) - 1) {
121 /* I hope this works with the right alignment,
122 * if not we're screwed */
123 ptr = realloc(ar->ptr,
124 ar->item_size *
125 (ar->nr_items + ar->chunk_size + 1));
126 if (!ptr) {
127 logprintf(LIRC_ERROR, "out of memory");
128 parse_error = 1;
129 return 0;
130 }
131 ar->ptr = ptr;
132 }
133 memcpy((ar->ptr) + (ar->item_size * ar->nr_items), dataptr, ar->item_size);
134 ar->nr_items = (ar->nr_items) + 1;
135 memset((ar->ptr) + (ar->item_size * ar->nr_items), 0, ar->item_size);
136 return 1;
137 }
138
139
141 void* get_void_array(struct void_array* ar)
142 {
143 return ar->ptr;
144 }
145
146
151 static void*
152 foreach_void_array(struct void_array* ar, array_guest_func func, void* arg)
153 {
154 void* r;
155 int i;
156
157 for (i = 0; i < ar->nr_items; i += 1) {
158 r = func(ar->ptr + (i * ar->item_size), arg);
159 if (r != NULL)
160 return r;
161 }
162 return NULL;
163 }
164
165
166 static int
167 ir_code_node_equals(struct ir_code_node* node1, struct ir_code_node* node2)
168 {
169 if (node1 == NULL || node2 == NULL)
170 return node1 == node2;
171 return node1->code == node2->code;
172 }
173
174
179 static void* array_guest_code_equals(void* arg1, void* arg2)
180 {
181
182 struct ir_ncode* code1 = (struct ir_ncode*) arg1;
183 struct ir_ncode* code2 = (struct ir_ncode*) arg2;
184 struct ir_code_node* next1;
185 struct ir_code_node* next2;
186
187 if (code1 == NULL || code2 == NULL)
188 return code1 == code2 ? arg1 : NULL;
189 if (code1->code != code2->code)
190 return NULL;
191 next1 = code1->next;
192 next2 = code2->next;
193 while (code1->next != NULL) {
194 if (!ir_code_node_equals(next1, next2))
195 return NULL;
196 next1 = code1->next;
197 next2 = code2->next;
198 }
199 return arg1;
200 }
201
202
207 static void* array_guest_ncode_cmp(void* item, void* arg)
208 {
209
210 struct ir_ncode* code1 = (struct ir_ncode*) item;
211 struct ir_ncode* code2 = (struct ir_ncode*) arg;
212
213 if (strcmp(code1->name, code2->name) == 0)
214 return item;
215 return NULL;
216 }
217
218
219 void* s_malloc(size_t size)
220 {
221 void* ptr;
222
223 ptr = malloc(size);
224 if (ptr == NULL) {
225 logprintf(LIRC_ERROR, "out of memory");
226 parse_error = 1;
227 return NULL;
228 }
229 memset(ptr, 0, size);
230 return ptr;
231 }
232
233 char* s_strdup(char* string)
234 {
235 char* ptr;
236
237 ptr = strdup(string);
238 if (!ptr) {
239 logprintf(LIRC_ERROR, "out of memory");
240 parse_error = 1;
241 return NULL;
242 }
243 return ptr;
244 }
245
246 ir_code s_strtocode(const char* val)
247 {
248 ir_code code = 0;
249 char* endptr;
250
251 errno = 0;
252 code = strtoull(val, &endptr, 0);
253 if ((code == (__u64) -1 && errno == ERANGE) || strlen(endptr) != 0 || strlen(val) == 0) {
254 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
255 logprintf(LIRC_ERROR, "\"%s\": must be a valid (__u64) number", val);
256 parse_error = 1;
257 return 0;
258 }
259 return code;
260 }
261
262 __u32 s_strtou32(char* val)
263 {
264 __u32 n;
265 char* endptr;
266
267 n = strtoul(val, &endptr, 0);
268 if (!*val || *endptr) {
269 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
270 logprintf(LIRC_ERROR, "\"%s\": must be a valid (__u32) number", val);
271 parse_error = 1;
272 return 0;
273 }
274 return n;
275 }
276
277 int s_strtoi(char* val)
278 {
279 char* endptr;
280 long n;
281 int h;
282
283 n = strtol(val, &endptr, 0);
284 h = (int)n;
285 if (!*val || *endptr || n != ((long)h)) {
286 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
287 logprintf(LIRC_ERROR, "\"%s\": must be a valid (int) number", val);
288 parse_error = 1;
289 return 0;
290 }
291 return h;
292 }
293
294 unsigned int s_strtoui(char* val)
295 {
296 char* endptr;
297 __u32 n;
298 unsigned int h;
299
300 n = strtoul(val, &endptr, 0);
301 h = (unsigned int)n;
302 if (!*val || *endptr || n != ((__u32)h)) {
303 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
304 logprintf(LIRC_ERROR, "\"%s\": must be a valid (unsigned int) number", val);
305 parse_error = 1;
306 return 0;
307 }
308 return h;
309 }
310
311 lirc_t s_strtolirc_t(char* val)
312 {
313 __u32 n;
314 lirc_t h;
315 char* endptr;
316
317 n = strtoul(val, &endptr, 0);
318 h = (lirc_t)n;
319 if (!*val || *endptr || n != ((__u32)h)) {
320 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
321 logprintf(LIRC_ERROR, "\"%s\": must be a valid (lirc_t) number", val);
322 parse_error = 1;
323 return 0;
324 }
325 if (h < 0) {
326 logprintf(LIRC_WARNING, "error in configfile line %d:", line);
327 logprintf(LIRC_WARNING, "\"%s\" is out of range", val);
328 }
329 return h;
330 }
331
332 int checkMode(int is_mode, int c_mode, char* error)
333 {
334 if (is_mode != c_mode) {
335 logprintf(LIRC_ERROR, "fatal error in configfile line %d:", line);
336 logprintf(LIRC_ERROR, "\"%s\" isn't valid at this position", error);
337 parse_error = 1;
338 return 0;
339 }
340 return 1;
341 }
342
343 int addSignal(struct void_array* signals, char* val)
344 {
345 unsigned int t;
346
347 t = s_strtoui(val);
348 if (parse_error)
349 return 0;
350 if (!add_void_array(signals, &t))
351 return 0;
352
353 return 1;
354 }
355
356 struct ir_ncode* defineCode(char* key, char* val, struct ir_ncode* code)
357 {
358 memset(code, 0, sizeof(*code));
359 code->name = s_strdup(key);
360 code->code = s_strtocode(val);
361 LOGPRINTF(3, " %-20s 0x%016llX", code->name, code->code);
362 return code;
363 }
364
365 struct ir_code_node* defineNode(struct ir_ncode* code, const char* val)
366 {
367 struct ir_code_node* node;
368
369 node = s_malloc(sizeof(*node));
370 if (node == NULL)
371 return NULL;
372
373 node->code = s_strtocode(val);
374 node->next = NULL;
375
376 LOGPRINTF(3, " 0x%016llX", node->code);
377
378 if (code->current == NULL) {
379 code->next = node;
380 code->current = node;
381 } else {
382 code->current->next = node;
383 code->current = node;
384 }
385 return node;
386 }
387
388 int parseFlags(char* val)
389 {
390 const struct flaglist* flaglptr;
391 int flags = 0;
392 char* flag;
393 char* help;
394
395 flag = help = val;
396 while (flag != NULL) {
397 while (*help != '|' && *help != 0)
398 help++;
399 if (*help == '|') {
400 *help = 0;
401 help++;
402 } else {
403 help = NULL;
404 }
405
406 flaglptr = all_flags;
407 while (flaglptr->name != NULL) {
408 if (strcasecmp(flaglptr->name, flag) == 0) {
409 if (flaglptr->flag & IR_PROTOCOL_MASK && flags & IR_PROTOCOL_MASK) {
410 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
411 logprintf(LIRC_ERROR, "multiple protocols given in flags: \"%s\"", flag);
412 parse_error = 1;
413 return 0;
414 }
415 flags = flags | flaglptr->flag;
416 LOGPRINTF(3, "flag %s recognized", flaglptr->name);
417 break;
418 }
419 flaglptr++;
420 }
421 if (flaglptr->name == NULL) {
422 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
423 logprintf(LIRC_ERROR, "unknown flag: \"%s\"", flag);
424 parse_error = 1;
425 return 0;
426 }
427 flag = help;
428 }
429 LOGPRINTF(2, "flags value: %d", flags);
430
431 return flags;
432 }
433
434 int defineRemote(char* key, char* val, char* val2, struct ir_remote* rem)
435 {
436 if ((strcasecmp("name", key)) == 0) {
437 if (rem->name != NULL)
438 free((void*)(rem->name));
439 rem->name = s_strdup(val);
440 logprintf(LIRC_INFO, "Using remote: %s.", val);
441 return 1;
442 }
443 if (options_getboolean("lircd:dynamic-codes")) {
444 if ((strcasecmp("dyncodes_name", key)) == 0) {
445 if (rem->dyncodes_name != NULL)
446 free(rem->dyncodes_name);
447 rem->dyncodes_name = s_strdup(val);
448 return 1;
449 }
450 } else if (strcasecmp("driver", key) == 0) {
451 if (rem->driver != NULL)
452 free((void*)(rem->driver));
453 rem->driver = s_strdup(val);
454 return 1;
455 } else if ((strcasecmp("bits", key)) == 0) {
456 rem->bits = s_strtoi(val);
457 return 1;
458 } else if (strcasecmp("flags", key) == 0) {
459 rem->flags |= parseFlags(val);
460 return 1;
461 } else if (strcasecmp("eps", key) == 0) {
462 rem->eps = s_strtoi(val);
463 return 1;
464 } else if (strcasecmp("aeps", key) == 0) {
465 rem->aeps = s_strtoi(val);
466 return 1;
467 } else if (strcasecmp("plead", key) == 0) {
468 rem->plead = s_strtolirc_t(val);
469 return 1;
470 } else if (strcasecmp("ptrail", key) == 0) {
471 rem->ptrail = s_strtolirc_t(val);
472 return 1;
473 } else if (strcasecmp("pre_data_bits", key) == 0) {
474 rem->pre_data_bits = s_strtoi(val);
475 return 1;
476 } else if (strcasecmp("pre_data", key) == 0) {
477 rem->pre_data = s_strtocode(val);
478 return 1;
479 } else if (strcasecmp("post_data_bits", key) == 0) {
480 rem->post_data_bits = s_strtoi(val);
481 return 1;
482 } else if (strcasecmp("post_data", key) == 0) {
483 rem->post_data = s_strtocode(val);
484 return 1;
485 } else if (strcasecmp("gap", key) == 0) {
486 if (val2 != NULL)
487 rem->gap2 = s_strtou32(val2);
488 rem->gap = s_strtou32(val);
489 return val2 != NULL ? 2 : 1;
490 } else if (strcasecmp("repeat_gap", key) == 0) {
491 rem->repeat_gap = s_strtou32(val);
492 return 1;
493 } else if (strcasecmp("repeat_mask", key) == 0) {
494 rem->repeat_mask = s_strtocode(val);
495 return 1;
496 }
497 /* obsolete: use toggle_bit_mask instead */
498 else if (strcasecmp("toggle_bit", key) == 0) {
499 rem->toggle_bit = s_strtoi(val);
500 return 1;
501 } else if (strcasecmp("toggle_bit_mask", key) == 0) {
502 rem->toggle_bit_mask = s_strtocode(val);
503 return 1;
504 } else if (strcasecmp("toggle_mask", key) == 0) {
505 rem->toggle_mask = s_strtocode(val);
506 return 1;
507 } else if (strcasecmp("rc6_mask", key) == 0) {
508 rem->rc6_mask = s_strtocode(val);
509 return 1;
510 } else if (strcasecmp("ignore_mask", key) == 0) {
511 rem->ignore_mask = s_strtocode(val);
512 return 1;
513 } else if (strcasecmp("manual_sort", key) == 0) {
514 rem->manual_sort = s_strtoi(val);
515 return 1;
516 }
517 /* obsolete name */
518 else if (strcasecmp("repeat_bit", key) == 0) {
519 rem->toggle_bit = s_strtoi(val);
520 return 1;
521 } else if (strcasecmp("suppress_repeat", key) == 0) {
522 rem->suppress_repeat = s_strtoi(val);
523 return 1;
524 } else if (strcasecmp("min_repeat", key) == 0) {
525 rem->min_repeat = s_strtoi(val);
526 return 1;
527 } else if (strcasecmp("min_code_repeat", key) == 0) {
528 rem->min_code_repeat = s_strtoi(val);
529 return 1;
530 } else if (strcasecmp("frequency", key) == 0) {
531 rem->freq = s_strtoui(val);
532 return 1;
533 } else if (strcasecmp("duty_cycle", key) == 0) {
534 rem->duty_cycle = s_strtoui(val);
535 return 1;
536 } else if (strcasecmp("baud", key) == 0) {
537 rem->baud = s_strtoui(val);
538 return 1;
539 } else if (strcasecmp("serial_mode", key) == 0) {
540 if (val[0] < '5' || val[0] > '9') {
541 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
542 logprintf(LIRC_ERROR, "bad bit count");
543 parse_error = 1;
544 return 0;
545 }
546 rem->bits_in_byte = val[0] - '0';
547 switch (toupper(val[1])) {
548 case 'N':
549 rem->parity = IR_PARITY_NONE;
550 break;
551 case 'E':
552 rem->parity = IR_PARITY_EVEN;
553 break;
554 case 'O':
555 rem->parity = IR_PARITY_ODD;
556 break;
557 default:
558 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
559 logprintf(LIRC_ERROR, "unsupported parity mode");
560 parse_error = 1;
561 return 0;
562 }
563 if (strcmp(val + 2, "1.5") == 0)
564 rem->stop_bits = 3;
565 else
566 rem->stop_bits = s_strtoui(val + 2) * 2;
567 return 1;
568 } else if (val2 != NULL) {
569 if (strcasecmp("header", key) == 0) {
570 rem->phead = s_strtolirc_t(val);
571 rem->shead = s_strtolirc_t(val2);
572 return 2;
573 } else if (strcasecmp("three", key) == 0) {
574 rem->pthree = s_strtolirc_t(val);
575 rem->sthree = s_strtolirc_t(val2);
576 return 2;
577 } else if (strcasecmp("two", key) == 0) {
578 rem->ptwo = s_strtolirc_t(val);
579 rem->stwo = s_strtolirc_t(val2);
580 return 2;
581 } else if (strcasecmp("one", key) == 0) {
582 rem->pone = s_strtolirc_t(val);
583 rem->sone = s_strtolirc_t(val2);
584 return 2;
585 } else if (strcasecmp("zero", key) == 0) {
586 rem->pzero = s_strtolirc_t(val);
587 rem->szero = s_strtolirc_t(val2);
588 return 2;
589 } else if (strcasecmp("foot", key) == 0) {
590 rem->pfoot = s_strtolirc_t(val);
591 rem->sfoot = s_strtolirc_t(val2);
592 return 2;
593 } else if (strcasecmp("repeat", key) == 0) {
594 rem->prepeat = s_strtolirc_t(val);
595 rem->srepeat = s_strtolirc_t(val2);
596 return 2;
597 } else if (strcasecmp("pre", key) == 0) {
598 rem->pre_p = s_strtolirc_t(val);
599 rem->pre_s = s_strtolirc_t(val2);
600 return 2;
601 } else if (strcasecmp("post", key) == 0) {
602 rem->post_p = s_strtolirc_t(val);
603 rem->post_s = s_strtolirc_t(val2);
604 return 2;
605 }
606 }
607 if (val2) {
608 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
609 logprintf(LIRC_ERROR, "unknown definiton: \"%s %s %s\"", key, val, val2);
610 } else {
611 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
612 logprintf(LIRC_ERROR, "unknown definiton or too few arguments: \"%s %s\"", key, val);
613 }
614 parse_error = 1;
615 return 0;
616 }
617
618 static int sanityChecks(struct ir_remote* rem, const char* path)
619 {
620 struct ir_ncode* codes;
621 struct ir_code_node* node;
622
623 path = path != NULL ? path : "unknown file";
624
625 if (!rem->name) {
626 logprintf(LIRC_ERROR,
627 "%s: %s: Missing remote name", path, rem);
628 return 0;
629 }
630 if (rem->gap == 0) {
631 logprintf(LIRC_WARNING, "%s: %s: Gap value missing or invalid",
632 path, rem->name);
633 }
634 if (has_repeat_gap(rem) && is_const(rem)) {
635 logprintf(LIRC_WARNING,
636 "%s: %s: Repeat_gap ignored (CONST_LENGTH is set)",
637 path, rem->name);
638 }
639
640 if (is_raw(rem))
641 return 1;
642
643 if ((rem->pre_data & gen_mask(rem->pre_data_bits)) != rem->pre_data) {
644 logprintf(LIRC_WARNING,
645 "%s: %s: Invalid pre_data", path, rem->name);
646 rem->pre_data &= gen_mask(rem->pre_data_bits);
647 }
648 if ((rem->post_data & gen_mask(rem->post_data_bits)) != rem->post_data) {
649 logprintf(LIRC_WARNING, "%s: %s: Invalid post_data",
650 path, rem->name);
651 rem->post_data &= gen_mask(rem->post_data_bits);
652 }
653 for (codes = rem->codes; codes->name != NULL; codes++) {
654 if ((codes->code & gen_mask(rem->bits)) != codes->code) {
655 logprintf(LIRC_WARNING, "%s: %s: Invalid code : %s",
656 path, rem->name, codes->name);
657 codes->code &= gen_mask(rem->bits);
658 }
659 for (node = codes->next; node != NULL; node = node->next) {
660 if ((node->code & gen_mask(rem->bits)) != node->code) {
661 logprintf(LIRC_WARNING, "%s: %s: Invalid code %s: %s",
662 path, rem->name, codes->name);
663 node->code &= gen_mask(rem->bits);
664 }
665 }
666 }
667 return 1;
668 }
669
676 static int remote_bits_cmp(struct ir_remote* r1, struct ir_remote* r2)
677 {
678 int r1_size;
679 int r2_size;
680 struct ir_ncode* c;
681
682 int r1_is_raw = is_raw(r1);
683 int r2_is_raw = is_raw(r2);
684
685 if (!r1_is_raw && r2_is_raw)
686 return -1;
687 if (r1_is_raw && !r2_is_raw)
688 return 1;
689
690 if (r1_is_raw && r2_is_raw) {
691 for (c = r1->codes, r1_size = 0; c->name != NULL; c++)
692 r1_size += 1;
693 for (c = r2->codes, r2_size = 0; c->name != NULL; c++)
694 r2_size += 1;
695 } else {
696 r1_size = bit_count(r1);
697 r2_size = bit_count(r2);
698 }
699 if (r1_size == r2_size)
700 return 0;
701 return r1_size < r2_size ? -1 : 1;
702 }
703
704
709 static struct ir_remote* sort_by_bit_count(struct ir_remote* remotes)
710 {
711 struct ir_remote* top;
712 struct ir_remote* rem;
713 struct ir_remote* next;
714 struct ir_remote* prev;
715 struct ir_remote* scan;
716 struct ir_remote* r;
717
718 for (r = remotes; r != NULL && r != (void*)-1; r = r->next)
719 if (r->manual_sort)
720 return remotes;
721 rem = remotes;
722 top = NULL;
723 while (rem != NULL && rem != (void*)-1) {
724 next = rem->next;
725
726 scan = top;
727 prev = NULL;
728 while (scan && remote_bits_cmp(scan, rem) <= 0) {
729 prev = scan;
730 scan = scan->next;
731 }
732 if (prev)
733 prev->next = rem;
734 else
735 top = rem;
736 if (scan)
737 rem->next = scan;
738 else
739 rem->next = NULL;
740
741 rem = next;
742 }
743
744 return top;
745 }
746
747 static const char* lirc_parse_include(char* s)
748 {
749 char* last;
750 size_t len;
751
752 len = strlen(s);
753 if (len < 2)
754 return NULL;
755 last = s + len - 1;
756 while (last > s && strchr(whitespace, *last) != NULL)
757 last--;
758 if (last <= s)
759 return NULL;
760 if (*s != '"' && *s != '<')
761 return NULL;
762 if (*s == '"' && *last != '"')
763 return NULL;
764 else if (*s == '<' && *last != '>')
765 return NULL;
766 *last = 0;
767 memmove(s, s + 1, len - 2 + 1); /* terminating 0 is copied, and
768 * maybe more, but we don't care */
769 return s;
770 }
771
772
774 static const char* lirc_parse_relative(char* dst,
775 size_t dst_size,
776 const char* child,
777 const char* current)
778 {
779 char* dir;
780 size_t dirlen;
781
782 if (!current)
783 return child;
784
785 /* Not a relative path */
786 if (*child == '/')
787 return child;
788
789 if (strlen(current) >= dst_size)
790 return NULL;
791 strcpy(dst, current);
792 dir = dirname(dst);
793 dirlen = strlen(dir);
794 if (dir != dst)
795 memmove(dst, dir, dirlen + 1);
796
797 if (dirlen + 1 + strlen(child) + 1 > dst_size)
798 return NULL;
799 strcat(dst, "/");
800 strcat(dst, child);
801
802 return dst;
803 }
804
805
807 static struct ir_remote*
808 ir_remotes_append(struct ir_remote* root, struct ir_remote* what)
809 {
810 struct ir_remote* r;
811
812 if (root == (struct ir_remote*)-1)
813 root = NULL;
814 if (what == (struct ir_remote*)-1)
815 what = NULL;
816 if (root == NULL && what != NULL)
817 return what;
818 if (what == NULL)
819 return root;
820 for (r = root; r->next != NULL; r = r->next)
821 ;
822 r->next = what;
823 return root;
824 }
825
826
827 struct ir_remote* read_config(FILE* f, const char* name)
828 {
829 struct ir_remote* head;
830
831 head = read_config_recursive(f, name, 0);
832 head = sort_by_bit_count(head);
833 return head;
834 }
835
836
847 static struct ir_remote*
848 read_included(const char* name, int depth, char* val, struct ir_remote* top_rem)
849 {
850 FILE* childFile;
851 const char* childName;
852 struct ir_remote* rem = NULL;
853
854 if (depth > MAX_INCLUDES) {
855 logprintf(LIRC_ERROR, "error opening child file defined at %s:%d", name, line);
856 logprintf(LIRC_ERROR, "too many files included");
857 return top_rem;
858 }
859 childName = lirc_parse_include(val);
860 if (!childName) {
861 logprintf(LIRC_ERROR, "error parsing child file value defined at line %d:", line);
862 logprintf(LIRC_ERROR, "invalid quoting");
863 return top_rem;
864 }
865 childFile = fopen(childName, "r");
866 if (childFile == NULL) {
867 logprintf(LIRC_ERROR, "error opening child file '%s' defined at line %d:",
868 childName, line);
869 logprintf(LIRC_ERROR, "ignoring this child file for now.");
870 return NULL;
871 }
872 rem = read_config_recursive(childFile, childName, depth + 1);
873 top_rem = ir_remotes_append(top_rem, rem);
874 fclose(childFile);
875 return top_rem;
876 }
877
878
889 static struct ir_remote* read_all_included(const char* name,
890 int depth,
891 char* val,
892 struct ir_remote* top_rem)
893 {
894 int i;
895 glob_t globbuf;
896 char buff[256] = { '\0' };
897
898 memset(&globbuf, 0, sizeof(globbuf));
899 val = val + 1; // Strip quotes
900 val[strlen(val) - 1] = '\0';
901 lirc_parse_relative(buff, sizeof(buff), val, name);
902 glob(buff, 0, NULL, &globbuf);
903 for (i = 0; i < globbuf.gl_pathc; i += 1) {
904 snprintf(buff, sizeof(buff), "\"%s\"", globbuf.gl_pathv[i]);
905 top_rem = read_included(name, depth, buff, top_rem);
906 }
907 globfree(&globbuf);
908 return top_rem;
909 }
910
911
912 static void check_ncode_dups(const char* path,
913 const char* name,
914 struct void_array* ar,
915 struct ir_ncode* code)
916 {
917 if (foreach_void_array(ar, array_guest_ncode_cmp, code) != NULL) {
918 logprintf(LIRC_WARNING,
919 "%s: %s: Duplicate codes: %s",
920 path, name, code->name);
921 }
922 if (foreach_void_array(ar, array_guest_code_equals, code) != NULL) {
923 logprintf(LIRC_WARNING,
924 "%s: %s: Duplicate values: %s",
925 path, name, code->name);
926 }
927 }
928
929
930 static struct ir_remote*
931 read_config_recursive(FILE* f, const char* name, int depth)
932 {
933 char buf[LINE_LEN + 1];
934 char* key;
935 char* val;
936 char* val2;
937 int len, argc;
938 struct ir_remote* top_rem = NULL;
939 struct ir_remote* rem = NULL;
940 struct void_array codes_list, raw_codes, signals;
941 struct ir_ncode raw_code = { NULL, 0, 0, NULL };
942 struct ir_ncode name_code = { NULL, 0, 0, NULL };
943 struct ir_ncode* code;
944 int mode = ID_none;
945
946 line = 0;
947 parse_error = 0;
948 LOGPRINTF(2, "parsing '%s'", name);
949
950 while (fgets(buf, LINE_LEN, f) != NULL) {
951 line++;
952 len = strlen(buf);
953 if (len == LINE_LEN && buf[len - 1] != '\n') {
954 logprintf(LIRC_ERROR, "line %d too long in config file", line);
955 parse_error = 1;
956 break;
957 }
958
959 if (len > 0) {
960 len--;
961 if (buf[len] == '\n')
962 buf[len] = 0;
963 }
964 if (len > 0) {
965 len--;
966 if (buf[len] == '\r')
967 buf[len] = 0;
968 }
969 /* ignore comments */
970 if (buf[0] == '#')
971 continue;
972 key = strtok(buf, whitespace);
973 /* ignore empty lines */
974 if (key == NULL)
975 continue;
976 val = strtok(NULL, whitespace);
977 if (val != NULL) {
978 val2 = strtok(NULL, whitespace);
979 LOGPRINTF(3, "Tokens: \"%s\" \"%s\" \"%s\"", key, val, (val2 == NULL ? "(null)" : val));
980 if (strcasecmp("include", key) == 0) {
981 int save_line = line;
982
983 top_rem = read_all_included(name,
984 depth,
985 val,
986 top_rem);
987 line = save_line;
988 } else if (strcasecmp("begin", key) == 0) {
989 if (strcasecmp("codes", val) == 0) {
990 /* init codes mode */
991 LOGPRINTF(2, " begin codes");
992 if (!checkMode(mode, ID_remote, "begin codes"))
993 break;
994 if (rem->codes) {
995 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
996 logprintf(LIRC_ERROR, "codes are already defined");
997 parse_error = 1;
998 break;
999 }
1000
1001 init_void_array(&codes_list, 30, sizeof(struct ir_ncode));
1002 mode = ID_codes;
1003 } else if (strcasecmp("raw_codes", val) == 0) {
1004 /* init raw_codes mode */
1005 LOGPRINTF(2, " begin raw_codes");
1006 if (!checkMode(mode, ID_remote, "begin raw_codes"))
1007 break;
1008 if (rem->codes) {
1009 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
1010 logprintf(LIRC_ERROR, "codes are already defined");
1011 parse_error = 1;
1012 break;
1013 }
1014 set_protocol(rem, RAW_CODES);
1015 raw_code.code = 0;
1016 init_void_array(&raw_codes, 30, sizeof(struct ir_ncode));
1017 mode = ID_raw_codes;
1018 } else if (strcasecmp("remote", val) == 0) {
1019 /* create new remote */
1020 LOGPRINTF(1, "parsing remote");
1021 if (!checkMode(mode, ID_none, "begin remote"))
1022 break;
1023 mode = ID_remote;
1024 if (!top_rem) {
1025 /* create first remote */
1026 LOGPRINTF(2, "creating first remote");
1027 rem = top_rem = s_malloc(sizeof(struct ir_remote));
1028 } else {
1029 /* create new remote */
1030 LOGPRINTF(2, "creating next remote");
1031 rem = s_malloc(sizeof(struct ir_remote));
1032 ir_remotes_append(top_rem, rem);
1033 }
1034 } else if (mode == ID_codes) {
1035 code = defineCode(key, val, &name_code);
1036 while (!parse_error && val2 != NULL) {
1037 if (val2[0] == '#')
1038 break; /* comment */
1039 defineNode(code, val2);
1040 val2 = strtok(NULL, whitespace);
1041 }
1042 code->current = NULL;
1043 check_ncode_dups(name, rem->name, &codes_list, code);
1044 add_void_array(&codes_list, code);
1045 } else {
1046 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
1047 logprintf(LIRC_ERROR, "unknown section \"%s\"", val);
1048 parse_error = 1;
1049 }
1050 if (!parse_error && val2 != NULL) {
1051 logprintf(LIRC_WARNING,
1052 "%s: garbage after '%s' token "
1053 "in line %d ignored",
1054 rem->name, val, line);
1055 }
1056 } else if (strcasecmp("end", key) == 0) {
1057 if (strcasecmp("codes", val) == 0) {
1058 /* end Codes mode */
1059 LOGPRINTF(2, " end codes");
1060 if (!checkMode(mode, ID_codes, "end codes"))
1061 break;
1062 rem->codes = get_void_array(&codes_list);
1063 mode = ID_remote; /* switch back */
1064 } else if (strcasecmp("raw_codes", val) == 0) {
1065 /* end raw codes mode */
1066 LOGPRINTF(2, " end raw_codes");
1067
1068 if (mode == ID_raw_name) {
1069 raw_code.signals = get_void_array(&signals);
1070 raw_code.length = signals.nr_items;
1071 if (raw_code.length % 2 == 0) {
1072 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
1073 logprintf(LIRC_ERROR, "bad signal length");
1074 parse_error = 1;
1075 }
1076 if (!add_void_array(&raw_codes, &raw_code))
1077 break;
1078 mode = ID_raw_codes;
1079 }
1080 if (!checkMode(mode, ID_raw_codes, "end raw_codes"))
1081 break;
1082 rem->codes = get_void_array(&raw_codes);
1083 mode = ID_remote; /* switch back */
1084 } else if (strcasecmp("remote", val) == 0) {
1085 /* end remote mode */
1086 LOGPRINTF(2, "end remote");
1087 /* print_remote(rem); */
1088 if (!checkMode(mode, ID_remote, "end remote"))
1089 break;
1090 if (!sanityChecks(rem, name)) {
1091 parse_error = 1;
1092 break;
1093 }
1094 if (options_getboolean("lircd:dynamic-codes")) {
1095 if (rem->dyncodes_name == NULL)
1096 rem->dyncodes_name = s_strdup("unknown");
1097 rem->dyncodes[0].name = rem->dyncodes_name;
1098 rem->dyncodes[1].name = rem->dyncodes_name;
1099 }
1100 /* not really necessary because we
1101 * clear the alloced memory */
1102 rem->next = NULL;
1103 rem->last_code = NULL;
1104 mode = ID_none; /* switch back */
1105 } else if (mode == ID_codes) {
1106 code = defineCode(key, val, &name_code);
1107 while (!parse_error && val2 != NULL) {
1108 if (val2[0] == '#')
1109 break; /* comment */
1110 defineNode(code, val2);
1111 val2 = strtok(NULL, whitespace);
1112 }
1113 code->current = NULL;
1114 add_void_array(&codes_list, code);
1115 } else {
1116 logprintf(LIRC_ERROR, "error in configfile line %d:", line);
1117 logprintf(LIRC_ERROR, "unknown section %s", val);
1118 parse_error = 1;
1119 }
1120 if (!parse_error && val2 != NULL) {
1121 logprintf(LIRC_WARNING,
1122 "%s: garbage after '%s'"
1123 " token in line %d ignored",
1124 rem->name, val, line);
1125 }
1126 } else {
1127 switch (mode) {
1128 case ID_remote:
1129 argc = defineRemote(key, val, val2, rem);
1130 if (!parse_error
1131 && ((argc == 1 && val2 != NULL)
1132 || (argc == 2 && val2 != NULL && strtok(NULL, whitespace) != NULL))) {
1133 logprintf(LIRC_WARNING,
1134 "%s: garbage after '%s'"
1135 " token in line %d ignored",
1136 rem->name, key, line);
1137 }
1138 break;
1139 case ID_codes:
1140 code = defineCode(key, val, &name_code);
1141 while (!parse_error && val2 != NULL) {
1142 if (val2[0] == '#')
1143 break; /* comment */
1144 defineNode(code, val2);
1145 val2 = strtok(NULL, whitespace);
1146 }
1147 code->current = NULL;
1148 check_ncode_dups(name,
1149 rem->name,
1150 &codes_list,
1151 code);
1152 add_void_array(&codes_list, code);
1153 break;
1154 case ID_raw_codes:
1155 case ID_raw_name:
1156 if (strcasecmp("name", key) == 0) {
1157 LOGPRINTF(3, "Button: \"%s\"", val);
1158 if (mode == ID_raw_name) {
1159 raw_code.signals = get_void_array(&signals);
1160 raw_code.length = signals.nr_items;
1161 if (raw_code.length % 2 == 0) {
1162 logprintf(LIRC_ERROR, "error in configfile line %d:",
1163 line);
1164 logprintf(LIRC_ERROR, "bad signal length");
1165 parse_error = 1;
1166 }
1167 if (!add_void_array(&raw_codes, &raw_code))
1168 break;
1169 }
1170 raw_code.name = s_strdup(val);
1171 if (!raw_code.name)
1172 break;
1173 raw_code.code++;
1174 init_void_array(&signals, 50, sizeof(lirc_t));
1175 mode = ID_raw_name;
1176 if (!parse_error && val2 != NULL) {
1177 logprintf(LIRC_WARNING,
1178 "%s: garbage after '%s'"
1179 " token in line %d ignored",
1180 rem->name, key, line);
1181 }
1182 } else {
1183 if (mode == ID_raw_codes) {
1184 logprintf(LIRC_ERROR, "no name for signal defined at line %d",
1185 line);
1186 parse_error = 1;
1187 break;
1188 }
1189 if (!addSignal(&signals, key))
1190 break;
1191 if (!addSignal(&signals, val))
1192 break;
1193 if (val2)
1194 if (!addSignal(&signals, val2))
1195 break;
1196 while ((val = strtok(NULL, whitespace)))
1197 if (!addSignal(&signals, val))
1198 break;
1199 }
1200 break;
1201 }
1202 }
1203 } else if (mode == ID_raw_name) {
1204 if (!addSignal(&signals, key))
1205 break;
1206 } else {
1207 logprintf(LIRC_ERROR, "error in configfile line %d", line);
1208 parse_error = 1;
1209 break;
1210 }
1211 if (parse_error)
1212 break;
1213 }
1214 if (mode != ID_none) {
1215 switch (mode) {
1216 case ID_raw_name:
1217 if (raw_code.name != NULL) {
1218 free(raw_code.name);
1219 if (get_void_array(&signals) != NULL)
1220 free(get_void_array(&signals));
1221 }
1222 case ID_raw_codes:
1223 rem->codes = get_void_array(&raw_codes);
1224 break;
1225 case ID_codes:
1226 rem->codes = get_void_array(&codes_list);
1227 break;
1228 }
1229 if (!parse_error) {
1230 logprintf(LIRC_ERROR, "unexpected end of file");
1231 parse_error = 1;
1232 }
1233 }
1234 if (parse_error) {
1235 static int print_error = 1;
1236
1237 if (print_error) {
1238 logprintf(LIRC_ERROR, "reading of file '%s' failed", name);
1239 print_error = 0;
1240 }
1241 free_config(top_rem);
1242 if (depth == 0)
1243 print_error = 1;
1244 return (void*)-1;
1245 }
1246 /* kick reverse flag */
1247 /* handle RC6 flag to be backwards compatible: previous RC-6
1248 * config files did not set rc6_mask */
1249 rem = top_rem;
1250 while (rem != NULL) {
1251 if ((!is_raw(rem)) && rem->flags & REVERSE) {
1252 struct ir_ncode* codes;
1253
1254 if (has_pre(rem))
1255 rem->pre_data = reverse(rem->pre_data, rem->pre_data_bits);
1256 if (has_post(rem))
1257 rem->post_data = reverse(rem->post_data, rem->post_data_bits);
1258 codes = rem->codes;
1259 while (codes->name != NULL) {
1260 codes->code = reverse(codes->code, rem->bits);
1261 codes++;
1262 }
1263 rem->flags = rem->flags & (~REVERSE);
1264 rem->flags = rem->flags | COMPAT_REVERSE;
1265 /* don't delete the flag because we still need
1266 * it to remain compatible with older versions
1267 */
1268 }
1269 if (rem->flags & RC6 && rem->rc6_mask == 0 && rem->toggle_bit > 0) {
1270 int all_bits = bit_count(rem);
1271
1272 rem->rc6_mask = ((ir_code)1) << (all_bits - rem->toggle_bit);
1273 }
1274 if (rem->toggle_bit > 0) {
1275 int all_bits = bit_count(rem);
1276
1277 if (has_toggle_bit_mask(rem))
1278 logprintf(LIRC_WARNING, "%s uses both toggle_bit and toggle_bit_mask", rem->name);
1279 else
1280 rem->toggle_bit_mask = ((ir_code)1) << (all_bits - rem->toggle_bit);
1281 rem->toggle_bit = 0;
1282 }
1283 if (has_toggle_bit_mask(rem)) {
1284 if (!is_raw(rem) && rem->codes) {
1285 rem->toggle_bit_mask_state = (rem->codes->code & rem->toggle_bit_mask);
1286 if (rem->toggle_bit_mask_state)
1287 /* start with state set to 0 for backwards compatibility */
1288 rem->toggle_bit_mask_state ^= rem->toggle_bit_mask;
1289 }
1290 }
1291 if (is_serial(rem)) {
1292 lirc_t base;
1293
1294 if (rem->baud > 0) {
1295 base = 1000000 / rem->baud;
1296 if (rem->pzero == 0 && rem->szero == 0)
1297 rem->pzero = base;
1298 if (rem->pone == 0 && rem->sone == 0)
1299 rem->sone = base;
1300 }
1301 if (rem->bits_in_byte == 0)
1302 rem->bits_in_byte = 8;
1303 }
1304 if (rem->min_code_repeat > 0) {
1305 if (!has_repeat(rem) || rem->min_code_repeat > rem->min_repeat) {
1306 logprintf(LIRC_WARNING, "invalid min_code_repeat value");
1307 rem->min_code_repeat = 0;
1308 }
1309 }
1310 calculate_signal_lengths(rem);
1311 rem = rem->next;
1312 }
1313
1314 return top_rem;
1315 }
1316
1317 void calculate_signal_lengths(struct ir_remote* remote)
1318 {
1319 if (is_const(remote)) {
1320 remote->min_total_signal_length = min_gap(remote);
1321 remote->max_total_signal_length = max_gap(remote);
1322 } else {
1323 remote->min_gap_length = min_gap(remote);
1324 remote->max_gap_length = max_gap(remote);
1325 }
1326
1327 lirc_t min_signal_length = 0, max_signal_length = 0;
1328 lirc_t max_pulse = 0, max_space = 0;
1329 int first_sum = 1;
1330 struct ir_ncode* c = remote->codes;
1331 int i;
1332
1333 while (c->name) {
1334 struct ir_ncode code = *c;
1335 struct ir_code_node* next = code.next;
1336 int first = 1;
1337 int repeat = 0;
1338
1339 do {
1340 if (first) {
1341 first = 0;
1342 } else {
1343 code.code = next->code;
1344 next = next->next;
1345 }
1346 for (repeat = 0; repeat < 2; repeat++) {
1347 if (init_sim(remote, &code, repeat)) {
1348 lirc_t sum = send_buffer_sum();
1349
1350 if (sum) {
1351 if (first_sum || sum < min_signal_length)
1352 min_signal_length = sum;
1353 if (first_sum || sum > max_signal_length)
1354 max_signal_length = sum;
1355 first_sum = 0;
1356 }
1357 for (i = 0; i < send_buffer_length(); i++) {
1358 if (i & 1) { /* space */
1359 if (send_buffer_data()[i] > max_space)
1360 max_space = send_buffer_data()[i];
1361 } else { /* pulse */
1362 if (send_buffer_data()[i] > max_pulse)
1363 max_pulse = send_buffer_data()[i];
1364 }
1365 }
1366 }
1367 }
1368 } while (next);
1369 c++;
1370 }
1371 if (first_sum) {
1372 /* no timing data, so assume gap is the actual total
1373 * length */
1374 remote->min_total_signal_length = min_gap(remote);
1375 remote->max_total_signal_length = max_gap(remote);
1376 remote->min_gap_length = min_gap(remote);
1377 remote->max_gap_length = max_gap(remote);
1378 } else if (is_const(remote)) {
1379 if (remote->min_total_signal_length > max_signal_length) {
1380 remote->min_gap_length = remote->min_total_signal_length - max_signal_length;
1381 } else {
1382 logprintf(LIRC_WARNING,
1383 "min_gap_length is 0 for '%s' remote",
1384 remote->name);
1385 remote->min_gap_length = 0;
1386 }
1387 if (remote->max_total_signal_length > min_signal_length) {
1388 remote->max_gap_length = remote->max_total_signal_length - min_signal_length;
1389 } else {
1390 logprintf(LIRC_WARNING, "max_gap_length is 0 for '%s' remote", remote->name);
1391 remote->max_gap_length = 0;
1392 }
1393 } else {
1394 remote->min_total_signal_length = min_signal_length + remote->min_gap_length;
1395 remote->max_total_signal_length = max_signal_length + remote->max_gap_length;
1396 }
1397 LOGPRINTF(1, "lengths: %lu %lu %lu %lu", remote->min_total_signal_length, remote->max_total_signal_length,
1398 remote->min_gap_length, remote->max_gap_length);
1399 }
1400
1401 void free_config(struct ir_remote* remotes)
1402 {
1403 struct ir_remote* next;
1404 struct ir_ncode* codes;
1405
1406 while (remotes != NULL) {
1407 next = remotes->next;
1408
1409 if (remotes->dyncodes_name != NULL)
1410 free(remotes->dyncodes_name);
1411 if (remotes->name != NULL)
1412 free((void*)(remotes->name));
1413 if (remotes->codes != NULL) {
1414 codes = remotes->codes;
1415 while (codes->name != NULL) {
1416 struct ir_code_node* node;
1417 struct ir_code_node* next_node;
1418
1419 free(codes->name);
1420 if (codes->signals != NULL)
1421 free(codes->signals);
1422 node = codes->next;
1423 while (node) {
1424 next_node = node->next;
1425 free(node);
1426 node = next_node;
1427 }
1428 codes++;
1429 }
1430 free(remotes->codes);
1431 }
1432 free(remotes);
1433 remotes = next;
1434 }
1435 }
ir_remote
Definition: ir_remote_types.h:163
ir_remote::bits
int bits
Definition: ir_remote_types.h:167
send_buffer_data
const lirc_t * send_buffer_data(void)
Definition: transmit.c:372
ir_remote::min_total_signal_length
lirc_t min_total_signal_length
Definition: ir_remote_types.h:243
NO_FOOT_REP
#define NO_FOOT_REP
Definition: ir_remote_types.h:132
RC6
#define RC6
Definition: ir_remote_types.h:119
ir_code_node
Definition: ir_remote_types.h:61
ir_remote::freq
unsigned int freq
Definition: ir_remote_types.h:216
ir_remote::max_gap_length
lirc_t max_gap_length
Definition: ir_remote_types.h:246
array_guest_func
void *(* array_guest_func)(void *item, void *arg)
Definition: config_file.c:63
GOLDSTAR
#define GOLDSTAR
Definition: ir_remote_types.h:123
ir_remote::max_total_signal_length
lirc_t max_total_signal_length
Definition: ir_remote_types.h:244
ir_remote::post_data
ir_code post_data
Definition: ir_remote_types.h:195
ir_remote::post_s
lirc_t post_s
Definition: ir_remote_types.h:197
ir_remote::plead
lirc_t plead
Definition: ir_remote_types.h:187
ir_remote::repeat_mask
ir_code repeat_mask
Definition: ir_remote_types.h:230
ir_ncode::next
struct ir_code_node * next
Definition: ir_remote_types.h:87
ir_remote::baud
unsigned int baud
Definition: ir_remote_types.h:222
ir_remote::name
const char * name
Definition: ir_remote_types.h:164
SPACE_ENC
#define SPACE_ENC
Definition: ir_remote_types.h:121
free_config
void free_config(struct ir_remote *remotes)
Definition: config_file.c:1401
ir_ncode::signals
lirc_t * signals
Definition: ir_remote_types.h:83
COMPAT_REVERSE
#define COMPAT_REVERSE
Definition: ir_remote_types.h:136
ir_remote::eps
int eps
Definition: ir_remote_types.h:169
ir_remote::last_code
struct ir_ncode * last_code
Definition: ir_remote_types.h:236
ir_remote::parity
unsigned int parity
Definition: ir_remote_types.h:224
ir_code
__u64 ir_code
Definition: ir_remote_types.h:55
ir_remote::sfoot
lirc_t sfoot
Definition: ir_remote_types.h:189
ir_remote::ptrail
lirc_t ptrail
Definition: ir_remote_types.h:188
ir_remote::pre_data_bits
int pre_data_bits
Definition: ir_remote_types.h:192
ir_remote::min_gap_length
lirc_t min_gap_length
Definition: ir_remote_types.h:245
ir_remote::manual_sort
int manual_sort
Definition: ir_remote_types.h:250
flaglist
Definition: config_flags.h:13
ir_ncode::name
char * name
Definition: ir_remote_types.h:74
ir_ncode::current
struct ir_code_node * current
Definition: ir_remote_types.h:91
ir_remote::duty_cycle
unsigned int duty_cycle
Definition: ir_remote_types.h:217
ir_remote::post_data_bits
int post_data_bits
Definition: ir_remote_types.h:194
ir_remote::sthree
lirc_t sthree
Definition: ir_remote_types.h:183
RCMM
#define RCMM
Definition: ir_remote_types.h:120
ir_remote::toggle_mask
ir_code toggle_mask
Definition: ir_remote_types.h:218
ir_remote::pre_data
ir_code pre_data
Definition: ir_remote_types.h:193
send_buffer_sum
lirc_t send_buffer_sum(void)
Definition: transmit.c:377
ir_remote::sone
lirc_t sone
Definition: ir_remote_types.h:185
RC5
#define RC5
Definition: ir_remote_types.h:113
ir_remote::dyncodes_name
char * dyncodes_name
Definition: ir_remote_types.h:176
ir_remote::shead
lirc_t shead
Definition: ir_remote_types.h:182
REPEAT_HEADER
#define REPEAT_HEADER
Definition: ir_remote_types.h:134
SPACE_FIRST
#define SPACE_FIRST
Definition: ir_remote_types.h:122
ir_remote::repeat_gap
__u32 repeat_gap
Definition: ir_remote_types.h:201
ir_remote::gap
__u32 gap
Definition: ir_remote_types.h:199
CONST_LENGTH
#define CONST_LENGTH
Definition: ir_remote_types.h:133
NO_HEAD_REP
#define NO_HEAD_REP
Definition: ir_remote_types.h:131
ir_remote::stop_bits
unsigned int stop_bits
Definition: ir_remote_types.h:225
ir_remote::pre_s
lirc_t pre_s
Definition: ir_remote_types.h:196
GRUNDIG
#define GRUNDIG
Definition: ir_remote_types.h:124
ir_remote::szero
lirc_t szero
Definition: ir_remote_types.h:186
get_void_array
void * get_void_array(struct void_array *ar)
Definition: config_file.c:141
LOGPRINTF
#define LOGPRINTF(level, fmt, args...)
Definition: lirc_log.h:75
ir_ncode
Definition: ir_remote_types.h:72
ir_remote::stwo
lirc_t stwo
Definition: ir_remote_types.h:184
ir_remote::flags
int flags
Definition: ir_remote_types.h:168
ir_remote::aeps
unsigned int aeps
Definition: ir_remote_types.h:170
ir_remote::srepeat
lirc_t srepeat
Definition: ir_remote_types.h:190
SERIAL
#define SERIAL
Definition: ir_remote_types.h:126
SHIFT_ENC
#define SHIFT_ENC
Definition: ir_remote_types.h:114
BO
#define BO
Definition: ir_remote_types.h:125
ir_remote::suppress_repeat
int suppress_repeat
Definition: ir_remote_types.h:204
ir_ncode::code
ir_code code
Definition: ir_remote_types.h:77
ir_remote::toggle_bit
int toggle_bit
Definition: ir_remote_types.h:202
ir_remote::driver
const char * driver
Definition: ir_remote_types.h:165
ir_remote::min_code_repeat
unsigned int min_code_repeat
Definition: ir_remote_types.h:215
all_flags
const struct flaglist all_flags[]
Definition: config_file.c:91
ir_remote::dyncodes
struct ir_ncode dyncodes[2]
Definition: ir_remote_types.h:178
flaglist::name
char * name
Definition: config_flags.h:14
ir_remote::rc6_mask
ir_code rc6_mask
Definition: ir_remote_types.h:219
flaglist::flag
int flag
Definition: config_flags.h:15
send_buffer_length
int send_buffer_length(void)
Definition: transmit.c:366
ir_remote::toggle_bit_mask
ir_code toggle_bit_mask
Definition: ir_remote_types.h:203
ir_remote::gap2
__u32 gap2
Definition: ir_remote_types.h:200
ir_remote::min_repeat
int min_repeat
Definition: ir_remote_types.h:207
RAW_CODES
#define RAW_CODES
Definition: ir_remote_types.h:112
read_config
struct ir_remote * read_config(FILE *f, const char *name)
Definition: config_file.c:827
ir_remote::ignore_mask
ir_code ignore_mask
Definition: ir_remote_types.h:229
XMP
#define XMP
Definition: ir_remote_types.h:127
ir_remote::bits_in_byte
unsigned int bits_in_byte
Definition: ir_remote_types.h:223
add_void_array
int add_void_array(struct void_array *ar, void *dataptr)
Definition: config_file.c:116
ir_ncode::length
int length
Definition: ir_remote_types.h:80