1 /* Copyright (c) 2011-2015, 2018 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_NDEBUG 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 <grp.h>
41 #include <errno.h>
42 #include <loc_cfg.h>
43 #include <loc_pla.h>
44 #include <loc_target.h>
45 #include <loc_misc_utils.h>
46 #ifdef USE_GLIB
47 #include <glib.h>
48 #endif
49 #include "log_util.h"
50
51 /*=============================================================================
52 *
53 * GLOBAL DATA DECLARATION
54 *
55 *============================================================================*/
56
57 /* Parameter data */
58 static uint32_t DEBUG_LEVEL = 0xff;
59 static uint32_t TIMESTAMP = 0;
60 static uint32_t DATUM_TYPE = 0;
61 static bool sVendorEnhanced = true;
62 static uint32_t sLogBufferEnabled = 0;
63
64 /* Parameter spec table */
65 static const loc_param_s_type loc_param_table[] =
66 {
67 {"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'},
68 {"TIMESTAMP", &TIMESTAMP, NULL, 'n'},
69 {"DATUM_TYPE", &DATUM_TYPE, NULL, 'n'},
70 {"LOG_BUFFER_ENABLED", &sLogBufferEnabled, NULL, 'n'},
71 };
72 static const int loc_param_num = sizeof(loc_param_table) / sizeof(loc_param_s_type);
73
74 typedef struct loc_param_v_type
75 {
76 char* param_name;
77 char* param_str_value;
78 int param_int_value;
79 double param_double_value;
80 }loc_param_v_type;
81
82 // Reference below arrays wherever needed to avoid duplicating
83 // same conf path string over and again in location code.
84 const char LOC_PATH_GPS_CONF[] = LOC_PATH_GPS_CONF_STR;
85 const char LOC_PATH_IZAT_CONF[] = LOC_PATH_IZAT_CONF_STR;
86 const char LOC_PATH_FLP_CONF[] = LOC_PATH_FLP_CONF_STR;
87 const char LOC_PATH_LOWI_CONF[] = LOC_PATH_LOWI_CONF_STR;
88 const char LOC_PATH_SAP_CONF[] = LOC_PATH_SAP_CONF_STR;
89 const char LOC_PATH_APDR_CONF[] = LOC_PATH_APDR_CONF_STR;
90 const char LOC_PATH_XTWIFI_CONF[] = LOC_PATH_XTWIFI_CONF_STR;
91 const char LOC_PATH_QUIPC_CONF[] = LOC_PATH_QUIPC_CONF_STR;
92
isVendorEnhanced()93 bool isVendorEnhanced() {
94 return sVendorEnhanced;
95 }
setVendorEnhanced(bool vendorEnhanced)96 void setVendorEnhanced(bool vendorEnhanced) {
97 sVendorEnhanced = vendorEnhanced;
98 }
99
100 /*===========================================================================
101 FUNCTION loc_get_datum_type
102
103 DESCRIPTION
104 get datum type
105
106 PARAMETERS:
107 N/A
108
109 DEPENDENCIES
110 N/A
111
112 RETURN VALUE
113 DATUM TYPE
114
115 SIDE EFFECTS
116 N/A
117 ===========================================================================*/
loc_get_datum_type()118 int loc_get_datum_type()
119 {
120 return DATUM_TYPE;
121 }
122
123 /*===========================================================================
124 FUNCTION loc_set_config_entry
125
126 DESCRIPTION
127 Potentially sets a given configuration table entry based on the passed in
128 configuration value. This is done by using a string comparison of the
129 parameter names and those found in the configuration file.
130
131 PARAMETERS:
132 config_entry: configuration entry in the table to possibly set
133 config_value: value to store in the entry if the parameter names match
134
135 DEPENDENCIES
136 N/A
137
138 RETURN VALUE
139 None
140
141 SIDE EFFECTS
142 N/A
143 ===========================================================================*/
loc_set_config_entry(const loc_param_s_type * config_entry,loc_param_v_type * config_value)144 int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type* config_value)
145 {
146 int ret=-1;
147 if(NULL == config_entry || NULL == config_value)
148 {
149 LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__);
150 return ret;
151 }
152
153 if (strcmp(config_entry->param_name, config_value->param_name) == 0 &&
154 config_entry->param_ptr)
155 {
156 switch (config_entry->param_type)
157 {
158 case 's':
159 if (strcmp(config_value->param_str_value, "NULL") == 0)
160 {
161 *((char*)config_entry->param_ptr) = '\0';
162 }
163 else {
164 strlcpy((char*) config_entry->param_ptr,
165 config_value->param_str_value,
166 LOC_MAX_PARAM_STRING);
167 }
168 /* Log INI values */
169 LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__,
170 config_entry->param_name, (char*)config_entry->param_ptr);
171
172 if(NULL != config_entry->param_set)
173 {
174 *(config_entry->param_set) = 1;
175 }
176 ret = 0;
177 break;
178 case 'n':
179 *((int *)config_entry->param_ptr) = config_value->param_int_value;
180 /* Log INI values */
181 LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__,
182 config_entry->param_name, config_value->param_int_value);
183
184 if(NULL != config_entry->param_set)
185 {
186 *(config_entry->param_set) = 1;
187 }
188 ret = 0;
189 break;
190 case 'f':
191 *((double *)config_entry->param_ptr) = config_value->param_double_value;
192 /* Log INI values */
193 LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__,
194 config_entry->param_name, config_value->param_double_value);
195
196 if(NULL != config_entry->param_set)
197 {
198 *(config_entry->param_set) = 1;
199 }
200 ret = 0;
201 break;
202 default:
203 LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s",
204 __FUNCTION__, config_entry->param_name);
205 }
206 }
207 return ret;
208 }
209
210 /*===========================================================================
211 FUNCTION loc_fill_conf_item
212
213 DESCRIPTION
214 Takes a line of configuration item and sets defined values based on
215 the passed in configuration table. This table maps strings to values to
216 set along with the type of each of these values.
217
218 PARAMETERS:
219 input_buf : buffer contanis config item
220 config_table: table definition of strings to places to store information
221 table_length: length of the configuration table
222
223 DEPENDENCIES
224 N/A
225
226 RETURN VALUE
227 0: Number of records in the config_table filled with input_buf
228
229 SIDE EFFECTS
230 N/A
231 ===========================================================================*/
loc_fill_conf_item(char * input_buf,const loc_param_s_type * config_table,uint32_t table_length)232 int loc_fill_conf_item(char* input_buf,
233 const loc_param_s_type* config_table, uint32_t table_length)
234 {
235 int ret = 0;
236
237 if (input_buf && config_table) {
238 char *lasts;
239 loc_param_v_type config_value;
240 memset(&config_value, 0, sizeof(config_value));
241
242 /* Separate variable and value */
243 config_value.param_name = strtok_r(input_buf, "=", &lasts);
244 /* skip lines that do not contain "=" */
245 if (config_value.param_name) {
246 config_value.param_str_value = strtok_r(NULL, "=", &lasts);
247
248 /* skip lines that do not contain two operands */
249 if (config_value.param_str_value) {
250 /* Trim leading and trailing spaces */
251 loc_util_trim_space(config_value.param_name);
252 loc_util_trim_space(config_value.param_str_value);
253
254 /* Parse numerical value */
255 if ((strlen(config_value.param_str_value) >=3) &&
256 (config_value.param_str_value[0] == '0') &&
257 (tolower(config_value.param_str_value[1]) == 'x'))
258 {
259 /* hex */
260 config_value.param_int_value = (int) strtol(&config_value.param_str_value[2],
261 (char**) NULL, 16);
262 }
263 else {
264 config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */
265 config_value.param_int_value = atoi(config_value.param_str_value); /* dec */
266 }
267
268 for(uint32_t i = 0; NULL != config_table && i < table_length; i++)
269 {
270 if(!loc_set_config_entry(&config_table[i], &config_value)) {
271 ret += 1;
272 }
273 }
274 }
275 }
276 }
277
278 return ret;
279 }
280
281 /*===========================================================================
282 FUNCTION loc_read_conf_r (repetitive)
283
284 DESCRIPTION
285 Reads the specified configuration file and sets defined values based on
286 the passed in configuration table. This table maps strings to values to
287 set along with the type of each of these values.
288 The difference between this and loc_read_conf is that this function returns
289 the file pointer position at the end of filling a config table. Also, it
290 reads a fixed number of parameters at a time which is equal to the length
291 of the configuration table. This functionality enables the caller to
292 repeatedly call the function to read data from the same file.
293
294 PARAMETERS:
295 conf_fp : file pointer
296 config_table: table definition of strings to places to store information
297 table_length: length of the configuration table
298
299 DEPENDENCIES
300 N/A
301
302 RETURN VALUE
303 0: Table filled successfully
304 1: No more parameters to read
305 -1: Error filling table
306
307 SIDE EFFECTS
308 N/A
309 ===========================================================================*/
loc_read_conf_r(FILE * conf_fp,const loc_param_s_type * config_table,uint32_t table_length)310 int loc_read_conf_r(FILE *conf_fp, const loc_param_s_type* config_table, uint32_t table_length)
311 {
312 int ret=0;
313
314 unsigned int num_params=table_length;
315 if(conf_fp == NULL) {
316 LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__);
317 ret = -1;
318 goto err;
319 }
320
321 /* Clear all validity bits */
322 for(uint32_t i = 0; NULL != config_table && i < table_length; i++)
323 {
324 if(NULL != config_table[i].param_set)
325 {
326 *(config_table[i].param_set) = 0;
327 }
328 }
329
330 char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */
331
332 LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params);
333 while(num_params)
334 {
335 if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) {
336 LOC_LOGD("%s:%d]: fgets returned NULL\n", __func__, __LINE__);
337 break;
338 }
339
340 num_params -= loc_fill_conf_item(input_buf, config_table, table_length);
341 }
342
343 err:
344 return ret;
345 }
346
347 /*===========================================================================
348 FUNCTION loc_udpate_conf
349
350 DESCRIPTION
351 Parses the passed in buffer for configuration items, and update the table
352 that is also passed in.
353
354 Reads the specified configuration file and sets defined values based on
355 the passed in configuration table. This table maps strings to values to
356 set along with the type of each of these values.
357
358 PARAMETERS:
359 conf_data: configuration items in bufferas a string
360 length: strlen(conf_data)
361 config_table: table definition of strings to places to store information
362 table_length: length of the configuration table
363
364 DEPENDENCIES
365 N/A
366
367 RETURN VALUE
368 number of the records in the table that is updated at time of return.
369
370 SIDE EFFECTS
371 N/A
372 ===========================================================================*/
loc_update_conf(const char * conf_data,int32_t length,const loc_param_s_type * config_table,uint32_t table_length)373 int loc_update_conf(const char* conf_data, int32_t length,
374 const loc_param_s_type* config_table, uint32_t table_length)
375 {
376 int ret = -1;
377
378 if (conf_data && length && config_table && table_length) {
379 // make a copy, so we do not tokenize the original data
380 char* conf_copy = (char*)malloc(length+1);
381
382 if (conf_copy != NULL)
383 {
384 memcpy(conf_copy, conf_data, length);
385 // we hard NULL the end of string to be safe
386 conf_copy[length] = 0;
387
388 // start with one record off
389 uint32_t num_params = table_length - 1;
390 char* saveptr = NULL;
391 char* input_buf = strtok_r(conf_copy, "\n", &saveptr);
392 ret = 0;
393
394 LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params);
395 while(num_params && input_buf) {
396 ret++;
397 num_params -= loc_fill_conf_item(input_buf, config_table, table_length);
398 input_buf = strtok_r(NULL, "\n", &saveptr);
399 }
400 free(conf_copy);
401 }
402 }
403
404 return ret;
405 }
406
407 /*===========================================================================
408 FUNCTION loc_read_conf
409
410 DESCRIPTION
411 Reads the specified configuration file and sets defined values based on
412 the passed in configuration table. This table maps strings to values to
413 set along with the type of each of these values.
414
415 PARAMETERS:
416 conf_file_name: configuration file to read
417 config_table: table definition of strings to places to store information
418 table_length: length of the configuration table
419
420 DEPENDENCIES
421 N/A
422
423 RETURN VALUE
424 None
425
426 SIDE EFFECTS
427 N/A
428 ===========================================================================*/
loc_read_conf(const char * conf_file_name,const loc_param_s_type * config_table,uint32_t table_length)429 void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_table,
430 uint32_t table_length)
431 {
432 FILE *conf_fp = NULL;
433
434 log_buffer_init(false);
435 if((conf_fp = fopen(conf_file_name, "r")) != NULL)
436 {
437 LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name);
438 if(table_length && config_table) {
439 loc_read_conf_r(conf_fp, config_table, table_length);
440 rewind(conf_fp);
441 }
442 loc_read_conf_r(conf_fp, loc_param_table, loc_param_num);
443 fclose(conf_fp);
444 }
445 /* Initialize logging mechanism with parsed data */
446 loc_logger_init(DEBUG_LEVEL, TIMESTAMP);
447 log_buffer_init(sLogBufferEnabled);
448 }
449
450 /*=============================================================================
451 *
452 * Define and Structures for Parsing Location Process Configuration File
453 *
454 *============================================================================*/
455 #define MAX_NUM_STRINGS 20
456
457 //We can have 8 masks for now
458 #define CONFIG_MASK_TARGET_ALL 0X01
459 #define CONFIG_MASK_TARGET_FOUND 0X02
460 #define CONFIG_MASK_TARGET_CHECK 0X03
461 #define CONFIG_MASK_BASEBAND_ALL 0X04
462 #define CONFIG_MASK_BASEBAND_FOUND 0X08
463 #define CONFIG_MASK_BASEBAND_CHECK 0x0c
464 #define CONFIG_MASK_AUTOPLATFORM_ALL 0x10
465 #define CONFIG_MASK_AUTOPLATFORM_FOUND 0x20
466 #define CONFIG_MASK_AUTOPLATFORM_CHECK 0x30
467 #define CONFIG_MASK_SOCID_ALL 0x40
468 #define CONFIG_MASK_SOCID_FOUND 0x80
469 #define CONFIG_MASK_SOCID_CHECK 0xc0
470
471 #define LOC_FEATURE_MASK_GTP_WIFI_BASIC 0x01
472 #define LOC_FEATURE_MASK_GTP_WIFI_PREMIUM 0X02
473 #define LOC_FEATURE_MASK_GTP_CELL_BASIC 0X04
474 #define LOC_FEATURE_MASK_GTP_CELL_PREMIUM 0X08
475 #define LOC_FEATURE_MASK_SAP_BASIC 0x40
476 #define LOC_FEATURE_MASK_SAP_PREMIUM 0X80
477 #define LOC_FEATURE_MASK_GTP_WAA_BASIC 0X100
478 #define LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC 0X400
479 #define LOC_FEATURE_MASK_ODCPI 0x1000
480 #define LOC_FEATURE_MASK_FREE_WIFI_SCAN_INJECT 0x2000
481 #define LOC_FEATURE_MASK_SUPL_WIFI 0x4000
482 #define LOC_FEATURE_MASK_WIFI_SUPPLICANT_INFO 0x8000
483
484 typedef struct {
485 char proc_name[LOC_MAX_PARAM_STRING];
486 char proc_argument[LOC_MAX_PARAM_STRING];
487 char proc_status[LOC_MAX_PARAM_STRING];
488 char group_list[LOC_MAX_PARAM_STRING];
489 unsigned int premium_feature;
490 unsigned int loc_feature_mask;
491 char platform_list[LOC_MAX_PARAM_STRING];
492 char baseband[LOC_MAX_PARAM_STRING];
493 char low_ram_targets[LOC_MAX_PARAM_STRING];
494 char soc_id_list[LOC_MAX_PARAM_STRING];
495 unsigned int sglte_target;
496 char feature_gtp_mode[LOC_MAX_PARAM_STRING];
497 char feature_gtp_waa[LOC_MAX_PARAM_STRING];
498 char feature_sap[LOC_MAX_PARAM_STRING];
499 char feature_odcpi[LOC_MAX_PARAM_STRING];
500 char feature_free_wifi_scan_inject[LOC_MAX_PARAM_STRING];
501 char feature_supl_wifi[LOC_MAX_PARAM_STRING];
502 char feature_wifi_supplicant_info[LOC_MAX_PARAM_STRING];
503 char auto_platform[LOC_MAX_PARAM_STRING];
504 unsigned int vendor_enhanced_process;
505 } loc_launcher_conf;
506
507 /* process configuration parameters */
508 static loc_launcher_conf conf;
509
510 /* gps.conf Parameter spec table */
511 static const loc_param_s_type gps_conf_parameter_table[] = {
512 {"SGLTE_TARGET", &conf.sglte_target, NULL, 'n'},
513 };
514
515 /* location feature conf, e.g.: izat.conf feature mode table*/
516 static const loc_param_s_type loc_feature_conf_table[] = {
517 {"GTP_MODE", &conf.feature_gtp_mode, NULL, 's'},
518 {"GTP_WAA", &conf.feature_gtp_waa, NULL, 's'},
519 {"SAP", &conf.feature_sap, NULL, 's'},
520 {"ODCPI", &conf.feature_odcpi, NULL, 's'},
521 {"FREE_WIFI_SCAN_INJECT", &conf.feature_free_wifi_scan_inject, NULL, 's'},
522 {"SUPL_WIFI", &conf.feature_supl_wifi, NULL, 's'},
523 {"WIFI_SUPPLICANT_INFO", &conf.feature_wifi_supplicant_info, NULL, 's'},
524 };
525
526 /* location process conf, e.g.: izat.conf Parameter spec table */
527 static const loc_param_s_type loc_process_conf_parameter_table[] = {
528 {"PROCESS_NAME", &conf.proc_name, NULL, 's'},
529 {"PROCESS_ARGUMENT", &conf.proc_argument, NULL, 's'},
530 {"PROCESS_STATE", &conf.proc_status, NULL, 's'},
531 {"PROCESS_GROUPS", &conf.group_list, NULL, 's'},
532 {"PREMIUM_FEATURE", &conf.premium_feature, NULL, 'n'},
533 {"IZAT_FEATURE_MASK", &conf.loc_feature_mask, NULL, 'n'},
534 {"PLATFORMS", &conf.platform_list, NULL, 's'},
535 {"SOC_IDS", &conf.soc_id_list, NULL, 's'},
536 {"BASEBAND", &conf.baseband, NULL, 's'},
537 {"LOW_RAM_TARGETS", &conf.low_ram_targets, NULL, 's'},
538 {"HARDWARE_TYPE", &conf.auto_platform, NULL, 's'},
539 {"VENDOR_ENHANCED_PROCESS", &conf.vendor_enhanced_process, NULL, 'n'},
540 };
541
542 /*===========================================================================
543 FUNCTION loc_read_process_conf
544
545 DESCRIPTION
546 Parse the specified conf file and return info for the processes defined.
547 The format of the file should conform with izat.conf.
548
549 PARAMETERS:
550 conf_file_name: configuration file to read
551 process_count_ptr: pointer to store number of processes defined in the conf file.
552 process_info_table_ptr: pointer to store the process info table.
553
554 DEPENDENCIES
555 The file must be in izat.conf format.
556
557 RETURN VALUE
558 0: success
559 none-zero: failure
560
561 SIDE EFFECTS
562 N/A
563
564 NOTES:
565 On success, memory pointed by (*process_info_table_ptr) must be freed.
566 ===========================================================================*/
loc_read_process_conf(const char * conf_file_name,uint32_t * process_count_ptr,loc_process_info_s_type ** process_info_table_ptr)567 int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_ptr,
568 loc_process_info_s_type** process_info_table_ptr) {
569 loc_process_info_s_type *child_proc = nullptr;
570 volatile int i=0;
571 unsigned int j=0;
572 gid_t gid_list[LOC_PROCESS_MAX_NUM_GROUPS];
573 char *split_strings[MAX_NUM_STRINGS];
574 int name_length=0, group_list_length=0, platform_length=0, baseband_length=0, ngroups=0, ret=0;
575 int auto_platform_length = 0, soc_id_list_length=0;
576 int group_index=0, nstrings=0, status_length=0;
577 FILE* conf_fp = nullptr;
578 char platform_name[PROPERTY_VALUE_MAX], baseband_name[PROPERTY_VALUE_MAX];
579 int low_ram_target=0;
580 char autoplatform_name[PROPERTY_VALUE_MAX], socid_value[PROPERTY_VALUE_MAX];
581 unsigned int loc_service_mask=0;
582 unsigned char config_mask = 0;
583 unsigned char proc_list_length=0;
584 int gtp_cell_ap_enabled = 0;
585 char arg_gtp_waa[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
586 char arg_gtp_modem_cell[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
587 char arg_gtp_wifi[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
588 char arg_sap[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
589 char arg_disabled[LOC_PROCESS_MAX_ARG_STR_LENGTH] = LOC_FEATURE_MODE_DISABLED;
590 char arg_basic[LOC_PROCESS_MAX_ARG_STR_LENGTH] = LOC_FEATURE_MODE_BASIC;
591 char arg_premium[LOC_PROCESS_MAX_ARG_STR_LENGTH] = LOC_FEATURE_MODE_PREMIUM;
592
593 if (process_count_ptr == NULL || process_info_table_ptr == NULL) {
594 return -1;
595 }
596
597 //Read gps.conf and fill parameter table
598 UTIL_READ_CONF(LOC_PATH_GPS_CONF, gps_conf_parameter_table);
599
600 //Form argument strings
601 strlcat(arg_gtp_waa, LOC_FEATURE_GTP_WAA, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
602 strlcat(arg_gtp_modem_cell, LOC_FEATURE_GTP_MODEM_CELL, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
603 strlcat(arg_gtp_wifi, LOC_FEATURE_GTP_WIFI, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
604 strlcat(arg_sap, LOC_FEATURE_SAP, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
605
606 //Get platform name from ro.board.platform property
607 loc_get_platform_name(platform_name, sizeof(platform_name));
608 //Get baseband name from ro.baseband property
609 loc_get_target_baseband(baseband_name, sizeof(baseband_name));
610 //Identify if this is an automotive platform
611 loc_get_auto_platform_name(autoplatform_name,sizeof(autoplatform_name));
612 //Identify if this is a low ram target from ro.config.low_ram property
613 low_ram_target = loc_identify_low_ram_target();
614 // Get the soc-id for this device.
615 loc_get_device_soc_id(socid_value, sizeof(socid_value));
616
617 UTIL_READ_CONF(conf_file_name, loc_feature_conf_table);
618
619 //Set service mask for GTP_MODE
620 if(strcmp(conf.feature_gtp_mode, "DISABLED") == 0) {
621 LOC_LOGD("%s:%d]: GTP MODE DISABLED", __func__, __LINE__);
622 }
623 else if(strcmp(conf.feature_gtp_mode, "LEGACY_WWAN") == 0) {
624 LOC_LOGD("%s:%d]: Setting GTP MODE to mode: LEGACY_WWAN", __func__, __LINE__);
625 loc_service_mask |= LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC;
626 }
627 else if(strcmp(conf.feature_gtp_mode, "SDK") == 0) {
628 LOC_LOGD("%s:%d]: Setting GTP MODE to mode: SDK", __func__, __LINE__);
629 loc_service_mask |= LOC_FEATURE_MASK_GTP_WIFI_BASIC;
630 }
631 //conf file has a garbage value
632 else {
633 LOC_LOGE("%s:%d]: Unrecognized value for GTP MODE Mode."\
634 " Setting GTP WIFI to default mode: DISABLED", __func__, __LINE__);
635 }
636 //Set service mask for GTP_WAA
637 if(strcmp(conf.feature_gtp_waa, "BASIC") == 0) {
638 LOC_LOGD("%s:%d]: Setting GTP WAA to mode: BASIC", __func__, __LINE__);
639 loc_service_mask |= LOC_FEATURE_MASK_GTP_WAA_BASIC;
640 }
641 else if(strcmp(conf.feature_gtp_waa, "DISABLED") == 0) {
642 LOC_LOGD("%s:%d]: GTP WAA DISABLED", __func__, __LINE__);
643 }
644 //conf file has a garbage value
645 else {
646 LOC_LOGE("%s:%d]: Unrecognized value for GTP WAA Mode."\
647 " Setting GTP WAA to default mode: DISABLED", __func__, __LINE__);
648 }
649
650 //Set service mask for SAP
651 if(strcmp(conf.feature_sap, "PREMIUM") == 0) {
652 LOC_LOGD("%s:%d]: Setting SAP to mode: PREMIUM", __func__, __LINE__);
653 loc_service_mask |= LOC_FEATURE_MASK_SAP_PREMIUM;
654 }
655 else if(strcmp(conf.feature_sap, "BASIC") == 0) {
656 LOC_LOGD("%s:%d]: Setting SAP to mode: BASIC", __func__, __LINE__);
657 loc_service_mask |= LOC_FEATURE_MASK_SAP_BASIC;
658 }
659 else if(strcmp(conf.feature_sap, "MODEM_DEFAULT") == 0) {
660 LOC_LOGD("%s:%d]: Setting SAP to mode: MODEM_DEFAULT", __func__, __LINE__);
661 }
662 else if(strcmp(conf.feature_sap, "DISABLED") == 0) {
663 LOC_LOGD("%s:%d]: Setting SAP to mode: DISABLED", __func__, __LINE__);
664 }
665 else {
666 LOC_LOGE("%s:%d]: Unrecognized value for SAP Mode."\
667 " Setting SAP to default mode: BASIC", __func__, __LINE__);
668 loc_service_mask |= LOC_FEATURE_MASK_SAP_BASIC;
669 }
670
671 // Set service mask for ODCPI
672 if(strcmp(conf.feature_odcpi, "BASIC") == 0) {
673 LOC_LOGD("%s:%d]: Setting ODCPI to mode: BASIC", __func__, __LINE__);
674 loc_service_mask |= LOC_FEATURE_MASK_ODCPI;
675 }
676 else if(strcmp(conf.feature_odcpi, "DISABLED") == 0) {
677 LOC_LOGD("%s:%d]: Setting ODCPI to mode: DISABLED", __func__, __LINE__);
678 }
679 else if(strcmp(conf.feature_odcpi, "PREMIUM") == 0) {
680 LOC_LOGD("%s:%d]: Unrecognized value for ODCPI mode."\
681 "Setting ODCPI to default mode: BASIC", __func__, __LINE__);
682 loc_service_mask |= LOC_FEATURE_MASK_ODCPI;
683 }
684
685 // Set service mask for FREE_WIFI_SCAN_INJECT
686 if(strcmp(conf.feature_free_wifi_scan_inject, "BASIC") == 0) {
687 LOC_LOGD("%s:%d]: Setting FREE_WIFI_SCAN_INJECT to mode: BASIC", __func__, __LINE__);
688 loc_service_mask |= LOC_FEATURE_MASK_FREE_WIFI_SCAN_INJECT;
689 }
690 else if(strcmp(conf.feature_free_wifi_scan_inject, "DISABLED") == 0) {
691 LOC_LOGD("%s:%d]: Setting FREE_WIFI_SCAN_INJECT to mode: DISABLED", __func__, __LINE__);
692 }
693 else if(strcmp(conf.feature_free_wifi_scan_inject, "PREMIUM") == 0) {
694 LOC_LOGD("%s:%d]: Unrecognized value for FREE_WIFI_SCAN_INJECT mode."\
695 "Setting FREE_WIFI_SCAN_INJECT to default mode: BASIC", __func__, __LINE__);
696 loc_service_mask |= LOC_FEATURE_MASK_FREE_WIFI_SCAN_INJECT;
697 }
698
699 // Set service mask for SUPL_WIFI
700 if(strcmp(conf.feature_supl_wifi, "BASIC") == 0) {
701 LOC_LOGD("%s:%d]: Setting SUPL_WIFI to mode: BASIC", __func__, __LINE__);
702 loc_service_mask |= LOC_FEATURE_MASK_SUPL_WIFI;
703 }
704 else if(strcmp(conf.feature_supl_wifi, "DISABLED") == 0) {
705 LOC_LOGD("%s:%d]: Setting SUPL_WIFI to mode: DISABLED", __func__, __LINE__);
706 }
707 else if(strcmp(conf.feature_supl_wifi, "PREMIUM") == 0) {
708 LOC_LOGD("%s:%d]: Unrecognized value for SUPL_WIFI mode."\
709 "Setting SUPL_WIFI to default mode: BASIC", __func__, __LINE__);
710 loc_service_mask |= LOC_FEATURE_MASK_SUPL_WIFI;
711 }
712
713 // Set service mask for WIFI_SUPPLICANT_INFO
714 if(strcmp(conf.feature_wifi_supplicant_info, "BASIC") == 0) {
715 LOC_LOGD("%s:%d]: Setting WIFI_SUPPLICANT_INFO to mode: BASIC", __func__, __LINE__);
716 loc_service_mask |= LOC_FEATURE_MASK_WIFI_SUPPLICANT_INFO;
717 }
718 else if(strcmp(conf.feature_wifi_supplicant_info, "DISABLED") == 0) {
719 LOC_LOGD("%s:%d]: Setting WIFI_SUPPLICANT_INFO to mode: DISABLED", __func__, __LINE__);
720 }
721 else if(strcmp(conf.feature_wifi_supplicant_info, "PREMIUM") == 0) {
722 LOC_LOGD("%s:%d]: Unrecognized value for WIFI_SUPPLICANT_INFO mode."\
723 "Setting LOC_FEATURE_MASK_WIFI_SUPPLICANT_INFO to default mode: BASIC", __func__, __LINE__);
724 loc_service_mask |= LOC_FEATURE_MASK_WIFI_SUPPLICANT_INFO;
725 }
726
727 LOC_LOGD("%s:%d]: loc_service_mask: %x\n", __func__, __LINE__, loc_service_mask);
728
729 if((conf_fp = fopen(conf_file_name, "r")) == NULL) {
730 LOC_LOGE("%s:%d]: Error opening %s %s\n", __func__,
731 __LINE__, conf_file_name, strerror(errno));
732 ret = -1;
733 goto err;
734 }
735
736 //Parse through the file to find out how many processes are to be launched
737 proc_list_length = 0;
738 do {
739 conf.proc_name[0] = 0;
740 //Here note that the 3rd parameter is passed as 1.
741 //This is so that only the first parameter in the table which is "PROCESS_NAME"
742 //is read. We do not want to read the entire block of parameters at this time
743 //since we are only counting the number of processes to launch.
744 //Therefore, only counting the occurrences of PROCESS_NAME parameter
745 //should suffice
746 if(loc_read_conf_r(conf_fp, loc_process_conf_parameter_table, 1)) {
747 LOC_LOGE("%s:%d]: Unable to read conf file. Failing\n", __func__, __LINE__);
748 ret = -1;
749 goto err;
750 }
751 name_length=(int)strlen(conf.proc_name);
752 if(name_length) {
753 proc_list_length++;
754 LOC_LOGD("Process name:%s", conf.proc_name);
755 }
756 } while(name_length);
757 LOC_LOGD("Process cnt = %d", proc_list_length);
758
759 child_proc = (loc_process_info_s_type *)calloc(proc_list_length, sizeof(loc_process_info_s_type));
760 if(child_proc == NULL) {
761 LOC_LOGE("%s:%d]: ERROR: Malloc returned NULL\n", __func__, __LINE__);
762 ret = -1;
763 goto err;
764 }
765
766 //Move file descriptor to the beginning of the file
767 //so that the parameters can be read
768 rewind(conf_fp);
769
770 for(j=0; j<proc_list_length; j++) {
771 //Set defaults for all the child process structs
772 child_proc[j].proc_status = DISABLED;
773 memset(child_proc[j].group_list, 0, sizeof(child_proc[j].group_list));
774 config_mask=0;
775 if(loc_read_conf_r(conf_fp, loc_process_conf_parameter_table,
776 sizeof(loc_process_conf_parameter_table)/sizeof(loc_process_conf_parameter_table[0]))) {
777 LOC_LOGE("%s:%d]: Unable to read conf file. Failing\n", __func__, __LINE__);
778 ret = -1;
779 goto err;
780 }
781
782 name_length=(int)strlen(conf.proc_name);
783 group_list_length=(int)strlen(conf.group_list);
784 platform_length = (int)strlen(conf.platform_list);
785 baseband_length = (int)strlen(conf.baseband);
786 status_length = (int)strlen(conf.proc_status);
787 auto_platform_length = (int)strlen(conf.auto_platform);
788 soc_id_list_length = (int)strlen(conf.soc_id_list);
789
790 if(!name_length || !group_list_length || !platform_length ||
791 !baseband_length || !status_length || !auto_platform_length || !soc_id_list_length) {
792 LOC_LOGE("%s:%d]: Error: i: %d; One of the parameters not specified in conf file",
793 __func__, __LINE__, i);
794 continue;
795 }
796
797 if (!isVendorEnhanced() && (conf.vendor_enhanced_process != 0)) {
798 LOC_LOGD("%s:%d]: Process %s is disabled via vendor enhanced process check",
799 __func__, __LINE__, conf.proc_name);
800 child_proc[j].proc_status = DISABLED_VIA_VENDOR_ENHANCED_CHECK;
801 continue;
802 }
803
804 if(strcmp(conf.proc_status, "DISABLED") == 0) {
805 LOC_LOGD("%s:%d]: Process %s is disabled in conf file",
806 __func__, __LINE__, conf.proc_name);
807 child_proc[j].proc_status = DISABLED_FROM_CONF;
808 continue;
809 }
810 else if(strcmp(conf.proc_status, "ENABLED") == 0) {
811 LOC_LOGD("%s:%d]: Process %s is enabled in conf file",
812 __func__, __LINE__, conf.proc_name);
813 }
814
815 //Since strlcpy copies length-1 characters, we add 1 to name_length
816 if((name_length+1) > LOC_MAX_PARAM_STRING) {
817 LOC_LOGE("%s:%d]: i: %d; Length of name parameter too long. Max length: %d",
818 __func__, __LINE__, i, LOC_MAX_PARAM_STRING);
819 continue;
820 }
821 strlcpy(child_proc[j].name[0], conf.proc_name, sizeof (child_proc[j].name[0]));
822
823 child_proc[j].num_groups = 0;
824 ngroups = loc_util_split_string(conf.group_list, split_strings, MAX_NUM_STRINGS, ' ');
825 for(i=0; i<ngroups; i++) {
826 struct group* grp = getgrnam(split_strings[i]);
827 if (grp) {
828 child_proc[j].group_list[child_proc[j].num_groups] = grp->gr_gid;
829 child_proc[j].num_groups++;
830 LOC_LOGd("Group %s = %d", split_strings[i], grp->gr_gid);
831 }
832 }
833
834 nstrings = loc_util_split_string(conf.platform_list, split_strings, MAX_NUM_STRINGS, ' ');
835 if(strcmp("all", split_strings[0]) == 0) {
836 if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
837 LOC_LOGD("%s:%d]: Enabled for all targets\n", __func__, __LINE__);
838 config_mask |= CONFIG_MASK_TARGET_ALL;
839 }
840 else if (nstrings > 2 && (strcmp("exclude", split_strings[1]) == 0)) {
841 config_mask |= CONFIG_MASK_TARGET_FOUND;
842 for (i=2; i<nstrings; i++) {
843 if(strcmp(platform_name, split_strings[i]) == 0) {
844 LOC_LOGD("%s:%d]: Disabled platform %s\n", __func__, __LINE__, platform_name);
845 config_mask &= ~CONFIG_MASK_TARGET_FOUND;
846 break;
847 }
848 }
849 }
850 }
851 else {
852 for(i=0; i<nstrings; i++) {
853 if(strcmp(platform_name, split_strings[i]) == 0) {
854 LOC_LOGD("%s:%d]: Matched platform: %s\n",
855 __func__, __LINE__, split_strings[i]);
856 config_mask |= CONFIG_MASK_TARGET_FOUND;
857 break;
858 }
859 }
860 }
861
862 // SOC Id's check
863 nstrings = loc_util_split_string(conf.soc_id_list, split_strings, MAX_NUM_STRINGS, ' ');
864 if (strcmp("all", split_strings[0]) == 0) {
865 if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
866 LOC_LOGd("Enabled for all SOC ids\n");
867 config_mask |= CONFIG_MASK_SOCID_ALL;
868 }
869 else if (nstrings > 2 && (strcmp("exclude", split_strings[1]) == 0)) {
870 config_mask |= CONFIG_MASK_SOCID_FOUND;
871 for (i = 2; i < nstrings; i++) {
872 if (strcmp(socid_value, split_strings[i]) == 0) {
873 LOC_LOGd("Disabled for SOC id %s\n", socid_value);
874 config_mask &= ~CONFIG_MASK_SOCID_FOUND;
875 break;
876 }
877 }
878 }
879 }
880 else {
881 for (i = 0; i < nstrings; i++) {
882 if (strcmp(socid_value, split_strings[i]) == 0) {
883 LOC_LOGd("Matched SOC id : %s\n", split_strings[i]);
884 config_mask |= CONFIG_MASK_SOCID_FOUND;
885 break;
886 }
887 }
888 }
889
890 nstrings = loc_util_split_string(conf.baseband, split_strings, MAX_NUM_STRINGS, ' ');
891 if(strcmp("all", split_strings[0]) == 0) {
892 if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
893 LOC_LOGD("%s:%d]: Enabled for all basebands\n", __func__, __LINE__);
894 config_mask |= CONFIG_MASK_BASEBAND_ALL;
895 }
896 else if (nstrings > 2 && (strcmp("exclude", split_strings[1]) == 0)) {
897 config_mask |= CONFIG_MASK_BASEBAND_FOUND;
898 for (i=2; i<nstrings; i++) {
899 if(strcmp(baseband_name, split_strings[i]) == 0) {
900 LOC_LOGD("%s:%d]: Disabled band %s\n", __func__, __LINE__, baseband_name);
901 config_mask &= ~CONFIG_MASK_BASEBAND_FOUND;
902 break;
903 }
904 }
905 }
906 }
907 else {
908 for(i=0; i<nstrings; i++) {
909 if(strcmp(baseband_name, split_strings[i]) == 0) {
910 LOC_LOGD("%s:%d]: Matched baseband: %s\n",
911 __func__, __LINE__, split_strings[i]);
912 config_mask |= CONFIG_MASK_BASEBAND_FOUND;
913 break;
914 }
915 //Since ro.baseband is not a reliable source for detecting sglte
916 //the alternative is to read the SGLTE_TARGET parameter from gps.conf
917 //this parameter is read into conf_sglte_target
918 else if((strcmp("sglte", split_strings[i]) == 0 ) && conf.sglte_target) {
919 LOC_LOGD("%s:%d]: Matched baseband SGLTE\n", __func__, __LINE__);
920 config_mask |= CONFIG_MASK_BASEBAND_FOUND;
921 break;
922 }
923 }
924 }
925
926 nstrings = loc_util_split_string(conf.auto_platform, split_strings, MAX_NUM_STRINGS, ' ');
927 if(strcmp("all", split_strings[0]) == 0) {
928 LOC_LOGD("%s:%d]: Enabled for all auto platforms\n", __func__, __LINE__);
929 config_mask |= CONFIG_MASK_AUTOPLATFORM_ALL;
930 }
931 else {
932 for(i=0; i<nstrings; i++) {
933 if(strcmp(autoplatform_name, split_strings[i]) == 0) {
934 LOC_LOGD("%s:%d]: Matched auto platform: %s\n",
935 __func__, __LINE__, split_strings[i]);
936 config_mask |= CONFIG_MASK_AUTOPLATFORM_FOUND;
937 break;
938 }
939 }
940 }
941
942 nstrings = loc_util_split_string(conf.low_ram_targets, split_strings, MAX_NUM_STRINGS, ' ');
943 if (!strcmp("DISABLED", split_strings[0]) && low_ram_target) {
944 LOC_LOGd("Disabled for low ram targets\n");
945 child_proc[j].proc_status = DISABLED;
946 continue;
947 }
948
949 if((config_mask & CONFIG_MASK_TARGET_CHECK) &&
950 (config_mask & CONFIG_MASK_BASEBAND_CHECK) &&
951 (config_mask & CONFIG_MASK_AUTOPLATFORM_CHECK) &&
952 (config_mask & CONFIG_MASK_SOCID_CHECK) &&
953 (child_proc[j].proc_status != DISABLED_FROM_CONF) &&
954 (child_proc[j].proc_status != DISABLED_VIA_VENDOR_ENHANCED_CHECK)) {
955
956 //Set args
957 //The first argument passed through argv is usually the name of the
958 //binary when started from commandline.
959 //getopt() seems to ignore this first argument and hence we assign it
960 //to the process name for consistency with command line args
961 i = 0;
962 char* temp_arg = ('/' == child_proc[j].name[0][0]) ?
963 (strrchr(child_proc[j].name[0], '/') + 1) : child_proc[j].name[0];
964 strlcpy (child_proc[j].args[i++], temp_arg, sizeof (child_proc[j].args[i++]));
965
966 if(conf.premium_feature) {
967 if(conf.loc_feature_mask & loc_service_mask) {
968 LOC_LOGD("%s:%d]: Enabled. %s has service mask: %x\n",
969 __func__, __LINE__, child_proc[j].name[0], conf.loc_feature_mask);
970 child_proc[j].proc_status = ENABLED;
971
972 if(conf.loc_feature_mask &
973 (LOC_FEATURE_MASK_GTP_WIFI_BASIC | LOC_FEATURE_MASK_GTP_WIFI_PREMIUM)) {
974 if(loc_service_mask & LOC_FEATURE_MASK_GTP_WIFI_BASIC) {
975 strlcpy(child_proc[j].args[i++], arg_gtp_wifi,
976 LOC_PROCESS_MAX_ARG_STR_LENGTH);
977 strlcpy(child_proc[j].args[i++], arg_basic,
978 LOC_PROCESS_MAX_ARG_STR_LENGTH);
979 }
980 else if(loc_service_mask & LOC_FEATURE_MASK_GTP_WIFI_PREMIUM) {
981 strlcpy(child_proc[j].args[i++], arg_gtp_wifi,
982 LOC_PROCESS_MAX_ARG_STR_LENGTH);
983 strlcpy(child_proc[j].args[i++], arg_premium,
984 LOC_PROCESS_MAX_ARG_STR_LENGTH);
985 }
986 else
987 {
988 strlcpy(child_proc[j].args[i++], arg_gtp_wifi,
989 LOC_PROCESS_MAX_ARG_STR_LENGTH);
990 strlcpy(child_proc[j].args[i++], arg_disabled,
991 LOC_PROCESS_MAX_ARG_STR_LENGTH);
992 }
993 }
994 if(conf.loc_feature_mask &
995 (LOC_FEATURE_MASK_GTP_CELL_BASIC | LOC_FEATURE_MASK_GTP_CELL_PREMIUM )) {
996 if(loc_service_mask & LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC) {
997 strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
998 LOC_PROCESS_MAX_ARG_STR_LENGTH);
999 strlcpy(child_proc[j].args[i++], arg_basic,
1000 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1001 }
1002 else {
1003 strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
1004 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1005 strlcpy(child_proc[j].args[i++], arg_disabled,
1006 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1007 }
1008 }
1009 if(conf.loc_feature_mask &
1010 (LOC_FEATURE_MASK_SAP_BASIC | LOC_FEATURE_MASK_SAP_PREMIUM)) {
1011 if(loc_service_mask & LOC_FEATURE_MASK_SAP_BASIC) {
1012 strlcpy(child_proc[j].args[i++], arg_sap,
1013 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1014 strlcpy(child_proc[j].args[i++], arg_basic,
1015 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1016 }
1017 else if(loc_service_mask & LOC_FEATURE_MASK_SAP_PREMIUM) {
1018 strlcpy(child_proc[j].args[i++], arg_sap,
1019 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1020 strlcpy(child_proc[j].args[i++], arg_premium,
1021 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1022 }
1023 else
1024 {
1025 strlcpy(child_proc[j].args[i++], arg_sap,
1026 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1027 strlcpy(child_proc[j].args[i++], arg_disabled,
1028 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1029 }
1030 }
1031
1032 if(conf.loc_feature_mask & LOC_FEATURE_MASK_GTP_WAA_BASIC) {
1033 if(loc_service_mask & LOC_FEATURE_MASK_GTP_WAA_BASIC) {
1034 strlcpy(child_proc[j].args[i++], arg_gtp_waa,
1035 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1036 strlcpy(child_proc[j].args[i++], arg_basic,
1037 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1038 }
1039 else
1040 {
1041 strlcpy(child_proc[j].args[i++], arg_gtp_waa,
1042 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1043 strlcpy(child_proc[j].args[i++], arg_disabled,
1044 LOC_PROCESS_MAX_ARG_STR_LENGTH);
1045 }
1046 }
1047 IF_LOC_LOGD {
1048 LOC_LOGD("%s:%d]: %s args\n", __func__, __LINE__, child_proc[j].name[0]);
1049 for(unsigned int k=0; k<LOC_PROCESS_MAX_NUM_ARGS; k++) {
1050 if(child_proc[j].args[k][0] != '\0') {
1051 LOC_LOGD("%s:%d]: k: %d, %s\n", __func__, __LINE__, k,
1052 child_proc[j].args[k]);
1053 }
1054 }
1055 LOC_LOGD("%s:%d]: \n", __func__, __LINE__);
1056 }
1057 }
1058 else {
1059 LOC_LOGD("%s:%d]: Disabled. %s has service mask: %x \n",
1060 __func__, __LINE__, child_proc[j].name[0], conf.loc_feature_mask);
1061 }
1062 }
1063 else {
1064 LOC_LOGD("%s:%d]: %s not a premium feature. Enabled\n",
1065 __func__, __LINE__, child_proc[j].name[0]);
1066 child_proc[j].proc_status = ENABLED;
1067 }
1068
1069 /*Fill up the remaining arguments from configuration file*/
1070 LOC_LOGD("%s] Parsing Process_Arguments from Configuration: %s \n",
1071 __func__, conf.proc_argument);
1072 if(0 != conf.proc_argument[0])
1073 {
1074 /**************************************
1075 ** conf_proc_argument is shared by all the programs getting launched,
1076 ** hence copy to process specific argument string and parse the same.
1077 ***************************************/
1078 strlcpy(child_proc[j].argumentString, conf.proc_argument,
1079 sizeof(child_proc[j].argumentString));
1080 char *temp_args[LOC_PROCESS_MAX_NUM_ARGS];
1081 memset (temp_args, 0, sizeof (temp_args));
1082 loc_util_split_string(child_proc[j].argumentString, &temp_args[i],
1083 (LOC_PROCESS_MAX_NUM_ARGS - i), ' ');
1084 // copy argument from the pointer to the memory
1085 for (unsigned int index = i; index < LOC_PROCESS_MAX_NUM_ARGS; index++) {
1086 if (temp_args[index] == NULL) {
1087 break;
1088 }
1089 strlcpy (child_proc[j].args[index], temp_args[index],
1090 sizeof (child_proc[j].args[index]));
1091 }
1092 }
1093 }
1094 else {
1095 LOC_LOGD("%s:%d]: Process %s is disabled\n",
1096 __func__, __LINE__, child_proc[j].name[0]);
1097 }
1098 }
1099
1100 err:
1101 if (conf_fp) {
1102 fclose(conf_fp);
1103 }
1104 if (ret != 0) {
1105 LOC_LOGE("%s:%d]: ret: %d", __func__, __LINE__, ret);
1106 if (child_proc) {
1107 free (child_proc);
1108 child_proc = nullptr;
1109 }
1110 *process_count_ptr = 0;
1111 *process_info_table_ptr = nullptr;
1112
1113 }
1114 else {
1115 *process_count_ptr = proc_list_length;
1116 *process_info_table_ptr = child_proc;
1117 }
1118
1119 return ret;
1120 }
1121