loc_cfg.cpp revision fe660078f05f448ececb0b1170ecd79e600db440
1/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation, nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30#define LOG_NDDEBUG 0 31#define LOG_TAG "LocSvc_utils_cfg" 32 33#include <stdio.h> 34#include <stdlib.h> 35#include <pthread.h> 36#include <string.h> 37#include <ctype.h> 38#include <unistd.h> 39#include <time.h> 40#include <loc_cfg.h> 41#include <log_util.h> 42#include <loc_misc_utils.h> 43#ifdef USE_GLIB 44#include <glib.h> 45#endif 46#include "platform_lib_includes.h" 47 48/*============================================================================= 49 * 50 * GLOBAL DATA DECLARATION 51 * 52 *============================================================================*/ 53 54/* Parameter data */ 55static uint8_t DEBUG_LEVEL = 0xff; 56static uint8_t TIMESTAMP = 0; 57 58/* Parameter spec table */ 59static loc_param_s_type loc_param_table[] = 60{ 61 {"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'}, 62 {"TIMESTAMP", &TIMESTAMP, NULL, 'n'}, 63}; 64int loc_param_num = sizeof(loc_param_table) / sizeof(loc_param_s_type); 65 66typedef struct loc_param_v_type 67{ 68 char* param_name; 69 char* param_str_value; 70 int param_int_value; 71 double param_double_value; 72}loc_param_v_type; 73 74/*=========================================================================== 75FUNCTION loc_set_config_entry 76 77DESCRIPTION 78 Potentially sets a given configuration table entry based on the passed in 79 configuration value. This is done by using a string comparison of the 80 parameter names and those found in the configuration file. 81 82PARAMETERS: 83 config_entry: configuration entry in the table to possibly set 84 config_value: value to store in the entry if the parameter names match 85 86DEPENDENCIES 87 N/A 88 89RETURN VALUE 90 None 91 92SIDE EFFECTS 93 N/A 94===========================================================================*/ 95int loc_set_config_entry(loc_param_s_type* config_entry, loc_param_v_type* config_value) 96{ 97 int ret=-1; 98 if(NULL == config_entry || NULL == config_value) 99 { 100 LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__); 101 return ret; 102 } 103 104 if (strcmp(config_entry->param_name, config_value->param_name) == 0 && 105 config_entry->param_ptr) 106 { 107 switch (config_entry->param_type) 108 { 109 case 's': 110 if (strcmp(config_value->param_str_value, "NULL") == 0) 111 { 112 *((char*)config_entry->param_ptr) = '\0'; 113 } 114 else { 115 strlcpy((char*) config_entry->param_ptr, 116 config_value->param_str_value, 117 LOC_MAX_PARAM_STRING + 1); 118 } 119 /* Log INI values */ 120 LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, 121 config_entry->param_name, (char*)config_entry->param_ptr); 122 123 if(NULL != config_entry->param_set) 124 { 125 *(config_entry->param_set) = 1; 126 } 127 ret = 0; 128 break; 129 case 'n': 130 *((int *)config_entry->param_ptr) = config_value->param_int_value; 131 /* Log INI values */ 132 LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, 133 config_entry->param_name, config_value->param_int_value); 134 135 if(NULL != config_entry->param_set) 136 { 137 *(config_entry->param_set) = 1; 138 } 139 ret = 0; 140 break; 141 case 'f': 142 *((double *)config_entry->param_ptr) = config_value->param_double_value; 143 /* Log INI values */ 144 LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, 145 config_entry->param_name, config_value->param_double_value); 146 147 if(NULL != config_entry->param_set) 148 { 149 *(config_entry->param_set) = 1; 150 } 151 ret = 0; 152 break; 153 default: 154 LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s", 155 __FUNCTION__, config_entry->param_name); 156 } 157 } 158 return ret; 159} 160 161/*=========================================================================== 162FUNCTION loc_fill_conf_item 163 164DESCRIPTION 165 Takes a line of configuration item and sets defined values based on 166 the passed in configuration table. This table maps strings to values to 167 set along with the type of each of these values. 168 169PARAMETERS: 170 input_buf : buffer contanis config item 171 config_table: table definition of strings to places to store information 172 table_length: length of the configuration table 173 174DEPENDENCIES 175 N/A 176 177RETURN VALUE 178 0: No config or incomplete config or invalid parameter 179 1: Filled a record 180 181SIDE EFFECTS 182 N/A 183===========================================================================*/ 184int loc_fill_conf_item(char* input_buf, 185 loc_param_s_type* config_table, uint32_t table_length) 186{ 187 int ret = 0; 188 189 if (input_buf && config_table) { 190 char *lasts; 191 loc_param_v_type config_value; 192 memset(&config_value, 0, sizeof(config_value)); 193 194 /* Separate variable and value */ 195 config_value.param_name = strtok_r(input_buf, "=", &lasts); 196 /* skip lines that do not contain "=" */ 197 if (config_value.param_name) { 198 config_value.param_str_value = strtok_r(NULL, "=", &lasts); 199 200 /* skip lines that do not contain two operands */ 201 if (config_value.param_str_value) { 202 /* Trim leading and trailing spaces */ 203 loc_util_trim_space(config_value.param_name); 204 loc_util_trim_space(config_value.param_str_value); 205 206 /* Parse numerical value */ 207 if ((strlen(config_value.param_str_value) >=3) && 208 (config_value.param_str_value[0] == '0') && 209 (tolower(config_value.param_str_value[1]) == 'x')) 210 { 211 /* hex */ 212 config_value.param_int_value = (int) strtol(&config_value.param_str_value[2], 213 (char**) NULL, 16); 214 } 215 else { 216 config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */ 217 config_value.param_int_value = atoi(config_value.param_str_value); /* dec */ 218 } 219 220 for(uint32_t i = 0; NULL != config_table && i < table_length; i++) 221 { 222 if(!loc_set_config_entry(&config_table[i], &config_value)) { 223 ret = 1; 224 } 225 } 226 } 227 } 228 } 229 230 return ret; 231} 232 233/*=========================================================================== 234FUNCTION loc_read_conf_r (repetitive) 235 236DESCRIPTION 237 Reads the specified configuration file and sets defined values based on 238 the passed in configuration table. This table maps strings to values to 239 set along with the type of each of these values. 240 The difference between this and loc_read_conf is that this function returns 241 the file pointer position at the end of filling a config table. Also, it 242 reads a fixed number of parameters at a time which is equal to the length 243 of the configuration table. This functionality enables the caller to 244 repeatedly call the function to read data from the same file. 245 246PARAMETERS: 247 conf_fp : file pointer 248 config_table: table definition of strings to places to store information 249 table_length: length of the configuration table 250 251DEPENDENCIES 252 N/A 253 254RETURN VALUE 255 0: Table filled successfully 256 1: No more parameters to read 257 -1: Error filling table 258 259SIDE EFFECTS 260 N/A 261===========================================================================*/ 262int loc_read_conf_r(FILE *conf_fp, loc_param_s_type* config_table, uint32_t table_length) 263{ 264 int ret=0; 265 266 unsigned int num_params=table_length; 267 if(conf_fp == NULL) { 268 LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__); 269 ret = -1; 270 goto err; 271 } 272 273 /* Clear all validity bits */ 274 for(uint32_t i = 0; NULL != config_table && i < table_length; i++) 275 { 276 if(NULL != config_table[i].param_set) 277 { 278 *(config_table[i].param_set) = 0; 279 } 280 } 281 282 char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */ 283 284 LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params); 285 while(num_params) 286 { 287 if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) { 288 LOC_LOGD("%s:%d]: fgets returned NULL\n", __func__, __LINE__); 289 break; 290 } 291 292 num_params -= loc_fill_conf_item(input_buf, config_table, table_length); 293 } 294 295err: 296 return ret; 297} 298 299/*=========================================================================== 300FUNCTION loc_udpate_conf 301 302DESCRIPTION 303 Parses the passed in buffer for configuration items, and update the table 304 that is also passed in. 305 306Reads the specified configuration file and sets defined values based on 307 the passed in configuration table. This table maps strings to values to 308 set along with the type of each of these values. 309 310PARAMETERS: 311 conf_data: configuration items in bufferas a string 312 length: strlen(conf_data) 313 config_table: table definition of strings to places to store information 314 table_length: length of the configuration table 315 316DEPENDENCIES 317 N/A 318 319RETURN VALUE 320 number of the records in the table that is updated at time of return. 321 322SIDE EFFECTS 323 N/A 324===========================================================================*/ 325int loc_update_conf(const char* conf_data, int32_t length, 326 loc_param_s_type* config_table, uint32_t table_length) 327{ 328 int ret = -1; 329 330 if (conf_data && length && config_table && table_length) { 331 // make a copy, so we do not tokenize the original data 332 char* conf_copy = (char*)malloc(length+1); 333 memcpy(conf_copy, conf_data, length); 334 // we hard NULL the end of string to be safe 335 conf_copy[length] = 0; 336 // start with one record off 337 uint32_t num_params = table_length - 1; 338 char* saveptr = NULL; 339 char* input_buf = strtok_r(conf_copy, "\n", &saveptr); 340 ret = 0; 341 342 LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params); 343 while(num_params && input_buf) { 344 ret++; 345 num_params -= loc_fill_conf_item(input_buf, config_table, table_length); 346 input_buf = strtok_r(NULL, "\n", &saveptr); 347 } 348 } 349 350 return ret; 351} 352 353/*=========================================================================== 354FUNCTION loc_read_conf 355 356DESCRIPTION 357 Reads the specified configuration file and sets defined values based on 358 the passed in configuration table. This table maps strings to values to 359 set along with the type of each of these values. 360 361PARAMETERS: 362 conf_file_name: configuration file to read 363 config_table: table definition of strings to places to store information 364 table_length: length of the configuration table 365 366DEPENDENCIES 367 N/A 368 369RETURN VALUE 370 None 371 372SIDE EFFECTS 373 N/A 374===========================================================================*/ 375void loc_read_conf(const char* conf_file_name, loc_param_s_type* config_table, 376 uint32_t table_length) 377{ 378 FILE *conf_fp = NULL; 379 char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */ 380 char *lasts; 381 loc_param_v_type config_value; 382 uint32_t i; 383 384 if((conf_fp = fopen(conf_file_name, "r")) != NULL) 385 { 386 LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name); 387 if(table_length && config_table) { 388 loc_read_conf_r(conf_fp, config_table, table_length); 389 rewind(conf_fp); 390 } 391 loc_read_conf_r(conf_fp, loc_param_table, loc_param_num); 392 fclose(conf_fp); 393 } 394 /* Initialize logging mechanism with parsed data */ 395 loc_logger_init(DEBUG_LEVEL, TIMESTAMP); 396} 397