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
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
相关文章推荐
- Cubietruck---25.android蓝牙分析3_search分析 2
- Cubietruck---24.android蓝牙分析2_enable分析
- Cubietruck---23.android蓝牙分析1总
- Cubietruck---22.vold深入理解android第九章笔记
- Android root 原理
- Cubietruck---14. binder分析_深入理解android第六章笔记
- Cubietruck---13.sp与wp分析_深入理解android第五章笔记
- Android Studio如何取消与SVN的关联
- Android开发---ListView实现局部刷新及删除
- Android 左右滑屏 方向判断 ViewPager
- AndroidManifest.xml中的minSdkVersion、targetSdkVersion、maxSdkVersion和project.properties中target API lev
- uboot流程分析--修改android启动模式按键
- Activity生命周期
- 解决Lightmap在PC上与ios和Android上表现不同的问题
- 解决TimePickerDialog中onTimeSet执行两次的问题
- Android设置多个type
- Android APK反编译就这么简单 详解(附图)
- Android Studio NDK 开发 问题记录
- 王学岗Android的三级缓存(待续)
- android studio 中使用gradle命令行