TEST_F(ConfigTest, config_no_bad_keys) { config_t *config = config_new(CONFIG_FILE); EXPECT_FALSE(config_has_key(config, "DID_BAD", "primaryRecord")); EXPECT_FALSE(config_has_key(config, "DID", "primaryRecord_BAD")); EXPECT_FALSE(config_has_key(config, CONFIG_DEFAULT_SECTION, "primaryRecord")); config_free(config); }
TEST_F(ConfigTest, config_has_keys) { config_t *config = config_new(CONFIG_FILE); EXPECT_TRUE(config_has_key(config, "DID", "recordNumber")); EXPECT_TRUE(config_has_key(config, "DID", "primaryRecord")); EXPECT_TRUE(config_has_key(config, "DID", "productId")); EXPECT_TRUE(config_has_key(config, "DID", "version")); config_free(config); }
TEST_F(ConfigTest, config_remove_key) { config_t *config = config_new(CONFIG_FILE); EXPECT_EQ(config_get_int(config, "DID", "productId", 999), 0x1200); EXPECT_TRUE(config_remove_key(config, "DID", "productId")); EXPECT_FALSE(config_has_key(config, "DID", "productId")); config_free(config); }
TEST_F(ConfigTest, config_remove_section) { config_t *config = config_new(CONFIG_FILE); EXPECT_TRUE(config_remove_section(config, "DID")); EXPECT_FALSE(config_has_section(config, "DID")); EXPECT_FALSE(config_has_key(config, "DID", "productId")); config_free(config); }
bool btif_config_exist(const char *section, const char *key) { assert(config != NULL); assert(section != NULL); assert(key != NULL); pthread_mutex_lock(&lock); bool ret = config_has_key(config, section, key); pthread_mutex_unlock(&lock); return ret; }
bool btc_config_exist(const char *section, const char *key) { assert(config != NULL); assert(section != NULL); assert(key != NULL); osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT); bool ret = config_has_key(config, section, key); osi_mutex_unlock(&lock); return ret; }
bool btif_config_get_int(const char *section, const char *key, int *value) { assert(config != NULL); assert(section != NULL); assert(key != NULL); assert(value != NULL); pthread_mutex_lock(&lock); bool ret = config_has_key(config, section, key); if (ret) *value = config_get_int(config, section, key, *value); pthread_mutex_unlock(&lock); return ret; }
bool btc_config_get_int(const char *section, const char *key, int *value) { assert(config != NULL); assert(section != NULL); assert(key != NULL); assert(value != NULL); osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT); bool ret = config_has_key(config, section, key); if (ret) { *value = config_get_int(config, section, key, *value); } osi_mutex_unlock(&lock); return ret; }
void btc_config_save(void) { assert(config != NULL); // Garbage collection process: the config file accumulates // cached information about remote devices during regular // inquiry scans. We remove some of these junk entries // so the file doesn't grow indefinitely. We have to take care // to make sure we don't remove information about bonded // devices (hence the check for link keys). static const size_t CACHE_MAX = 256; const char *keys[CACHE_MAX]; size_t num_keys = 0; size_t total_candidates = 0; osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT); for (const config_section_node_t *snode = config_section_begin(config); snode != config_section_end(config); snode = config_section_next(snode)) { const char *section = config_section_name(snode); if (!string_is_bdaddr(section)) { continue; } if (config_has_key(config, section, "LinkKey") || config_has_key(config, section, "LE_KEY_PENC") || config_has_key(config, section, "LE_KEY_PID") || config_has_key(config, section, "LE_KEY_PCSRK") || config_has_key(config, section, "LE_KEY_LENC") || config_has_key(config, section, "LE_KEY_LCSRK")) { continue; } if (num_keys < CACHE_MAX) { keys[num_keys++] = section; } ++total_candidates; } if (total_candidates > CACHE_MAX * 2) while (num_keys > 0) { config_remove_section(config, keys[--num_keys]); } config_save(config, CONFIG_FILE_PATH); osi_mutex_unlock(&lock); }
TEST_F(ConfigTest, config_has_key_in_default_section) { config_t *config = config_new(CONFIG_FILE); EXPECT_TRUE(config_has_key(config, CONFIG_DEFAULT_SECTION, "first_key")); EXPECT_STREQ(config_get_string(config, CONFIG_DEFAULT_SECTION, "first_key", "meow"), "value"); config_free(config); }
/** recursively read the menu hierarchy */ MenuEntry *menu_read(MenuEntry *parent, const char *name) { static int id = 0; if ((name != NULL) && (config_has_section(name))) { MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements if (me == NULL) return NULL; // set common entries me->id = id++; me->name = strdup(name); if (me->name == NULL) { //menu_free(me); return NULL; } me->displayname = strdup(config_get_string(name, "DisplayName", 0, name)); if (me->displayname == NULL) { //menu_free(me); return NULL; } me->parent = parent; me->next = NULL; me->children = NULL; me->numChildren = 0; if (config_get_string(name, "Entry", 0, NULL) != NULL) { MenuEntry **addr = &me->children; const char *entryname; // it is a sub-menu me->type = MT_MENU; // read menu entries while ((entryname = config_get_string(name, "Entry", me->numChildren, NULL)) != NULL) { MenuEntry *entry = menu_read(me, entryname); if (entry == NULL) { //menu_free(me); return NULL; } me->numChildren++; *addr = entry; addr = &entry->next; } } else if (config_get_string(name, "Exec", 0, NULL) != NULL) { MenuEntry **addr = &me->children; const char *entryname; // it's a command to execute me->type = MT_EXEC; me->data.exec.command = strdup(config_get_string(name, "Exec", 0, "")); if (me->data.exec.command == NULL) { //menu_free(me); return NULL; } me->data.exec.feedback = config_get_bool(name, "Feedback", 0, 0); // try to read parameters while ((entryname = config_get_string(name, "Parameter", me->numChildren, NULL)) != NULL) { MenuEntry *entry = menu_read(me, entryname); if (entry == NULL) { //menu_free(me); return NULL; } me->numChildren++; *addr = entry; addr = &entry->next; } // automagically add an "Apply ?" action if ((me->numChildren > 0) && (addr != NULL)) *addr = menu_read(me, NULL); } else if (config_get_string(name, "Type", 0, NULL) != NULL) { // it's a command parameter const char *type; type = config_get_string(name, "Type", 0, ""); if (strcasecmp(type, "slider") == 0) { char buf[35]; me->type = MT_ARG_SLIDER; me->data.slider.value = config_get_int(name, "Value", 0, 0); me->data.slider.minval = config_get_int(name, "MinValue", 0, 0); me->data.slider.maxval = config_get_int(name, "MaxValue", 0, 1000); sprintf(buf, "%d", me->data.slider.minval); me->data.slider.mintext = strdup(config_get_string(name, "MinText", 0, buf)); sprintf(buf, "%d", me->data.slider.maxval); me->data.slider.maxtext = strdup(config_get_string(name, "MaxText", 0, buf)); me->data.slider.stepsize = config_get_int(name, "StepSize", 0, 1); } else if (strcasecmp(type, "ring") == 0) { const char *tmp; int numStrings = 0; int i = 0; me->type = MT_ARG_RING; me->data.ring.value = config_get_int(name, "Value", 0, 0); numStrings = config_has_key(name, "String"); me->data.ring.strings = calloc(sizeof(char *), numStrings+1); me->data.ring.strings[numStrings] = NULL; while ((tmp = config_get_string(name, "String", i, NULL)) != NULL) { me->data.ring.strings[i] = strdup(tmp); i++; } me->data.ring.strings[i] = NULL; } else if (strcasecmp(type, "numeric") == 0) { me->type = MT_ARG_NUMERIC; me->data.numeric.value = config_get_int(name, "Value", 0, 0); me->data.numeric.minval = config_get_int(name, "MinValue", 0, 0); me->data.numeric.maxval = config_get_int(name, "MaxValue", 0, 1000); } else if (strcasecmp(type, "alpha") == 0) { me->type = MT_ARG_ALPHA; me->data.alpha.value = strdup(config_get_string(name, "Value", 0, "")); me->data.alpha.minlen = config_get_int(name, "MinLength", 0, 0); me->data.alpha.maxlen = config_get_int(name, "MaxLength", 0, 100); me->data.alpha.allowed = strdup(config_get_string(name, "AllowedChars", 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")); } else if (strcasecmp(type, "ip") == 0) { me->type = MT_ARG_IP; me->data.ip.value = strdup(config_get_string(name, "Value", 0, "")); me->data.ip.v6 = config_get_bool(name, "Value", 0, 0); } else if (strcasecmp(type, "checkbox") == 0) { const char *tmp; me->type = MT_ARG_CHECKBOX; me->data.checkbox.allow_gray = config_get_bool(name, "AllowGray", 0, 0); me->data.checkbox.value = (me->data.checkbox.allow_gray) ? config_get_tristate(name, "Value", 0, "gray", 0) : config_get_bool(name, "Value", 0, 0); // get replacement strings for different values tmp = config_get_string(name, "OffText", 0, NULL); me->data.checkbox.map[0] = (tmp != NULL) ? strdup(tmp) : NULL; tmp = config_get_string(name, "OnText", 0, NULL); me->data.checkbox.map[1] = (tmp != NULL) ? strdup(tmp) : NULL; tmp = config_get_string(name, "GrayText", 0, NULL); me->data.checkbox.map[2] = (tmp != NULL) ? strdup(tmp) : NULL; } else { report(RPT_DEBUG, "illegal parameter type"); //menu_free(me); return NULL; } } else { report(RPT_DEBUG, "unknown menu entry type"); //menu_free(me); return NULL; } return me; } else { /* the magic stuff: if name is NULL and parent is an EXEC entry, * then generate an Action entry with the name "Apply" */ if ((name == NULL) && (parent != NULL) && (parent->type = MT_EXEC)) { MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements if (me == NULL) return NULL; // set common entries me->id = id++; me->name = malloc(strlen(parent->name) + 10); if (me->name == NULL) { //menu_free(me); return NULL; } strcpy(me->name, "Apply_"); strcat(me->name, parent->name); me->displayname = strdup("Apply!"); if (me->displayname == NULL) { //menu_free(me); return NULL; } me->parent = parent; me->next = NULL; me->children = NULL; me->numChildren = 0; me->type = MT_ARG_ACTION | MT_AUTOMATIC; return me; } } return NULL; }