您的位置:首页 > 移动开发 > Android开发

Cubietruck---26.android蓝牙分析4_pair分析

2016-06-28 18:35 302 查看
一. setting中的调用

1. 当在屏幕上点击搜索到的蓝牙设备时,会产生一个onClicked事件

在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/BluetoothDevicePreference.java中

void onClicked() {

int bondState = mCachedDevice.getBondState();

if (mCachedDevice.isConnected()) {

askDisconnect();

} else if (bondState == BluetoothDevice.BOND_BONDED) {

mCachedDevice.connect(true);

} else if (bondState == BluetoothDevice.BOND_NONE) {

pair();

}

}

会调用pair函数

private void pair() {

if (!mCachedDevice.startPairing()) {

Utils.showError(getContext(), mCachedDevice.getName(),

R.string.bluetooth_pairing_error_message);

}

}

mCachedDevice是一个CachedBluetoothDevice

2. 在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java中

boolean startPairing() {

if (mLocalAdapter.isDiscovering()) {

mLocalAdapter.cancelDiscovery();

}

if (!mDevice.createBond()) {

return false;

}

mConnectAfterPairing = true; // auto-connect
after pairing

return true;

}

在pair时,如果正在搜索,则停止搜索,并调用 CachedBluetoothDevice的createBond,
mDevice是一个 BluetoothDevice在framework层

二. framework层中的调用

在./frameworks/base/core/java/android/bluetooth/BluetoothDevice.java中

public boolean createBond() {

if (sService == null) {

return false;

}

try {

return sService.createBond(this);

} catch (RemoteException e) {Log.e(TAG, "", e);}

return false;

}

调用了sService的createBond,
其中sService是IBluetooth,要到packages层去了

三.packages中的调用

3.1 在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java中

的AdapterServiceBinder类中

public boolean createBond(BluetoothDevice device) {

if (!Utils.checkCaller()) {

return false;

}

AdapterService service = getService();

if (service == null) return false;

return service.createBond(device);

}

在AdapterService类中

boolean createBond(BluetoothDevice device) {

enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN
permission");

DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);

if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {

return false;

}

Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);

msg.obj = device;

mBondStateMachine.sendMessage(msg);

return true;

}

发送了一个CREATE_BOND的消息

3.2 在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java中

public boolean processMessage(Message msg) {

switch(msg.what) {

case CREATE_BOND:

createBond(dev, true);

break;

}

}

在消息处理函数createBond中

private boolean createBond(BluetoothDevice dev, boolean
transition) {

if (dev.getBondState() == BluetoothDevice.BOND_NONE) {

byte[] addr = Utils.getBytesFromAddress(dev.getAddress());

if (!mAdapterService.createBondNative(addr)) {

sendIntent(dev, BluetoothDevice.BOND_NONE,

BluetoothDevice.UNBOND_REASON_REMOVED);

return false;

} else if (transition) {

transitionTo(mPendingCommandState);

}

return true;

}

return false;

}

看到createBondNative这个函数,就知道要调用jni了。

四. jni中的调用

在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中

static jboolean createBondNative(JNIEnv* env, jobject
obj, jbyteArray address) {

jbyte *addr;

jboolean result = JNI_FALSE;

if (!sBluetoothInterface) return
result;

addr = env->GetByteArrayElements(address, NULL);

int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr);

env->ReleaseByteArrayElements(address, addr, NULL);

result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;

return result;

}

其中这个sBluetoothInterface是协议栈的接口

五.协议栈bluedroid中的调用

5.1 在./external/bluetooth/bluedroid/btif/src/bluetooth.c中

static int create_bond(const bt_bdaddr_t *bd_addr)

{

/* sanity check */

if (interface_ready() == FALSE)

return BT_STATUS_NOT_READY;

return btif_dm_create_bond(bd_addr);

}

5.2 在./external/bluetooth/bluedroid/btif/src/btif_dm.c中

bt_status_t btif_dm_create_bond(const bt_bdaddr_t *bd_addr)

{

bdstr_t bdstr;

if (pairing_cb.state != BT_BOND_STATE_NONE)

return BT_STATUS_BUSY;

btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_CREATE_BOND,

(char *)bd_addr, sizeof(bt_bdaddr_t), NULL);

return BT_STATUS_SUCCESS;

}

具体的如何调用到了这个回调函数,参见附录1

5.3 在回调函数中进行具体的处理

在./external/bluetooth/bluedroid/btif/src/btif_dm.c中

