1/* Copyright (c) 2011 Code Aurora Forum. 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 Code Aurora Forum, Inc. 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
43/*=============================================================================
44 *
45 *                          GLOBAL DATA DECLARATION
46 *
47 *============================================================================*/
48
49/* Parameter data */
50loc_gps_cfg_s_type gps_conf;
51
52/* Parameter spec table */
53
54loc_param_s_type loc_parameter_table[] =
55{
56  {"INTERMEDIATE_POS",               &gps_conf.INTERMEDIATE_POS,               'n'},
57  {"ACCURACY_THRES",                 &gps_conf.ACCURACY_THRES,                 'n'},
58  {"ENABLE_WIPER",                   &gps_conf.ENABLE_WIPER,                   'n'},
59  /* DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info
60                   4 - Debug, 5 - Verbose  */
61  {"DEBUG_LEVEL",                    &gps_conf.DEBUG_LEVEL,                    'n'},
62  {"SUPL_VER",                       &gps_conf.SUPL_VER,                       'n'},
63  {"CAPABILITIES",                   &gps_conf.CAPABILITIES,                   'n'},
64  {"TIMESTAMP",                      &gps_conf.TIMESTAMP,                      'n'},
65  {"GYRO_BIAS_RANDOM_WALK",          &gps_conf.GYRO_BIAS_RANDOM_WALK,          'f'},
66  {"SENSOR_ACCEL_BATCHES_PER_SEC",   &gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC,   'n'},
67  {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, 'n'},
68  {"SENSOR_GYRO_BATCHES_PER_SEC",    &gps_conf.SENSOR_GYRO_BATCHES_PER_SEC,    'n'},
69  {"SENSOR_GYRO_SAMPLES_PER_BATCH",  &gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,  'n'},
70  {"SENSOR_CONTROL_MODE",            &gps_conf.SENSOR_CONTROL_MODE,            'n'},
71  {"SENSOR_USAGE",                   &gps_conf.SENSOR_USAGE,                   'n'},
72};
73
74int loc_param_num = sizeof(loc_parameter_table) / sizeof(loc_param_s_type);
75
76/*===========================================================================
77FUNCTION loc_default_parameters
78
79DESCRIPTION
80   Resets the parameters to default
81
82DEPENDENCIES
83   N/A
84
85RETURN VALUE
86   None
87
88SIDE EFFECTS
89   N/A
90===========================================================================*/
91
92static void loc_default_parameters()
93{
94   /* defaults */
95   gps_conf.INTERMEDIATE_POS = 0;
96   gps_conf.ACCURACY_THRES = 0;
97   gps_conf.ENABLE_WIPER = 0;
98   gps_conf.DEBUG_LEVEL = 3; /* debug level */
99   gps_conf.SUPL_VER = 0x10000;
100   gps_conf.CAPABILITIES = 0x7;
101   gps_conf.TIMESTAMP = 0;
102
103   gps_conf.GYRO_BIAS_RANDOM_WALK = 0;
104
105   gps_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
106   gps_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
107   gps_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
108   gps_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
109   gps_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
110   gps_conf.SENSOR_USAGE = 0; /* Enabled */
111
112   /* Value MUST be set by OEMs in configuration for sensor-assisted
113      navigation to work. There is NO default value */
114   gps_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
115
116   /* reset logging mechanism */
117   loc_logger_init(gps_conf.DEBUG_LEVEL, 0);
118}
119
120/*===========================================================================
121FUNCTION trim_space
122
123DESCRIPTION
124   Removes leading and trailing spaces of the string
125
126DEPENDENCIES
127   N/A
128
129RETURN VALUE
130   None
131
132SIDE EFFECTS
133   N/A
134===========================================================================*/
135void trim_space(char *org_string)
136{
137   char *scan_ptr, *write_ptr;
138   char *first_nonspace = NULL, *last_nonspace = NULL;
139
140   scan_ptr = write_ptr = org_string;
141
142   while (*scan_ptr)
143   {
144      if ( !isspace(*scan_ptr) && first_nonspace == NULL)
145      {
146         first_nonspace = scan_ptr;
147      }
148
149      if (first_nonspace != NULL)
150      {
151         *(write_ptr++) = *scan_ptr;
152         if ( !isspace(*scan_ptr))
153         {
154            last_nonspace = write_ptr;
155         }
156      }
157
158      scan_ptr++;
159   }
160
161   if (last_nonspace) { *last_nonspace = '\0'; }
162}
163
164/*===========================================================================
165FUNCTION loc_read_gps_conf
166
167DESCRIPTION
168   Reads the gps.conf file and sets global parameter data
169
170DEPENDENCIES
171   N/A
172
173RETURN VALUE
174   None
175
176SIDE EFFECTS
177   N/A
178===========================================================================*/
179void loc_read_gps_conf(void)
180{
181   FILE *gps_conf_fp = NULL;
182   char input_buf[LOC_MAX_PARAM_LINE];  /* declare a char array */
183   char *lasts;
184   char *param_name, *param_str_value;
185   int     param_int_value = 0;
186   double  param_double_value = 0;
187   int i;
188
189   loc_default_parameters();
190
191   if((gps_conf_fp = fopen(GPS_CONF_FILE, "r")) != NULL)
192   {
193      LOC_LOGD("%s: using %s", __FUNCTION__, GPS_CONF_FILE);
194   }
195   else
196   {
197      LOC_LOGW("%s: no %s file, using defaults", __FUNCTION__, GPS_CONF_FILE);
198      return; /* no parameter file */
199   }
200
201   while(fgets(input_buf, LOC_MAX_PARAM_LINE, gps_conf_fp) != NULL)
202   {
203      /* Separate variable and value */
204      param_name = strtok_r(input_buf, "=", &lasts);
205      if (param_name == NULL) continue;       /* skip lines that do not contain "=" */
206      param_str_value = strtok_r(NULL, "=", &lasts);
207      if (param_str_value == NULL) continue;  /* skip lines that do not contain two operands */
208
209      /* Trim leading and trailing spaces */
210      trim_space(param_name);
211      trim_space(param_str_value);
212
213      // printf("*(%s) = (%s)\n", param_name, param_str_value);
214
215      /* Parse numerical value */
216      if (param_str_value[0] == '0' && tolower(param_str_value[1]) == 'x')
217      {
218         /* hex */
219         param_int_value = (int) strtol(&param_str_value[2], (char**) NULL, 16);
220      }
221      else {
222         param_double_value = (double) atof(param_str_value); /* float */
223         param_int_value = atoi(param_str_value); /* dec */
224      }
225
226      if (strcmp("GYRO_BIAS_RANDOM_WALK", param_name) == 0)
227      {
228         gps_conf.GYRO_BIAS_RANDOM_WALK_VALID = 1;
229      }
230
231      for(i = 0; i < loc_param_num; i++)
232      {
233         if (strcmp(loc_parameter_table[i].param_name, param_name) == 0 &&
234               loc_parameter_table[i].param_ptr)
235         {
236            switch (loc_parameter_table[i].param_type)
237            {
238            case 's':
239               if (strcmp(param_str_value, "NULL") == 0)
240               {
241                  *((char*)loc_parameter_table[i].param_ptr) = '\0';
242               }
243               else {
244                  strlcpy((char*) loc_parameter_table[i].param_ptr,
245                        param_str_value,
246                        LOC_MAX_PARAM_STRING + 1);
247               }
248               /* Log INI values */
249               LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, param_name, (char*)loc_parameter_table[i].param_ptr);
250               break;
251            case 'n':
252               *((int *)loc_parameter_table[i].param_ptr) = param_int_value;
253               /* Log INI values */
254               LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, param_name, param_int_value);
255               break;
256            case 'f':
257               *((double *)loc_parameter_table[i].param_ptr) = param_double_value;
258               /* Log INI values */
259               LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, param_name, param_double_value);
260               break;
261            default:
262               LOC_LOGE("%s: PARAM %s parameter type must be n or n", __FUNCTION__, param_name);
263            }
264         }
265      }
266   }
267
268   fclose(gps_conf_fp);
269
270   /* Initialize logging mechanism with parsed data */
271   loc_logger_init(gps_conf.DEBUG_LEVEL, gps_conf.TIMESTAMP);
272}
273