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