首頁

網站建設

移動端開發

設計

案例

網絡營銷

新聞動態

關于我們

當前位置:首頁 > 新聞動態 > 常州APP開發 >常州開發安卓系統公司分析藍牙協議棧 bluedroid 的使能流程

常州開發安卓系統公司分析藍牙協議棧 bluedroid 的使能流程

責任編輯:常州開發藍牙協議棧 點擊: 發表時間:2021-01-11 11:45:01

安卓原生的藍牙協議棧bluedroid在分層上被分為btif、bta、stack、hci這四層,每層的作用各不相同,但實際程序運行是在不同的線程運行的,為了方便大家對使能流程有更為深刻的了解,所以上述的使能時序圖是以線程為依據。接下來就按照上述時序分別作出說明。

藍牙服務層JNI使能協議棧bluedroid,通過interface函數接口下發指令到達協議棧入口。

stack_manager_get_interface()->start_up_stack_async();將使能指令下發到協議棧管理模塊,模塊內部通過線程stack_manage繼續處理。

依次使能btif_config、btsnoop、hci等模塊

btsnoop模塊:

判斷snoop開關是否打開,從而決定是否創建snoop文件來記錄hci的交互信息。

snoop開關位置在開發者選項中,打開該關開,則persist.bluetooth.btsnoopenable 全局變量會被置為true;反之開關關閉,該變量會被置為false。

snoop文件默認存儲位置:/data/misc/bluetooth/logs/

由于打開snoop開關的步驟比較復雜,一般用戶根本不會進到開發者選項中,甚至連從哪兒打開開發者選項都是一個難題,所以藍牙開發過程中可以修改源碼或重置persist.bluetooth.btsnoopenable的值來達到創建snoop文件記錄hci的交互信息的目的?,F提供如下兩種方法:

1、修改源碼中獲取 persist.bluetooth.btsnoopenable 值時設置的錯誤值

2-1.png

該全局變量是第一次在開發者選項中打開snoop開關時創建的,所以從來沒操作過snoop開關,則該全局變量就沒有定義。如果操作過開發者選項中的snoop開關,則獲取上述全局變量就可以獲取到對應的值,從而錯誤值不再起作用。

2、通過指令:

adb shell setprop persist.bluetooth.btsnoopenabletrue,開啟藍牙hci-snoop的開關。

persist.bluetooth.btsnoopenable 全局變量的存儲路徑因安卓版本而有些許差異:

Android 8的存儲路徑:

/data/property/persist.bluetooth.btsnoopenable/

Android 9的存儲路徑:

/data/property/persistent_properties/

HCI 模塊:

創建hci_thread線程,專門處理hci相關的流程,并同時初始化藍牙芯片。

通過HIDL技術獲取芯片Controller模塊對外提供的接口:

 

btHci = IBluetoothHci::getService();

android::sp<IBluetoothHciCallbacks>callbacks=new BluetoothHciCallbacks();

btHci->initialize(callbacks);

HIDL:全稱是HAL interface definitionlanguage(硬件抽象層接口定義語言),在此之前Android 有AIDL,架構在Android binder 之上,用來定義Android 基于Binder通信的Client與Service之間的接口。HIDL也是類似的作用,只不過定義的是Android Framework與Android HAL實現之間的接口。

 

Android HAL的實現方式由于芯片廠商的不同而有差異,實現內容都是類似于安卓源碼中hardware\interfaces\bluetooth\1.0\中的實現方式。廠商再在HAL的實現中與自家芯片進行交互。這樣通過統一的HAL接口就可以實現軟硬件分離,安卓系統就可以集成不同廠家的藍牙芯片。

 

芯片模塊初始化完成后會通過回調告知android層,這樣藍牙協議棧才會繼續后面的使能流程。

隨著HCI模塊使能完成就進入BTU_StartUp( )函數中開始初始化BTU控制模塊,包括BTU、BTM、L2CAP、SDP等協議棧關鍵模塊

使能controller模塊,實際上就是通過一組HCI命令從芯片層獲取支持的功能參數

typedef struct {

   BT_HDR* (*make_reset)(void);

   BT_HDR* (*make_read_buffer_size)(void);

   BT_HDR* (*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count);

   BT_HDR* (*make_read_local_version_info)(void);

   BT_HDR* (*make_read_bd_addr)(void);

   BT_HDR* (*make_read_local_supported_commands)(void);

   BT_HDR*(*make_read_local_extended_features)(uint8_t page_number);

   BT_HDR* (*make_write_simple_pairing_mode)(uint8_t mode);

   BT_HDR*(*make_write_secure_connections_host_support)(uint8_t mode);

   BT_HDR*(*make_set_event_mask)(constbt_event_mask_t* event_mask);

   BT_HDR*(*make_ble_write_host_support)(uint8_t supported_host, uint8_t  simultaneous_host);

   BT_HDR* (*make_ble_read_white_list_size)(void);

   BT_HDR* (*make_ble_read_buffer_size)(void);

   BT_HDR* (*make_ble_read_supported_states)(void);

   BT_HDR* (*make_ble_read_local_supported_features)(void);

   BT_HDR* (*make_ble_read_resolving_list_size)(void);

   BT_HDR* (*make_ble_read_suggested_default_data_length)(void);

   BT_HDR* (*make_ble_read_maximum_data_length)(void);

   BT_HDR* (*make_ble_read_maximum_advertising_data_length)(void);

BT_HDR*(*make_ble_read_number_of_supported_advertising_sets)(void);

   BT_HDR*(*make_ble_set_event_mask)(const bt_event_mask_t* event_mask);

   BT_HDR* (*make_read_local_supported_codecs)(void);}

 HCI層的交互如下圖:

2-2.png

Reset完成后協議棧會主動下發HCI命令讀取本端的藍牙名字,并將新的名字下發給芯片,同時通過JNI層的回調將本端的藍牙名字和地址上報給服務層。如果存在配對的藍牙設備,也會將該設備信息上報。

緊接著會初始化協議棧的socket模塊,這部分主要是為建立OBEX連接和數據交互做準備的。

協議棧所有使能工作完成,通過HALbt_hal_cbacks->adapter_state_changed_cb回調將藍牙使能成功的消息上報到JNI層。至此藍牙協議棧bluedroid的使能流程的全部過程就分析完畢。

本篇協議棧使能的分析就到這兒了,感興趣的訪問常州開發APP公司點個贊科技http://www.mydreamtorontohome.com致電留言一起討論。


售前咨詢 定制開發在線咨詢 售后咨詢 QQ : 2776216202 電話溝通 免費咨詢 :0519-8996-6566

嘿,掃碼咨詢客服唄~

常州點個贊信息科技有限公司 | 版權所有

Copyright2015-2020 | © 蘇ICP備18008139號-3

免费的三级黄网站