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 
 
#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. 
 
void *(* array_guest_func)(void *item, void *arg)
foreach_void_array argument. 
 
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.