You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
13 KiB
400 lines
13 KiB
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions are |
|
* met: |
|
* * Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* * Redistributions in binary form must reproduce the above |
|
* copyright notice, this list of conditions and the following |
|
* disclaimer in the documentation and/or other materials provided |
|
* with the distribution. |
|
* * Neither the name of The Linux Foundation, nor the names of its |
|
* contributors may be used to endorse or promote products derived |
|
* from this software without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
* |
|
*/ |
|
|
|
#define LOG_NDDEBUG 0 |
|
#define LOG_TAG "LocSvc_utils_cfg" |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <pthread.h> |
|
#include <string.h> |
|
#include <ctype.h> |
|
#include <unistd.h> |
|
#include <time.h> |
|
#include <loc_cfg.h> |
|
#include <log_util.h> |
|
#include <loc_misc_utils.h> |
|
#ifdef USE_GLIB |
|
#include <glib.h> |
|
#endif |
|
#include "platform_lib_includes.h" |
|
|
|
/*============================================================================= |
|
* |
|
* GLOBAL DATA DECLARATION |
|
* |
|
*============================================================================*/ |
|
|
|
/* Parameter data */ |
|
static uint32_t DEBUG_LEVEL = 0xff; |
|
static uint32_t TIMESTAMP = 0; |
|
|
|
/* Parameter spec table */ |
|
static const loc_param_s_type loc_param_table[] = |
|
{ |
|
{"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'}, |
|
{"TIMESTAMP", &TIMESTAMP, NULL, 'n'}, |
|
}; |
|
static const int loc_param_num = sizeof(loc_param_table) / sizeof(loc_param_s_type); |
|
|
|
typedef struct loc_param_v_type |
|
{ |
|
char* param_name; |
|
char* param_str_value; |
|
int param_int_value; |
|
double param_double_value; |
|
}loc_param_v_type; |
|
|
|
/*=========================================================================== |
|
FUNCTION loc_set_config_entry |
|
|
|
DESCRIPTION |
|
Potentially sets a given configuration table entry based on the passed in |
|
configuration value. This is done by using a string comparison of the |
|
parameter names and those found in the configuration file. |
|
|
|
PARAMETERS: |
|
config_entry: configuration entry in the table to possibly set |
|
config_value: value to store in the entry if the parameter names match |
|
|
|
DEPENDENCIES |
|
N/A |
|
|
|
RETURN VALUE |
|
None |
|
|
|
SIDE EFFECTS |
|
N/A |
|
===========================================================================*/ |
|
int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type* config_value) |
|
{ |
|
int ret=-1; |
|
if(NULL == config_entry || NULL == config_value) |
|
{ |
|
LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__); |
|
return ret; |
|
} |
|
|
|
if (strcmp(config_entry->param_name, config_value->param_name) == 0 && |
|
config_entry->param_ptr) |
|
{ |
|
switch (config_entry->param_type) |
|
{ |
|
case 's': |
|
if (strcmp(config_value->param_str_value, "NULL") == 0) |
|
{ |
|
*((char*)config_entry->param_ptr) = '\0'; |
|
} |
|
else { |
|
strlcpy((char*) config_entry->param_ptr, |
|
config_value->param_str_value, |
|
LOC_MAX_PARAM_STRING + 1); |
|
} |
|
/* Log INI values */ |
|
LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, |
|
config_entry->param_name, (char*)config_entry->param_ptr); |
|
|
|
if(NULL != config_entry->param_set) |
|
{ |
|
*(config_entry->param_set) = 1; |
|
} |
|
ret = 0; |
|
break; |
|
case 'n': |
|
*((int *)config_entry->param_ptr) = config_value->param_int_value; |
|
/* Log INI values */ |
|
LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, |
|
config_entry->param_name, config_value->param_int_value); |
|
|
|
if(NULL != config_entry->param_set) |
|
{ |
|
*(config_entry->param_set) = 1; |
|
} |
|
ret = 0; |
|
break; |
|
case 'f': |
|
*((double *)config_entry->param_ptr) = config_value->param_double_value; |
|
/* Log INI values */ |
|
LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, |
|
config_entry->param_name, config_value->param_double_value); |
|
|
|
if(NULL != config_entry->param_set) |
|
{ |
|
*(config_entry->param_set) = 1; |
|
} |
|
ret = 0; |
|
break; |
|
default: |
|
LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s", |
|
__FUNCTION__, config_entry->param_name); |
|
} |
|
} |
|
return ret; |
|
} |
|
|
|
/*=========================================================================== |
|
FUNCTION loc_fill_conf_item |
|
|
|
DESCRIPTION |
|
Takes a line of configuration item and sets defined values based on |
|
the passed in configuration table. This table maps strings to values to |
|
set along with the type of each of these values. |
|
|
|
PARAMETERS: |
|
input_buf : buffer contanis config item |
|
config_table: table definition of strings to places to store information |
|
table_length: length of the configuration table |
|
|
|
DEPENDENCIES |
|
N/A |
|
|
|
RETURN VALUE |
|
0: Number of records in the config_table filled with input_buf |
|
|
|
SIDE EFFECTS |
|
N/A |
|
===========================================================================*/ |
|
int loc_fill_conf_item(char* input_buf, |
|
const loc_param_s_type* config_table, uint32_t table_length) |
|
{ |
|
int ret = 0; |
|
|
|
if (input_buf && config_table) { |
|
char *lasts; |
|
loc_param_v_type config_value; |
|
memset(&config_value, 0, sizeof(config_value)); |
|
|
|
/* Separate variable and value */ |
|
config_value.param_name = strtok_r(input_buf, "=", &lasts); |
|
/* skip lines that do not contain "=" */ |
|
if (config_value.param_name) { |
|
config_value.param_str_value = strtok_r(NULL, "=", &lasts); |
|
|
|
/* skip lines that do not contain two operands */ |
|
if (config_value.param_str_value) { |
|
/* Trim leading and trailing spaces */ |
|
loc_util_trim_space(config_value.param_name); |
|
loc_util_trim_space(config_value.param_str_value); |
|
|
|
/* Parse numerical value */ |
|
if ((strlen(config_value.param_str_value) >=3) && |
|
(config_value.param_str_value[0] == '0') && |
|
(tolower(config_value.param_str_value[1]) == 'x')) |
|
{ |
|
/* hex */ |
|
config_value.param_int_value = (int) strtol(&config_value.param_str_value[2], |
|
(char**) NULL, 16); |
|
} |
|
else { |
|
config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */ |
|
config_value.param_int_value = atoi(config_value.param_str_value); /* dec */ |
|
} |
|
|
|
for(uint32_t i = 0; NULL != config_table && i < table_length; i++) |
|
{ |
|
if(!loc_set_config_entry(&config_table[i], &config_value)) { |
|
ret += 1; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
/*=========================================================================== |
|
FUNCTION loc_read_conf_r (repetitive) |
|
|
|
DESCRIPTION |
|
Reads the specified configuration file and sets defined values based on |
|
the passed in configuration table. This table maps strings to values to |
|
set along with the type of each of these values. |
|
The difference between this and loc_read_conf is that this function returns |
|
the file pointer position at the end of filling a config table. Also, it |
|
reads a fixed number of parameters at a time which is equal to the length |
|
of the configuration table. This functionality enables the caller to |
|
repeatedly call the function to read data from the same file. |
|
|
|
PARAMETERS: |
|
conf_fp : file pointer |
|
config_table: table definition of strings to places to store information |
|
table_length: length of the configuration table |
|
|
|
DEPENDENCIES |
|
N/A |
|
|
|
RETURN VALUE |
|
0: Table filled successfully |
|
1: No more parameters to read |
|
-1: Error filling table |
|
|
|
SIDE EFFECTS |
|
N/A |
|
===========================================================================*/ |
|
int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table, uint32_t table_length) |
|
{ |
|
int ret=0; |
|
|
|
unsigned int num_params=table_length; |
|
if(conf_fp == NULL) { |
|
LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__); |
|
ret = -1; |
|
goto err; |
|
} |
|
|
|
/* Clear all validity bits */ |
|
for(uint32_t i = 0; NULL != config_table && i < table_length; i++) |
|
{ |
|
if(NULL != config_table[i].param_set) |
|
{ |
|
*(config_table[i].param_set) = 0; |
|
} |
|
} |
|
|
|
char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */ |
|
|
|
LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params); |
|
while(num_params) |
|
{ |
|
if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) { |
|
LOC_LOGD("%s:%d]: fgets returned NULL\n", __func__, __LINE__); |
|
break; |
|
} |
|
|
|
num_params -= loc_fill_conf_item(input_buf, config_table, table_length); |
|
} |
|
|
|
err: |
|
return ret; |
|
} |
|
|
|
/*=========================================================================== |
|
FUNCTION loc_udpate_conf |
|
|
|
DESCRIPTION |
|
Parses the passed in buffer for configuration items, and update the table |
|
that is also passed in. |
|
|
|
Reads the specified configuration file and sets defined values based on |
|
the passed in configuration table. This table maps strings to values to |
|
set along with the type of each of these values. |
|
|
|
PARAMETERS: |
|
conf_data: configuration items in bufferas a string |
|
length: strlen(conf_data) |
|
config_table: table definition of strings to places to store information |
|
table_length: length of the configuration table |
|
|
|
DEPENDENCIES |
|
N/A |
|
|
|
RETURN VALUE |
|
number of the records in the table that is updated at time of return. |
|
|
|
SIDE EFFECTS |
|
N/A |
|
===========================================================================*/ |
|
int loc_update_conf(const char* conf_data, int32_t length, |
|
const loc_param_s_type* config_table, uint32_t table_length) |
|
{ |
|
int ret = -1; |
|
|
|
if (conf_data && length && config_table && table_length) { |
|
// make a copy, so we do not tokenize the original data |
|
char* conf_copy = (char*)malloc(length+1); |
|
|
|
if (conf_copy != NULL) |
|
{ |
|
memcpy(conf_copy, conf_data, length); |
|
// we hard NULL the end of string to be safe |
|
conf_copy[length] = 0; |
|
|
|
// start with one record off |
|
uint32_t num_params = table_length - 1; |
|
char* saveptr = NULL; |
|
char* input_buf = strtok_r(conf_copy, "\n", &saveptr); |
|
ret = 0; |
|
|
|
LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params); |
|
while(num_params && input_buf) { |
|
ret++; |
|
num_params -= loc_fill_conf_item(input_buf, config_table, table_length); |
|
input_buf = strtok_r(NULL, "\n", &saveptr); |
|
} |
|
free(conf_copy); |
|
} |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
/*=========================================================================== |
|
FUNCTION loc_read_conf |
|
|
|
DESCRIPTION |
|
Reads the specified configuration file and sets defined values based on |
|
the passed in configuration table. This table maps strings to values to |
|
set along with the type of each of these values. |
|
|
|
PARAMETERS: |
|
conf_file_name: configuration file to read |
|
config_table: table definition of strings to places to store information |
|
table_length: length of the configuration table |
|
|
|
DEPENDENCIES |
|
N/A |
|
|
|
RETURN VALUE |
|
None |
|
|
|
SIDE EFFECTS |
|
N/A |
|
===========================================================================*/ |
|
void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_table, |
|
uint32_t table_length) |
|
{ |
|
FILE *conf_fp = NULL; |
|
char *lasts; |
|
loc_param_v_type config_value; |
|
uint32_t i; |
|
|
|
if((conf_fp = fopen(conf_file_name, "r")) != NULL) |
|
{ |
|
LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name); |
|
if(table_length && config_table) { |
|
loc_read_conf_r(conf_fp, config_table, table_length); |
|
rewind(conf_fp); |
|
} |
|
loc_read_conf_r(conf_fp, loc_param_table, loc_param_num); |
|
fclose(conf_fp); |
|
} |
|
/* Initialize logging mechanism with parsed data */ |
|
loc_logger_init(DEBUG_LEVEL, TIMESTAMP); |
|
}
|
|
|