




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android源碼個個擊破之6.0藍(lán)牙廣播開啟源碼
藍(lán)牙模塊架構(gòu)詳解:/tronteng/article/details/53435217藍(lán)牙連接過程分析:/info/info_218.html由于公司想節(jié)約成本,將藍(lán)牙盒子的功能由android來實現(xiàn),但是發(fā)現(xiàn)android廣播包的數(shù)據(jù)的拼組順序與藍(lán)牙盒子的不一致。所以需要看看源碼是如何組包的,是否可以去修改。開啟廣播的源碼
》》注冊客戶端|
AdvertiseCallbackWrapper是BluetoothAdvertiser的內(nèi)部類
|
上面的mBluetoothGatt其實就是GattService的BluetoothGattBinder對象,但是注意廣播的數(shù)據(jù)advertiseData并沒有往下傳遞。
|
Binder又調(diào)用了外部類GattService的方法
然后調(diào)用了Native的方法,調(diào)用到這里突然發(fā)現(xiàn)TMD的廣播包數(shù)據(jù)沒有傳遞過來。所以往回看,搜索廣播包存儲的變量mAdertisment.
》》客戶端注冊成功,真正的開啟廣播
先調(diào)用binder的方法startMultiAdvertising
然后binder再調(diào)用service里的方法
可以看到廣播的數(shù)據(jù)被封進(jìn)了AdvertiseClient對象
service然后再調(diào)用AdvertiseManager的方法
|
|
調(diào)用AdvertiseNative方法,注意這個類是AdvertiseManager的內(nèi)部類
先看單個廣播的方法startSingleAdvertising:
第一步,先使能廣播。
第二步,設(shè)置廣播的數(shù)據(jù)
。
看看JNI方法,注意是JNI,不是C。
注意上面的JNI方法env->GetByteArrayElements和ReleaseByteArrayElements,獲取數(shù)組然后又釋放了數(shù)組。所以主要看sGattIf->client->set_adv_data這個方法
搜索到這個方法的定義的h文件:
那么sGattIf是什么,client又是什么?這個方法的實現(xiàn)在哪里呢?
追溯sGattIf
追溯btIf
|
|
這個方法是在classInitNative方法里被調(diào)用的
那么classInitNative肯定有個地方被用,我們找找,注意這是jni類的方法,那么它肯定是要被上層代碼所調(diào)用的:
|
|
可以發(fā)現(xiàn)classInitNative正好是GattService的本地方法,并且在GattService類加載時就調(diào)用了。觀察GattService和com_android_bluetooth_btservice_AdapterService.cpp兩個類,
發(fā)現(xiàn)它們也是在同一個應(yīng)用下。所以上面方法調(diào)用推理是沒有毛病的。
所以我們接著上面的源碼說起
上面引用調(diào)用十分復(fù)雜:static
void
classInitNative(JNIEnv*
env,
jclass
clazz)
{
int
err;
hw_module_t*
module;
char
value[PROPERTY_VALUE_MAX];
//從配置文件里獲取key
=
"bluetooth.mock_stack"的值
property_get("bluetooth.mock_stack",
value,
"");
//得到module的ID
const
char
*id
=
(strcmp(value,
"1")?
BT_STACK_MODULE_ID
:
BT_STACK_TEST_MODULE_ID);
//給module賦值
err
=
hw_get_module(id,
(hw_module_t
const**)&module);
if
(err
==
0)
{
hw_device_t*
abstraction;
err
=
module->methods->open(module,
id,
&abstraction);
if
(err
==
0)
{
bluetooth_module_t*
btStack
=
(bluetooth_module_t
*)abstraction;
sBluetoothInterface
=
btStack->get_bluetooth_interface();
}
else
{
ALOGE("Error
while
opening
Bluetooth
library");
}
}
else
{
ALOGE("No
Bluetooth
Library
found");
}
}
上面的hw_get_module已經(jīng)在和硬件打交道了
上面方法的調(diào)用就不去具體深究了,下面看看看
sBluetoothInterface這個變量的類型
它是bt_interface_t的指針類型,bt_interface_t的定義:
/**
Represents
the
standard
Bluetooth
DM
interface.
*/
typedef
struct
{
/**
set
to
sizeof(bt_interface_t)
*/
size_t
size;
/**
*
Opens
the
interface
and
provides
the
callback
routines
*
to
the
implemenation
of
this
interface.
*/
int
(*init)(bt_callbacks_t*
callbacks
);
/**
Enable
Bluetooth.
*/
int
(*enable)(void);
/**
Disable
Bluetooth.
*/
int
(*disable)(void);
/**
Closes
the
interface.
*/
void
(*cleanup)(void);
/**
Get
all
Bluetooth
Adapter
properties
at
init
*/
int
(*get_adapter_properties)(void);
/**
Get
Bluetooth
Adapter
property
of
'type'
*/
int
(*get_adapter_property)(bt_property_type_t
type);
/**
Set
Bluetooth
Adapter
property
of
'type'
*/
/*
Based
on
the
type,
val
shall
be
one
of
*
bt_bdaddr_t
or
bt_bdname_t
or
bt_scanmode_t
etc
*/
int
(*set_adapter_property)(const
bt_property_t
*property);
/**
Get
all
Remote
Device
properties
*/
int
(*get_remote_device_properties)(bt_bdaddr_t
*remote_addr);
/**
Get
Remote
Device
property
of
'type'
*/
int
(*get_remote_device_property)(bt_bdaddr_t
*remote_addr,
bt_property_type_t
type);
/**
Set
Remote
Device
property
of
'type'
*/
int
(*set_remote_device_property)(bt_bdaddr_t
*remote_addr,
const
bt_property_t
*property);
/**
Get
Remote
Device's
service
record
for
the
given
UUID
*/
int
(*get_remote_service_record)(bt_bdaddr_t
*remote_addr,
bt_uuid_t
*uuid);
/**
Start
SDP
to
get
remote
services
*/
int
(*get_remote_services)(bt_bdaddr_t
*remote_addr);
/**
Start
Discovery
*/
int
(*start_discovery)(void);
/**
Cancel
Discovery
*/
int
(*cancel_discovery)(void);
/**
Create
Bluetooth
Bonding
*/
int
(*create_bond)(const
bt_bdaddr_t
*bd_addr,
int
transport);
/**
Remove
Bond
*/
int
(*remove_bond)(const
bt_bdaddr_t
*bd_addr);
/**
Cancel
Bond
*/
int
(*cancel_bond)(const
bt_bdaddr_t
*bd_addr);
/**
*
Get
the
connection
status
for
a
given
remote
device.
*
return
value
of
0
means
the
device
is
not
connected,
*
non-zero
return
status
indicates
an
active
connection.
*/
int
(*get_connection_state)(const
bt_bdaddr_t
*bd_addr);
/**
BT
Legacy
PinKey
Reply
*/
/**
If
accept==FALSE,
then
pin_len
and
pin_code
shall
be
0x0
*/
int
(*pin_reply)(const
bt_bdaddr_t
*bd_addr,
uint8_t
accept,
uint8_t
pin_len,
bt_pin_code_t
*pin_code);
/**
BT
SSP
Reply
-
Just
Works,
Numeric
Comparison
and
Passkey
*
passkey
shall
be
zero
for
BT_SSP_VARIANT_PASSKEY_COMPARISON
&
*
BT_SSP_VARIANT_CONSENT
*
For
BT_SSP_VARIANT_PASSKEY_ENTRY,
if
accept==FALSE,
then
passkey
*
shall
be
zero
*/
int
(*ssp_reply)(const
bt_bdaddr_t
*bd_addr,
bt_ssp_variant_t
variant,
uint8_t
accept,
uint32_t
passkey);
/**
Get
Bluetooth
profile
interface
*/
const
void*
(*get_profile_interface)
(const
char
*profile_id);
/**
Bluetooth
Test
Mode
APIs
-
Bluetooth
must
be
enabled
for
these
APIs
*/
/*
Configure
DUT
Mode
-
Use
this
mode
to
enter/exit
DUT
mode
*/
int
(*dut_mode_configure)(uint8_t
enable);
/*
Send
any
test
HCI
(vendor-specific)
command
to
the
controller.
Must
be
in
DUT
Mode
*/
int
(*dut_mode_send)(uint16_t
opcode,
uint8_t
*buf,
uint8_t
len);
/**
BLE
Test
Mode
APIs
*/
/*
opcode
MUST
be
one
of:
LE_Receiver_Test,
LE_Transmitter_Test,
LE_Test_End
*/
int
(*le_test_mode)(uint16_t
opcode,
uint8_t
*buf,
uint8_t
len);
/*
enable
or
disable
bluetooth
HCI
snoop
log
*/
int
(*config_hci_snoop_log)(uint8_t
enable);
/**
Sets
the
OS
call-out
functions
that
bluedroid
needs
for
alarms
and
wake
locks.
*
This
should
be
called
immediately
after
a
successful
|init|.
*/
int
(*set_os_callouts)(bt_os_callouts_t
*callouts);
/**
Read
Energy
info
details
-
return
value
indicates
BT_STATUS_SUCCESS
or
BT_STATUS_NOT_READY
*
Success
indicates
that
the
VSC
command
was
sent
to
controller
*/
int
(*read_energy_info)();
/**
*
Native
support
for
dumpsys
function
*
Function
is
synchronous
and
|fd|
is
owned
by
caller.
*/
void
(*dump)(int
fd);
/**
*
Clear
/data/misc/bt_config.conf
and
erase
all
stored
connections
*/
int
(*config_clear)(void);
}
bt_interface_t;
可以知道bt_interface_t是個結(jié)構(gòu)體類型
其實吧,源碼看到這兒我又走偏了,我們主要是分析set_adv_data是由那個類實現(xiàn)的
搜索這個方法的調(diào)用是很繞的
只能搜索一個bt_gatt_client.h文件,那么繼續(xù)搜索bt_gatt_client.h文件
繼續(xù)搜索bt_gatt.h文件
然后一個一個文件點進(jìn)去搜索set_adv_data方法,發(fā)現(xiàn)只有/system/bt/btif/src/btif_gatt_client.c這個類里包涵這個方法,但是名字不是完全一模一樣。
那么這個模塊是怎么和外部模塊建立關(guān)聯(lián)的?用的什么機制?
搜索btgattClientInterface這個變量
|
搜索btif_gatt_get_interface方法
看看調(diào)用的方法:
這個好像就是藍(lán)牙架構(gòu)里的Profile層??
在bluetooth.c又將上面的get_profile_interface封裝到bluetoothInterface
|
看看id
這不正是打開藍(lán)牙棧嗎?但是死活沒有搜索到HAL_MODULE_INFO_SYM在哪里被調(diào)用。
看了這個博客/myarrow/article/details/7175204,應(yīng)該就能明白。HAL如何向上層提供接口
回顧前面的源碼
看看id
2個module的id一模一樣,這不正好與上面的HAL_MODULE_INFO_SYM這個Module不謀而合??????MD,分析源碼,終于有一次合上了。
至此,我們找到了方法的調(diào)用棧,但這不是我的目的。我的目的,還在set_adv_data那里。所以繼續(xù)前面的源碼接著說:
第1步:打包數(shù)據(jù)
就是把數(shù)據(jù)封裝到adv_data這個變量里。
(client_ifbool
set_scan_rspbool
include_namebool
include_txpowermin_intervalmax_intervalappearancemanufacturer_len*
manufacturer_dataservice_data_len*
service_dataservice_uuid_len*
service_uuidbtif_adv_data_t
*p_multi_adv_inst)
{
memset(p_multi_adv_instsizeof(btif_adv_data_t))p_multi_adv_inst->=
(uint8_t)
p_multi_adv_inst->=
p_multi_adv_inst->=
p_multi_adv_inst->=
p_multi_adv_inst->=
p_multi_adv_inst->=
p_multi_adv_inst->=
p_multi_adv_inst->=
(manufacturer_len
>
)
{
p_multi_adv_inst->p_manufacturer_data
=
GKI_getbuf()memcpy(p_
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【科銳國際】人才市場洞察及薪酬指南2025
- 【光子盒】2025全球量子計算產(chǎn)業(yè)發(fā)展展望報告
- 無菌敷貼可行性研究報告
- 江蘇省鎮(zhèn)江市宜城中學(xué)教育集團五校聯(lián)考2024-2025學(xué)年七年級下學(xué)期3月月考數(shù)學(xué)試題(原卷版+解析版)
- 公共安全事件應(yīng)對與處理指南
- 船舶運輸管樁報價策略分析
- 養(yǎng)老服務(wù)中心可行性研究報告模板
- 游戲開發(fā)行業(yè)游戲設(shè)計與用戶體驗優(yōu)化方案
- 三農(nóng)村經(jīng)濟發(fā)展規(guī)劃方案
- 項目可行研究報告
- 大學(xué)生信息素養(yǎng)大賽考試題庫及答案
- 兒童保?。祻?fù))管理信息系統(tǒng)需求說明
- 文獻(xiàn)檢索與論文寫作
- 《麻醉與BIS監(jiān)測》課件
- 嶺南版二年級美術(shù)上冊期末試題B
- 勞務(wù)派遣人員安全培訓(xùn)方案
- 組建新部門規(guī)劃方案
- 行政審批政策法規(guī)知識講座
- 合肥娃哈哈廠勞動合同
- 【盒馬鮮生生鮮類產(chǎn)品配送服務(wù)問題及優(yōu)化建議分析10000字(論文)】
- 《江蘇住宅物業(yè)管理服務(wù)標(biāo)準(zhǔn)》(DB32T538-2002)
評論
0/150
提交評論