Android BlueDroid(三):BlueDroid藍芽開啟過程enable
關鍵詞: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();//呼叫Native函式; 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();//JNI部分Native函式呼叫C語言中的函式實現; 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();//enable汗的具體實現;
}
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();//BTE部分的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();//BT log 程序建立;
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初始化;
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;
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);
12、 配置成功後回撥函式fwcfg_cb
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
}
preload_cb的實現,把BT_EVT_PRELOAD_CMPL成功訊息通過GKI返回BTU_TASK;
external\bluetooth\bluedroid\main\bte_main.c
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實現流程;