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 ===========================================================================*/
trim_space(char * org_string)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 ===========================================================================*/
loc_set_config_entry(loc_param_s_type * config_entry,loc_param_v_type * config_value)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 ===========================================================================*/
loc_read_conf(const char * conf_file_name,loc_param_s_type * config_table,uint32_t table_length)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