30 #include <sys/socket.h>
33 #include <sys/types.h>
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"
46 enum directive { ID_none, ID_remote, ID_codes, ID_raw_codes, ID_raw_name };
63 typedef void* (*array_guest_func)(
void* item,
void* arg);
67 #define MAX_INCLUDES 10
69 const char* whitespace =
" \t";
72 static int parse_error;
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);
77 void** init_void_array(
struct void_array* ar,
size_t chunk_size,
size_t item_size)
79 ar->chunk_size = chunk_size;
80 ar->item_size = item_size;
82 ar->ptr = calloc(chunk_size, ar->item_size);
84 logprintf(LIRC_ERROR,
"out of memory");
105 {
"REVERSE", REVERSE },
120 if ((ar->nr_items % ar->chunk_size) == (ar->chunk_size) - 1) {
123 ptr = realloc(ar->ptr,
125 (ar->nr_items + ar->chunk_size + 1));
127 logprintf(LIRC_ERROR,
"out of memory");
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);
157 for (i = 0; i < ar->nr_items; i += 1) {
158 r = func(ar->ptr + (i * ar->item_size), arg);
169 if (node1 == NULL || node2 == NULL)
170 return node1 == node2;
171 return node1->code == node2->code;
179 static void* array_guest_code_equals(
void* arg1,
void* arg2)
187 if (code1 == NULL || code2 == NULL)
188 return code1 == code2 ? arg1 : NULL;
193 while (code1->
next != NULL) {
194 if (!ir_code_node_equals(next1, next2))
207 static void* array_guest_ncode_cmp(
void* item,
void* arg)
213 if (strcmp(code1->
name, code2->
name) == 0)
219 void* s_malloc(
size_t size)
225 logprintf(LIRC_ERROR,
"out of memory");
229 memset(ptr, 0, size);
233 char* s_strdup(
char*
string)
237 ptr = strdup(
string);
239 logprintf(LIRC_ERROR,
"out of memory");
246 ir_code s_strtocode(
const char* val)
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);
262 __u32 s_strtou32(
char* val)
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);
277 int s_strtoi(
char* val)
283 n = strtol(val, &endptr, 0);
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);
294 unsigned int s_strtoui(
char* val)
300 n = strtoul(val, &endptr, 0);
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);
311 lirc_t s_strtolirc_t(
char* val)
317 n = strtoul(val, &endptr, 0);
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);
326 logprintf(LIRC_WARNING,
"error in configfile line %d:", line);
327 logprintf(LIRC_WARNING,
"\"%s\" is out of range", val);
332 int checkMode(
int is_mode,
int c_mode,
char* error)
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);
343 int addSignal(
struct void_array*
signals,
char* val)
358 memset(code, 0,
sizeof(*code));
359 code->
name = s_strdup(key);
360 code->
code = s_strtocode(val);
369 node = s_malloc(
sizeof(*node));
373 node->code = s_strtocode(val);
388 int parseFlags(
char* val)
396 while (flag != NULL) {
397 while (*help !=
'|' && *help != 0)
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);
415 flags = flags | flaglptr->
flag;
421 if (flaglptr->
name == NULL) {
422 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
423 logprintf(LIRC_ERROR,
"unknown flag: \"%s\"", flag);
434 int defineRemote(
char* key,
char* val,
char* val2,
struct ir_remote* rem)
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);
443 if (options_getboolean(
"lircd:dynamic-codes")) {
444 if ((strcasecmp(
"dyncodes_name", key)) == 0) {
450 }
else if (strcasecmp(
"driver", key) == 0) {
452 free((
void*)(rem->
driver));
453 rem->
driver = s_strdup(val);
455 }
else if ((strcasecmp(
"bits", key)) == 0) {
456 rem->
bits = s_strtoi(val);
458 }
else if (strcasecmp(
"flags", key) == 0) {
459 rem->
flags |= parseFlags(val);
461 }
else if (strcasecmp(
"eps", key) == 0) {
462 rem->
eps = s_strtoi(val);
464 }
else if (strcasecmp(
"aeps", key) == 0) {
465 rem->
aeps = s_strtoi(val);
467 }
else if (strcasecmp(
"plead", key) == 0) {
468 rem->
plead = s_strtolirc_t(val);
470 }
else if (strcasecmp(
"ptrail", key) == 0) {
471 rem->
ptrail = s_strtolirc_t(val);
473 }
else if (strcasecmp(
"pre_data_bits", key) == 0) {
476 }
else if (strcasecmp(
"pre_data", key) == 0) {
479 }
else if (strcasecmp(
"post_data_bits", key) == 0) {
482 }
else if (strcasecmp(
"post_data", key) == 0) {
485 }
else if (strcasecmp(
"gap", key) == 0) {
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) {
493 }
else if (strcasecmp(
"repeat_mask", key) == 0) {
498 else if (strcasecmp(
"toggle_bit", key) == 0) {
501 }
else if (strcasecmp(
"toggle_bit_mask", key) == 0) {
504 }
else if (strcasecmp(
"toggle_mask", key) == 0) {
507 }
else if (strcasecmp(
"rc6_mask", key) == 0) {
510 }
else if (strcasecmp(
"ignore_mask", key) == 0) {
513 }
else if (strcasecmp(
"manual_sort", key) == 0) {
518 else if (strcasecmp(
"repeat_bit", key) == 0) {
521 }
else if (strcasecmp(
"suppress_repeat", key) == 0) {
524 }
else if (strcasecmp(
"min_repeat", key) == 0) {
527 }
else if (strcasecmp(
"min_code_repeat", key) == 0) {
530 }
else if (strcasecmp(
"frequency", key) == 0) {
531 rem->
freq = s_strtoui(val);
533 }
else if (strcasecmp(
"duty_cycle", key) == 0) {
536 }
else if (strcasecmp(
"baud", key) == 0) {
537 rem->
baud = s_strtoui(val);
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");
547 switch (toupper(val[1])) {
549 rem->
parity = IR_PARITY_NONE;
552 rem->
parity = IR_PARITY_EVEN;
555 rem->
parity = IR_PARITY_ODD;
558 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
559 logprintf(LIRC_ERROR,
"unsupported parity mode");
563 if (strcmp(val + 2,
"1.5") == 0)
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);
573 }
else if (strcasecmp(
"three", key) == 0) {
574 rem->pthree = s_strtolirc_t(val);
575 rem->
sthree = s_strtolirc_t(val2);
577 }
else if (strcasecmp(
"two", key) == 0) {
578 rem->ptwo = s_strtolirc_t(val);
579 rem->
stwo = s_strtolirc_t(val2);
581 }
else if (strcasecmp(
"one", key) == 0) {
582 rem->pone = s_strtolirc_t(val);
583 rem->
sone = s_strtolirc_t(val2);
585 }
else if (strcasecmp(
"zero", key) == 0) {
586 rem->pzero = s_strtolirc_t(val);
587 rem->
szero = s_strtolirc_t(val2);
589 }
else if (strcasecmp(
"foot", key) == 0) {
590 rem->pfoot = s_strtolirc_t(val);
591 rem->
sfoot = s_strtolirc_t(val2);
593 }
else if (strcasecmp(
"repeat", key) == 0) {
594 rem->prepeat = s_strtolirc_t(val);
595 rem->
srepeat = s_strtolirc_t(val2);
597 }
else if (strcasecmp(
"pre", key) == 0) {
598 rem->pre_p = s_strtolirc_t(val);
599 rem->
pre_s = s_strtolirc_t(val2);
601 }
else if (strcasecmp(
"post", key) == 0) {
602 rem->post_p = s_strtolirc_t(val);
603 rem->
post_s = s_strtolirc_t(val2);
608 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
609 logprintf(LIRC_ERROR,
"unknown definiton: \"%s %s %s\"", key, val, val2);
611 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
612 logprintf(LIRC_ERROR,
"unknown definiton or too few arguments: \"%s %s\"", key, val);
618 static int sanityChecks(
struct ir_remote* rem,
const char* path)
623 path = path != NULL ? path :
"unknown file";
626 logprintf(LIRC_ERROR,
627 "%s: %s: Missing remote name", path, rem);
631 logprintf(LIRC_WARNING,
"%s: %s: Gap value missing or invalid",
634 if (has_repeat_gap(rem) && is_const(rem)) {
635 logprintf(LIRC_WARNING,
636 "%s: %s: Repeat_gap ignored (CONST_LENGTH is set)",
644 logprintf(LIRC_WARNING,
645 "%s: %s: Invalid pre_data", path, rem->
name);
649 logprintf(LIRC_WARNING,
"%s: %s: Invalid post_data",
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",
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",
663 node->code &= gen_mask(rem->
bits);
682 int r1_is_raw = is_raw(r1);
683 int r2_is_raw = is_raw(r2);
685 if (!r1_is_raw && r2_is_raw)
687 if (r1_is_raw && !r2_is_raw)
690 if (r1_is_raw && r2_is_raw) {
691 for (c = r1->codes, r1_size = 0; c->
name != NULL; c++)
693 for (c = r2->codes, r2_size = 0; c->
name != NULL; c++)
696 r1_size = bit_count(r1);
697 r2_size = bit_count(r2);
699 if (r1_size == r2_size)
701 return r1_size < r2_size ? -1 : 1;
718 for (r = remotes; r != NULL && r != (
void*)-1; r = r->next)
723 while (rem != NULL && rem != (
void*)-1) {
728 while (scan && remote_bits_cmp(scan, rem) <= 0) {
747 static const char* lirc_parse_include(
char* s)
756 while (last > s && strchr(whitespace, *last) != NULL)
760 if (*s !=
'"' && *s !=
'<')
762 if (*s ==
'"' && *last !=
'"')
764 else if (*s ==
'<' && *last !=
'>')
767 memmove(s, s + 1, len - 2 + 1);
774 static const char* lirc_parse_relative(
char* dst,
789 if (strlen(current) >= dst_size)
791 strcpy(dst, current);
793 dirlen = strlen(dir);
795 memmove(dst, dir, dirlen + 1);
797 if (dirlen + 1 + strlen(child) + 1 > dst_size)
816 if (root == NULL && what != NULL)
820 for (r = root; r->next != NULL; r = r->next)
832 head = read_config_recursive(f, name, 0);
833 head = sort_by_bit_count(head);
849 read_included(
const char*
name,
int depth,
char* val,
struct ir_remote* top_rem)
852 const char* childName;
855 if (depth > MAX_INCLUDES) {
856 logprintf(LIRC_ERROR,
"error opening child file defined at %s:%d", name, line);
857 logprintf(LIRC_ERROR,
"too many files included");
860 childName = lirc_parse_include(val);
862 logprintf(LIRC_ERROR,
"error parsing child file value defined at line %d:", line);
863 logprintf(LIRC_ERROR,
"invalid quoting");
866 childFile = fopen(childName,
"r");
867 if (childFile == NULL) {
868 logprintf(LIRC_ERROR,
"error opening child file '%s' defined at line %d:",
870 logprintf(LIRC_ERROR,
"ignoring this child file for now.");
873 rem = read_config_recursive(childFile, childName, depth + 1);
874 top_rem = ir_remotes_append(top_rem, rem);
890 static struct ir_remote* read_all_included(
const char* name,
897 char buff[256] = {
'\0' };
899 memset(&globbuf, 0,
sizeof(globbuf));
901 val[strlen(val) - 1] =
'\0';
902 lirc_parse_relative(buff,
sizeof(buff), val, name);
903 glob(buff, 0, NULL, &globbuf);
904 for (i = 0; i < globbuf.gl_pathc; i += 1) {
905 snprintf(buff,
sizeof(buff),
"\"%s\"", globbuf.gl_pathv[i]);
906 top_rem = read_included(name, depth, buff, top_rem);
913 static void check_ncode_dups(
const char* path,
915 struct void_array* ar,
918 if (foreach_void_array(ar, array_guest_ncode_cmp, code) != NULL) {
919 logprintf(LIRC_WARNING,
920 "%s: %s: Duplicate codes: %s",
921 path, name, code->
name);
923 if (foreach_void_array(ar, array_guest_code_equals, code) != NULL) {
924 logprintf(LIRC_WARNING,
925 "%s: %s: Duplicate values: %s",
926 path, name, code->
name);
932 read_config_recursive(FILE* f,
const char* name,
int depth)
934 char buf[LINE_LEN + 1];
941 struct void_array codes_list, raw_codes, signals;
942 struct ir_ncode raw_code = { NULL, 0, 0, NULL };
943 struct ir_ncode name_code = { NULL, 0, 0, NULL };
951 while (fgets(buf, LINE_LEN, f) != NULL) {
954 if (len == LINE_LEN && buf[len - 1] !=
'\n') {
955 logprintf(LIRC_ERROR,
"line %d too long in config file", line);
962 if (buf[len] ==
'\n')
967 if (buf[len] ==
'\r')
973 key = strtok(buf, whitespace);
977 val = strtok(NULL, whitespace);
979 val2 = strtok(NULL, whitespace);
980 LOGPRINTF(3,
"Tokens: \"%s\" \"%s\" \"%s\"", key, val, (val2 == NULL ?
"(null)" : val));
981 if (strcasecmp(
"include", key) == 0) {
982 int save_line = line;
984 top_rem = read_all_included(name,
989 }
else if (strcasecmp(
"begin", key) == 0) {
990 if (strcasecmp(
"codes", val) == 0) {
993 if (!checkMode(mode, ID_remote,
"begin codes"))
996 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
997 logprintf(LIRC_ERROR,
"codes are already defined");
1002 init_void_array(&codes_list, 30,
sizeof(
struct ir_ncode));
1004 }
else if (strcasecmp(
"raw_codes", val) == 0) {
1007 if (!checkMode(mode, ID_remote,
"begin raw_codes"))
1010 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
1011 logprintf(LIRC_ERROR,
"codes are already defined");
1017 init_void_array(&raw_codes, 30,
sizeof(
struct ir_ncode));
1018 mode = ID_raw_codes;
1019 }
else if (strcasecmp(
"remote", val) == 0) {
1022 if (!checkMode(mode, ID_none,
"begin remote"))
1028 rem = top_rem = s_malloc(
sizeof(
struct ir_remote));
1032 rem = s_malloc(
sizeof(
struct ir_remote));
1033 ir_remotes_append(top_rem, rem);
1035 }
else if (mode == ID_codes) {
1036 code = defineCode(key, val, &name_code);
1037 while (!parse_error && val2 != NULL) {
1040 defineNode(code, val2);
1041 val2 = strtok(NULL, whitespace);
1044 check_ncode_dups(name, rem->
name, &codes_list, code);
1047 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
1048 logprintf(LIRC_ERROR,
"unknown section \"%s\"", val);
1051 if (!parse_error && val2 != NULL) {
1052 logprintf(LIRC_WARNING,
1053 "%s: garbage after '%s' token "
1054 "in line %d ignored",
1055 rem->
name, val, line);
1057 }
else if (strcasecmp(
"end", key) == 0) {
1058 if (strcasecmp(
"codes", val) == 0) {
1061 if (!checkMode(mode, ID_codes,
"end codes"))
1065 }
else if (strcasecmp(
"raw_codes", val) == 0) {
1069 if (mode == ID_raw_name) {
1071 raw_code.
length = signals.nr_items;
1072 if (raw_code.
length % 2 == 0) {
1073 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
1074 logprintf(LIRC_ERROR,
"bad signal length");
1079 mode = ID_raw_codes;
1081 if (!checkMode(mode, ID_raw_codes,
"end raw_codes"))
1085 }
else if (strcasecmp(
"remote", val) == 0) {
1089 if (!checkMode(mode, ID_remote,
"end remote"))
1091 if (!sanityChecks(rem, name)) {
1095 if (options_getboolean(
"lircd:dynamic-codes")) {
1106 }
else if (mode == ID_codes) {
1107 code = defineCode(key, val, &name_code);
1108 while (!parse_error && val2 != NULL) {
1111 defineNode(code, val2);
1112 val2 = strtok(NULL, whitespace);
1117 logprintf(LIRC_ERROR,
"error in configfile line %d:", line);
1118 logprintf(LIRC_ERROR,
"unknown section %s", val);
1121 if (!parse_error && val2 != NULL) {
1122 logprintf(LIRC_WARNING,
1123 "%s: garbage after '%s'"
1124 " token in line %d ignored",
1125 rem->
name, val, line);
1130 argc = defineRemote(key, val, val2, rem);
1132 && ((argc == 1 && val2 != NULL)
1133 || (argc == 2 && val2 != NULL && strtok(NULL, whitespace) != NULL))) {
1134 logprintf(LIRC_WARNING,
1135 "%s: garbage after '%s'"
1136 " token in line %d ignored",
1137 rem->
name, key, line);
1141 code = defineCode(key, val, &name_code);
1142 while (!parse_error && val2 != NULL) {
1145 defineNode(code, val2);
1146 val2 = strtok(NULL, whitespace);
1149 check_ncode_dups(name,
1157 if (strcasecmp(
"name", key) == 0) {
1159 if (mode == ID_raw_name) {
1161 raw_code.
length = signals.nr_items;
1162 if (raw_code.
length % 2 == 0) {
1163 logprintf(LIRC_ERROR,
"error in configfile line %d:",
1165 logprintf(LIRC_ERROR,
"bad signal length");
1171 raw_code.
name = s_strdup(val);
1175 init_void_array(&signals, 50,
sizeof(lirc_t));
1177 if (!parse_error && val2 != NULL) {
1178 logprintf(LIRC_WARNING,
1179 "%s: garbage after '%s'"
1180 " token in line %d ignored",
1181 rem->
name, key, line);
1184 if (mode == ID_raw_codes) {
1185 logprintf(LIRC_ERROR,
"no name for signal defined at line %d",
1190 if (!addSignal(&signals, key))
1192 if (!addSignal(&signals, val))
1195 if (!addSignal(&signals, val2))
1197 while ((val = strtok(NULL, whitespace)))
1198 if (!addSignal(&signals, val))
1204 }
else if (mode == ID_raw_name) {
1205 if (!addSignal(&signals, key))
1208 logprintf(LIRC_ERROR,
"error in configfile line %d", line);
1215 if (mode != ID_none) {
1218 if (raw_code.
name != NULL) {
1219 free(raw_code.
name);
1231 logprintf(LIRC_ERROR,
"unexpected end of file");
1236 static int print_error = 1;
1239 logprintf(LIRC_ERROR,
"reading of file '%s' failed", name);
1251 while (rem != NULL) {
1252 if ((!is_raw(rem)) && rem->
flags & REVERSE) {
1260 while (codes->
name != NULL) {
1271 int all_bits = bit_count(rem);
1276 int all_bits = bit_count(rem);
1278 if (has_toggle_bit_mask(rem))
1279 logprintf(LIRC_WARNING,
"%s uses both toggle_bit and toggle_bit_mask", rem->
name);
1284 if (has_toggle_bit_mask(rem)) {
1285 if (!is_raw(rem) && rem->codes) {
1287 if (rem->toggle_bit_mask_state)
1292 if (is_serial(rem)) {
1295 if (rem->
baud > 0) {
1296 base = 1000000 / rem->
baud;
1297 if (rem->pzero == 0 && rem->
szero == 0)
1299 if (rem->pone == 0 && rem->
sone == 0)
1307 logprintf(LIRC_WARNING,
"invalid min_code_repeat value");
1311 calculate_signal_lengths(rem);
1318 void calculate_signal_lengths(
struct ir_remote* remote)
1320 if (is_const(remote)) {
1328 lirc_t min_signal_length = 0, max_signal_length = 0;
1329 lirc_t max_pulse = 0, max_space = 0;
1331 struct ir_ncode* c = remote->codes;
1344 code.
code = next->code;
1347 for (repeat = 0; repeat < 2; repeat++) {
1348 if (init_sim(remote, &code, repeat)) {
1352 if (first_sum || sum < min_signal_length)
1353 min_signal_length = sum;
1354 if (first_sum || sum > max_signal_length)
1355 max_signal_length = sum;
1379 }
else if (is_const(remote)) {
1383 logprintf(LIRC_WARNING,
1384 "min_gap_length is 0 for '%s' remote",
1391 logprintf(LIRC_WARNING,
"max_gap_length is 0 for '%s' remote", remote->
name);
1407 while (remotes != NULL) {
1408 next = remotes->next;
1412 if (remotes->
name != NULL)
1413 free((
void*)(remotes->
name));
1414 if (remotes->codes != NULL) {
1415 codes = remotes->codes;
1416 while (codes->
name != NULL) {
1425 next_node = node->next;
1431 free(remotes->codes);
const lirc_t * send_buffer_data(void)
lirc_t min_total_signal_length
lirc_t max_total_signal_length
struct ir_code_node * next
void free_config(struct ir_remote *remotes)
struct ir_ncode * last_code
struct ir_code_node * current
lirc_t send_buffer_sum(void)
void * get_void_array(struct void_array *ar)
#define LOGPRINTF(level, fmt, args...)
void *(* array_guest_func)(void *item, void *arg)
unsigned int min_code_repeat
const struct flaglist all_flags[]
struct ir_ncode dyncodes[2]
int send_buffer_length(void)
struct ir_remote * read_config(FILE *f, const char *name)
unsigned int bits_in_byte
int add_void_array(struct void_array *ar, void *dataptr)