編輯:關於Android編程
關鍵詞:bluedroid enableNative BTIF_TASK BTU_TASK bt_hc_work_thread set_power preload GKI
作者:xubin341719(歡迎轉載,請注明作者,請尊重版權,謝謝!)
繪圖工具:Edraw Maindmap
歡迎指正錯誤,共同學習、共同進步!!
一、enableNative函數的的實現
(1)、初始化BTE;
(2)、創建BTIU_TASK;
(3)、初始化HCI、串口相關,啟動HCI工作主線程:bt_hc_callback,芯片上電、RF參數初始化;
1、應用部分對enableNative函數的調用
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\AdapterState.java
public boolean processMessage(Message msg) { boolean isTurningOn= isTurningOn(); boolean isTurningOff = isTurningOff(); ……………… case STARTED: { if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); //Remove start timeout removeMessages(START_TIMEOUT); //Enable boolean ret = adapterService.enableNative(); if (!ret) { Log.e(TAG, "Error while turning Bluetooth On"); notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); transitionTo(mOffState); } else { sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY); } } break; ……………… } /*package*/ native boolean enableNative();
2、JNI函數的實現
packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
static jboolean enableNative(JNIEnv* env, jobject obj) { ALOGV("%s:",__FUNCTION__); jboolean result = JNI_FALSE; if (!sBluetoothInterface) return result; int ret = sBluetoothInterface->enable(); result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;//判斷是打開還是關閉狀態; return result; }
3、C函數中對enable函數的實現,這部分和init的流程一樣
external\bluetooth\bluedroid\btif\src\bluetooth.c
static int enable( void ) { ALOGI("enable"); /* sanity check */ if (interface_ready() == FALSE) return BT_STATUS_NOT_READY; return btif_enable_bluetooth(); }
4、btif_enable_bluetooth函數的實現,Performschip power on and kickstarts OS scheduler
external\bluetooth\bluedroid\btif\src\btif_core.c|
bt_status_t btif_enable_bluetooth(void) { BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH"); if (btif_core_state != BTIF_CORE_STATE_DISABLED) { ALOGD("not disabled\n"); return BT_STATUS_DONE; } btif_core_state = BTIF_CORE_STATE_ENABLING;//設定為正在打開狀態; /* Create the GKI tasks and run them */ bte_main_enable(); return BT_STATUS_SUCCESS; }
5、bte_main_enable函數,這個函數是enable函數的具體實現
BTEMAIN API - Creates all the BTE tasks. Should be called part of the Bluetooth stack enable sequence
iexternal\bluetooth\bluedroid\main\bte_main.c
void bte_main_enable() { int ret = -1; APPL_TRACE_DEBUG1("%s", __FUNCTION__); /* Initialize BTE control block */ BTE_Init();//(1)、初始化BTE控制塊; lpm_enabled = FALSE; //(2)、創建BTU_TASK 進程 GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR, (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE), sizeof(bte_btu_stack)); bte_hci_enable();//(3)、打開HCI和廠商模塊控制; GKI_run(0); ret = bte_snoop_create_task(); if(ret != 0) APPL_TRACE_DEBUG1("bte_snoop_create_task fail %d",ret); }
(1)、初始化BTE控制塊
BTE_Init(); BTU:Bluetooth Upper Layer, The Broadcom implementations of L2CAP RFCOMM, SDP and the BTIf run as one GKI task. The btu_task switches between them.
(2)、創建BTU_TASK 進程
GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR, (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE), sizeof(bte_btu_stack));
external\bluetooth\bluedroid\stack\btu\btu_task.c
This is the main task of the Bluetooth Upper Layers unit. It sits in aloop waiting for messages, and dispatches them to the appropiate handlers.
btu_task這個函數非常重要,大部分event的處理都通過它來完成;
BTU_API UINT32 btu_task (UINT32 param) { ………… /* Initialize the mandatory core stack control blocks (BTU, BTM, L2CAP, and SDP) */ btu_init_core();//1)、初始化核心control block,比如BTU, BTM, L2CAP, and SDP /* Initialize any optional stack components */ BTE_InitStack();//2)、初始化BTE控制塊,比如RFCOMM, DUN, SPP, HSP2, HFP, OBX, BIP #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE) bta_sys_init();//3)、初始化BTA #endif ………… /* Wait for, and process, events */ for (;;)//進入循環狀態 { event = GKI_wait (0xFFFF, 0);//4)、獲取相應EVENT; if (event & TASK_MBOX_0_EVT_MASK) {…………} if (event & TIMER_0_EVT_MASK) {…………} #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) if (event & TIMER_2_EVT_MASK) { btu_process_quick_timer_evt(); } #endif #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE) if (event & TASK_MBOX_2_EVT_MASK)//這個狀態比較重要 { while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL) { bta_sys_event(p_msg);//接收到的event在這裡解析,然後執行BTU中的函數。 } } if (event & TIMER_1_EVT_MASK) { bta_sys_timer_update(); } #endif if (event & EVENT_MASK(APPL_EVT_7)) break; } return(0); }
(3)、bte_hci_enable,Enable HCI & Vendor modules,打開HCI和廠商模塊
bte_hci_enable的實現流程如下圖所示
external\bluetooth\bluedroid\main\bte_main.c
static void bte_hci_enable(void) { APPL_TRACE_DEBUG1("%s", __FUNCTION__); preload_start_wait_timer(); if (bt_hc_if) { int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);//初始化串口,HCI_H4、HCI工作線等; ……………… bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);//給相應模塊上電; bt_hc_if->preload(NULL);//下載相關配置參數; if (hci_logging_enabled == TRUE || hci_logging_config == TRUE) bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile); } }
6、相對於HCI接口庫接口函數,這部分跟藍牙芯片相關
external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c
static const bt_hc_interface_t bluetoothHCLibInterface = { sizeof(bt_hc_interface_t), init,//HCLib中的init; set_power,// HCLib中的power設定; lpm, preload, HCLib中的preload; postload, transmit_buf, set_rxflow, logging, cleanup };
7、bluetoothHCLibInterface 中INIT實現過程
完成H4初始化、串口驅動初始化、LMP初始化、啟動bt_hc_worker_thread主線程。
(1)、init函數實現
external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c
static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr) { ………… /* store reference to user callbacks */ bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb; init_vnd_if(local_bdaddr);//完成廠商模塊的接口函數; userial_init();//串口初始化 lpm_init();//LPM初始化 ………… extern tHCI_IF hci_h4_func_table;// 應用HCI H4接口回調 p_hci_if = &hci_h4_func_table; p_hci_if->init();//調用hci_h4_func_table的init辦法,初始化H4模塊 utils_queue_init(&tx_q); //初始化發送隊列 ………… if (pthread_create(&hc_cb.worker_thread, &thread_attr, \ bt_hc_worker_thread, NULL) != 0) //起工作線程 { ALOGE("pthread_create failed!"); lib_running = 0; return BT_HC_STATUS_FAIL; } ………… }
1)、bt_hc_callbacks_t*bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb; //保存回調;
2)、init_vnd_if(local_bdaddr);//調用廠商庫裡面的bt_vendor_interface_t*接口,初始化藍牙設備;
3)、p_hci_if =&hci_h4_func_table; //應用HCI H4接口回調;
4)、p_hci_if->init(); //調用hci_h4_func_table的init辦法,初始化H4模塊;
5)、userial_init();//初始化uart數據布局;
6)、lpm_init();//初始化低功耗模塊,調用bt_vendor_interface_t的op接口;
7)、utils_queue_init(&tx_q); //初始化發送隊列;
8)、pthread_create(&hc_cb.worker_thread,&thread_attr, bt_hc_worker_thread, NULL) != 0) //起工作線程;
(2)、init_vnd_if 的實現過程
idh.code\external\bluetooth\bluedroid\hci\src\bt_hw.c
void init_vnd_if(unsigned char *local_bdaddr) { void *dlhandle; dlhandle = dlopen("libbt-vendor.so", RTLD_NOW);// 1)、dlopen()函數以指定模式打開指定的動態鏈接庫文件,並返回一個句柄給dlsym()的調用進程。 ……………… bt_vnd_if = (bt_vendor_interface_t *) dlsym(dlhandle, "BLUETOOTH_VENDOR_LIB_INTERFACE");//2)、返回符號BLUETOOTH_VENDOR_LIB_INTERFACE,所對應的地址。 ………… bt_vnd_if->init(&vnd_callbacks, local_bdaddr);//3)、調用返回地址結構體中的init函數; }
1)、dlopen()
函數以指定模式打開指定的動態鏈接庫文件,並返回一個句柄給dlsym()的調用進程。
dlhandle = dlopen("libbt-vendor.so", RTLD_NOW); void * dlopen( const char * pathname, int mode); mode是打開方式,其值有多個,不同操作系統上實現的功能有所不同,在linux下,按功能可分為三類:
解析方式
RTLD_LAZY:
在dlopen返回前,對於動態庫中的未定義的符號不執行解析(只對函數引用有效,對於變量引用總是立即解析)。
RTLD_NOW:
需要在dlopen返回前,解析出所有未定義符號,如果解析不出來,在dlopen會返回NULL,錯誤為:: undefined symbol: xxxx.......
作用范圍,可與解析方式通過“|”組合使用。
RTLD_GLOBAL:
動態庫中定義的符號可被其後打開的其它庫重定位。
RTLD_LOCAL:
與RTLD_GLOBAL作用相反,動態庫中定義的符號不能被其後打開的其它庫重定位。如果沒有指明是RTLD_GLOBAL還是RTLD_LOCAL,則缺省為RTLD_LOCAL。
作用方式
RTLD_NODELETE:
在dlclose()期間不卸載庫,並且在以後使用dlopen()重新加載庫時不初始化庫中的靜態變量。這個flag不是POSIX-2001標准。
RTLD_NOLOAD:
不加載庫。可用於測試庫是否已加載(dlopen()返回NULL說明未加載,否則說明已加載),也可用於改變已加載庫的flag,如:先前加載庫的flag為RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)後flag將變成RTLD_GLOBAL。這個flag不是POSIX-2001標准。
RTLD_DEEPBIND:
在搜索全局符號前先搜索庫內的符號,避免同名符號的沖突。這個flag不是POSIX-2001標准。
2)、dlsym根據動態鏈接庫操作句柄與符號,返回符號對應的地址
返回符號BLUETOOTH_VENDOR_LIB_INTERFACE,所對應的地址,也就是:
const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { sizeof(bt_vendor_interface_t), init, op, cleanup };
3)、調用返回地址結構體中的init函數
bt_vnd_if->init(&vnd_callbacks,local_bdaddr);
有兩個參數:廠商提供的回調函數vnd_callbacks;藍牙地址:local_badaddr。
函數init的實現:
vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c
const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { sizeof(bt_vendor_interface_t), init, op, cleanup };
BLUETOOTH_VENDOR_LIB_INTERFACE中INIT函數實現
vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c
static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr) { ………… /* store reference to user callbacks */ bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;//把vnd_callbacks回調函數,保存到用戶回調bt_vendor_cback; ………… }
vnd_callbacks,這些函數在
//The libbt-vendor Callback Functions Table
static const bt_vendor_callbacks_t vnd_callbacks = { sizeof(bt_vendor_callbacks_t), fwcfg_cb, scocfg_cb, lpm_vnd_cb, alloc, dealloc, xmit_cb, epilog_cb };
(3)、hci_h4_func_table中init函數的初始化
extern tHCI_IF hci_h4_func_table; p_hci_if = &hci_h4_func_table; p_hci_if->init();1)、hci_h4_func_table結構體成員函數
const tHCI_IF hci_h4_func_table = { hci_h4_init, hci_h4_cleanup, hci_h4_send_msg,//發送msg; hci_h4_send_int_cmd,//發送int命令; hci_h4_get_acl_data_length, hci_h4_receive_msg//接收信息; };
2)、 p_hci_if->init();調用hci_h4_func_table的init辦法,初始化H4模塊,對應實現函數對應:hci_h4_init
void hci_h4_init(void) { HCIDBG("hci_h4_init"); memset(&h4_cb, 0, sizeof(tHCI_H4_CB)); utils_queue_init(&(h4_cb.acl_rx_q)); /* Per HCI spec., always starts with 1 */ num_hci_cmd_pkts = 1; /* Give an initial values of Host Controller's ACL data packet length * Will update with an internal HCI(_LE)_Read_Buffer_Size request */ h4_cb.hc_acl_data_size = 1021;//hci ACL 數據的最大長度; h4_cb.hc_ble_acl_data_size = 27;//BLE ACL最大數據長度; btsnoop_init(); }
(4)、初始化串口、LPM
userial_init();
lpm_init();
(5)、創建工作線程
if(pthread_create(&hc_cb.worker_thread, &thread_attr, \
bt_hc_worker_thread, NULL) != 0)
idh.code\external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c
bt_hc_worker_thread工作線程,監聽各種狀態,處理相對應。
static void *bt_hc_worker_thread(void *arg) { ………… if (events & HC_EVENT_PRELOAD) { userial_open(USERIAL_PORT_1); ………… bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL); ………… } if (events & HC_EVENT_POSTLOAD) ………… if (events & HC_EVENT_TX) ………… if (events & HC_EVENT_LPM_ENABLE) ……………… }
8、bluetoothHCLibInterface中set_power流程
這部分主要完成上電操作,SPRD的藍牙芯片集成到AP端,由芯片內部控制。如果用其他藍牙WIFI芯片,這部分應該對應相關power PIN腳操作。
idh.code\external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c
/** Chip power control */ static void set_power(bt_hc_chip_power_state_t state) { int pwr_state; ………… pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF; if (bt_vnd_if) bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);//設置controller POWER ON/OFF ………… }
bt_vnd_if這個結構體在idh.code\external\bluetooth\bluedroid\hci\include\bt_vendor_lib.h中定義,相對應的op函數在bt_vendor_sprd.c中實現。
(1)、bt_vnd_if結構體:
typedef struct { size_t size; int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr); int (*op)(bt_vendor_opcode_t opcode, void *param); void (*cleanup)(void); } bt_vendor_interface_t;
(2)、bt_vnd_if->op的函數實現
vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c
相對應不同op操作
BT_VND_OP_POWER_CTRL
Power on or off the BT Controller
BT_VND_OP_FW_CFG
Perform any vendor specific initialization or configuration on the BT Controller. This is called before stack initialization
BT_VND_OP_SCO_CFG
Perform any vendor specific SCO/PCM configuration on the BT Controller.This is called after stack initialization.
BT_VND_OP_USERIAL_OPEN
Open UART port on where the BT Controller is attached. This is called before stack initialization.
BT_VND_OP_USERIAL_CLOSE
Close the previously opened UART port.
BT_VND_OP_GET_LPM_IDLE_TIMEOUT
Get the LPM idle timeout in milliseconds.The stack uses this information to launch a timer delay before it attempts to de-assert LPM WAKE signal once downstream HCI packet has been delivered.
BT_VND_OP_LPM_SET_MODE
Enable or disable LPM mode on BT Controller.
BT_VND_OP_LPM_WAKE_SET_STATE
Assert or Deassert LPM WAKE on BT Controller.
BT_VND_OP_EPILOG
The epilog call to the vendor module so that it can perform any vendor-specific processes (e.g. send a HCI_RESET to BT Controller)before the caller calls for cleanup().
static int op(bt_vendor_opcode_t opcode, void *param) { ………… switch(opcode) { case BT_VND_OP_POWER_CTRL://如果是power控制 { ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL"); #if 0//這部分代碼展訊平台沒有控制; nState = *(int *) param; retval = hw_config(nState); if(nState == BT_VND_PWR_ON && retval == 0 && is_hw_ready() == TRUE) { retval = 0; } #endif } break; ………… }
9、bluetoothHCLibInterface中Preload流程
這部分主要完成藍牙MAC地址、RF射頻相關設定,流程如下所示。
(1)、發送HC_EVENT_POSTLOAD 信令,線程bt_hc_worker_thread接收並處理
external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c
/** Called post stack initialization */ static void postload(TRANSAC transac) { BTHCDBG("postload"); bthc_signal_event(HC_EVENT_POSTLOAD);//發送信號量給線程bt_hc_worker_thread }
10、bt_hc_worker_thread處理HC_EVENT_PRELOAD
static void *bt_hc_worker_thread(void *arg) { uint16_t events; HC_BT_HDR *p_msg, *p_next_msg; ………… if (events & HC_EVENT_PRELOAD) { userial_open(USERIAL_PORT_1);//打開串口; /* Calling vendor-specific part */ if (bt_vnd_if) { bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);//(1)、mac、ini、pskey初始化 } else { if (bt_hc_cbacks) bt_hc_cbacks->preload_cb(NULL, BT_HC_PRELOAD_FAIL);(2)、失敗preload 回調函數 ………… }
11、bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);調用
vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c中的OP函數:
static int op(bt_vendor_opcode_t opcode, void *param) { ………… case BT_VND_OP_FW_CFG: { ALOGI("bt-vendor : BT_VND_OP_FW_CFG"); retval = sprd_config_init(s_bt_fd,NULL,NULL);//初始化展訊平台 ALOGI("bt-vendor : sprd_config_init retval = %d.",retval); if(bt_vendor_cbacks) { if(retval == 0) { ALOGI("Bluetooth Firmware and smd is initialized"); bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);//初始化成功後回調函數 } else { ALOGE("Error : hci, smd initialization Error"); bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); } } } break; }
(1)、sprd_config_init的實現
這部分針對芯片部分,展訊的藍牙芯片處理流程,在這裡完成:藍牙MAC地址、RF ini文件相關;
vendor\sprd\open-source\libs\libbt\src\ bt_vendor_sprd.c中sprd_config_init
//******************create bt addr end*********************** int sprd_config_init(int fd, char *bdaddr, struct termios *ti) { ……………… if(access(BT_MAC_FILE, F_OK) == 0)// MAC地址創建如果btmac不存在,隨機生成; { ALOGI("%s: %s exists",__FUNCTION__, BT_MAC_FILE); read_btmac=read_mac_from_file(BT_MAC_FILE,bt_mac); } if(read_btmac == 1) { for(i=0; i<6; i++) { bt_mac_tmp[i*2] = bt_mac[3*(5-i)]; bt_mac_tmp[i*2+1] = bt_mac[3*(5-i)+1]; } ALOGI("====bt_mac_tmp=%s", bt_mac_tmp); ConvertHexToBin((uint8*)bt_mac_tmp, strlen(bt_mac_tmp), bt_mac_bin); } /* Reset the BT Chip */ memset(resp, 0, sizeof(resp)); ret = bt_getPskeyFromFile(&bt_para_tmp);//1)、GETPSKEY FOROMFILE,這裡完成INI文件的初始化 ………… { ALOGI("get_pskey_from_file ok \n"); /* Send command from pskey_bt.txt*/ if(read_btmac == 1) { memcpy(bt_para_tmp.device_addr, bt_mac_bin, sizeof(bt_para_tmp.device_addr)); } if (write(s_bt_fd, (char *)&bt_para_tmp, sizeof(BT_PSKEY_CONFIG_T)) != sizeof(BT_PSKEY_CONFIG_T)) { ALOGI("Failed to write pskey command from pskey file\n"); return -1; } } ALOGI("sprd_config_init write pskey command ok \n"); while (1) { r = read(s_bt_fd, resp, 1); if (r <= 0) return -1; if (resp[0] == 0x05) { ALOGI("read pskey response ok \n"); break; } } ALOGI("sprd_config_init ok \n"); return 0; }1)、GETPSKEY FOROMFILE,這裡完成INI文件的初始化:這部分內容和芯片相關, 不同廠商的芯片有不同的處理方法;
++++++sprd start 其他平台可以不看+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vendor\sprd\open-source\libs\libbt\src\bt_vendor_sprd.c
int bt_getPskeyFromFile(void *pData) { ………… #ifdef HW_ADC_ADAPT_SUPPORT//不同INI文件 char *CFG_2351_PATH[] = { "/system/etc/connectivity_configure_hw100.ini", "/system/etc/connectivity_configure_hw102.ini", "/system/etc/connectivity_configure_hw104.ini" }; #else char *CFG_2351_PATH[] = { "/system/etc/connectivity_configure.ini" }; #endif #ifdef HW_ADC_ADAPT_SUPPORT //如果是不同的硬件,獲取板子信息,給board_type賦值,後面選擇用那個ini文件。這個是展訊平台相關,不同平台有不同的做法; char *BOARD_TYPE_PATH = "/dev/board_type"; int fd_board_type; char board_type_str[MAX_BOARD_TYPE_LEN] = {0}; fd_board_type = open(BOARD_TYPE_PATH, O_RDONLY);//(1)、獲取硬件版本信息 if (fd_board_type<0) { ALOGI("#### %s file open %s err ####\n", __FUNCTION__, BOARD_TYPE_PATH); board_type = 2; // default is 1.0.4 } else { len = read(fd_board_type, board_type_str, MAX_BOARD_TYPE_LEN); if (strstr(board_type_str, "1.0.0")) { board_type = 0; } ………… #endif ALOGI("begin to bt_getPskeyFromFile"); fd = open(CFG_2351_PATH[board_type], O_RDONLY, 0644); if(-1 != fd) { len = bt_getFileSize(CFG_2351_PATH[board_type]);//(2)、獲得相應的版本的PSKEY; pBuf = (unsigned char *)malloc(len); ret = read(fd, pBuf, len); ………… ret = bt_getDataFromBuf(pData, pBuf, len); if(-1 == ret) { free(pBuf); return -1; } ALOGI("begin to dumpPskey"); bt_dumpPskey((BT_PSKEY_CONFIG_T *)pData);//(3)、解析相應數據 free(pBuf); return 0; }
獲取硬件版本信息
fd_board_type = open(BOARD_TYPE_PATH,O_RDONLY);
Board_type如下圖:
獲得相應的版本的PSKEY;<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD48cHJlIGNsYXNzPQ=="brush:java;">char *CFG_2351_PATH[] = {
"/system/etc/connectivity_configure_hw100.ini",
"/system/etc/connectivity_configure_hw102.ini",
"/system/etc/connectivity_configure_hw104.ini"
};
解析相應數據
bt_dumpPskey((BT_PSKEY_CONFIG_T*)pData);
bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);//初始化成功後回調函數,這部分在case BT_VND_OP_FW_CFG中完成
external\bluetooth\bluedroid\hci\src\bt_hw.c
static void fwcfg_cb(bt_vendor_op_result_tresult) { bt_hc_postload_result_tstatus = (result == BT_VND_OP_RESULT_SUCCESS) ? \ BT_HC_PRELOAD_SUCCESS : BT_HC_PRELOAD_FAIL;//判定prelaod是否成功; fwcfg_acked = TRUE; if (bt_hc_cbacks) bt_hc_cbacks->preload_cb(NULL, status);//對應preload_cb }
static void preload_cb(TRANSACtransac, bt_hc_preload_result_t result) { APPL_TRACE_EVENT1("HC preload_cb %d[0:SUCCESS 1:FAIL]", result); if (result == BT_HC_PRELOAD_SUCCESS) { preload_stop_wait_timer(); /* notify BTU task that libbt-hci isready */ GKI_send_event(BTU_TASK, BT_EVT_PRELOAD_CMPL);//發送BT_EVT_PRELOAD_CMPL到BTU_TASK } }
preload完成後,回調函數返回到BTU_TASK,啟動BT其他協議層的初始化。
下節我們分析:
1、GKI_send_msg進程間通信如何完成;
2、bta_sys_sendmsg event如何解析;
3、GKI_Wait實現流程;
近段時間來Android上最火的框架非react native莫屬了,這裡我不去評價這個框架的好壞,畢竟只有用過的人才會有深刻的體會。但是我個人有一個習慣,在使用一個開源
我們來講個老生常談的話題,估計大家都用過的—>ViewPager,用它來做新手導航頁面,雖然這次也是講這個,但是和以往的用法可能有些不同,大家都看到標題進來的,應該
先看看電影票在線選座功能實現的效果圖: 界面比較粗糙,主要看原理。這個界面主要包括以下幾部分 1、座位 2、左邊的排數 3、左上方的縮略圖 4、縮略圖中的紅色區域 5、手
書接上篇 《Android網絡請求庫 - Say hello to OkHttp》,今天接著來簡單的看一下常用的網絡請求庫中的第二種庫:Volley。 Volley是谷歌