多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > (gps)gps.conf中DEBUG_LEVEL的解析

(gps)gps.conf中DEBUG_LEVEL的解析

來源:程序員人生   發布時間:2015-03-28 08:31:03 閱讀次數:6930次

gps.conf是gps的配置文件,這里面經常使用到的DEBUG_LEVEL配置項是gps HAL層logcat的開關,弄清楚這個配置項的解析流程一樣對全部gps.conf的解析有很大的幫助,這里來走1下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(); }

在前面open_gps里面有提到過,gps__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; }

所以需要查到get_gps_interface在哪里調用的,以下:

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); } } ... }

所以接下來看下get_gps_interface()定義,以下:

hardware/qcom/gps/loc_api/libloc_api_50001/loc.cpp

extern "C" const GpsInterface* get_gps_interface() { unsigned int target = TARGET_DEFAULT; loc_eng_read_config(); ... }

hardware/qcom/gps/loc_api/libloc_api_50001/loc_eng.cpp

int loc_eng_read_config(void) { ENTRY_LOG_CALLFLOW(); if(configAlreadyRead == false) { //gps config信息只用read1次 // Initialize our defaults before reading of configuration file overwrites them. //初始化1些參數 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 "); } EXIT_LOG(%d, 0); return 0; }

看下UTIL_READ_CONF的定義:
hardware/qcom/gps/utils/loc_cfg.h

#define UTIL_READ_CONF(filename, config_table) loc_read_conf((filename), (config_table), sizeof(config_table) / sizeof(config_table[0]))

這里面傳入兩個參數,1個是const char* conf_file_name,這里的值是”/etc/gps.conf”,另外一個是1個gps_conf_table,有必要看下這個table的類型:

hardware/qcom/gps/loc_api/libloc_api_50001/loc_eng.cpp

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'}, };

數組的每一個單項的類型是loc_param_s_type,這個單項的定義以下:

hardware/qcom/gps/utils/loc_cfg.h

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;

table項的第2個參數用到了gps_conf變量,而gps_conf是loc_gps_cfg_s_type類型的,定義以下:

hardware/qcom/gps/loc_api/libloc_api_50001/loc_eng.h

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;

hardware/qcom/gps/utils/loc_cfg.cpp

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的第1步 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); //走過1邊以后,conf_fp的文件指針已知道文件尾部了,rewind1下conf_fp又到了文件頭部 rewind(conf_fp); } //這里是是讀DEBUG_LEVEL的地方,重點跟進1下 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); } 先看下loc_param_table的定義和初始化: /* 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); 在來看下loc_read_conf_r的具體實現: 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 ", __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 ", __func__, __LINE__, num_params); while(num_params) { //弄了半天,fp是有了但是1直沒有讀conf,這個fgets馬上跟進 if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) { //逐行來解析,如果讀到文件尾就結束 LOC_LOGD("%s:%d]: fgets returned NULL ", __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; }

在loc_fill_conf_item之前,有1個類型需要關注1下:

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;

這個是用來存儲從conf里面讀出來的內容的,param_name用來存儲conf的key的,param_str_value是用來存儲value的字符串形態,param_int_value是用來存儲value的int形態,param_double_value是用來存儲value的double形態

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; //定義和初始化1個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) { //第2次用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做1下處理,清除里面的無用空格 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類型都存儲1次 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; }

看下是config_table里面的DEBUG_LEVEL是怎樣被賦值的:

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(由因而逐行匹配,第1個就是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) = ' 主站蜘蛛池模板: 手机看片亚洲 | 另类五月 | 综合网伊人 | 欧美日韩国产一区二区三区欧 | 国产一二三区在线 | 欧美日韩性生活视频 | 秋霞一级特黄真人毛片 | 18到20女人一级毛片 | 国产aaa女人十八毛片 | 91精品国产91久久久久久最新 | 成人精品一区二区www | 伊人久久大香 | 在线亚洲日产一区二区 | wwwjizz欧美| 久久国产亚洲欧美日韩精品 | 波多野结衣资源在线 | 亚洲国产精品成 | 亚洲欧美一区二区三区图片 | 久久成人免费 | 国产精品国产精品国产专区不卡 | 男女激情视频软件 | 欧美70一80老妇性大片 | 男女羞羞视频免费 | 夜夜精品视频一区二区 | 亚洲最色网站 | 欧美一区二区三区男人的天堂 | 亚洲精品专区一区二区欧美 | 最新日本中文字幕 | 国产亚洲精品久久精品6 | 综合欧美一区二区三区 | 欧美jizzhd欧美精品巨大 | 欧美三级大片在线观看 | 视频1区 | 国产一级做a爰片久久毛片 国产一级做a爰片久久毛片99 | 久久精品国产400部免费看 | 亚洲欧美日韩网站 | 四虎在线永久精品高清 | 日本叼嘿视频 | 欧美一级爱爱 | 久草视频播放 | 国产精品99久久久久久人 |