static void btif_dm_generic_evt(UINT16 event, char* p_param)

{

switch(event) //这个event就是发送的命令

{

case BTIF_DM_CB_CREATE_BOND:

{

btif_dm_cb_create_bond((bt_bdaddr_t *)p_param);

}

break;

}

}

5.3.1 回调的具体处理

在./external/bluetooth/bluedroid/btif/src/btif_dm.c中

static void btif_dm_cb_create_bond(bt_bdaddr_t *bd_addr)

{

//状态由BT_BOND_STATE_NONE--> BT_BOND_STATE_BONDING,并通知上层

//这儿具体如何调用上层的过程,参见附录2

bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);

if (check_cod(bd_addr, COD_HID_POINTING)){

int status;

status = btif_hh_connect(bd_addr);

if(status != BT_STATUS_SUCCESS)

bond_state_changed(status, bd_addr, BT_BOND_STATE_NONE);

}

else

{

BTA_DmBond ((UINT8 *)bd_addr->address);

}

pairing_cb.is_local_initiated = TRUE;

}

5.3.2

在./external/bluetooth/bluedroid/bta/dm/bta_dm_api.c中

void BTA_DmBond(BD_ADDR bd_addr)

{

tBTA_DM_API_BOND *p_msg;

if ((p_msg = (tBTA_DM_API_BOND *) GKI_getbuf(sizeof(tBTA_DM_API_BOND))) != NULL)

{

p_msg->hdr.event = BTA_DM_API_BOND_EVT;

bdcpy(p_msg->bd_addr, bd_addr);

bta_sys_sendmsg(p_msg);

}

}

在./external/bluetooth/bluedroid/bta/sys/bta_sys_main.c中

void bta_sys_sendmsg(void *p_msg)

{

GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);

}

又到了这个sendmsg,不过这次的跟上一次不一样的地方是参数task_id不是BTIF_TASK, 所以接收者不是btif_task而是btu_task

5.3.3 在./stack/btu/btu_task.c中

BTU_API UINT32 btu_task (UINT32 param)

{

if (event & TASK_MBOX_2_EVT_MASK)

{

while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)

{

bta_sys_event(p_msg);

}

}

}

在./bta/sys/bta_sys_main.c中

BTA_API void bta_sys_event(BT_HDR *p_msg)

{

UINT8 id;

BOOLEAN freebuf = TRUE;

id = (UINT8) (p_msg->event >> 8);

freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);

}

会调用全局函数bta_sys_cb.reg[id]->evt_hdlr,这个东东是从哪儿来的呢?

5.4 bta_sys_cb.reg[id]->evt_hdlr的由来

在bta/sys/bta_sys_main.c中

void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)

{

bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;

bta_sys_cb.is_reg[id] = TRUE;

}

在bta/dm/bta_dm_api.c中

static const tBTA_SYS_REG bta_dm_reg =

{

bta_dm_sm_execute,

bta_dm_sm_disable

};

通过bta_sys_register (BTA_ID_DM, &bta_dm_reg )注册的,

所以这儿的bta_sys_cb.reg[id]->evt_hdlr调用的就是bta_dm_sm_execute

5.5 bta_dm_sm_execute

在bta/dm/bta_dm_main.c中

BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg)

{

UINT16 event = p_msg->event & 0x00ff;

if(event < BTA_DM_NUM_ACTIONS)

{

(*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg);

}

return TRUE;

}

bta_dm_action是一个函数指针的数组,此时event=10,在数组中是函数bta_dm_bond

5.6

在./bta/dm/bta_dm_act.c中

void bta_dm_bond (tBTA_DM_MSG *p_data)

{

tBTM_STATUS status;

tBTA_DM_SEC sec_event;

char *p_name;

status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );

if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))

{

p_name = BTM_SecReadDevName(p_data->bond.bd_addr);

if (!p_name)

p_name = "";

memset(&sec_event, 0, sizeof(tBTA_DM_SEC));

bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);

memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));

sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;

sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;

if (status == BTM_SUCCESS)

sec_event.auth_cmpl.success = TRUE;

bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);

}

}

5.6.1 在./stack/btm/btm_sec.c中

tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32
trusted_mask[])

{

p_dev_rec = btm_find_or_alloc_dev (bd_addr);
//第一次配对时alloc一个device

status = btm_sec_dd_create_conn(p_dev_rec);
//进入下一步

return status;

}

在stack/l2cap/l2c_utils.c中



附一: 协议栈中消息的传递

