2015年1月26日 星期一

Android藍芽協議棧BlueDroid分析(0)-初始化和enable (轉)

歡迎轉載opendevkit文章, 更好排版和效果, 請關注文章原始地址: http://www.opendevkit.com/?e=111

瞭解初始化,方便從頭捋順整個流程,做到心有框架。

1. java層初始化,引起jni和協議棧部分初始化


(1) AdapterService.java的static塊會在AdapterService整個類初始化的時候調用,static塊裡調用的是classInitNative。


(2) com_android_bluetooth_btservice_AdapterService.cpp的classInitNative接口關鍵部分是:


[1] 拿到java層類接口的回調,以便將來有通知好回調

......
  474     method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
  475                                                            "discoveryStateChangeCallback", "(I)V");
  476
  477     method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
  478                                                             "devicePropertyChangedCallback",
  479                                                             "([B[I[[B)V");
  480     method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
  481     method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
  482                                                  "([B[BI)V");
  483     method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
  484                                                  "([B[BIII)V");
......

[2] 加載stack庫,後去stack接口

  494     const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);                                               
  495
  496     err = hw_get_module(id, (hw_module_t const**)&module);
  497
  498     if (err == 0) {
  499         hw_device_t* abstraction;
  500         err = module->methods->open(module, id, &abstraction);
  501         if (err == 0) {
  502             bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
  503             sBluetoothInterface = btStack->get_bluetooth_interface();

(3) AdapterService這個服務初始化的時候,onCreate被調用,onCreate調用了initNative,initNative也是com_android_bluetooth_btservice_AdapterService.cpp的接口:


[1] 根據(2)裡拿到的interface,初始化interface,傳遞了jni層給interface層的回調,也就是interface層有通知會回調這些接口:
  517     if (sBluetoothInterface) {
  518         int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
  519         if (ret != BT_STATUS_SUCCESS) {
  520             ALOGE("Error while setting the callbacks \n");                                                                             
  521             sBluetoothInterface = NULL;
  522             return JNI_FALSE;
  523         }
[2] 通過bt interface獲取socket interface,這個socket interface是上層使用rfcom通信的關鍵對象。
  524         if ( (sBluetoothSocketInterface = (btsock_interface_t *)
  525                   sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
  526                 ALOGE("Error getting socket interface");
  527         }

(4)  (3).[1]調用了,bt interface的init接口,正是bluetooth.c文件中,bluetoothInterface結構的init成員:


  346 static const bt_interface_t bluetoothInterface = {
  347     sizeof(bt_interface_t),
  348     init,                                                                                                                              
  349     enable,
  350     disable,
  351     cleanup,
這個接口定義在bluetooth.c中,分別:
[1] 保存jni層傳遞下來的回調
bt_hal_cbacks = callbacks;
[2] 調用btif_init_bluetooth();初始化bt interface層;簡單初始化bte, 這個簡單初始化bte實際上有個關鍵的部分:獲取hc接口,下面enable的時候要用到; 獲取本地藍芽地址;創建了一個task,用於bt interface層。
  455     btif_config_init();
   456     bte_main_boot_entry();會調用bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()
   457
   458     /* As part of the init, fetch the local BD ADDR */
   459     memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));
   460     btif_fetch_local_bdaddr(&btif_local_bd_addr);
   461
   462     /* start btif task */
   463     status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
   464                 (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
   465                 sizeof(btif_task_stack));
經過以上步驟,java層帶動jni層初始化了協議棧bt interface接口層,創建了一個任務btif_task。java層有jni層的interface,jni層有java層的回調。jni層有協議棧bt interface,協議棧有jni層的回調。

2. bt使能引起的初始化


(1) bt使能調用過程


bt使能由java層發起,自然要發生在1中的java層和jni層初始化之後。
路線是:BluetoothAdapter.getDefaultAdapter().enable (BluetoothAdapter.java)
-> enable (AdapterService.java)
-> mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); (AdapterService.java) 
-> mAdapterService.processStart(); (AdapterState.java)
-> mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); (AdapterService.java)
-> boolean ret = mAdapterService.enableNative(); (AdapterState.java)
-> enableNative (AdapterService.java)
-> enableNative (android_bluetooth_btservice_AdapterService.cpp)
-> bluetoothInterface->enable (bluetooth.c)
  346 static const bt_interface_t bluetoothInterface = {
  347     sizeof(bt_interface_t),
  348     init,
  349     enable,
bt interface的enable接口,被java經過jni調用下來。

(2)  bluetoothInterface的enable接口


調用btif_enable_bluetooth -> bte_main_enable比較關鍵:
  166     /* Initialize BTE control block */
  167     BTE_Init();
  168
  169     lpm_enabled = FALSE;
  170
  171     if (bt_hc_if)
  172     {
  173         int result = bt_hc_if->init(&hc_callbacks, local_addr); 初始化hc interface,也會同時初始化libbt-vendor.so,也就是hci是libbt-vendor.so相關的。
  174         APPL_TRACE_EVENT1("libbt-hci init returns %d", result);
  175
  176         assert(result == BT_HC_STATUS_SUCCESS);
  177
  178         if (hci_logging_enabled == TRUE)
  179             bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);
  180
  181 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
  182         APPL_TRACE_DEBUG1("%s  Not Turninig Off the BT before Turninig ON", __FUNCTION__);
  183                                                                                                                                        
  184         /* Do not power off the chip before powering on  if BT_CLEAN_TURN_ON_DISABLED flag
  185          is defined and set to TRUE to avoid below mentioned issue.
  186
  187          Wingray kernel driver maintains a combined  counter to keep track of
  188          BT-Wifi state. Invoking  set_power(BT_HC_CHIP_PWR_OFF) when the BT is already
  189          in OFF state causes this counter to be incorrectly decremented and results in undesired
  190          behavior of the chip.
  191
  192          This is only a workaround and when the issue is fixed in the kernel this work around
  193          should be removed. */
  194 #else
  195         /* toggle chip power to ensure we will reset chip in case
  196            a previous stack shutdown wasn't completed gracefully */
  197         bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
  198 #endif
  199         bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);此處比較關鍵,chip已經上電了!
  200
  201         bt_hc_if->preload(NULL);
  202     }
  203
  204     GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
  205                     (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
  206                     sizeof(bte_btu_stack));
