31 #include <sys/socket.h>
34 #include <sys/types.h>
38 #ifdef HAVE_KERNEL_LIRC_H
39 #include <linux/lirc.h>
41 #include "media/lirc.h"
44 #include "lirc/lirc_log.h"
45 #include "lirc/lirc_options.h"
46 #include "lirc/ir_remote.h"
47 #include "lirc/config_file.h"
48 #include "lirc/transmit.h"
49 #include "lirc/config_flags.h"
54 enum directive { ID_none, ID_remote, ID_codes, ID_raw_codes, ID_raw_name };
71 typedef void* (*array_guest_func)(
void* item,
void* arg);
75 #define MAX_INCLUDES 10
77 const char* whitespace =
" \t";
80 static int parse_error;
82 static struct ir_remote* read_config_recursive(FILE* f,
const char*
name,
int depth);
83 static void calculate_signal_lengths(
struct ir_remote* remote);
85 void** init_void_array(
struct void_array* ar,
size_t chunk_size,
size_t item_size)
87 ar->chunk_size = chunk_size;
88 ar->item_size = item_size;
90 ar->ptr = calloc(chunk_size, ar->item_size);
113 {
"REVERSE", REVERSE },
128 if ((ar->nr_items % ar->chunk_size) == (ar->chunk_size) - 1) {
131 ptr = realloc(ar->ptr,
133 (ar->nr_items + ar->chunk_size + 1));
141 memcpy((ar->ptr) + (ar->item_size * ar->nr_items), dataptr, ar->item_size);
142 ar->nr_items = (ar->nr_items) + 1;
143 memset((ar->ptr) + (ar->item_size * ar->nr_items), 0, ar->item_size);
165 for (i = 0; i < ar->nr_items; i += 1) {
166 r = func(ar->ptr + (i * ar->item_size), arg);
177 if (node1 == NULL || node2 == NULL)
178 return node1 == node2;
179 return node1->code == node2->code;
187 static void* array_guest_code_equals(
void* arg1,
void* arg2)
195 if (code1 == NULL || code2 == NULL)
201 while (next1 != NULL) {
202 if (!ir_code_node_equals(next1, next2))
207 return next2 == NULL ? arg1 : NULL;
215 static void* array_guest_ncode_cmp(
void* item,
void* arg)
221 if (strcmp(code1->
name, code2->
name) == 0)
227 void* s_malloc(
size_t size)
237 memset(ptr, 0, size);
241 char* s_strdup(
char*
string)
245 ptr = strdup(
string);
254 ir_code s_strtocode(
const char* val)
260 code = strtoull(val, &endptr, 0);
261 if ((code == (uint64_t) -1 && errno == ERANGE) || strlen(endptr) != 0 || strlen(val) == 0) {
262 log_error(
"error in configfile line %d:", line);
263 log_error(
"\"%s\": must be a valid (uint64_t) number", val);
270 uint32_t s_strtou32(
char* val)
275 n = strtoul(val, &endptr, 0);
276 if (!*val || *endptr) {
277 log_error(
"error in configfile line %d:", line);
278 log_error(
"\"%s\": must be a valid (uint32_t) number", val);
285 int s_strtoi(
char* val)
291 n = strtol(val, &endptr, 0);
293 if (!*val || *endptr || n != ((
long)h)) {
294 log_error(
"error in configfile line %d:", line);
295 log_error(
"\"%s\": must be a valid (int) number", val);
302 unsigned int s_strtoui(
char* val)
308 n = strtoul(val, &endptr, 0);
310 if (!*val || *endptr || n != ((uint32_t)h)) {
311 log_error(
"error in configfile line %d:", line);
312 log_error(
"\"%s\": must be a valid (unsigned int) number", val);
319 lirc_t s_strtolirc_t(
char* val)
325 n = strtoul(val, &endptr, 0);
327 if (!*val || *endptr || n != ((uint32_t)h)) {
328 log_error(
"error in configfile line %d:", line);
329 log_error(
"\"%s\": must be a valid (lirc_t) number", val);
334 log_warn(
"error in configfile line %d:", line);
335 log_warn(
"\"%s\" is out of range", val);
340 int checkMode(
int is_mode,
int c_mode,
char* error)
342 if (is_mode != c_mode) {
343 log_error(
"fatal error in configfile line %d:", line);
344 log_error(
"\"%s\" isn't valid at this position", error);
351 int addSignal(
struct void_array*
signals,
char* val)
366 memset(code, 0,
sizeof(*code));
367 code->
name = s_strdup(key);
368 code->
code = s_strtocode(val);
377 node = s_malloc(
sizeof(*node));
381 node->code = s_strtocode(val);
396 int parseFlags(
char* val)
404 while (flag != NULL) {
405 while (*help !=
'|' && *help != 0)
415 while (flaglptr->
name != NULL) {
416 if (strcasecmp(flaglptr->
name, flag) == 0) {
417 if (flaglptr->
flag & IR_PROTOCOL_MASK && flags & IR_PROTOCOL_MASK) {
418 log_error(
"error in configfile line %d:", line);
419 log_error(
"multiple protocols given in flags: \"%s\"", flag);
423 flags = flags | flaglptr->
flag;
429 if (flaglptr->
name == NULL) {
430 log_error(
"error in configfile line %d:", line);
442 int defineRemote(
char* key,
char* val,
char* val2,
struct ir_remote* rem)
444 if ((strcasecmp(
"name", key)) == 0) {
445 if (rem->
name != NULL)
446 free((
void*)(rem->
name));
447 rem->
name = s_strdup(val);
451 if (options_getboolean(
"lircd:dynamic-codes")) {
452 if ((strcasecmp(
"dyncodes_name", key)) == 0) {
458 }
else if (strcasecmp(
"driver", key) == 0) {
460 free((
void*)(rem->
driver));
461 rem->
driver = s_strdup(val);
463 }
else if ((strcasecmp(
"bits", key)) == 0) {
464 rem->
bits = s_strtoi(val);
466 }
else if (strcasecmp(
"flags", key) == 0) {
467 rem->
flags |= parseFlags(val);
469 }
else if (strcasecmp(
"eps", key) == 0) {
470 rem->
eps = s_strtoi(val);
472 }
else if (strcasecmp(
"aeps", key) == 0) {
473 rem->
aeps = s_strtoi(val);
475 }
else if (strcasecmp(
"plead", key) == 0) {
476 rem->
plead = s_strtolirc_t(val);
478 }
else if (strcasecmp(
"ptrail", key) == 0) {
479 rem->
ptrail = s_strtolirc_t(val);
481 }
else if (strcasecmp(
"pre_data_bits", key) == 0) {
484 }
else if (strcasecmp(
"pre_data", key) == 0) {
487 }
else if (strcasecmp(
"post_data_bits", key) == 0) {
490 }
else if (strcasecmp(
"post_data", key) == 0) {
493 }
else if (strcasecmp(
"gap", key) == 0) {
495 rem->
gap2 = s_strtou32(val2);
496 rem->
gap = s_strtou32(val);
497 return val2 != NULL ? 2 : 1;
498 }
else if (strcasecmp(
"repeat_gap", key) == 0) {
501 }
else if (strcasecmp(
"repeat_mask", key) == 0) {
506 else if (strcasecmp(
"toggle_bit", key) == 0) {
509 }
else if (strcasecmp(
"toggle_bit_mask", key) == 0) {
512 }
else if (strcasecmp(
"toggle_mask", key) == 0) {
515 }
else if (strcasecmp(
"rc6_mask", key) == 0) {
518 }
else if (strcasecmp(
"ignore_mask", key) == 0) {
521 }
else if (strcasecmp(
"manual_sort", key) == 0) {
526 else if (strcasecmp(
"repeat_bit", key) == 0) {
529 }
else if (strcasecmp(
"suppress_repeat", key) == 0) {
532 }
else if (strcasecmp(
"min_repeat", key) == 0) {
535 }
else if (strcasecmp(
"min_code_repeat", key) == 0) {
538 }
else if (strcasecmp(
"frequency", key) == 0) {
539 rem->
freq = s_strtoui(val);
541 }
else if (strcasecmp(
"duty_cycle", key) == 0) {
544 }
else if (strcasecmp(
"baud", key) == 0) {
545 rem->
baud = s_strtoui(val);
547 }
else if (strcasecmp(
"serial_mode", key) == 0) {
548 if (val[0] <
'5' || val[0] >
'9') {
549 log_error(
"error in configfile line %d:", line);
555 switch (toupper(val[1])) {
557 rem->
parity = IR_PARITY_NONE;
560 rem->
parity = IR_PARITY_EVEN;
563 rem->
parity = IR_PARITY_ODD;
566 log_error(
"error in configfile line %d:", line);
571 if (strcmp(val + 2,
"1.5") == 0)
576 }
else if (val2 != NULL) {
577 if (strcasecmp(
"header", key) == 0) {
578 rem->phead = s_strtolirc_t(val);
579 rem->
shead = s_strtolirc_t(val2);
581 }
else if (strcasecmp(
"three", key) == 0) {
582 rem->pthree = s_strtolirc_t(val);
583 rem->
sthree = s_strtolirc_t(val2);
585 }
else if (strcasecmp(
"two", key) == 0) {
586 rem->ptwo = s_strtolirc_t(val);
587 rem->
stwo = s_strtolirc_t(val2);
589 }
else if (strcasecmp(
"one", key) == 0) {
590 rem->pone = s_strtolirc_t(val);
591 rem->
sone = s_strtolirc_t(val2);
593 }
else if (strcasecmp(
"zero", key) == 0) {
594 rem->pzero = s_strtolirc_t(val);
595 rem->
szero = s_strtolirc_t(val2);
597 }
else if (strcasecmp(
"foot", key) == 0) {
598 rem->pfoot = s_strtolirc_t(val);
599 rem->
sfoot = s_strtolirc_t(val2);
601 }
else if (strcasecmp(
"repeat", key) == 0) {
602 rem->prepeat = s_strtolirc_t(val);
603 rem->
srepeat = s_strtolirc_t(val2);
605 }
else if (strcasecmp(
"pre", key) == 0) {
606 rem->pre_p = s_strtolirc_t(val);
607 rem->
pre_s = s_strtolirc_t(val2);
609 }
else if (strcasecmp(
"post", key) == 0) {
610 rem->post_p = s_strtolirc_t(val);
611 rem->
post_s = s_strtolirc_t(val2);
616 log_error(
"error in configfile line %d:", line);
617 log_error(
"unknown definiton: \"%s %s %s\"", key, val, val2);
619 log_error(
"error in configfile line %d:", line);
620 log_error(
"unknown definiton or too few arguments: \"%s %s\"", key, val);
626 static int sanityChecks(
struct ir_remote* rem,
const char* path)
631 path = path != NULL ? path :
"unknown file";
634 log_error(
"%s: Missing remote name", path);
638 log_warn(
"%s: %s: Gap value missing or invalid",
641 if (has_repeat_gap(rem) && is_const(rem)) {
642 log_warn(
"%s: %s: Repeat_gap ignored (CONST_LENGTH is set)",
651 "%s: %s: Invalid pre_data", path, rem->
name);
655 log_warn(
"%s: %s: Invalid post_data",
663 for (codes = rem->codes; codes->
name != NULL; codes++) {
664 if ((codes->
code & gen_mask(rem->
bits)) != codes->
code) {
665 log_warn(
"%s: %s: Invalid code : %s",
669 for (node = codes->
next; node != NULL; node = node->next) {
670 if ((node->code & gen_mask(rem->
bits)) != node->code) {
671 log_warn(
"%s: %s: Invalid code %s: %s",
673 node->code &= gen_mask(rem->
bits);
692 int r1_is_raw = is_raw(r1);
693 int r2_is_raw = is_raw(r2);
695 if (!r1_is_raw && r2_is_raw)
697 if (r1_is_raw && !r2_is_raw)
700 if (r1_is_raw && r2_is_raw) {
701 for (c = r1->codes, r1_size = 0; c->
name != NULL; c++)
703 for (c = r2->codes, r2_size = 0; c->
name != NULL; c++)
706 r1_size = bit_count(r1);
707 r2_size = bit_count(r2);
709 if (r1_size == r2_size)
711 return r1_size < r2_size ? -1 : 1;
728 for (r = remotes; r != NULL && r != (
void*)-1; r = r->next)
733 while (rem != NULL && rem != (
void*)-1) {
738 while (scan && remote_bits_cmp(scan, rem) <= 0) {
757 static const char* lirc_parse_include(
char* s)
766 while (last > s && strchr(whitespace, *last) != NULL)
770 if (*s !=
'"' && *s !=
'<')
772 if (*s ==
'"' && *last !=
'"')
774 else if (*s ==
'<' && *last !=
'>')
777 memmove(s, s + 1, len - 2 + 1);
784 static const char* lirc_parse_relative(
char* dst,
797 snprintf(dst, dst_size,
"%s", child);
800 if (strlen(current) >= dst_size)
802 strcpy(dst, current);
804 dirlen = strlen(dir);
806 memmove(dst, dir, dirlen + 1);
808 if (dirlen + 1 + strlen(child) + 1 > dst_size)
827 if (root == NULL && what != NULL)
831 for (r = root; r->next != NULL; r = r->next)
842 head = read_config_recursive(f, name, 0);
843 head = sort_by_bit_count(head);
859 read_included(
const char*
name,
int depth,
char* val,
struct ir_remote* top_rem)
862 const char* childName;
865 if (depth > MAX_INCLUDES) {
866 log_error(
"error opening child file defined at %s:%d", name, line);
870 childName = lirc_parse_include(val);
872 log_error(
"error parsing child file value defined at line %d:", line);
876 childFile = fopen(childName,
"r");
877 if (childFile == NULL) {
878 log_error(
"error opening child file '%s' defined at line %d:",
880 log_error(
"ignoring this child file for now.");
883 rem = read_config_recursive(childFile, childName, depth + 1);
884 top_rem = ir_remotes_append(top_rem, rem);
900 static struct ir_remote* read_all_included(
const char* name,
907 char buff[256] = {
'\0' };
909 memset(&globbuf, 0,
sizeof(globbuf));
911 val[strlen(val) - 1] =
'\0';
912 lirc_parse_relative(buff,
sizeof(buff), val, name);
913 glob(buff, 0, NULL, &globbuf);
914 for (i = 0; i < globbuf.gl_pathc; i += 1) {
915 snprintf(buff,
sizeof(buff),
"\"%s\"", globbuf.gl_pathv[i]);
916 top_rem = read_included(name, depth, buff, top_rem);
923 static void check_ncode_dups(
const char* path,
925 struct void_array* ar,
928 if (foreach_void_array(ar, array_guest_ncode_cmp, code) != NULL) {
929 log_notice(
"%s: %s: Multiple definitions of: %s",
930 path, name, code->
name);
932 if (foreach_void_array(ar, array_guest_code_equals, code) != NULL) {
933 log_notice(
"%s: %s: Multiple values for same code: %s",
934 path, name, code->
name);
940 read_config_recursive(FILE* f,
const char* name,
int depth)
942 char buf[LINE_LEN + 1];
949 struct void_array codes_list, raw_codes, signals;
950 struct ir_ncode raw_code = { NULL, 0, 0, NULL };
951 struct ir_ncode name_code = { NULL, 0, 0, NULL };
959 while (fgets(buf, LINE_LEN, f) != NULL) {
962 if (len == LINE_LEN && buf[len - 1] !=
'\n') {
963 log_error(
"line %d too long in config file", line);
970 if (buf[len] ==
'\n')
975 if (buf[len] ==
'\r')
981 key = strtok(buf, whitespace);
985 val = strtok(NULL, whitespace);
987 val2 = strtok(NULL, whitespace);
988 log_trace2(
"Tokens: \"%s\" \"%s\" \"%s\"", key, val, (val2 == NULL ?
"(null)" : val));
989 if (strcasecmp(
"include", key) == 0) {
990 int save_line = line;
992 top_rem = read_all_included(name,
997 }
else if (strcasecmp(
"begin", key) == 0) {
998 if (strcasecmp(
"codes", val) == 0) {
1001 if (!checkMode(mode, ID_remote,
"begin codes"))
1004 log_error(
"error in configfile line %d:", line);
1010 init_void_array(&codes_list, 30,
sizeof(
struct ir_ncode));
1012 }
else if (strcasecmp(
"raw_codes", val) == 0) {
1015 if (!checkMode(mode, ID_remote,
"begin raw_codes"))
1018 log_error(
"error in configfile line %d:", line);
1025 init_void_array(&raw_codes, 30,
sizeof(
struct ir_ncode));
1026 mode = ID_raw_codes;
1027 }
else if (strcasecmp(
"remote", val) == 0) {
1030 if (!checkMode(mode, ID_none,
"begin remote"))
1036 rem = top_rem = s_malloc(
sizeof(
struct ir_remote));
1037 rem->
freq = DEFAULT_FREQ;
1041 rem = s_malloc(
sizeof(
struct ir_remote));
1042 rem->
freq = DEFAULT_FREQ;
1043 ir_remotes_append(top_rem, rem);
1045 }
else if (mode == ID_codes) {
1046 code = defineCode(key, val, &name_code);
1047 while (!parse_error && val2 != NULL) {
1050 defineNode(code, val2);
1051 val2 = strtok(NULL, whitespace);
1054 check_ncode_dups(name, rem->
name, &codes_list, code);
1057 log_error(
"error in configfile line %d:", line);
1058 log_error(
"unknown section \"%s\"", val);
1061 if (!parse_error && val2 != NULL) {
1062 log_warn(
"%s: garbage after '%s' token "
1063 "in line %d ignored",
1064 rem->
name, val, line);
1066 }
else if (strcasecmp(
"end", key) == 0) {
1067 if (strcasecmp(
"codes", val) == 0) {
1070 if (!checkMode(mode, ID_codes,
"end codes"))
1074 }
else if (strcasecmp(
"raw_codes", val) == 0) {
1078 if (mode == ID_raw_name) {
1080 raw_code.
length = signals.nr_items;
1081 if (raw_code.
length % 2 == 0) {
1082 log_error(
"error in configfile line %d:", line);
1088 mode = ID_raw_codes;
1090 if (!checkMode(mode, ID_raw_codes,
"end raw_codes"))
1094 }
else if (strcasecmp(
"remote", val) == 0) {
1098 if (!checkMode(mode, ID_remote,
"end remote"))
1100 if (!sanityChecks(rem, name)) {
1104 if (options_getboolean(
"lircd:dynamic-codes")) {
1115 }
else if (mode == ID_codes) {
1116 code = defineCode(key, val, &name_code);
1117 while (!parse_error && val2 != NULL) {
1120 defineNode(code, val2);
1121 val2 = strtok(NULL, whitespace);
1126 log_error(
"error in configfile line %d:", line);
1130 if (!parse_error && val2 != NULL) {
1132 "%s: garbage after '%s'"
1133 " token in line %d ignored",
1134 rem->
name, val, line);
1139 argc = defineRemote(key, val, val2, rem);
1141 && ((argc == 1 && val2 != NULL)
1142 || (argc == 2 && val2 != NULL && strtok(NULL, whitespace) != NULL))) {
1144 " token in line %d ignored",
1145 rem->
name, key, line);
1149 code = defineCode(key, val, &name_code);
1150 while (!parse_error && val2 != NULL) {
1153 defineNode(code, val2);
1154 val2 = strtok(NULL, whitespace);
1157 check_ncode_dups(name,
1165 if (strcasecmp(
"name", key) == 0) {
1167 if (mode == ID_raw_name) {
1169 raw_code.
length = signals.nr_items;
1170 if (raw_code.
length % 2 == 0) {
1171 log_error(
"error in configfile line %d:",
1179 raw_code.
name = s_strdup(val);
1183 init_void_array(&signals, 50,
sizeof(lirc_t));
1185 if (!parse_error && val2 != NULL) {
1187 " token in line %d ignored",
1188 rem->
name, key, line);
1191 if (mode == ID_raw_codes) {
1192 log_error(
"no name for signal defined at line %d",
1197 if (!addSignal(&signals, key))
1199 if (!addSignal(&signals, val))
1202 if (!addSignal(&signals, val2))
1204 while ((val = strtok(NULL, whitespace)))
1205 if (!addSignal(&signals, val))
1211 }
else if (mode == ID_raw_name) {
1212 if (!addSignal(&signals, key))
1215 log_error(
"error in configfile line %d", line);
1222 if (mode != ID_none) {
1225 if (raw_code.
name != NULL) {
1226 free(raw_code.
name);
1243 static int print_error = 1;
1246 log_error(
"reading of file '%s' failed", name);
1258 while (rem != NULL) {
1259 if ((!is_raw(rem)) && rem->
flags & REVERSE) {
1267 while (codes->
name != NULL) {
1278 int all_bits = bit_count(rem);
1283 int all_bits = bit_count(rem);
1285 if (has_toggle_bit_mask(rem)) {
1286 log_warn(
"%s uses both toggle_bit and toggle_bit_mask", rem->
name);
1292 if (has_toggle_bit_mask(rem)) {
1293 if (!is_raw(rem) && rem->codes) {
1295 if (rem->toggle_bit_mask_state)
1300 if (is_serial(rem)) {
1303 if (rem->
baud > 0) {
1304 base = 1000000 / rem->
baud;
1305 if (rem->pzero == 0 && rem->
szero == 0)
1307 if (rem->pone == 0 && rem->
sone == 0)
1315 log_warn(
"invalid min_code_repeat value");
1319 calculate_signal_lengths(rem);
1326 void calculate_signal_lengths(
struct ir_remote* remote)
1328 if (is_const(remote)) {
1336 lirc_t min_signal_length = 0, max_signal_length = 0;
1337 lirc_t max_pulse = 0, max_space = 0;
1339 struct ir_ncode* c = remote->codes;
1352 code.
code = next->code;
1355 for (repeat = 0; repeat < 2; repeat++) {
1356 if (init_sim(remote, &code, repeat)) {
1360 if (first_sum || sum < min_signal_length)
1361 min_signal_length = sum;
1362 if (first_sum || sum > max_signal_length)
1363 max_signal_length = sum;
1387 }
else if (is_const(remote)) {
1391 log_warn(
"min_gap_length is 0 for '%s' remote",
1398 log_warn(
"max_gap_length is 0 for '%s' remote", remote->
name);
1414 while (remotes != NULL) {
1415 next = remotes->next;
1419 if (remotes->
name != NULL)
1420 free((
void*)(remotes->
name));
1421 if (remotes->codes != NULL) {
1422 codes = remotes->codes;
1423 while (codes->
name != NULL) {
1432 next_node = node->next;
1438 free(remotes->codes);
One remote as represented in the configuration file.
int bits
bits (length of code)
const lirc_t * send_buffer_data(void)
lirc_t min_total_signal_length
how long is the shortest signal including gap
#define NO_FOOT_REP
no foot for key repeats
#define RC6
IR data follows RC6 protocol.
An ir_code for entering into (singly) linked lists, i.e.
unsigned int freq
modulation frequency
lirc_t max_gap_length
how long is the longest gap
void *(* array_guest_func)(void *item, void *arg)
foreach_void_array argument.
#define GOLDSTAR
encoding found on Goldstar remote
lirc_t max_total_signal_length
how long is the longest signal including gap
ir_code post_data
data which the remote sends after actual keycode
lirc_t post_s
signal between keycode and post_code
lirc_t plead
leading pulse
ir_code repeat_mask
mask defines which bits are inverted for repeats
struct ir_code_node * next
Linked list of the subsequent ir_code's, after the first one.
unsigned int baud
can be overridden by [p|s]zero, [p|s]one
const char * name
name of remote control
#define SPACE_ENC
IR data is space encoded.
void free_config(struct ir_remote *remotes)
Free() an ir_remote instance obtained using read_config().
lirc_t * signals
(private)
#define COMPAT_REVERSE
compatibility mode for REVERSE flag
int eps
eps (relative tolerance)
struct ir_ncode * last_code
code received or sent last
unsigned int parity
currently unsupported
#define log_warn(fmt,...)
Log a warning message.
lirc_t ptrail
trailing pulse
int pre_data_bits
length of pre_data
lirc_t min_gap_length
how long is the shortest gap
int manual_sort
If set in any remote, disables automatic sorting.
logchannel_t
Log channels used to filter messages.
Description of flag to print.
char * name
Name of command.
#define log_trace2(fmt,...)
Log a trace2 message.
struct ir_code_node * current
Should point at the ir_code currently being transmitted, or NULL if none.
unsigned int duty_cycle
int post_data_bits
length of post_data
lirc_t sthree
3 (only used for RC-MM)
#define RCMM
IR data follows RC-MM protocol.
ir_code toggle_mask
Sharp (?) error detection scheme.
#define log_trace1(fmt,...)
Log a trace1 message.
#define log_error(fmt,...)
Log an error message.
ir_code pre_data
data which the remote sends before actual keycode
lirc_t send_buffer_sum(void)
uint32_t gap
time between signals in usecs
#define log_trace(fmt,...)
Log a trace message.
#define RC5
IR data follows RC5 protocol.
char * dyncodes_name
name for unknown buttons
uint32_t repeat_gap
time between two repeat codes if different from gap
#define REPEAT_HEADER
header is also sent before repeat code
#define SPACE_FIRST
bits are encoded as space+pulse
#define CONST_LENGTH
signal length+gap is always constant
uint32_t gap2
time between signals in usecs
#define NO_HEAD_REP
no header for key repeats
unsigned int stop_bits
mapping: 1->2 1.5->3 2->4
lirc_t pre_s
signal between pre_data and keycode
#define GRUNDIG
encoding found on Grundig remote
void * get_void_array(struct void_array *ar)
Return the array dataptr, an array[nr_items] of item_size elements.
IR Command, corresponding to one (command defining) line of the configuration file.
lirc_t stwo
2 (only used for RC-MM)
unsigned int aeps
detecting very short pulses is difficult with relative tolerance for some remotes, this is an absolute tolerance to solve this problem usually you can say 0 here.
lirc_t srepeat
indicate repeating
#define SERIAL
serial protocol
#define SHIFT_ENC
IR data is shift encoded (name obsolete)
#define BO
encoding found on Bang & Olufsen remote
int suppress_repeat
suppress unwanted repeats
ir_code code
The first code of the command.
const char * driver
Name of driver for LIRCCODE cases.
unsigned int min_code_repeat
meaningful only if remote sends a repeat code: in this case this value indicates how often the real c...
const struct flaglist all_flags[]
All flags i config file: Their name and mask.
struct ir_ncode dyncodes[2]
helper structs for unknown buttons
ir_code rc6_mask
RC-6 doubles signal length of some bits.
int send_buffer_length(void)
Do not document this function.
#define log_info(fmt,...)
Log an info message.
ir_code toggle_bit_mask
previously only one bit called toggle_bit
int min_repeat
code is repeated at least x times code sent once -> min_repeat=0
#define RAW_CODES
for internal use only
struct ir_remote * read_config(FILE *f, const char *name)
Parse a lircd.conf config file.
#define log_notice(fmt,...)
Log a notice message.
ir_code ignore_mask
mask defines which bits can be ignored when matching a code
uint64_t ir_code
Denotes an internal coded representation for an IR transmission.
unsigned int bits_in_byte
default: 8
int add_void_array(struct void_array *ar, void *dataptr)
Add *dataptr to end of ar, re-allocating as necessary.