在btif_dm_create_bond中调用了函数btif_transfer_context来发送CREATE_BOND命令

btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_CREATE_BOND,

(char *)bd_addr, sizeof(bt_bdaddr_t), NULL);

其中btif_dm_generic_evt 是回调函数,

BTIF_DM_CB_CREATE_BOND是命令

(char *)bd_addr是参数

1.1 stack中消息的发送与处理过程

在./external/bluetooth/bluedroid/btif/src/btif_core.c中

bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16
event, char* p_params, int param_len, tBTIF_COPY_CBACK *p_copy_cback)

{

tBTIF_CONTEXT_SWITCH_CBACK *p_msg;

//第1步获取msg的buffer

if ((p_msg = (tBTIF_CONTEXT_SWITCH_CBACK *) GKI_getbuf(sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len)) != NULL)

{

//第2步组成一个msg

p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT;

p_msg->p_cb = p_cback;

p_msg->event = event;

if (p_copy_cback)

{

p_copy_cback(event, p_msg->p_param, p_params);

}

else if (p_params)

{

memcpy(p_msg->p_param, p_params, param_len); /* callback
parameter data */

}

/第3步,最后一步发送

btif_sendmsg(p_msg);

return BT_STATUS_SUCCESS;

}

else

{

return BT_STATUS_NOMEM;

}

}

1.2 进入core

在 ./external/bluetooth/bluedroid/btif/src/btif_core.c中

void btif_sendmsg(void *p_msg)

{

GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);

}

1.3 组成命令,并发送//这个event就是发送的命令

在./external/bluetooth/bluedroid/gki/common/gki_buffer.c中

void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)

{

BUFFER_HDR_T *p_hdr;

tGKI_COM_CB *p_cb = &gki_cb.com;

p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);

GKI_disable();

if (p_cb->OSTaskQFirst[task_id][mbox])

p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;

else

p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;

p_cb->OSTaskQLast[task_id][mbox] = p_hdr;

p_hdr->p_next = NULL;

p_hdr->status = BUF_STATUS_QUEUED;

p_hdr->task_id = task_id;

GKI_enable();

GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));

return;

}

1.4 具体的发送过程

这儿说是发送,并不是发送msg,而是向接收者发送了一个信号。

在./external/bluetooth/bluedroid/gki/ulinux/gki_ulinux.c中

UINT8 GKI_send_event (UINT8 task_id, UINT16 event)

{

if (task_id < GKI_MAX_TASKS)

{

pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);

gki_cb.com.OSWaitEvt[task_id] |= event;

pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);

pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);

return ( GKI_SUCCESS );

}

return (GKI_FAILURE);

}

1.5 接收者

因为GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);发送的task是BTIF_TASK

所以在./external/bluetooth/bluedroid/btif/src/btif_core.c中

static void btif_task(UINT32 params)

{

UINT16 event;

BT_HDR *p_msg;

btif_associate_evt();

for(;;)

{

//上面的pthread_cond_signal,把下面的wait打断

event = GKI_wait(0xFFFF, 0);

if(event & TASK_MBOX_1_EVT_MASK)

{//这个event就是发送的命令

while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL)

{

switch (p_msg->event)

{

case BT_EVT_CONTEXT_SWITCH_EVT: //执行到这儿

btif_context_switched(p_msg);

break;

default:

break;

}

GKI_freebuf(p_msg);

}

}

}

btif_disassociate_evt();

}

1.6 最后调用回调函数

在./external/bluetooth/bluedroid/btif/src/btif_core.c中

static void btif_context_switched(void *p_msg)

{

tBTIF_CONTEXT_SWITCH_CBACK *p;

BTIF_TRACE_VERBOSE0("btif_context_switched");

p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg;

//调用回调函数

if (p->p_cb)

p->p_cb(p->event, p->p_param);

}

1.7 在回调函数中进行具体的处理

在./external/bluetooth/bluedroid/btif/src/btif_dm.c中

static void btif_dm_generic_evt(UINT16 event, char* p_param)

{

switch(event) //这个event就是发送的命令

{

case BTIF_DM_CB_CREATE_BOND:

{

btif_dm_cb_create_bond((bt_bdaddr_t *)p_param);

}

break;

}

}

1.8

根据task_id来区分是发送给btif_task还是btu_task

2.5 总结一下

附三:

在stack/hcic/hcicmds.c中

BOOLEAN btsnd_hcic_delete_stored_key (BD_ADDR bd_addr, BOOLEAN delete_all_flag)