此處又創建了一個任務,btu_task,負責處理bte btu的事件等任務。

(3) btu_task任務初始化部分


  170 #if (defined(HCISU_H4_INCLUDED) && HCISU_H4_INCLUDED == TRUE)
  171     /* wait an event that HCISU is ready */
  172     GKI_wait(0xFFFF, 0);
  173 #endif
  174     /* Initialize the mandatory core stack control blocks
  175        (BTU, BTM, L2CAP, and SDP)
  176      */
  177     btu_init_core();   核心協議棧初始化  -> btm_init,l2c_init,sdp_init
  178
  179     /* Initialize any optional stack components */
  180     BTE_InitStack();    擴展協議初始化RFCOMM_Init,SPP_Init
  181
  182 #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
  183     bta_sys_init();     bta sys初始化這裡比較關鍵的是bta_sys_cb.task_id = GKI_get_taskid(),我們會看到bta sys這裡保存的是btu_task這個任務的id,也就是將來bta_sys_sendmsg發送的都是發到btu_task裡的!
  184 #endif
  185
  186     /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init()
  187      * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL
  188      */
  189 #if ( BT_USE_TRACES==TRUE )
  190     BTE_InitTraceLevels();
  191 #endif
  192
  193     /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
  194     GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);給bt interface task發事件BT_EVT_TRIGGER_STACK_INIT,告訴bt interface task協議棧已初始化
  195
  196     raise_priority_a2dp(TASK_HIGH_BTU);

(4) 真正的協議棧使能操作'


bt interface task也就是btif_task處理BT_EVT_TRIGGER_STACK_INIT事件:
btif_task -> BTA_EnableBluetooth接口, 這個接口主要工作是:
    84         p_msg->hdr.event = BTA_DM_API_ENABLE_EVT;
    85         p_msg->p_sec_cback = p_cback;
    86         bta_sys_sendmsg(p_msg);
向btu_task發送BTA_DM_API_ENABLE_EVT事件!
btu_task用下面的代碼:
  517         if (event & TASK_MBOX_2_EVT_MASK)
  518         {
  519             while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
  520             {
  521                 bta_sys_event(p_msg);                                                                                                  
  522             }
  523         }
調用bta_sys_event來處理,bta_sys_event中:
 490 BTA_API void bta_sys_event(BT_HDR *p_msg)
  491 {
  492     UINT8       id;   
  493     BOOLEAN     freebuf = TRUE;  
  494
  495     APPL_TRACE_EVENT1("BTA got event 0x%x", p_msg->event);
  496
  497     /* get subsystem id from event */
  498     id = (UINT8) (p_msg->event >> 8);
  499
  500     /* verify id and call subsystem event handler */
  501     if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))
  502     {
  503         freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);

實際就是,先取得事件對應的子系統id,之後回調對應子系統的回調,而子系統是用類似:

bta_sys_register( BTA_ID_SYS,  &bta_sys_hw_reg);這樣的接口註冊的!

#define BT_EVT_TRIGGER_STACK_INIT   EVENT_MASK(APPL_EVT_0)
#define APPL_EVT_0          8
#define EVENT_MASK(evt)       ((UINT16)(0x0001 << (evt)))
BT_EVT_TRIGGER_STACK_INIT事件對應的子系統就是1,也就是#define BTA_ID_DM           1

搜索BTA_ID_DM是在BTA_EnableBluetooth接口中,bta_sys_register (BTA_ID_DM, &bta_dm_reg );註冊的。也就是:

bta_dm_reg -> bta_dm_sm_execute -> bta_dm_action[0] -> bta_dm_enable:
bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback ); 註冊回調
sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT;發送給btu_task任務事件,經過上邊分析,我們知道這個事件會被註冊的bta_sys_register( BTA_ID_SYS,  &bta_sys_hw_reg);的bta_sys_hw_reg->bta_sys_sm_execute處理,
bta_sys_sm_execute -> bta_sys_action -> bta_sys_hw_api_enable -> bta_sys_hw_co_enable -> bta_sys_hw_ci_enabled( module );這個接口又發送 p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;事件。
bta_sys_sm_execute -> bta_sys_action -> bta_sys_hw_evt_enabled -> BTM_DeviceReset( NULL ); -> btm_dev_reset (); -> btsnd_hcic_reset (LOCAL_BR_EDR_CONTROLLER_ID); -> btu_hcif_send_cmd (local_controller_id,  p); -> HCI_CMD_TO_LOWER(p_buf); -> bte_main_hci_send -> bt_hc_if->transmit_buf(( -> 被bt_hc_worker_thread線程調用p_hci_if->send(sending_msg_que[i]);調用hci_h4_send_msg -> bytes_sent = userial_write(event,(uint8_t *) p,bytes_to_send); 最終寫到了uart上了!

事情實際上還沒有完,chip雖然reset了,但是上邊還是需要處理reset的狀態!


不過初始化部分就算結束了!

沒有留言:

張貼留言