【移動應(yīng)用開發(fā)技術(shù)】Android源碼個個擊破之6.0藍(lán)牙廣播開啟源碼_第1頁
【移動應(yīng)用開發(fā)技術(shù)】Android源碼個個擊破之6.0藍(lán)牙廣播開啟源碼_第2頁
【移動應(yīng)用開發(fā)技術(shù)】Android源碼個個擊破之6.0藍(lán)牙廣播開啟源碼_第3頁
【移動應(yīng)用開發(fā)技術(shù)】Android源碼個個擊破之6.0藍(lán)牙廣播開啟源碼_第4頁
【移動應(yīng)用開發(fā)技術(shù)】Android源碼個個擊破之6.0藍(lán)牙廣播開啟源碼_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論