{

BT_HDR *p;

UINT8 *pp;

p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_DELETE_STORED_KEY);
//获取buffer

pp = (UINT8 *)(p + 1);

p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_DELETE_STORED_KEY;

p->offset = 0;

UINT16_TO_STREAM (pp, HCI_DELETE_STORED_LINK_KEY);

UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_DELETE_STORED_KEY);

BDADDR_TO_STREAM (pp, bd_addr);

UINT8_TO_STREAM (pp, delete_all_flag);

btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);

return (TRUE);

}

在stack/btu/btu_hcif.c中

void btu_hcif_send_cmd (UINT8 controller_id, BT_HDR *p_buf)

{

if (controller_id == LOCAL_BR_EDR_CONTROLLER_ID)

HCI_CMD_TO_LOWER(p_buf);

}

#define HCI_CMD_TO_LOWER(p) bte_main_hci_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_CMD);

在main/bte_main.c 中

void bte_main_hci_send (BT_HDR *p_msg, UINT16
event)

{

UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local
controller ID */

p_msg->event = event;

if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || (sub_event == LOCAL_BLE_CONTROLLER_ID))

{

if (bt_hc_if)

{

bt_hc_if->transmit_buf((TRANSAC)p_msg, (char *) (p_msg + 1), p_msg->len);

}

else

GKI_freebuf(p_msg);

}

}

在hci/src/bt_hci_bdroid.c中

static int transmit_buf(TRANSAC transac, char *p_buf, int len)

{

utils_enqueue(&tx_q, (void *) transac);

bthc_signal_event(HC_EVENT_TX);

return BT_HC_STATUS_SUCCESS;

}

发送了一个HC_EVENT_TX信号

那么是谁来接收这个HC_EVENT_TX命令呢?

在hci/src/bt_hci_bdroid.c中

static void *bt_hc_worker_thread(void *arg)

{

if (events & HC_EVENT_TX)

{

tx_cmd_pkts_pending = FALSE;

HC_BT_HDR * sending_msg_que[64];

int sending_msg_count = 0;

utils_lock();

p_next_msg = tx_q.p_first;

while (p_next_msg && sending_msg_count < (int)sizeof(sending_msg_que)/sizeof(sending_msg_que[0]))

{

if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)

{

if ((tx_cmd_pkts_pending == TRUE) || (num_hci_cmd_pkts <= 0))

{

tx_cmd_pkts_pending = TRUE;

p_next_msg = utils_getnext(p_next_msg);

continue;

}

}

p_msg = p_next_msg;

p_next_msg = utils_getnext(p_msg);

utils_remove_from_queue_unlocked(&tx_q, p_msg);

sending_msg_que[sending_msg_count++] = p_msg;

}

utils_unlock();

int i;

for(i = 0; i < sending_msg_count; i++)

p_hci_if->send(sending_msg_que[i]);

if (tx_cmd_pkts_pending == TRUE)

BTHCDBG("Used up Tx Cmd credits");

}

}

其中p_hci_if的初始化是在hci/src/bt_hci_bdroid.c中

static int init(const bt_hc_callbacks_t* p_cb, unsigned
char *local_bdaddr)

{

#ifdef HCI_USE_MCT //MCT: Multi-Channels Transport

extern tHCI_IF hci_mct_func_table;

p_hci_if = &hci_mct_func_table;

#elif defined HCI_USE_RTK_H5

extern tHCI_IF hci_h5_func_table;

p_hci_if = &hci_h5_func_table;

#else

extern tHCI_IF hci_h4_func_table;

p_hci_if = &hci_h4_func_table; //这儿是用的这个

#endif

p_hci_if->init();

}

在hci/src/userial.c中

uint16_t userial_write(uint16_t msg_id, uint8_t *p_data, uint16_t len)

{

int ret, total = 0;

while(len != 0)

{

ret = write(userial_cb.fd, p_data+total, len);

total += ret;

len -= ret;

}

return ((uint16_t)total);

}

在hci/src/userial.c中,初始化了userial_cb.fd

uint8_t userial_open(uint8_t port)

{

bt_vnd_if->op(BT_VND_OP_USERIAL_OPEN, &fd_array); //向libbt_verder.so发消息

userial_cb.fd = fd_array[0];

}

root@android:/ # ls /dev/ttyS2 -l

crw-rw---- bluetooth
net_bt_stack 250, 2 2014-08-19 15:30
ttyS2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: