标签:gps
gps.conf是gps的配置文件,这里面常用到的DEBUG_LEVEL配置项是gps HAL层logcat的开关,搞清楚这个配置项的解析流程同样对整个gps.conf的解析有很大的帮助,这里来走一下flow。
hardware/qcom/gps/loc_api/libloc_api_50001/gps.c
const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev) { return get_gps_interface(); }
static int open_gps(const struct hw_module_t* module, char const* name, struct hw_device_t** device) { struct gps_device_t *dev = (struct gps_device_t *) malloc(sizeof(struct gps_device_t)); if(dev == NULL) return -1; memset(dev, 0, sizeof(*dev)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (struct hw_module_t*)module; dev->get_gps_interface = gps__get_gps_interface; *device = (struct hw_device_t*)dev; return 0; }
frameworks/base/services/core/jni/com_android_server_location_GpsLocationProvider.cpp static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { int err; hw_module_t* module; ... if (err == 0) { hw_device_t* device; err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); if (err == 0) { gps_device_t* gps_device = (gps_device_t *)device; sGpsInterface = gps_device->get_gps_interface(gps_device); } } ... }这个init是gps的在jni层的入口,至于为什么会走这里,以后再讲了
extern "C" const GpsInterface* get_gps_interface() { unsigned int target = TARGET_DEFAULT; loc_eng_read_config(); ... }
int loc_eng_read_config(void) { ENTRY_LOG_CALLFLOW(); if(configAlreadyRead == false) { //gps config信息只用read一次 // Initialize our defaults before reading of configuration file overwrites them. //初始化一些参数 loc_default_parameters(); // We only want to parse the conf file once. This is a good place to ensure that. // In fact one day the conf file should go into context. //暂时先只关注GPS_CONF_FILE,也就是/etc/gps.conf UTIL_READ_CONF(GPS_CONF_FILE, gps_conf_table); UTIL_READ_CONF(SAP_CONF_FILE, sap_conf_table); configAlreadyRead = true; } else { LOC_LOGV("GPS Config file has already been read\n"); } EXIT_LOG(%d, 0); return 0; }
#define UTIL_READ_CONF(filename, config_table) loc_read_conf((filename), (config_table), sizeof(config_table) / sizeof(config_table[0]))
static loc_param_s_type gps_conf_table[] = { {"GPS_LOCK", &gps_conf.GPS_LOCK, NULL, 'n'}, {"SUPL_VER", &gps_conf.SUPL_VER, NULL, 'n'}, {"LPP_PROFILE", &gps_conf.LPP_PROFILE, NULL, 'n'}, {"A_GLONASS_POS_PROTOCOL_SELECT", &gps_conf.A_GLONASS_POS_PROTOCOL_SELECT, NULL, 'n'}, {"AGPS_CERT_WRITABLE_MASK", &gps_conf.AGPS_CERT_WRITABLE_MASK, NULL, 'n'}, {"SUPL_MODE", &gps_conf.SUPL_MODE, NULL, 'n'}, {"INTERMEDIATE_POS", &gps_conf.INTERMEDIATE_POS, NULL, 'n'}, {"ACCURACY_THRES", &gps_conf.ACCURACY_THRES, NULL, 'n'}, {"NMEA_PROVIDER", &gps_conf.NMEA_PROVIDER, NULL, 'n'}, {"CAPABILITIES", &gps_conf.CAPABILITIES, NULL, 'n'}, {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", &gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'}, };
typedef struct { char param_name[LOC_MAX_PARAM_NAME]; void *param_ptr; uint8_t *param_set; /* was this value set by config file? */ char param_type; /* 'n' for number, 's' for string, 'f' for float */ } loc_param_s_type;
typedef struct loc_gps_cfg_s { uint32_t INTERMEDIATE_POS; uint32_t ACCURACY_THRES; uint32_t SUPL_VER; uint32_t SUPL_MODE; uint32_t CAPABILITIES; uint32_t LPP_PROFILE; uint32_t XTRA_VERSION_CHECK; char XTRA_SERVER_1[MAX_XTRA_SERVER_URL_LENGTH]; char XTRA_SERVER_2[MAX_XTRA_SERVER_URL_LENGTH]; char XTRA_SERVER_3[MAX_XTRA_SERVER_URL_LENGTH]; uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL; uint32_t NMEA_PROVIDER; uint32_t GPS_LOCK; uint32_t A_GLONASS_POS_PROTOCOL_SELECT; uint32_t AGPS_CERT_WRITABLE_MASK; } loc_gps_cfg_s_type;
void loc_read_conf(const char* conf_file_name, loc_param_s_type* config_table, uint32_t table_length) { FILE *conf_fp = NULL; char *lasts; loc_param_v_type config_value; uint32_t i; //打开/etc/gps.conf,拿到fp,这个是读取conf的第一步 if((conf_fp = fopen(conf_file_name, "r")) != NULL) { LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name); if(table_length && config_table) { //table_length和config_table前面有定义,肯定是走这里啦,这里面是填充config_table的 loc_read_conf_r(conf_fp, config_table, table_length); //走过一边之后,conf_fp的文件指针已经知道文件尾部了,rewind一下conf_fp又到了文件头部 rewind(conf_fp); } //这里是是读DEBUG_LEVEL的地方,重点跟进一下 loc_read_conf_r(conf_fp, loc_param_table, loc_param_num); fclose(conf_fp); } /* Initialize logging mechanism with parsed data */ loc_logger_init(DEBUG_LEVEL, TIMESTAMP); }
/* Parameter data */ static uint8_t DEBUG_LEVEL = 0xff; static uint8_t TIMESTAMP = 0; /* Parameter spec table */ static loc_param_s_type loc_param_table[] = { {"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'}, {"TIMESTAMP", &TIMESTAMP, NULL, 'n'}, }; int loc_param_num = sizeof(loc_param_table) / sizeof(loc_param_s_type);
int loc_read_conf_r(FILE *conf_fp, loc_param_s_type* config_table, uint32_t table_length) { //conf_fp rewind到文件头部了,config_table的定义和初始化前面也做了,table_length就是loc_param_num,这里值是2 int ret=0; unsigned int num_params=table_length; if(conf_fp == NULL) { LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__); ret = -1; goto err; } /* Clear all validity bits */ //param_set全部初始化为NULL,表明这些值还没有被conf file设置 for(uint32_t i = 0; NULL != config_table && i < table_length; i++) { if(NULL != config_table[i].param_set) { *(config_table[i].param_set) = 0; } } char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */ LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params); while(num_params) { //弄了半天,fp是有了但是一直没有读conf,这个fgets马上跟进 if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) { //逐行来解析,如果读到文件尾就结束 LOC_LOGD("%s:%d]: fgets returned NULL\n", __func__, __LINE__); break; } //根据读取的行,解析出里面的内容填充到config_table中,如果config_table填充完毕(就是说table里面的DEBUG_LEVEL和TIMESTAMP都填充完),这个循环同样结束 num_params -= loc_fill_conf_item(input_buf, config_table, table_length); } err: return ret; }
typedef struct loc_param_v_type { char* param_name; char* param_str_value; int param_int_value; double param_double_value; }loc_param_v_type;
int loc_fill_conf_item(char* input_buf, loc_param_s_type* config_table, uint32_t table_length) { int ret = 0; if (input_buf && config_table) { char *lasts; //定义和初始化一个loc_param_v_type,用来存储fgets读出来的这行conf loc_param_v_type config_value; memset(&config_value, 0, sizeof(config_value)); /* Separate variable and value */ 把这行conf用strtok_r分离出key,直接存储到param_name中 config_value.param_name = strtok_r(input_buf, "=", &lasts); /* skip lines that do not contain "=" */ if (config_value.param_name) { //第二次用strtok_r分离出value来,但是目前暂时不知道value的类型 config_value.param_str_value = strtok_r(NULL, "=", &lasts); /* skip lines that do not contain two operands */ if (config_value.param_str_value) { /* Trim leading and trailing spaces */ //对key和value做一下处理,清除里面的无用空格 loc_util_trim_space(config_value.param_name); loc_util_trim_space(config_value.param_str_value); /* Parse numerical value */ if ((strlen(config_value.param_str_value) >=3) && (config_value.param_str_value[0] == '0') && (tolower(config_value.param_str_value[1]) == 'x')) { //如果value的前两个字符是0x,那么认为value是int类型 /* hex */ config_value.param_int_value = (int) strtol(&config_value.param_str_value[2], (char**) NULL, 16); } else { //否则int和double类型都存储一次 config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */ config_value.param_int_value = atoi(config_value.param_str_value); /* dec */ } //前面的动作是把fgets拿到的行填充到loc_param_v_type struct里面去,接下来要把这个struct填充到config_table里面去 //针对DEBUG_LEVEL这个conf项,这里填充的结果如下: //param_name: DEBUG_LEVEL //param_str_value: 5 //param_int_value: 5 //param_double_value: 5 (由于没有0x开头,所以double也被填充了) for(uint32_t i = 0; NULL != config_table && i < table_length; i++) { //table_length是2,前面有说到,也就是说把fgets拿到的行在config_table里面逐行的匹配 if(!loc_set_config_entry(&config_table[i], &config_value)) { ret += 1; } } } } } return ret; }
int loc_set_config_entry(loc_param_s_type* config_entry, loc_param_v_type* config_value) { //loc_param_s_type在前面有定义过 int ret=-1; if(NULL == config_entry || NULL == config_value) { LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__); return ret; } //填充好的config_value的param_name(前面有分析的结果是DEBUG_LEVEL)跟config_table的param_name(由于是逐行匹配,第一个就是DEBUG_LEVEL)做匹配 if (strcmp(config_entry->param_name, config_value->param_name) == 0 && config_entry->param_ptr) { //如果匹配成功,且param_ptr的值不是NULL则继续分析 switch (config_entry->param_type) { //config_table的定义和初始化前面有给出,param_type的值都是'n' case 's': if (strcmp(config_value->param_str_value, "NULL") == 0) { *((char*)config_entry->param_ptr) = '\0'; } else { strlcpy((char*) config_entry->param_ptr, config_value->param_str_value, LOC_MAX_PARAM_STRING + 1); } /* Log INI values */ LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, config_entry->param_name, (char*)config_entry->param_ptr); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } ret = 0; break; case 'n': //config_value的param_int_value赋值给config_entry的param_ptr,这里的值是5,这样子DEBUG_LEVEL的值就被改成了conf中的值了(也就是5) *((int *)config_entry->param_ptr) = config_value->param_int_value; /* Log INI values */ LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, config_entry->param_name, config_value->param_int_value); if(NULL != config_entry->param_set) { //param_set置1,说明该config_entry被conf修改过 *(config_entry->param_set) = 1; } ret = 0; break; case 'f': *((double *)config_entry->param_ptr) = config_value->param_double_value; /* Log INI values */ LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, config_entry->param_name, config_value->param_double_value); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } ret = 0; break; default: LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s", __FUNCTION__, config_entry->param_name); } } return ret; }
void loc_logger_init(unsigned long debug, unsigned long timestamp) { //这个函数主要是把传入的参数填充到loc_logger里面 loc_logger.DEBUG_LEVEL = debug; #ifdef TARGET_BUILD_VARIANT_USER // force user builds to 2 or less if (loc_logger.DEBUG_LEVEL > 2) { loc_logger.DEBUG_LEVEL = 2; } #endif loc_logger.TIMESTAMP = timestamp; }
typedef struct loc_logger_s { unsigned long DEBUG_LEVEL; unsigned long TIMESTAMP; } loc_logger_s_type;
#define LOC_LOGE(...) IF_LOC_LOGE { ALOGE("E/" __VA_ARGS__); } else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGE("E/" __VA_ARGS__); }
if ((loc_logger.DEBUG_LEVEL >= 1) && (loc_logger.DEBUG_LEVEL <= 5)){ ALOGE("E/" __VA_ARGS__); } else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGE("E/" __VA_ARGS__); }
#define LOC_LOGV(...) IF_LOC_LOGV { ALOGE("V/" __VA_ARGS__); } else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGV("V/" __VA_ARGS__); }
if ((loc_logger.DEBUG_LEVEL >= 5) && (loc_logger.DEBUG_LEVEL <= 5)){ ALOGE("E/" __VA_ARGS__); } else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGE("E/" __VA_ARGS__); }
标签:gps
原文地址:http://blog.csdn.net/lele_cheny/article/details/44101579