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