日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

蓝牙地址的name为null_蓝牙, enable协议栈流程

發布時間:2025/4/5 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝牙地址的name为null_蓝牙, enable协议栈流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章開始之前,先看兩張圖

原諒我這個不擅長美工沒有藝術細菌的程序媛,圖畫的很簡陋,但也算是勾勒出了大致的流程如果你對這兩張圖感興趣,那么歡迎繼續閱讀本文,也期待多多提出意見如果無感,甚至感覺目前根本沒有耐心看下去,那我建議你此時可以放棄閱讀本文的想法。每個人的時間都是很寶貴的,沒有必要逼著自己,完成這項違背意愿的任務你看或不看,文章就在這里...只有在心情愉悅時,才能創造出令人愉悅的代碼接下來的任務,就是和我一起對這兩張圖進行分析上文分析了enable的上層的處理藍牙,信息獲取和enable狀態切換,本文分析協議棧的處理分析過程中關于前面兩個文章中分析過的代碼,就不再進行分析通過兩篇文章的分析
  • 藍牙,從系統開機說起

  • 藍牙,信息獲取和enable狀態切換

可以確定BluetoothManagerService是藍牙系統級別的服務,運行在system進程。并且在開機之后長存,與藍牙的開關狀態無關藍牙開啟的第一個服務是AdapterService,也就是藍牙的入口。AdapterService是和藍牙的開關狀態保持一致的在開啟藍牙時最先要bind起來的就是該服務。所以直接來看該服務的處理藍牙應用中有一個Application:AdapterApp.代碼很少,一起順帶分析了
在AdapterService創建時靜態加載jni的庫1//AdapterApp.java
2?System.loadLibrary("bluetooth_jni");
靜態初始化native1//AdapterService.java
2?classInitNative();
接下來在服務的生命周期方法onCreate,創建時又再次初始化native,但是調用的方法不一樣1//AdapterService.java
2initNative();
打住,到此為止先分析一下,已經做了三件事兒
  • 加載jni庫libbluetooth_jni

  • 初始化操作classInitNative

  • 初始化操作initNative

  • 庫加載過程屬于common的方法就不再分析,重點關注初始化
    方法實現都在jni層

    首先是classInitNative方法

    1//com_android_bluetooth_btservice_AdapterService.cpp
    2static?void?classInitNative(JNIEnv*?env,?jclass?clazz)?{
    3...
    4jclass?jniCallbackClass?=
    5??env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
    6...
    7method_stateChangeCallback?=
    8??env->GetMethodID(jniCallbackClass,?"stateChangeCallback",?"(I)V");
    9...
    10if?(hal_util_load_bt_library((bt_interface_t?const**)&sBluetoothInterface))?{
    11??ALOGE("No?Bluetooth?Library?found");
    12}
    13...
    14}
    這個方法關注兩件事兒首先是把java層的方法映射過來,供jni層調用。映射過來的方法都是JniCallbacks.java中的方法,用來在hal層有消息回調時觸發給上層另一個操作就是去加載協議棧的so包,并獲取到變量名為bluetoothInterface的地址以后jni層再往下的調用就要依靠這個bluetoothInterface了加載的是哪個so包?拿到的so包的誰的地址?繼續分析1int?hal_util_load_bt_library(const?bt_interface_t**?interface)?{
    2??const?char*?sym?=?BLUETOOTH_INTERFACE_STRING;//"bluetoothInterface"
    3??...
    4??property_get(PROPERTY_BT_LIBRARY_NAME,?path,?DEFAULT_BT_LIBRARY_NAME);
    5??...
    6?(bt_interface_t*)dlsym(handle,?sym);
    7??...
    8}
    加載的是屬性值“ro.bluetooth.library_name”(可以使用adb命令查看屬性值)字段所聲明的一個地址下的so包拿到是blutoothInterface的地址完事兒了,拿到之后把地址交給sBluetoothInterface,之后jni就可以通過該字段來訪問藍牙所提供的接口了也即是說,classInitNative的作用有兩個
  • 映射java層方法

  • 獲取協議棧的藍牙接口對象地址

  • 相當于在jni層獲取兩個對象,一個java層對象,一個是協議棧的so包中的對象獲取對象之后,你就可以調用對象的方法了獲取到的藍牙接口對jni提供的方法有哪些?
    都在bluetooth.cc文件中列出來了

    bluetoothInterface接口方法如上,就不一一分析了

    另一個initNative

    在獲取到對象之后,需要對這個對象進行初始化,配置一些基本信息。
    先看一下代碼 1//com_android_bluetooth_btservice_AdapterService.cpp
    2static?bool?initNative(JNIEnv*?env,?jobject?obj)?{
    3??...
    4??sBluetoothInterface->init(&sBluetoothCallbacks);
    5??...
    6??sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
    7??...
    8??sBluetoothSocketInterface?=
    9???(btsock_interface_t*)sBluetoothInterface->get_profile_interface(
    10???????BT_PROFILE_SOCKETS_ID);
    11???...
    12}
    主要就是這三件事兒了
  • init調用藍牙接口的初始化

  • set_os_callouts這個主要是對wakelock喚醒鎖的管理,目前以功能分析為主,暫時不分析代碼設計

  • 獲取到socket的profile對象,有何用?繼續分析

  • 拆開分析,去bluetooth.cc文件中查看方法的實現第一個,init干了什么? 1//system/bt/btif/src/bluetooth.cc
    2static?int?init(bt_callbacks_t*?callbacks)?{
    3??...
    4??bt_hal_cbacks?=?callbacks;
    5??...
    6??stack_manager_get_interface()->init_stack();
    7??...
    8??btif_debug_init();
    9??...
    10}
    越往下分析你會發現代碼越簡單,java層要考慮各種功能和交互而hal層代碼只需要認真的把功能實現就好了,順便再把狀態回調給上層就ok了所以init中也很簡單,首先是把jni層的callback對象拿過來,方便后續進行回調之后,看函數名字應該就是初始化stack了,也就是藍牙核心模塊要初始化了最后是初始化log相關的了(初始化btsnoop)。重點關注stack的初始化,分析一下對stack的處理 1//system/bt/btif/src/stack_manager.cc
    2static?void?event_init_stack(void*?context)?{
    3...
    4???module_management_start();
    5???module_init(get_module(OSI_MODULE));
    6???module_init(get_module(BT_UTILS_MODULE));
    7???module_init(get_module(BTIF_CONFIG_MODULE));
    8???btif_init_bluetooth();
    9...
    10}
    協議棧的初始化好像東西有點兒多啊,還有三個排比句get_module方法其實就是dlsym(RTLD_DEFAULT, name),會在當前進程中按照默認lib包的搜索順序來搜索name這個symbol?module_init方法就是對所傳入的module調用init方法
    • 開啟核心模塊的管理,這個方法目前是空實現

    • OSI_MODULE,初始化osi模塊:搜索到的symbol是osi_module.cc文件中的osi_module,也就是要調用osi_module的init方法。暫時不清楚用處,后續研究

    • BT_UTILS_MODULE,初始化bt_utils模塊:搜索到的symbol是bt_utils.cc文件中的bt_utils_module,這個init方法大致看了下,確認過眼神,是我不懂的操作。一些賦值操作,看名字和任務棧有關,后續如果分析到再看吧

    • BTIF_CONFIG_MODULE,初始話藍牙配置模塊:搜索到的symbol是btif_config.cc文件中的btif_config_module,init的目的就是去管理前文說到的bt_config相關的文件,比如恢復出廠后需要刪除文件重新創建啊,以及文件里邊兒現在要寫什么啊等等。總之就是管理藍牙配置文件的一個模塊

    • 初始化藍牙,從這兒開始就會把整個藍牙協議棧創建起來,為藍牙的開啟做準備工作

    各個模塊的初始化如上分析,不再深究了接下來看一下bt_init_bluetooth,也就是對藍牙的初始化1//system/bt/btif/src/btif_core.cc
    2bt_status_t?btif_init_bluetooth()?{
    3???//Creates?BTIF?task?and?prepares?BT?scheduler?for?startup
    4???...
    5???bte_main_boot_entry();
    6???...
    7}
    btif_init_bluetooth方法會創建藍牙接口任務棧,并且為藍牙的開啟做準備。主要是調用bte_main_boot_entry方法 1//system/bt/main/bte_main.cc
    2void?bte_main_boot_entry(void)?{
    3??//Entry?point?for?BTE?chip/stack?initialization
    4??...
    5??module_init(get_module(INTEROP_MODULE));
    6??...
    7??hci?=?hci_layer_get_interface();
    8??...
    9??module_init(get_module(STACK_CONFIG_MODULE));
    10??...
    11}
    bte_main_boot_entry方法用于初始化藍牙芯片和協議棧
    初始化的話主要是三個方面
  • INTEROP_MODULE初始化interop_module模塊,init為空實現,不需要考慮

  • hci,獲取到hci層接口,方法實現位于/system/bt/hci/src/hci_layer.cc文件中

  • STACK_CONFIG_MODULE初始化,會操作/etc/bluetooth/bt_stack.conf文件,文件中是對協議棧的一些配置,比如log是否開啟啊之類

  • 這個btif的init完成了到目前位置,上層的initNative的任務已經完成。也就是藍牙接口中的一些基本模塊已經初始化完成,基本上都是一些工具模塊和配置模塊,也包括把controller和host之間的接口hci給鋪好。要依賴的工具和配置都準備好了,小角色都已經暖好場了,大明星們該壓軸登場了,接下來enable的過程就是協議棧的核心角色的初始化了看到這里就有一個疑問了,為什么initNative是在onCreate方法中執行,而classInitNative是在靜態代碼段中和庫加載一起執行?為什么兩個不能都放在靜態代碼塊中執行?個人觀點是jni層加載so包需要一定的時間,需要放在靜態代碼塊中。而initNative是調用具體的接口方法,而且還需要使用java層的callback對象,所以放在AdapterService的onCreate中執行init完成之后,就可以看enable的過程了

    協議棧enable

    還記得上一篇文章藍牙,信息獲取和enable狀態切換嗎?enable的方法調用是在狀態切換過程中發生的,具體可以參考文章描寫enable的第三大部分,enable過程中的狀態切換此文不再贅述,上層調用jni層的enableNative方法開啟jni層也是直接調用bluetoothInterface的enable方法,而btif只是一個接口而已,方法實現還要去看協議棧 1//system/bt/btif/src/stack_manager.cc
    2//該方法為同步方法
    3static?void?event_start_up_stack(UNUSED_ATTR?void*?context)?{
    4?...
    5??module_start_up(get_module(BTIF_CONFIG_MODULE));
    6?...
    7??bte_main_enable();
    8?...
    9??btif_thread_post(event_signal_stack_up,?NULL);
    10}
    從這兒開始,可以很明顯的知道,協議棧的enable過程就三件事兒
  • 執行bt_config_module的start_up方法,但目前源碼中該方法是空實現,所以不予考慮

  • enable藍牙系統

  • 通知jni層,藍牙狀態發生了變化,新狀態為BT_STATE_ON

  • 主要是enable藍牙系統啊朋友們,感覺代碼分析馬上要進入核心了,有些小激動啊不看代碼還在等啥捏1//system/bt/main/bte_main.cc
    2void?bte_main_enable()?{
    3??module_start_up(get_module(BTSNOOP_MODULE));
    4??module_start_up(get_module(HCI_MODULE));
    5??BTU_StartUp();
    6}
    這個就是該方法的全部代碼,用于創建所有bte的任務
    三件事兒
  • BTSNOOP_MODULE,調用btsnoop_module的start_up方法,會打開一個文件用于存儲controller和host交互的log.平常所查詢的hci日志說的就是這個了,默認存放路徑為/data/misc/bluetooth/logs/btsnoop_hci.log

  • HCI_MODULE,調用hci的start_up方法,hci準備好,監控host和controller之間的交互。同時,會在這兒開啟controller

  • btu開啟,bluetooth upper layer開啟,藍牙上層協議棧開啟

  • BTU_StartUp又是一個有很多事兒要做的方法,該方法用于初始化btu控制塊兒。該方法中有一些對線程的控制代碼,但是根本功能是會調用btu_task_start_up方法,繼續對bt進行操作,來看看具體實現 1//system/bt/stack/btu/btu_task.cc
    2void?btu_task_start_up(UNUSED_ATTR?void*?context)?{
    3?/*?Initialize?the?mandatory?core?stack?control?blocks 4?????(BTU,?BTM,?L2CAP,?and?SDP) 5???*?初始化一些必備的核心協議棧控制塊兒 6???*/
    7??btu_init_core();
    8
    9??/*?Initialize?any?optional?stack?components10??*?初始化一些可選的組件11??*/
    12??BTE_InitStack();
    13
    14??bta_sys_init();
    15
    16??/*?Initialise?platform?trace?levels?at?this?point?as?BTE_InitStack()?and17???*?bta_sys_init()18???*?reset?the?control?blocks?and?preset?the?trace?level?with19???*?XXX_INITIAL_TRACE_LEVEL20???*?初始化bte的log模塊21???*/
    22??module_init(get_module(BTE_LOGMSG_MODULE));
    23
    24??message_loop_thread_?=?thread_new("btu?message?loop");
    25??if?(!message_loop_thread_)?{
    26????LOG(FATAL)?<"?unable?to?create?btu?message?loop?thread.";
    27??}
    28
    29??thread_set_rt_priority(message_loop_thread_,?THREAD_RT_PRIORITY);
    30??thread_post(message_loop_thread_,?btu_message_loop_run,?nullptr);
    31}
    藍牙芯片廠商在做藍牙芯片時,必須要遵循SIG給出的藍牙規范就像是現在大家公認的tcp/ip模型是統一的藍牙協議棧有些協議是必須支持的,也就是mandatory強制要求必備的通過btu_init_core來初始化這些核心協議有些協議是可選的BTE_InitStack來初始化 1//system/bt/stack/btu/btu_init.cc
    2void?btu_init_core(void)?{
    3??/*?Initialize?the?mandatory?core?stack?components?*/
    4??btm_init();//bluetoothManager初始化
    5
    6??l2c_init();//l2cap初始化
    7
    8??sdp_init();//sdp服務發現協議初始化
    9
    10??gatt_init();//gatt初始化
    11
    12??SMP_Init();//SecurityManager初始化
    13
    14??btm_ble_init();//bluetoothManager?ble初始化
    15}
    好熟悉,初始化l2cap,sdp,gatt,smp,ble同樣的,可以看到BTE_InitStack方法中會初始化rfcomm,bnep,pan,a2dp,avrc,gap,hid_host,mca(multi-channels application)代碼就不再貼出了具體各個協議賦值什么的,目前也不清楚有什么用,需要繼續來分析藍牙的配對,掃描,連接,通信等等功能,才能明白這些初始化的東西有什么用藍牙開啟的流程算是分析完了
    總結一下,藍牙開啟中會完成兩大任務
  • init,把基礎設施搭起來,

  • enable,基礎設施搭起來之后,要把核心架構都準備好,之后就可以順利工作了

  • 藍牙有三大部分,host--hci--controller,藍牙開啟的過程,也是這三部分使能的過程

    聽說,多多分享轉發這只錦鯉,好運會上門~

    原創聲明

    本文為作者原創文章,未經本人同意,禁止轉載和挪作他用

    往期精彩回顧

    我為什么要堅持寫筆記?

    碼農常犯的4個問題,你中招了嗎?Android鼠標源碼研究(三)---獲取輸入事件數據結構探究系(七)--二叉樹實現

    數據結構(八)--平衡二叉樹

    戳嗨,你還在看嗎?

    總結

    以上是生活随笔為你收集整理的蓝牙地址的name为null_蓝牙, enable协议栈流程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。