Home | History | Annotate | Download | only in utils
      1 /* Copyright (c) 2011-2013, 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 #ifdef USE_GLIB
     43 #include <glib.h>
     44 #endif
     45 #include "platform_lib_includes.h"
     46 
     47 /*=============================================================================
     48  *
     49  *                          GLOBAL DATA DECLARATION
     50  *
     51  *============================================================================*/
     52 
     53 /* Parameter data */
     54 static uint8_t DEBUG_LEVEL = 0xff;
     55 static uint8_t TIMESTAMP = 0;
     56 
     57 /* Parameter spec table */
     58 static loc_param_s_type loc_parameter_table[] =
     59 {
     60   {"DEBUG_LEVEL",                    &DEBUG_LEVEL, NULL,                   'n'},
     61   {"TIMESTAMP",                      &TIMESTAMP,   NULL,                   'n'},
     62 };
     63 int loc_param_num = sizeof(loc_parameter_table) / sizeof(loc_param_s_type);
     64 
     65 /*===========================================================================
     66 FUNCTION trim_space
     67 
     68 DESCRIPTION
     69    Removes leading and trailing spaces of the string
     70 
     71 DEPENDENCIES
     72    N/A
     73 
     74 RETURN VALUE
     75    None
     76 
     77 SIDE EFFECTS
     78    N/A
     79 ===========================================================================*/
     80 void trim_space(char *org_string)
     81 {
     82    char *scan_ptr, *write_ptr;
     83    char *first_nonspace = NULL, *last_nonspace = NULL;
     84 
     85    scan_ptr = write_ptr = org_string;
     86 
     87    while (*scan_ptr)
     88    {
     89       if ( !isspace(*scan_ptr) && first_nonspace == NULL)
     90       {
     91          first_nonspace = scan_ptr;
     92       }
     93 
     94       if (first_nonspace != NULL)
     95       {
     96          *(write_ptr++) = *scan_ptr;
     97          if ( !isspace(*scan_ptr))
     98          {
     99             last_nonspace = write_ptr;
    100          }
    101       }
    102 
    103       scan_ptr++;
    104    }
    105 
    106    if (last_nonspace) { *last_nonspace = '\0'; }
    107 }
    108 
    109 typedef struct loc_param_v_type
    110 {
    111    char* param_name;
    112 
    113    char* param_str_value;
    114    int param_int_value;
    115    double param_double_value;
    116 }loc_param_v_type;
    117 
    118 /*===========================================================================
    119 FUNCTION loc_set_config_entry
    120 
    121 DESCRIPTION
    122    Potentially sets a given configuration table entry based on the passed in
    123    configuration value. This is done by using a string comparison of the
    124    parameter names and those found in the configuration file.
    125 
    126 PARAMETERS:
    127    config_entry: configuration entry in the table to possibly set
    128    config_value: value to store in the entry if the parameter names match
    129 
    130 DEPENDENCIES
    131    N/A
    132 
    133 RETURN VALUE
    134    None
    135 
    136 SIDE EFFECTS
    137    N/A
    138 ===========================================================================*/
    139 void loc_set_config_entry(loc_param_s_type* config_entry, loc_param_v_type* config_value)
    140 {
    141    if(NULL == config_entry || NULL == config_value)
    142    {
    143       LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__);
    144       return;
    145    }
    146 
    147    if (strcmp(config_entry->param_name, config_value->param_name) == 0 &&
    148                config_entry->param_ptr)
    149    {
    150       switch (config_entry->param_type)
    151       {
    152       case 's':
    153          if (strcmp(config_value->param_str_value, "NULL") == 0)
    154          {
    155             *((char*)config_entry->param_ptr) = '\0';
    156          }
    157          else {
    158             strlcpy((char*) config_entry->param_ptr,
    159                   config_value->param_str_value,
    160                   LOC_MAX_PARAM_STRING + 1);
    161          }
    162          /* Log INI values */
    163          LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, config_entry->param_name, (char*)config_entry->param_ptr);
    164 
    165          if(NULL != config_entry->param_set)
    166          {
    167             *(config_entry->param_set) = 1;
    168          }
    169          break;
    170       case 'n':
    171          *((int *)config_entry->param_ptr) = config_value->param_int_value;
    172          /* Log INI values */
    173          LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, config_entry->param_name, config_value->param_int_value);
    174 
    175          if(NULL != config_entry->param_set)
    176          {
    177             *(config_entry->param_set) = 1;
    178          }
    179          break;
    180       case 'f':
    181          *((double *)config_entry->param_ptr) = config_value->param_double_value;
    182          /* Log INI values */
    183          LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, config_entry->param_name, config_value->param_double_value);
    184 
    185          if(NULL != config_entry->param_set)
    186          {
    187             *(config_entry->param_set) = 1;
    188          }
    189          break;
    190       default:
    191          LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s", __FUNCTION__, config_entry->param_name);
    192       }
    193    }
    194 }
    195 
    196 /*===========================================================================
    197 FUNCTION loc_read_conf
    198 
    199 DESCRIPTION
    200    Reads the specified configuration file and sets defined values based on
    201    the passed in configuration table. This table maps strings to values to
    202    set along with the type of each of these values.
    203 
    204 PARAMETERS:
    205    conf_file_name: configuration file to read
    206    config_table: table definition of strings to places to store information
    207    table_length: length of the configuration table
    208 
    209 DEPENDENCIES
    210    N/A
    211 
    212 RETURN VALUE
    213    None
    214 
    215 SIDE EFFECTS
    216    N/A
    217 ===========================================================================*/
    218 void loc_read_conf(const char* conf_file_name, loc_param_s_type* config_table, uint32_t table_length)
    219 {
    220    FILE *gps_conf_fp = NULL;
    221    char input_buf[LOC_MAX_PARAM_LINE];  /* declare a char array */
    222    char *lasts;
    223    loc_param_v_type config_value;
    224    uint32_t i;
    225 
    226    if((gps_conf_fp = fopen(conf_file_name, "r")) != NULL)
    227    {
    228       LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name);
    229    }
    230    else
    231    {
    232       LOC_LOGW("%s: no %s file found", __FUNCTION__, conf_file_name);
    233       loc_logger_init(DEBUG_LEVEL, TIMESTAMP);
    234       return; /* no parameter file */
    235    }
    236 
    237    /* Clear all validity bits */
    238    for(i = 0; NULL != config_table && i < table_length; i++)
    239    {
    240       if(NULL != config_table[i].param_set)
    241       {
    242          *(config_table[i].param_set) = 0;
    243       }
    244    }
    245 
    246    while(fgets(input_buf, LOC_MAX_PARAM_LINE, gps_conf_fp) != NULL)
    247    {
    248       memset(&config_value, 0, sizeof(config_value));
    249 
    250       /* Separate variable and value */
    251       config_value.param_name = strtok_r(input_buf, "=", &lasts);
    252       if (config_value.param_name == NULL) continue;       /* skip lines that do not contain "=" */
    253       config_value.param_str_value = strtok_r(NULL, "=", &lasts);
    254       if (config_value.param_str_value == NULL) continue;  /* skip lines that do not contain two operands */
    255 
    256       /* Trim leading and trailing spaces */
    257       trim_space(config_value.param_name);
    258       trim_space(config_value.param_str_value);
    259 
    260       /* Parse numerical value */
    261       if (config_value.param_str_value[0] == '0' && tolower(config_value.param_str_value[1]) == 'x')
    262       {
    263          /* hex */
    264          config_value.param_int_value = (int) strtol(&config_value.param_str_value[2], (char**) NULL, 16);
    265       }
    266       else {
    267          config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */
    268          config_value.param_int_value = atoi(config_value.param_str_value); /* dec */
    269       }
    270 
    271       for(i = 0; NULL != config_table && i < table_length; i++)
    272       {
    273          loc_set_config_entry(&config_table[i], &config_value);
    274       }
    275 
    276       for(i = 0; i < loc_param_num; i++)
    277       {
    278          loc_set_config_entry(&loc_parameter_table[i], &config_value);
    279       }
    280    }
    281 
    282    fclose(gps_conf_fp);
    283 
    284    /* Initialize logging mechanism with parsed data */
    285    loc_logger_init(DEBUG_LEVEL, TIMESTAMP);
    286 }
    287