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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/4/5 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝牙地址的name为null_蓝牙, enable协议栈流程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章開(kāi)始之前,先看兩張圖

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

  • 藍(lán)牙,信息獲取和enable狀態(tài)切換

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

  • 初始化操作classInitNative

  • 初始化操作initNative

  • 庫(kù)加載過(guò)程屬于common的方法就不再分析,重點(diǎn)關(guān)注初始化
    方法實(shí)現(xiàn)都在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}
    這個(gè)方法關(guān)注兩件事兒首先是把java層的方法映射過(guò)來(lái),供jni層調(diào)用。映射過(guò)來(lái)的方法都是JniCallbacks.java中的方法,用來(lái)在hal層有消息回調(diào)時(shí)觸發(fā)給上層另一個(gè)操作就是去加載協(xié)議棧的so包,并獲取到變量名為bluetoothInterface的地址以后jni層再往下的調(diào)用就要依靠這個(gè)bluetoothInterface了加載的是哪個(gè)so包?拿到的so包的誰(shuí)的地址?繼續(xù)分析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命令查看屬性值)字段所聲明的一個(gè)地址下的so包拿到是blutoothInterface的地址完事兒了,拿到之后把地址交給sBluetoothInterface,之后jni就可以通過(guò)該字段來(lái)訪問(wèn)藍(lán)牙所提供的接口了也即是說(shuō),classInitNative的作用有兩個(gè)
  • 映射java層方法

  • 獲取協(xié)議棧的藍(lán)牙接口對(duì)象地址

  • 相當(dāng)于在jni層獲取兩個(gè)對(duì)象,一個(gè)java層對(duì)象,一個(gè)是協(xié)議棧的so包中的對(duì)象獲取對(duì)象之后,你就可以調(diào)用對(duì)象的方法了獲取到的藍(lán)牙接口對(duì)jni提供的方法有哪些?
    都在bluetooth.cc文件中列出來(lái)了

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

    另一個(gè)initNative

    在獲取到對(duì)象之后,需要對(duì)這個(gè)對(duì)象進(jìn)行初始化,配置一些基本信息。
    先看一下代碼 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調(diào)用藍(lán)牙接口的初始化

  • set_os_callouts這個(gè)主要是對(duì)wakelock喚醒鎖的管理,目前以功能分析為主,暫時(shí)不分析代碼設(shè)計(jì)

  • 獲取到socket的profile對(duì)象,有何用?繼續(xù)分析

  • 拆開(kāi)分析,去bluetooth.cc文件中查看方法的實(shí)現(xiàn)第一個(gè),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}
    越往下分析你會(huì)發(fā)現(xiàn)代碼越簡(jiǎn)單,java層要考慮各種功能和交互而hal層代碼只需要認(rèn)真的把功能實(shí)現(xiàn)就好了,順便再把狀態(tài)回調(diào)給上層就ok了所以init中也很簡(jiǎn)單,首先是把jni層的callback對(duì)象拿過(guò)來(lái),方便后續(xù)進(jìn)行回調(diào)之后,看函數(shù)名字應(yīng)該就是初始化stack了,也就是藍(lán)牙核心模塊要初始化了最后是初始化log相關(guān)的了(初始化btsnoop)。重點(diǎn)關(guān)注stack的初始化,分析一下對(duì)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}
    協(xié)議棧的初始化好像東西有點(diǎn)兒多啊,還有三個(gè)排比句get_module方法其實(shí)就是dlsym(RTLD_DEFAULT, name),會(huì)在當(dāng)前進(jìn)程中按照默認(rèn)lib包的搜索順序來(lái)搜索name這個(gè)symbol?module_init方法就是對(duì)所傳入的module調(diào)用init方法
    • 開(kāi)啟核心模塊的管理,這個(gè)方法目前是空實(shí)現(xiàn)

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

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

    • BTIF_CONFIG_MODULE,初始話藍(lán)牙配置模塊:搜索到的symbol是btif_config.cc文件中的btif_config_module,init的目的就是去管理前文說(shuō)到的bt_config相關(guān)的文件,比如恢復(fù)出廠后需要?jiǎng)h除文件重新創(chuàng)建啊,以及文件里邊兒現(xiàn)在要寫什么啊等等。總之就是管理藍(lán)牙配置文件的一個(gè)模塊

    • 初始化藍(lán)牙,從這兒開(kāi)始就會(huì)把整個(gè)藍(lán)牙協(xié)議棧創(chuàng)建起來(lái),為藍(lán)牙的開(kāi)啟做準(zhǔn)備工作

    各個(gè)模塊的初始化如上分析,不再深究了接下來(lái)看一下bt_init_bluetooth,也就是對(duì)藍(lán)牙的初始化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方法會(huì)創(chuàng)建藍(lán)牙接口任務(wù)棧,并且為藍(lán)牙的開(kāi)啟做準(zhǔn)備。主要是調(diào)用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方法用于初始化藍(lán)牙芯片和協(xié)議棧
    初始化的話主要是三個(gè)方面
  • INTEROP_MODULE初始化interop_module模塊,init為空實(shí)現(xiàn),不需要考慮

  • hci,獲取到hci層接口,方法實(shí)現(xiàn)位于/system/bt/hci/src/hci_layer.cc文件中

  • STACK_CONFIG_MODULE初始化,會(huì)操作/etc/bluetooth/bt_stack.conf文件,文件中是對(duì)協(xié)議棧的一些配置,比如log是否開(kāi)啟啊之類

  • 這個(gè)btif的init完成了到目前位置,上層的initNative的任務(wù)已經(jīng)完成。也就是藍(lán)牙接口中的一些基本模塊已經(jīng)初始化完成,基本上都是一些工具模塊和配置模塊,也包括把controller和host之間的接口hci給鋪好。要依賴的工具和配置都準(zhǔn)備好了,小角色都已經(jīng)暖好場(chǎng)了,大明星們?cè)搲狠S登場(chǎng)了,接下來(lái)enable的過(guò)程就是協(xié)議棧的核心角色的初始化了看到這里就有一個(gè)疑問(wèn)了,為什么initNative是在onCreate方法中執(zhí)行,而classInitNative是在靜態(tài)代碼段中和庫(kù)加載一起執(zhí)行?為什么兩個(gè)不能都放在靜態(tài)代碼塊中執(zhí)行?個(gè)人觀點(diǎn)是jni層加載so包需要一定的時(shí)間,需要放在靜態(tài)代碼塊中。而initNative是調(diào)用具體的接口方法,而且還需要使用java層的callback對(duì)象,所以放在AdapterService的onCreate中執(zhí)行init完成之后,就可以看enable的過(guò)程了

    協(xié)議棧enable

    還記得上一篇文章藍(lán)牙,信息獲取和enable狀態(tài)切換嗎?enable的方法調(diào)用是在狀態(tài)切換過(guò)程中發(fā)生的,具體可以參考文章描寫enable的第三大部分,enable過(guò)程中的狀態(tài)切換此文不再贅述,上層調(diào)用jni層的enableNative方法開(kāi)啟jni層也是直接調(diào)用bluetoothInterface的enable方法,而btif只是一個(gè)接口而已,方法實(shí)現(xiàn)還要去看協(xié)議棧 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}
    從這兒開(kāi)始,可以很明顯的知道,協(xié)議棧的enable過(guò)程就三件事兒
  • 執(zhí)行bt_config_module的start_up方法,但目前源碼中該方法是空實(shí)現(xiàn),所以不予考慮

  • enable藍(lán)牙系統(tǒng)

  • 通知jni層,藍(lán)牙狀態(tài)發(fā)生了變化,新?tīng)顟B(tài)為BT_STATE_ON

  • 主要是enable藍(lán)牙系統(tǒng)啊朋友們,感覺(jué)代碼分析馬上要進(jìn)入核心了,有些小激動(dòng)啊不看代碼還在等啥捏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}
    這個(gè)就是該方法的全部代碼,用于創(chuàng)建所有bte的任務(wù)
    三件事兒
  • BTSNOOP_MODULE,調(diào)用btsnoop_module的start_up方法,會(huì)打開(kāi)一個(gè)文件用于存儲(chǔ)controller和host交互的log.平常所查詢的hci日志說(shuō)的就是這個(gè)了,默認(rèn)存放路徑為/data/misc/bluetooth/logs/btsnoop_hci.log

  • HCI_MODULE,調(diào)用hci的start_up方法,hci準(zhǔn)備好,監(jiān)控host和controller之間的交互。同時(shí),會(huì)在這兒開(kāi)啟controller

  • btu開(kāi)啟,bluetooth upper layer開(kāi)啟,藍(lán)牙上層協(xié)議棧開(kāi)啟

  • BTU_StartUp又是一個(gè)有很多事兒要做的方法,該方法用于初始化btu控制塊兒。該方法中有一些對(duì)線程的控制代碼,但是根本功能是會(huì)調(diào)用btu_task_start_up方法,繼續(xù)對(duì)bt進(jìn)行操作,來(lái)看看具體實(shí)現(xiàn) 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???*?初始化一些必備的核心協(xié)議棧控制塊兒 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}
    藍(lán)牙芯片廠商在做藍(lán)牙芯片時(shí),必須要遵循SIG給出的藍(lán)牙規(guī)范就像是現(xiàn)在大家公認(rèn)的tcp/ip模型是統(tǒng)一的藍(lán)牙協(xié)議棧有些協(xié)議是必須支持的,也就是mandatory強(qiáng)制要求必備的通過(guò)btu_init_core來(lái)初始化這些核心協(xié)議有些協(xié)議是可選的BTE_InitStack來(lái)初始化 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服務(wù)發(fā)現(xiàn)協(xié)議初始化
    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方法中會(huì)初始化rfcomm,bnep,pan,a2dp,avrc,gap,hid_host,mca(multi-channels application)代碼就不再貼出了具體各個(gè)協(xié)議賦值什么的,目前也不清楚有什么用,需要繼續(xù)來(lái)分析藍(lán)牙的配對(duì),掃描,連接,通信等等功能,才能明白這些初始化的東西有什么用藍(lán)牙開(kāi)啟的流程算是分析完了
    總結(jié)一下,藍(lán)牙開(kāi)啟中會(huì)完成兩大任務(wù)
  • init,把基礎(chǔ)設(shè)施搭起來(lái),

  • enable,基礎(chǔ)設(shè)施搭起來(lái)之后,要把核心架構(gòu)都準(zhǔn)備好,之后就可以順利工作了

  • 藍(lán)牙有三大部分,host--hci--controller,藍(lán)牙開(kāi)啟的過(guò)程,也是這三部分使能的過(guò)程

    聽(tīng)說(shuō),多多分享轉(zhuǎn)發(fā)這只錦鯉,好運(yùn)會(huì)上門~

    原創(chuàng)聲明

    本文為作者原創(chuàng)文章,未經(jīng)本人同意,禁止轉(zhuǎn)載和挪作他用

    往期精彩回顧

    我為什么要堅(jiān)持寫筆記?

    碼農(nóng)常犯的4個(gè)問(wèn)題,你中招了嗎?Android鼠標(biāo)源碼研究(三)---獲取輸入事件數(shù)據(jù)結(jié)構(gòu)探究系(七)--二叉樹(shù)實(shí)現(xiàn)

    數(shù)據(jù)結(jié)構(gòu)(八)--平衡二叉樹(shù)

    戳嗨,你還在看嗎?

    總結(jié)

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

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。