From: Chanwoo Choi Date: Wed, 28 Jul 2021 01:01:07 +0000 (+0900) Subject: pass: parser: Convert script format to json to improve readability X-Git-Tag: submit/tizen/20210809.032652~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=284147ad7bbdbb0b9ee98d9be0f31ec85221de79;p=platform%2Fcore%2Fsystem%2Fpass.git pass: parser: Convert script format to json to improve readability The legacy .conf file format is not better on side of readability. So that change the configuration file format to json style to improve readability. Change-Id: I056971e4674ccfee703d3b55636575f8a0d83fbd Signed-off-by: Chanwoo Choi --- diff --git a/CMakeLists.txt b/CMakeLists.txt index be26532..b381166 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,6 @@ SET(SRCS src/thermal/thermal.c src/thermal/thermal-parser.c src/core/common.c - src/core/config-parser.c src/core/device-notifier.c src/core/devices.c src/core/main.c diff --git a/include/pass/common.h b/include/pass/common.h index 851212c..25d079e 100644 --- a/include/pass/common.h +++ b/include/pass/common.h @@ -94,7 +94,6 @@ typedef unsigned long long uint64; #endif int sys_get_str(const char *fname, char *str); -int sys_strtol(const char *str); const char *get_string_from_object(json_object *obj, const char *key); const int get_int_from_object(json_object *obj, const char *key); diff --git a/include/pass/config-parser.h b/include/pass/config-parser.h deleted file mode 100644 index 32a0d9b..0000000 --- a/include/pass/config-parser.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * PASS - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __CONFIG_PARSER_H__ -#define __CONFIG_PARSER_H__ - -#define MATCH(a, b) (!strncmp(a, b, strlen(a))) -#define SET_CONF(a, b) (a = (b > 0.0 ? b : a)) - -struct parse_result { - char *section; - char *name; - char *value; -}; - -/** - * @brief Parse config file and call callback\n - * @param[in] file_name conf file. - * @param[in] cb cb is called when conf file is parsed line by line. - * @param[in] user_data user data is passed to cb. - * @return 0 on success, negative if failed - */ -int config_parse(const char *file_name, int cb(struct parse_result *result, - void *user_data), void *user_data); - -#endif diff --git a/src/core/common.c b/src/core/common.c index 66fe952..17f9f23 100644 --- a/src/core/common.c +++ b/src/core/common.c @@ -73,17 +73,6 @@ int sys_get_str(const char *fname, char *str) return -1; } -int sys_strtol(const char *str) -{ - long value; - - value = strtol(str, (char**)NULL, 10); - if (value > INT_MAX || value < INT_MIN) - return -EINVAL; - - return (int)value; -} - const char *get_string_from_object(json_object *obj, const char *key) { json_object *tmp = NULL; diff --git a/src/core/config-parser.c b/src/core/config-parser.c deleted file mode 100644 index b13a5b2..0000000 --- a/src/core/config-parser.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * PASS - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include - -#define BUFF_MAX 255 -#define MAX_SECTION 64 -#define WHITESPACE " \t" -#define NEWLINE "\n\r" -#define COMMENT '#' - -static inline char *trim_str(char *s) -{ - char *t; - /* left trim */ - s += strspn(s, WHITESPACE); - - /* right trim */ - for (t = strchr(s, 0); t > s; t--) - if (!strchr(WHITESPACE, t[-1])) - break; - *t = 0; - return s; -} - -int config_parse(const char *file_name, int cb(struct parse_result *result, - void *user_data), void *user_data) -{ - FILE *f = NULL; - struct parse_result result; - /* use stack for parsing */ - char line[BUFF_MAX]; - char section[MAX_SECTION]; - char *start, *end, *name, *value; - int lineno = 0, ret = 0; - - if (!file_name || !cb) { - ret = -EINVAL; - goto error; - } - - /* open conf file */ - f = fopen(file_name, "r"); - if (!f) { - ret = -EIO; - goto error; - } - - /* parsing line by line */ - while (fgets(line, BUFF_MAX, f) != NULL) { - lineno++; - - start = line; - start[strcspn(start, NEWLINE)] = '\0'; - start = trim_str(start); - - if (*start == COMMENT) { - continue; - } else if (*start == '[') { - /* parse section */ - end = strchr(start, ']'); - if (!end || *end != ']') { - ret = -EBADMSG; - goto error; - } - - *end = '\0'; - strncpy(section, start + 1, sizeof(section)); - section[MAX_SECTION-1] = '\0'; - } else if (*start) { - /* parse name & value */ - end = strchr(start, '='); - if (!end || *end != '=') { - ret = -EBADMSG; - goto error; - } - *end = '\0'; - name = trim_str(start); - value = trim_str(end + 1); - end = strchr(value, COMMENT); - if (end && *end == COMMENT) { - *end = '\0'; - value = trim_str(value); - } - - result.section = section; - result.name = name; - result.value = value; - /* callback with parse result */ - ret = cb(&result, user_data); - if (ret < 0) { - ret = -EBADMSG; - goto error; - } - } - } - - fclose(f); - return 0; - -error: - if (f) - fclose(f); - return ret; -} diff --git a/src/pass/pass-cpuhp.c b/src/pass/pass-cpuhp.c index 5345e03..7aaadb9 100644 --- a/src/pass/pass-cpuhp.c +++ b/src/pass/pass-cpuhp.c @@ -42,7 +42,6 @@ #include #include -#include #include "pass.h" #include "pass-rescon.h" diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index dac9724..77ebfd4 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -39,7 +39,6 @@ #include #include -#include #include #include "pass.h" @@ -49,7 +48,8 @@ #define MAX_TIMEOUT_SEC 3600.0 /* 1 hour */ #define INIT_VALUE -1 -static int compare_compatible_name(char *compatible, char *path_compatible) +static int compare_compatible_name(const char *compatible, + const char *path_compatible) { char buf[BUFF_MAX]; int len, ret; @@ -76,23 +76,6 @@ static int compare_compatible_name(char *compatible, char *path_compatible) return 0; } -static enum pass_state is_supported(char *value) -{ - enum pass_state state; - - if (!value) - return -EINVAL; - - if (MATCH(value, "yes")) - state = PASS_ON; - else if (MATCH(value, "no")) - state = PASS_OFF; - else - state = PASS_UNUSED; - - return state; -} - static void init_scenario(struct pass_scenario *scenario) { scenario->state = PASS_UNUSED; @@ -111,58 +94,56 @@ static void init_scenario(struct pass_scenario *scenario) /** * @brief Parse scenario section to get scenario name and information - * @param [in] result Parsed raw data from configuration + * @param [in] res Instance of h/w resource + * @param [in] obj Instance of json_object for h/w resource * @param [in] scenario Parsed data of a scenario will be saved to it * @return @c 0 on success, otherwise error value */ -static int parse_scenario(struct parse_result *result, +static int parse_scenario(struct pass_resource *res, json_object *obj, struct pass_scenario *scenario) { - int ret; - - if (!result || !scenario) - return 0; - - if (!result->section || !result->name || !result->value) - return 0; + const char *name = NULL; + int support; + int target_level; + int cpuhp_min_level; + int cpuhp_max_level; + int temperature; + int timer_interval_ms; + + /* Get property values */ + name = get_string_from_object(obj, "name"); + support = get_boolean_from_object(obj, "support"); + target_level= get_int_from_object(obj, "target_level"); + + /* - property for only pmqos module */ + cpuhp_min_level = get_int_from_object(obj, "cpuhp_min_level"); + cpuhp_max_level = get_int_from_object(obj, "cpuhp_max_level"); + + /* - property for only thermal module */ + temperature = get_int_from_object(obj, "temperature"); + timer_interval_ms = get_int_from_object(obj, "timer_interval_ms"); + + /* Check the mandatory property values are valid or not */ + if (!name) { + _E("Failed to get 'name' property in scenario section\n"); + return -EINVAL; + } else if (target_level < 0) { + _E("Failed to get 'target_level' property in scenario section\n"); + return -EINVAL; + } - /* Parse 'Scenario' section */ - if (MATCH(result->name, "name")) { - snprintf(scenario->name, BUFF_MAX, "%s", result->value); - } else if (MATCH(result->name, "support")) { - scenario->state = is_supported(result->value); - if (scenario->state < 0) - return -EINVAL; - } else if (MATCH(result->name, "scenario_level")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - scenario->level = ret; + /* Initialize config_data from property values of confiugartion file */ + snprintf(scenario->name, NAME_MAX, "%s", name); + scenario->state = (support < 0) ? 1 : support; + scenario->level = target_level; - /* Parse properties for only PASS_MODULE_PMQOS */ - } else if (MATCH(result->name, "min_level")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - scenario->pmqos.min_level = ret; - } else if (MATCH(result->name, "max_level")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - scenario->pmqos.max_level = ret; + /* - property for only pmqos module */ + scenario->pmqos.min_level = cpuhp_min_level; + scenario->pmqos.max_level = cpuhp_max_level; - /* Parse properties for only PASS_MODULE_THERMAL */ - } else if (MATCH(result->name, "temperature")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - scenario->thermal.temperature = ret; - } else if (MATCH(result->name, "timer_interval_ms")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - scenario->thermal.timer_interval = ret; - } + /* - property for only thermal module */ + scenario->thermal.temperature = temperature; + scenario->thermal.timer_interval = timer_interval_ms; return 0; } @@ -206,7 +187,7 @@ static int verify_level(int res_type, int level_idx, struct pass_level *level) return 0; } -static void init_level(struct pass_level *level) +static void initialize_level(struct pass_level *level) { level->limit_max_freq = INIT_VALUE; level->limit_min_freq = INIT_VALUE; @@ -234,16 +215,75 @@ static void init_level(struct pass_level *level) level->fault_around_bytes = INIT_VALUE; } -static int parse_level(struct parse_result *result, - struct pass_level *level) +static int parse_level(struct pass_resource *res, json_object *obj, + struct pass_level *target_level, int level_idx) { - int ret; - - if (!result || !level) - return 0; + int level; + int minimum_frequency_khz; + int maximum_frequency_khz; + int number_of_minimum_cpu; + int number_of_maximum_cpu; + int num_down_cond; + int num_down_cond_freq; + int num_down_cond_nr_running; + int num_down_cond_busy_cpu; + int num_up_cond; + int num_up_cond_freq; + int num_up_cond_nr_running; + int num_up_cond_busy_cpu; + int num_right_cond; + int num_right_cond_freq; + int num_right_cond_nr_running; + int num_right_cond_busy_cpu; + int num_left_cond; + int num_left_cond_freq; + int num_left_cond_nr_running; + int num_left_cond_busy_cpu; + double governor_timeout_sec; + int fault_around_bytes; + + /* Get property values */ + level = get_int_from_object(obj, "level"); + minimum_frequency_khz = get_int_from_object(obj, "dvfs,minimum_frequency_khz"); + maximum_frequency_khz = get_int_from_object(obj, "dvfs,maximum_frequency_khz"); + number_of_minimum_cpu = get_int_from_object(obj, "hotplug,number_of_minimum_cpu"); + number_of_maximum_cpu = get_int_from_object(obj, "hotplug,number_of_maximum_cpu"); + + num_down_cond = get_int_from_object(obj, "hotplug,num_down_cond"); + num_down_cond_freq = get_int_from_object(obj, "hotplug,num_down_cond_freq"); + num_down_cond_nr_running = get_int_from_object(obj, "hotplug,num_down_cond_nr_running"); + num_down_cond_busy_cpu = get_int_from_object(obj, "hotplug,num_down_cond_busy_cpu"); + + num_up_cond = get_int_from_object(obj, "hotplug,num_up_cond"); + num_up_cond_freq = get_int_from_object(obj, "hotplug,num_up_cond_freq"); + num_up_cond_nr_running = get_int_from_object(obj, "hotplug,num_up_cond_nr_running"); + num_up_cond_busy_cpu = get_int_from_object(obj, "hotplug,num_up_cond_busy_cpu"); + + num_right_cond = get_int_from_object(obj, "hotplug,num_right_cond"); + num_right_cond_freq = get_int_from_object(obj, "hotplug,num_right_cond_freq"); + num_right_cond_nr_running = get_int_from_object(obj, "hotplug,num_right_cond_nr_running"); + num_right_cond_busy_cpu = get_int_from_object(obj, "hotplug,num_right_cond_busy_cpu"); + + num_left_cond = get_int_from_object(obj, "hotplug,num_left_cond"); + num_left_cond_freq = get_int_from_object(obj, "hotplug,num_left_cond_freq"); + num_left_cond_nr_running = get_int_from_object(obj, "hotplug,num_left_cond_nr_running"); + num_left_cond_busy_cpu = get_int_from_object(obj, "hotplug,num_left_cond_busy_cpu"); + + governor_timeout_sec = get_double_from_object(obj, "hotplug,governor_timeout_sec"); + + fault_around_bytes = get_int_from_object(obj, "memory,fault_around_bytes"); + + /* Check the mandatory property values are valid or not */ + if (level < 0) { + _E("Failed to get 'level' property in 'level_list' section\n"); + return -EINVAL; + } else if (level != level_idx) { + _E("Invalid 'level' property value(%d) in 'level_list' section\n", + level); + return -EINVAL; + } - if (!result->section || !result->name || !result->value) - return 0; + /* Initialize config_data from property values of confiugartion file */ /* * Properties for the following h/w resources: @@ -251,189 +291,115 @@ static int parse_level(struct parse_result *result, * - PASS_RESOURCE_BUS_ID * - PASS_RESOURCE_GPU_ID */ - if (MATCH(result->name, "limit_max_freq")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->limit_max_freq = ret; - } else if (MATCH(result->name, "limit_min_freq")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->limit_min_freq = ret; + if (minimum_frequency_khz >= 0) + target_level->limit_min_freq = minimum_frequency_khz; + if (maximum_frequency_khz >= 0) + target_level->limit_max_freq = maximum_frequency_khz; /* * Properties for the following h/w resources: * - PASS_RESOURCE_CPU_ID */ - } else if (MATCH(result->name, "limit_max_cpu")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->limit_max_cpu = ret; - } else if (MATCH(result->name, "limit_min_cpu")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->limit_min_cpu = ret; - } else if (MATCH(result->name, "num_down_cond")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->num_down_cond = ret; - } else if (MATCH(result->name, "num_down_cond_freq")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->down_cond[0].freq = ret; - } else if (MATCH(result->name, "num_down_cond_nr_running")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->down_cond[0].nr_running = ret; - } else if (MATCH(result->name, "num_down_cond_busy_cpu")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->down_cond[0].busy_cpu = ret; - - } else if (MATCH(result->name, "num_up_cond")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->num_up_cond = ret; - } else if (MATCH(result->name, "num_up_cond_freq")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->up_cond[0].freq = ret; - } else if (MATCH(result->name, "num_up_cond_nr_running")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->up_cond[0].nr_running = ret; - } else if (MATCH(result->name, "num_up_cond_busy_cpu")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->up_cond[0].busy_cpu = ret; - - } else if (MATCH(result->name, "num_left_cond")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->num_left_cond = ret; - } else if (MATCH(result->name, "num_left_cond_freq")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->left_cond[0].freq = ret; - } else if (MATCH(result->name, "num_left_cond_nr_running")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->left_cond[0].nr_running = ret; - } else if (MATCH(result->name, "num_left_cond_busy_cpu")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->left_cond[0].busy_cpu = ret; - - } else if (MATCH(result->name, "num_right_cond")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->num_right_cond = ret; - } else if (MATCH(result->name, "num_right_cond_freq")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->right_cond[0].freq = ret; - } else if (MATCH(result->name, "num_right_cond_nr_running")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->right_cond[0].nr_running = ret; - } else if (MATCH(result->name, "num_right_cond_busy_cpu")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->right_cond[0].busy_cpu = ret; - - } else if (MATCH(result->name, "gov_timeout")) { - double gov_timeout = strtod(result->value, (char **)NULL); - - if (gov_timeout < MIN_TIMEOUT_SEC - || gov_timeout > MAX_TIMEOUT_SEC) - gov_timeout = MIN_TIMEOUT_SEC; - - level->gov_timeout = gov_timeout; + if (number_of_minimum_cpu >= 0) + target_level->limit_min_cpu = number_of_minimum_cpu; + if (number_of_maximum_cpu >= 0) + target_level->limit_max_cpu = number_of_maximum_cpu; + + if (num_down_cond >= 0) + target_level->num_down_cond = num_down_cond; + if (num_down_cond_freq >= 0) + target_level->down_cond[0].freq = num_down_cond_freq; + if (num_down_cond_nr_running >= 0) + target_level->down_cond[0].nr_running = num_down_cond_nr_running; + if (num_down_cond_busy_cpu >= 0) + target_level->down_cond[0].busy_cpu = num_down_cond_busy_cpu; + + if (num_up_cond >= 0) + target_level->num_up_cond = num_up_cond; + if (num_up_cond_freq >= 0) + target_level->up_cond[0].freq = num_up_cond_freq; + if (num_up_cond_nr_running >= 0) + target_level->up_cond[0].nr_running = num_up_cond_nr_running; + if (num_up_cond_busy_cpu >= 0) + target_level->up_cond[0].busy_cpu = num_up_cond_busy_cpu; + + if (num_left_cond >= 0) + target_level->num_left_cond = num_left_cond; + if (num_left_cond_freq >= 0) + target_level->left_cond[0].freq = num_left_cond_freq; + if (num_left_cond_nr_running >= 0) + target_level->left_cond[0].nr_running = num_left_cond_nr_running; + if (num_left_cond_busy_cpu >= 0) + target_level->left_cond[0].busy_cpu = num_left_cond_busy_cpu; + + if (num_right_cond >= 0) + target_level->num_right_cond = num_right_cond; + if (num_right_cond_freq >= 0) + target_level->right_cond[0].freq = num_right_cond_freq; + if (num_right_cond_nr_running >= 0) + target_level->right_cond[0].nr_running = num_right_cond_nr_running; + if (num_right_cond_busy_cpu >= 0) + target_level->right_cond[0].busy_cpu = num_right_cond_busy_cpu; + + if (governor_timeout_sec >= 0) { + if (governor_timeout_sec < MIN_TIMEOUT_SEC + || governor_timeout_sec > MAX_TIMEOUT_SEC) + governor_timeout_sec = MIN_TIMEOUT_SEC; + target_level->gov_timeout = governor_timeout_sec; + } /* * Properties for the following h/w resources: * - PASS_RESOURCE_MEMORY_ID */ - } else if (MATCH(result->name, "fault_around_bytes")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->fault_around_bytes = ret; - } + if (fault_around_bytes >= 0) + target_level->fault_around_bytes = fault_around_bytes; return 0; } /** * @brief Parse pmqos section to get PASS_MODULE_PMQOS information - * @param [in] result Parsed raw data from configuration - * @param [in] user_data Instance of h/w resource + * @param [in] res Instance of h/w resource + * @param [in] obj Instance of json_object for h/w resource * @return @c 0 on success, otherwise error value */ -static int parse_pmqos(struct parse_result *result, void *user_data) +static int parse_pmqos(struct pass_resource *res, json_object *obj) { - struct pass_resource *res = user_data; - struct pass_pmqos *pmqos = &res->pmqos; - - if (!result) - return 0; - - if (!result->section || !result->name || !result->value) + int pmqos_support; + json_object *pmqos_scenario_list = NULL; + int num_scenarios = 0, ret, i; + + /* Get property values */ + pmqos_support = get_boolean_from_object(obj, "pmqos_support"); + if (json_object_object_get_ex(obj, "pmqos_scenario_list", + &pmqos_scenario_list)) + num_scenarios = json_object_array_length(pmqos_scenario_list); + + /* Check the mandatory property values are valid or not */ + if (pmqos_support <= 0) return 0; - /* Parse 'PassScenario' section */ - if (MATCH(result->name, "pass_scenario_support")) { - pmqos->state = is_supported(result->value); - if (pmqos->state < 0) - return -EINVAL; + /* Initialize config_data from property values of confiugartion file */ + res->pmqos.state = pmqos_support; + res->pmqos.scenarios = calloc(num_scenarios, + sizeof(struct pass_scenario)); + if (!res->pmqos.scenarios) { + _E("cannot allocate memory for Scenario\n"); + return -EINVAL; + } + res->pmqos.num_scenarios = num_scenarios; - } else if (MATCH(result->name, "pass_num_scenarios")) { - unsigned int num_scenarios; - int ret; + for (i = 0; i < res->pmqos.num_scenarios; i++) { + json_object *scenario_obj + = json_object_array_get_idx(pmqos_scenario_list, i); + struct pass_scenario *scenario = &(res->pmqos.scenarios[i]); - ret = sys_strtol(result->value); - if (ret < 0) + init_scenario(scenario); + ret = parse_scenario(res, scenario_obj, scenario); + if (ret < 0) { + _E("cannot parse 'pmqos.scenario%d' section\n", i); return ret; - num_scenarios = ret; - - if (num_scenarios > MAX_NUM) { - _E("cannot parse %s\n", result->name); - return -EINVAL; - } - - if (num_scenarios > 0 && !pmqos->scenarios) { - int i; - - pmqos->scenarios = calloc(num_scenarios, - sizeof(struct pass_scenario)); - if (!pmqos->scenarios) { - _E("cannot allocate memory for Scenario\n"); - return -EINVAL; - } - - pmqos->num_scenarios = num_scenarios; - - for (i = 0; i < num_scenarios; i++) - init_scenario(&pmqos->scenarios[i]); } } @@ -442,515 +408,419 @@ static int parse_pmqos(struct parse_result *result, void *user_data) /** * @brief Parse thermal section to get PASS_MODULE_THERMAL information - * @param [in] result Parsed raw data from configuration - * @param [in] user_data Instance of h/w resource + * @param [in] res Instance of h/w resource + * @param [in] obj Instance of json_object for h/w resource * @return @c 0 on success, otherwise error value */ -static int parse_thermal(struct parse_result *result, void *user_data) +static int parse_thermal(struct pass_resource *res, json_object *obj) { - struct pass_resource *res = user_data; - struct pass_thermal *thermal = &res->thermal; - int ret; - - if (!result) - return 0; - - if (!result->section || !result->name || !result->value) + int thermal_support; + int thermal_timer_interval_ms; + json_object *thermal_scenario_list = NULL; + int num_scenarios = 0, ret, i; + + /* Get property values */ + thermal_support = get_boolean_from_object(obj, "thermal_support"); + thermal_timer_interval_ms + = get_int_from_object(obj, "thermal_timer_interval_ms"); + if (json_object_object_get_ex(obj, "thermal_scenario_list", + &thermal_scenario_list)) + num_scenarios = json_object_array_length(thermal_scenario_list); + + /* Check the mandatory property values are valid or not */ + if (thermal_support <= 0) return 0; - /* Parse 'thermal' section */ - if (MATCH(result->name, "thermal_support")) { - thermal->state = is_supported(result->value); - if (thermal->state < 0) - return -EINVAL; - } else if (MATCH(result->name, "thermal_number_of_scenario")) { - unsigned int num_scenarios; - - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - num_scenarios = ret; + /* Initialize config_data from property values of confiugartion file */ + res->thermal.state = thermal_support; + res->thermal.timer_interval = thermal_timer_interval_ms; - if (num_scenarios > MAX_NUM) { - _E("cannot parse %s\n", result->name); - return -EINVAL; - } - - if (num_scenarios > 0 && !thermal->scenarios) { - int i; + res->thermal.scenarios = calloc(num_scenarios, + sizeof(struct pass_scenario)); + if (!res->thermal.scenarios) { + _E("cannot allocate memory for Scenario\n"); + return -EINVAL; + } + res->thermal.num_scenarios = num_scenarios; - thermal->scenarios = calloc(num_scenarios, - sizeof(struct pass_scenario)); - if (!thermal->scenarios) { - _E("cannot allocate memory for Scenario\n"); - return -EINVAL; - } - thermal->num_scenarios = num_scenarios; + for (i = 0; i < res->thermal.num_scenarios; i++) { + json_object *scenario_obj + = json_object_array_get_idx(thermal_scenario_list, i); + struct pass_scenario *scenario = &(res->thermal.scenarios[i]); - for (i = 0; i < num_scenarios; i++) - init_scenario(&thermal->scenarios[i]); - } - } else if (MATCH(result->name, "thermal_timer_interval_ms")) { - ret = sys_strtol(result->value); - if (ret < 0) + init_scenario(scenario); + ret = parse_scenario(res, scenario_obj, scenario); + if (ret < 0) { + _E("cannot parse 'thermal.scenario%d' section\n", i); return ret; - thermal->timer_interval = ret; + } } return 0; } /** - * @brief Parse core section to get module information - * @param [in] result Parsed raw data from configuration - * @param [in] user_data Instance of h/w resource + * @brief Parse cpuhp section to get module information + * @param [in] res Instance of h/w resource + * @param [in] obj Instance of json_object for h/w resource * @return @c 0 on success, otherwise error value */ -static int parse_core(struct parse_result *result, void *user_data) +static int parse_cpuhp(struct pass_resource *res, json_object *obj) { - struct pass_resource *res = user_data; - int ret; - - if (!result) + int cpuhp_support; + int cpuhp_governor; + double cpuhp_timer_interval_sec; + int cpuhp_min_level; + int cpuhp_max_level; + int cpuhp_init_level; + int cpuhp_cpu_threshold; + int cpuhp_up_threshold; + int cpuhp_down_threshold; + json_object *cpuhp_level_list = NULL; + int cpuhp_num_levels = 0, ret, i; + + /* Get property values */ + cpuhp_support = get_int_from_object(obj, "cpuhp_support"); + cpuhp_governor = get_int_from_object(obj, "cpuhp_governor"); + cpuhp_timer_interval_sec = get_int_from_object(obj, "cpuhp_timer_interval_sec"); + cpuhp_min_level = get_int_from_object(obj, "cpuhp_min_level"); + cpuhp_max_level = get_int_from_object(obj, "cpuhp_max_level"); + cpuhp_init_level = get_int_from_object(obj, "cpuhp_init_level"); + cpuhp_cpu_threshold = get_int_from_object(obj, "cpuhp_cpu_threshold"); + cpuhp_up_threshold = get_int_from_object(obj, "cpuhp_up_threshold"); + cpuhp_down_threshold= get_int_from_object(obj, "cpuhp_down_threshold"); + + if (json_object_object_get_ex(obj, "cpuhp_level_list", &cpuhp_level_list)) + cpuhp_num_levels = json_object_array_length(cpuhp_level_list); + + /* Check the mandatory property values are valid or not */ + if (cpuhp_support <= 0) { return 0; - - if (!result->section || !result->name || !result->value) - return 0; - - if (MATCH(result->name, "pass_support")) { - int state; - - state = sys_strtol(result->value); - if (state < 0) - return state; - res->config_data.state = state; - } else if (MATCH(result->name, "pass_gov_type")) { - int gov_type; - - gov_type = sys_strtol(result->value); - if (gov_type < 0) - return gov_type; - res->config_data.gov_type = gov_type; - } else if (MATCH(result->name, "pass_num_levels")) { - int num_levels; - - num_levels = sys_strtol(result->value); - if (num_levels < 0) - return num_levels; - if (num_levels > MAX_NUM) { - _E("cannot parse %s\n", result->name); - return -EINVAL; - } - res->config_data.num_levels = num_levels; - } else if (MATCH(result->name, "pass_min_level")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - res->rescon.min_level = ret; - } else if (MATCH(result->name, "pass_max_level")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - res->rescon.max_level = ret; - } else if (MATCH(result->name, "pass_init_level")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - res->rescon.init_level = ret; - - } else if (MATCH(result->name, "pass_num_scenario_levels")) { - int num_scenario_levels; - - num_scenario_levels = sys_strtol(result->value); - if (num_scenario_levels < 0) - return num_scenario_levels; - if (num_scenario_levels > MAX_NUM) { - _E("cannot parse %s\n", result->name); - return -EINVAL; - } - res->config_data.num_scenario_levels = num_scenario_levels; - } else if (MATCH(result->name, "pass_init_scenario_level")) { - unsigned int init_level; - - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - init_level = ret; - - if (init_level > MAX_NUM) { - _E("cannot parse %s\n", result->name); - return -EINVAL; - } - res->rescon.init_scenario_level = init_level; - - } else if (MATCH(result->name, "pass_cpu_threshold")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - res->cpuhp.pass_cpu_threshold = ret; - } else if (MATCH(result->name, "pass_up_threshold")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - res->cpuhp.up_threshold = ret; - } else if (MATCH(result->name, "pass_down_threshold")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - res->cpuhp.down_threshold = ret; - } else if (MATCH(result->name, "pass_governor_timeout")) { - res->config_data.gov_timeout - = strtod(result->value, (char **)NULL); - - if (res->config_data.gov_timeout < MIN_TIMEOUT_SEC - || res->config_data.gov_timeout > MAX_TIMEOUT_SEC) - res->config_data.gov_timeout = MIN_TIMEOUT_SEC; + } else if (cpuhp_governor < 0) { + _E("Failed to get 'cpuhp_governor' property\n"); + return -EINVAL; + } else if (!cpuhp_level_list) { + _E("Failed to get 'cpuhp_level_list' property\n"); + return -EINVAL; + } else if (cpuhp_num_levels <= 0) { + _E("Must need to add at least one level in 'cpuhp_level_list' section\n"); + return -EINVAL; } - if (res->config_data.num_levels > 0 && !res->config_data.levels) { - int i; + /* Initialize config_data from property values of confiugartion file */ + /* - core */ + res->config_data.state = cpuhp_support; + res->config_data.gov_type = cpuhp_governor; + res->config_data.gov_timeout = cpuhp_timer_interval_sec; + if (res->config_data.gov_timeout < MIN_TIMEOUT_SEC + || res->config_data.gov_timeout > MAX_TIMEOUT_SEC) + res->config_data.gov_timeout = MIN_TIMEOUT_SEC; + + /* - properties for rescon module */ + res->rescon.min_level = cpuhp_min_level; + res->rescon.max_level = cpuhp_max_level; + res->rescon.init_level = cpuhp_init_level; + + /* - properties for cpuhp module */ + res->cpuhp.pass_cpu_threshold = cpuhp_cpu_threshold; + res->cpuhp.up_threshold = cpuhp_up_threshold; + res->cpuhp.down_threshold = cpuhp_down_threshold; + + res->config_data.num_levels = cpuhp_num_levels; + res->config_data.levels = calloc(res->config_data.num_levels, + sizeof(struct pass_level)); + if (!res->config_data.levels) { + _E("cannot allocate memory for cpuhp level list\n"); + return -EINVAL; + } - res->config_data.levels = calloc(res->config_data.num_levels, - sizeof(struct pass_level)); - if (!res->config_data.levels) { - _E("cannot allocate memory for levels\n"); - return -EINVAL; - } + for (i = 0; i < res->config_data.num_levels; i++) { + json_object *level_obj = json_object_array_get_idx(cpuhp_level_list, i); + struct pass_level *level = &res->config_data.levels[i]; - /* Initialize pass_level before parsing */ - for (i = 0; i < res->config_data.num_levels; i++) - init_level(&res->config_data.levels[i]); - } else if (res->config_data.num_scenario_levels > 0 - && !res->config_data.scenario_levels) { - int i; - - res->config_data.scenario_levels = - calloc(res->config_data.num_scenario_levels, - sizeof(struct pass_level)); - if (!res->config_data.scenario_levels) { - _E("cannot allocate memory for levels\n"); - return -EINVAL; + initialize_level(level); + ret = parse_level(res, level_obj, level, i); + if (ret < 0) { + _E("cannot parse level%d in 'level_list' section\n", i); + return ret; } - - /* Initialize scenariop pass_level before parsing */ - for (i = 0; i < res->config_data.num_scenario_levels; i++) - init_level(&res->config_data.scenario_levels[i]); } return 0; } + /** - * @brief Parse configuration for each h/w resource - * @param [in] result Parsed raw data from configuration - * @param [in] user_data Instance of h/w resource + * @brief Parse core section to get module information + * @param [in] res Instance of h/w resource + * @param [in] obj Instance of json_object for h/w resource * @return @c 0 on success, otherwise error value */ -static int parse_each_resource(struct parse_result *result, void *user_data) +static int parse_header(struct pass_resource *res, json_object *obj) { - struct pass_resource *res = user_data; - struct pass_pmqos *pmqos = &res->pmqos; - struct pass_thermal *thermal = &res->thermal; - struct pass_level *level; - char section_name[BUFF_MAX]; - int i, ret; - - if (!result) - return 0; - - if (!result->section || !result->name || !result->value) - return 0; - - /* Parsing 'PASS' section */ - if (MATCH(result->section, "Pass")) { - ret = parse_core(result, user_data); - if (ret < 0) { - _E("cannot parse the core part\n"); - return ret; - } - - goto out; + int support; + int init_level; + json_object *level_list = NULL; + int num_levels = 0, ret, i; + + /* Get property values */ + support = get_boolean_from_object(obj, "support"); + init_level = get_int_from_object(obj, "init_level"); + if (json_object_object_get_ex(obj, "level_list", &level_list)) + num_levels = json_object_array_length(level_list); + + /* Check the mandatory property values are valid or not */ + if (support < 0) { + _E("Failed to get 'support' property\n"); + return -EINVAL; + } else if (!level_list) { + _E("Failed to get 'level_list' property\n"); + return -EINVAL; + } else if (num_levels <= 0) { + _E("Must need to add at least one level in 'level_list' section\n"); + return -EINVAL; + } else if (init_level > num_levels) { + _E("Invalid 'init_level' in core section\n"); + return -EINVAL; } - /* Parsing 'Level' section */ - for (i = 0; i < res->config_data.num_levels; i++) { - ret = snprintf(section_name, BUFF_MAX, "Level%d", i); + if (init_level < 0) + init_level = 0; - if (MATCH(result->section, section_name)) { - ret = parse_level(result, &res->config_data.levels[i]); - if (ret < 0) { - _E("cannot parse 'Level%d' section\n", i); - return ret; - } - goto out; - } + /* Initialize config_data from property values of confiugartion file */ + res->config_data.state = support; + res->config_data.num_scenario_levels = num_levels; + res->rescon.init_scenario_level = init_level; + res->config_data.scenario_levels = calloc( + res->config_data.num_scenario_levels, + sizeof(struct pass_level)); + if (!res->config_data.scenario_levels) { + _E("cannot allocate memory for scenario level list\n"); + return -EINVAL; } - /* Parsing 'ScenarioLevel' section */ for (i = 0; i < res->config_data.num_scenario_levels; i++) { - ret = snprintf(section_name, BUFF_MAX, "ScenarioLevel%d", i); - - if (MATCH(result->section, section_name)) { - level = &res->config_data.scenario_levels[i]; - - ret = parse_level(result, level); - if (ret < 0) { - _E("cannot parse 'ScenarioLevel%d' section\n", i); - return ret; - } + json_object *level_obj = json_object_array_get_idx(level_list, i); + struct pass_level *level = &res->config_data.scenario_levels[i]; - goto out; - } - } - - /* Parsing 'PassScenario' section */ - if (MATCH(result->section, "PassScenario")) { - ret = parse_pmqos(result, user_data); + initialize_level(level); + ret = parse_level(res, level_obj, level, i); if (ret < 0) { - _E("cannot parse 'PassScenario' section\n"); + _E("cannot parse level%d in 'level_list' section\n", i); return ret; } - - goto out; } - /* Parsing 'Scenario' section */ - for (i = 0; i < pmqos->num_scenarios; i++) { - ret = snprintf(section_name, BUFF_MAX, "Scenario%d", i); + return 0; +} - if (MATCH(result->section, section_name)) { - ret = parse_scenario(result, &pmqos->scenarios[i]); - if (ret < 0) { - _E("cannot parse 'Scenario%d' section\n", i); - return ret; - } +/** + * @brief Parse configuration for each h/w resource + * @param [in] res Instance of h/w resource + * @param [in] obj Instance of json_object for h/w resource + * @return @c 0 on success, otherwise error value + */ +static int parse_each_resource(struct pass_resource *res, json_object *obj) +{ + int ret; - goto out; - } + /* Parse header */ + ret = parse_header(res, obj); + if (ret < 0) { + _E("cannot parse the core part\n"); + return ret; } - /* Parsing 'thermal' section */ - if (MATCH(result->section, "thermal")) { - ret = parse_thermal(result, user_data); - if (ret < 0) { - _E("cannot parse 'thermal' section\n"); - return ret; - } - - goto out; + /* Parse pmqos module */ + ret = parse_pmqos(res, obj); + if (ret < 0) { + _E("cannot parse 'PassScenario' section\n"); + return ret; } - /* Parsing 'thermal.scenario' section */ - for (i = 0; i < thermal->num_scenarios; i++) { - ret = snprintf(section_name, BUFF_MAX, "thermal.scenario%d", i); - - if (MATCH(result->section, section_name)) { - ret = parse_scenario(result, &thermal->scenarios[i]); - if (ret < 0) { - _E("cannot parse 'thermal.scenario%d' section\n", i); - return ret; - } + /* Parse thermal module */ + ret = parse_thermal(res, obj); + if (ret < 0) { + _E("cannot parse 'thermal' section\n"); + return ret; + } - goto out; - } + /* Parse cpuhp module */ + ret = parse_cpuhp(res, obj); + if (ret < 0) { + _E("cannot parse the cpuhp part\n"); + return ret; } -out: return 0; } /** * @brief Parse resource section in pass.conf for each h/w resource - * @param [in] result Parsed raw data from configuration - * @param [in] user_data Instance of h/w resource - * @param [in] id Resource index number + * @param [in] pass Instance of struct pass + * @param [in] obj Instance of json_object for h/w resource * @return @c 0 on success, otherwise error value */ -static int parse_resource_data(struct parse_result *result, - void *user_data, int id) +static int parse_resource_data(struct pass *pass, int id, json_object *obj) { - char buf[BUFF_MAX]; - struct pass *pass = user_data; struct pass_resource_config_data *config_data = &(pass->res[id].config_data); - int ret; - - if (!result) - return 0; + const char *device_type; + const char *device_name; + const char *thermal_device_name; + const char *device_config_path; + const char *cpu_load_path; + int number_of_cpus; + int first_cpu; + + /* Get property values */ + /* - mandatory properties */ + device_type = get_string_from_object(obj, "device_type"); + device_name = get_string_from_object(obj, "device_name"); + device_config_path = get_string_from_object(obj, "device_config_path"); + + /* - optional properties */ + thermal_device_name = get_string_from_object(obj, "thermal_device_name"); + + /* - optional properties for only CPU */ + cpu_load_path = get_string_from_object(obj, "cpu,cpu_load_path"); + number_of_cpus = get_int_from_object(obj, "cpu,number_of_cpus"); + first_cpu = get_int_from_object(obj, "cpu,first_cpu"); + + /* Check the mandatory property values are valid or not */ + if (!device_type) { + _E("Failed to get 'device_type' property of resource in 'device_list' of %s\n", + config_data->res_name); + return -EINVAL; + } else if (!device_name) { + _E("Failed to get 'device_name' property of resource in 'device_list' of %s\n", + config_data->res_name); + return -EINVAL; + } else if (!device_config_path) { + _E("Failed to get 'device_config_path' property of resource in 'device_list' of %s\n", + config_data->res_name); + return -EINVAL; + } - if (MATCH(result->name, "pass_res_type")) { - int i; - - memset(buf, 0, BUFF_MAX); - for (i = 0; i < strlen(result->value); i++) - buf[i] = tolower(result->value[i]); - - if (!strncmp(buf, PASS_RESOURCE_CPU_NAME, strlen(buf))) - config_data->res_type = PASS_RESOURCE_CPU_ID; - else if (!strncmp(buf, PASS_RESOURCE_GPU_NAME, strlen(buf))) - config_data->res_type = PASS_RESOURCE_GPU_ID; - else if (!strncmp(buf, PASS_RESOURCE_BUS_NAME, strlen(buf))) - config_data->res_type = PASS_RESOURCE_BUS_ID; - else if (!strncmp(buf, PASS_RESOURCE_MEMORY_NAME, strlen(buf))) - config_data->res_type = PASS_RESOURCE_MEMORY_ID; - else if (!strncmp(buf, PASS_RESOURCE_NONSTANDARD_NAME, strlen(buf))) - config_data->res_type = PASS_RESOURCE_NONSTANDARD_ID; - else - return -EINVAL; - } else if (MATCH(result->name, "pass_res_name")) { - snprintf(config_data->res_name, BUFF_MAX, "%s", result->value); - } else if (MATCH(result->name, "pass_res_thermal_name")) { - snprintf(config_data->res_thermal_name, BUFF_MAX, "%s", result->value); - } else if (MATCH(result->name, "pass_path_conf_file")) { - snprintf(config_data->path_conf_file, BUFF_MAX, "%s", result->value); - } else if (MATCH(result->name, "pass_path_load_table")) { - snprintf(config_data->path_load_table, BUFF_MAX, "%s", result->value); - } else if (MATCH(result->name, "pass_first_cpu")) { - int res_type = config_data->res_type; - - switch (res_type) { - case PASS_RESOURCE_CPU_ID: - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - config_data->cpu = ret; - break; - default: - return -EINVAL; - } - } else if (MATCH(result->name, "pass_num_cpus")) { - int res_type = config_data->res_type; - - switch (res_type) { - case PASS_RESOURCE_CPU_ID: - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - config_data->num_cpus = ret; - break; - default: + switch (config_data->res_type) { + case PASS_RESOURCE_CPU_ID: + if (number_of_cpus < 0 || first_cpu < 0) { + _E("Invalid 'number_of_cpus'(%d) or 'first_cpu'(%d) property value of %s\n", + number_of_cpus, first_cpu, config_data->res_name); return -EINVAL; } + break; + default: + break; + } + + /* Initialize config_data from property values of confiugartion file */ + if (!strncmp(device_type, PASS_RESOURCE_CPU_NAME, strlen(device_type))) + config_data->res_type = PASS_RESOURCE_CPU_ID; + else if (!strncmp(device_type, PASS_RESOURCE_GPU_NAME, strlen(device_type))) + config_data->res_type = PASS_RESOURCE_GPU_ID; + else if (!strncmp(device_type, PASS_RESOURCE_BUS_NAME, strlen(device_type))) + config_data->res_type = PASS_RESOURCE_BUS_ID; + else if (!strncmp(device_type, PASS_RESOURCE_MEMORY_NAME, strlen(device_type))) + config_data->res_type = PASS_RESOURCE_MEMORY_ID; + else if (!strncmp(device_type, PASS_RESOURCE_NONSTANDARD_NAME, strlen(device_type))) + config_data->res_type = PASS_RESOURCE_NONSTANDARD_ID; + else { + _E("Unknown 'device_type' property value (%s)\n", device_type); + return -EINVAL; } + snprintf(config_data->res_name, BUFF_MAX, "%s", device_name); + snprintf(config_data->res_thermal_name, BUFF_MAX, "%s", thermal_device_name); + snprintf(config_data->path_conf_file, BUFF_MAX, "%s", device_config_path); + snprintf(config_data->path_load_table, BUFF_MAX, "%s", cpu_load_path); + config_data->num_cpus = number_of_cpus; + config_data->cpu = first_cpu; + return 0; } /** * @brief Parse pass.conf for all h/w resources to get list of supported * h/w resources - * @param [in] result Parsed raw data from configuration - * @param [in] user_data Instance of h/w resource + * @param [in] pass Instance of struct pass + * @param [in] obj Instance of json_object for h/w resource * @return @c 0 on success, otherwise error value */ -static int parse_resource(struct parse_result *result, void *user_data) +static int parse_resource(struct pass *pass, json_object *obj) { - static char path[BUFF_MAX]; - static bool is_compatible = false; - static char compatible[BUFF_MAX]; - struct pass *pass = user_data; - char section_name[BUFF_MAX]; - int id, len, ret; - - if (!result) - return 0; + json_object *device_list = NULL; + const char *board_name = NULL; + const char *board_name_path = NULL; + int num_resources = 0, ret, i; + + /* Get property values */ + /* - mandatory properties */ + board_name = get_string_from_object(obj, "board_name"); + board_name_path = get_string_from_object(obj, "board_name_path"); + if (json_object_object_get_ex(obj, "device_list", &device_list)) + num_resources = json_object_array_length(device_list); + + /* Check the mandatory property values are valid or not */ + if (!board_name || !board_name_path) { + _E("Failed to get 'board_name' property\n"); + return -EINVAL; + } else if (!device_list) { + _E("Failed to get 'device_list' property\n"); + return -EINVAL; + } else if (num_resources <= 0) { + _E("Must need to add at least one resource in 'device_list' section\n"); + return -EINVAL; + } - if (!result->section || !result->name || !result->value) - return 0; + ret = compare_compatible_name(board_name, board_name_path); + if (ret < 0) { + _E("Cannot match 'board_name' from 'board_name_path'\n"); + return -EINVAL; + } - /* Parsing 'PassResource' section */ - if (MATCH(result->section, "PassResource")) { - if (MATCH(result->name, "pass_compatible")) { - len = strlen(result->value); - snprintf(compatible, len + 1, "%s", result->value); - - len = strlen(path); - if (len > 0) { - ret = compare_compatible_name(compatible, path); - if (ret < 0) - return ret; - - is_compatible = true; - } - } else if (MATCH(result->name, "pass_path_compatible")) { - len = strlen(result->value); - snprintf(path, len + 1, "%s", result->value); - - len = strlen(compatible); - if (len > 0) { - ret = compare_compatible_name(compatible, path); - if (ret < 0) - return ret; - - is_compatible = true; - } - } else if (MATCH(result->name, "pass_num_resources")) { - unsigned int num_resources; - int i, ret; - - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - num_resources = ret; - - if ((num_resources > MAX_NUM) || - (num_resources < 1)) { - _E("cannot parse %s\n", result->name); - return -EINVAL; - } - - pass->res = calloc(num_resources, - sizeof(struct pass_resource)); - if (!pass->res) { - _E("cannot allocate the memory for resource"); - return -ENOMEM; - } - - pass->num_resources = num_resources; - - /* Set init. value of initdata for each h/w resource */ - for (i = 0; i < num_resources ; i++) { - struct pass_resource *cur; - - cur = &pass->res[i]; - - cur->init_data.dvfs.governor = NULL; - cur->init_data.dvfs.min_freq = -1; - cur->init_data.dvfs.max_freq = -1; - cur->init_data.dvfs.up_threshold = -1; - - cur->init_data.hotplug.online_state = NULL; - cur->init_data.hotplug.online_min_num = -1; - cur->init_data.hotplug.online_max_num = -1; - - cur->init_data.memory.fault_around_bytes = -1; - } - } else { - _E("cannot parse the number of resource\n"); - return -ENOENT; - } + /* Initialize config_data from property values of confiugartion file */ + pass->res = calloc(num_resources, sizeof(struct pass_resource)); + if (!pass->res) { + _E("Cannot allocate the memory for resources"); + return -ENOMEM; } + pass->num_resources = num_resources; + + for (i = 0; i < num_resources ; i++) { + struct pass_resource *cur; + json_object *resource_obj = + json_object_array_get_idx(device_list, i); + + cur = &pass->res[i]; + + cur->init_data.dvfs.governor = NULL; + cur->init_data.dvfs.min_freq = -1; + cur->init_data.dvfs.max_freq = -1; + cur->init_data.dvfs.up_threshold = -1; - /* Parsing 'PassResource[X]' section */ - for (id = 0; id < pass->num_resources; id++) { - ret = snprintf(section_name, BUFF_MAX, "PassResource%d", id); - - if (MATCH(section_name, result->section)) { - if (!is_compatible) { - _E("cannot match [compatible] with the string read from [path]\n"); - return -EINVAL; - } - ret = parse_resource_data(result, pass, id); - if (ret < 0) { - _E("cannot parse 'PassResource%d' section\n", - id); - return ret; - } + cur->init_data.hotplug.online_state = NULL; + cur->init_data.hotplug.online_min_num = -1; + cur->init_data.hotplug.online_max_num = -1; + + cur->init_data.memory.fault_around_bytes = -1; + + ret = parse_resource_data(pass, i, resource_obj); + if (ret < 0) { + _E("cannot parse of %dth resource in 'device_list' section\n", i); + ret = -EINVAL; + goto err; } } return 0; + +err: + pass->num_resources = 0; + free(pass->res); + + return ret; } /** @@ -961,7 +831,23 @@ static int parse_resource(struct parse_result *result, void *user_data) */ int pass_parser_get_resource_config(struct pass *pass, char *path) { - return config_parse(path, parse_resource, pass); + int ret; + json_object *obj = NULL; + + obj = json_object_from_file(path); + if (!obj) { + _E("Failed to get json_object from %s (%s)\n", + path, json_util_get_last_err()); + return -EINVAL; + } + + ret = parse_resource(pass, obj); + if (ret < 0) + _E("Failed to parse resource from %s\n", path); + + json_object_put(obj); + + return ret; } /** @@ -988,6 +874,7 @@ int pass_parser_get_each_resource_config(struct pass_resource *res, char *path) struct pass_pmqos *pmqos; struct pass_thermal *thermal; int ret, i; + json_object *obj = NULL; if (!res) return -EINVAL; @@ -1021,13 +908,20 @@ int pass_parser_get_each_resource_config(struct pass_resource *res, char *path) /* Initialize the Thermal's data */ thermal->state = PASS_UNUSED; - /* Parse pass_level */ - ret = config_parse(path, parse_each_resource, res); - if (ret < 0) { - _E("cannot parse %s\n", path); + /* Parse configuration */ + obj = json_object_from_file(path); + if (!obj) { + _E("Failed to get json_object from %s (%s)\n", + path, json_util_get_last_err()); return -EINVAL; } + ret = parse_each_resource(res, obj); + if (ret < 0) { + _E("Failed to parse %s\n", path); + goto out; + } + /* Verify the parsed pass_level */ for (i = 0; i < res->config_data.num_levels; i++) ret |= verify_level(res->config_data.res_type, @@ -1036,7 +930,7 @@ int pass_parser_get_each_resource_config(struct pass_resource *res, char *path) if (ret < 0) { _E("failed to verify Level of '%s' resource\n", res->config_data.res_name); - return -EINVAL; + goto out; } /* Verify the parsed scenario pass_level */ @@ -1047,18 +941,23 @@ int pass_parser_get_each_resource_config(struct pass_resource *res, char *path) if (ret < 0) { _E("failed to verify ScenarioLevel of '%s' resource\n", res->config_data.res_name); - return -EINVAL; + goto out; } - if (res->config_data.state == PASS_UNUSED) - return -EINVAL; + if (res->config_data.state == PASS_UNUSED) { + ret = -EINVAL; + goto out; + } if (pmqos->state == PASS_UNUSED) _W("don't include the list of pass-scenario\n"); else if (pmqos->state == PASS_OFF) _I("cannot use pass-scenario"); - return 0; +out: + json_object_put(obj); + + return ret; } /** diff --git a/src/pass/pass-pmqos.c b/src/pass/pass-pmqos.c index 8ac9187..484377f 100644 --- a/src/pass/pass-pmqos.c +++ b/src/pass/pass-pmqos.c @@ -33,7 +33,6 @@ #include #include -#include #include "pass.h" #include "pass-rescon.h" @@ -60,7 +59,7 @@ static int find_scenario_index(struct pass_pmqos *pmqos, char *name) int index; for (index = 0; index < pmqos->num_scenarios; index++) - if (MATCH(pmqos->scenarios[index].name, name)) + if (!strncmp(pmqos->scenarios[index].name, name, strlen(name))) return index; return -EINVAL; diff --git a/src/pass/pass.c b/src/pass/pass.c index ae9592f..a92513f 100644 --- a/src/pass/pass.c +++ b/src/pass/pass.c @@ -42,7 +42,7 @@ #include "pass-parser.h" #include "pass-hal.h" -#define PASS_CONF_PATH "/hal/etc/pass/pass.conf" +#define PASS_JSON_PATH "/hal/etc/pass/pass.json" /** * @brief Specify the supported modules according to the type of h/w @@ -205,7 +205,8 @@ static int pass_init_resource(struct pass_resource *res) int i; /* Get configuration of each resource from pass-resource*.conf */ - ret = pass_parser_get_each_resource_config(res, res->config_data.path_conf_file); + ret = pass_parser_get_each_resource_config(res, + res->config_data.path_conf_file); if (ret < 0) { _E("cannot parse %s\n", res->config_data.path_conf_file); return -1; @@ -361,9 +362,9 @@ static int pass_init_done(void *data, void *user_data) int i, ret; /* Get configuration of resource list from pass.conf */ - ret = pass_parser_get_resource_config(&g_pass, PASS_CONF_PATH); + ret = pass_parser_get_resource_config(&g_pass, PASS_JSON_PATH); if (ret < 0) { - _E("cannot parse %s\n", PASS_CONF_PATH); + _E("cannot parse %s\n", PASS_JSON_PATH); return ret; } diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 12a56db..b940c73 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -3,7 +3,6 @@ PROJECT(pass C CXX) SET(SRCS ${CMAKE_SOURCE_DIR}/src/pass/pass-hal.c ${CMAKE_SOURCE_DIR}/src/pass/pass-parser.c ${CMAKE_SOURCE_DIR}/src/core/common.c - ${CMAKE_SOURCE_DIR}/src/core/config-parser.c ) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) diff --git a/unittest/power-haltests.cpp b/unittest/power-haltests.cpp index 8e475e5..0e0e828 100644 --- a/unittest/power-haltests.cpp +++ b/unittest/power-haltests.cpp @@ -107,14 +107,14 @@ TEST_F(PowerHaltest, GetResourceConfig_HandlesValidInput) { int ret = 0; unsigned int i; - char path[] = "/hal/etc/pass/pass.conf"; + char path_json[] = "/hal/etc/pass/pass.json"; /* Stop PASS daemon before HAL testing */ ret = pass_test_method_call(DBUS_CORE_PATH, DBUS_CORE_INTERFACE, "stop", NULL); ASSERT_EQ(ret, 0) << "PassServiceStop Failed"; - ret = pass_parser_get_resource_config(&g_pass, path); + ret = pass_parser_get_resource_config(&g_pass, path_json); ASSERT_EQ(ret, 0) << "GetResourceConfig Failed"; for (i = 0; i < g_pass.num_resources; i++) {