一. start_disconvery的上层一系列的调用
1. 界面上的"search for device"
在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/BluetoothSettings.java中
当点击“searching devices"或者打开时就会去扫描蓝牙设备
-
public boolean onOptionsItemSelected(MenuItem item) {
-
switch (item.getItemId()) {
-
case MENU_ID_SCAN:
-
if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
-
startScanning();
-
}
-
return true;
-
}
在device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/BluetoothSettings.java中
-
private void startScanning() {
-
if (!mAvailableDevicesCategoryIsPresent) {
-
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
-
}
-
mLocalAdapter.startScanning(true);
-
}
在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/LocalBluetoothAdapter.java中
-
void startScanning(boolean force) {
-
if (!mAdapter.isDiscovering()) {
-
if (!force) {
-
if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
-
return;
-
}
-
A2dpProfile a2dp = mProfileManager.getA2dpProfile();
-
if (a2dp != null && a2dp.isA2dpPlaying()) {
-
return;
-
}
-
}
-
-
if (mAdapter.startDiscovery()) {
-
mLastScan = System.currentTimeMillis();
-
}
-
}
-
}
2. frameworks中的调用
在frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java中
-
public boolean startDiscovery() {
-
if (getState() != STATE_ON) return false;
-
try {
-
synchronized(mManagerCallback) {
-
if (mService != null) return mService.startDiscovery();
-
}
-
} catch (RemoteException e) {Log.e(TAG, "", e);}
-
return false;
-
}
mService
用binder调用
startDiscovery
3. packages中的调用
在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java中
-
private static class AdapterServiceBinder extends IBluetooth.Stub {
-
public boolean startDiscovery() {
-
if (!Utils.checkCaller()) {
-
Log.w(TAG,"startDiscovery(): not allowed for non-active user");
-
return false;
-
}
-
-
AdapterService service = getService();
-
if (service == null) return false;
-
return service.startDiscovery();
-
}
-
}
3.1 server的
在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java中
-
public class AdapterService extends Service {
-
boolean startDiscovery() {
-
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, “Need BLUETOOTH ADMIN permission");
-
return startDiscoveryNative();
-
}
-
}
会调用jni的startDiscoveryNative
4. jni中的调用
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
-
static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
-
ALOGV("%s:",__FUNCTION__);
-
-
jboolean result = JNI_FALSE;
-
if (!sBluetoothInterface) return result;
-
-
int ret = sBluetoothInterface->start_discovery();
-
result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
-
return result;
-
}
sBluetoothInterface是bluetooth.default.so的接口,即协议栈的接口
二.协议栈中的start_discovery
到了协议栈了,协议栈是在./external/bluetooth/bluedroid/中
2.1在./btif/src/bluetooth.c中
-
static int start_discovery(void)
-
{
-
/* sanity check */
-
if (interface_ready() == FALSE)
-
return BT_STATUS_NOT_READY;
-
-
return btif_dm_start_discovery();
-
}
2.2在btif/src/btif_dm.c中
-
bt_status_t btif_dm_start_discovery(void)
-
{
-
tBTA_DM_INQ inq_params;
-
tBTA_SERVICE_MASK services = 0;
-
inq_params.mode = BTA_DM_GENERAL_INQUIRY;
-
inq_params.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION;
-
inq_params.max_resps = BTIF_DM_DEFAULT_INQ_MAX_RESULTS;
-
inq_params.report_dup = TRUE;
-
inq_params.filter_type = BTA_DM_INQ_CLR;
-
btif_dm_inquiry_in_progress = FALSE;
-
BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
-
return BT_STATUS_SUCCESS;
-
}
2.3在bta/dm/bta_dm_api.c中
-
void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK services, tBTA_DM_SEARCH_CBACK *p_cback)
-
{
-
tBTA_DM_API_SEARCH *p_msg;
-
if ((p_msg = (tBTA_DM_API_SEARCH *) GKI_getbuf(sizeof(tBTA_DM_API_SEARCH))) != NULL)
-
{
-
memset(p_msg, 0, sizeof(tBTA_DM_API_SEARCH));
-
p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
-
memcpy(&p_msg->inq_params, p_dm_inq, sizeof(tBTA_DM_INQ)); //将这个inq复制到了inq_params中
-
p_msg->services = services;
-
p_msg->p_cback = p_cback;
-
p_msg->rs_res = BTA_DM_RS_NONE;
-
bta_sys_sendmsg(p_msg);
-
}
-
}
其作用是调用bta_sys_sendmsg是向btu_task发送一个命令:p_msg->hdr.event = BTA_DM_API_SEARCH_EVT,参数是:inq_params
2.4 在stack/btu/btu_task.c中
-
BTU_API UINT32 btu_task (UINT32 param)
-
{
-
event = GKI_wait (0xFFFF, 0); //从GKI_wait返回的event是4,这个不重要不管它了
-
if (event & TASK_MBOX_2_EVT_MASK)
-
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL) //从这里面读取的才是真正发送的msg
-
bta_sys_event(p_msg); //进行msg的处理,这里的msg才是BTA_DmSearch中发送的msg
-
}
2.5在bta/sys/bta_sys_main.c中
-
BTA_API void bta_sys_event(BT_HDR *p_msg)
-
{
-
id = (UINT8) (p_msg->event >> 8);
-
if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))
-
{
-
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
-
}
-
}
又一个函数指针数组,那么这个evt_hdlr是在哪个地方初始化的呢?
2.6.evt_hdlr的初始化
在
bta/dm/bta_dm_api.c中
-
static const tBTA_SYS_REG bta_dm_search_reg =
-
{
-
bta_dm_search_sm_execute,
-
bta_dm_search_sm_disable
-
};
-
-
tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback)
-
{
-
bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );
-
}
下面就进入函数bta_dm_search_sm_execute
2.7 在bta/dm/bta_dm_main.c中,此时的msg还是BTA_DmSearch中发送的msg
-
BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg)
-
{
-
tBTA_DM_ST_TBL state_table;
-
UINT8 action;
-
int i;
-
state_table = bta_dm_search_st_tbl[bta_dm_search_cb.state];
-
bta_dm_search_cb.state = state_table[p_msg->event & 0x00ff][BTA_DM_SEARCH_NEXT_STATE];
-
-
for (i = 0; i < BTA_DM_SEARCH_ACTIONS; i++)
-
{
-
if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_DM_SEARCH_IGNORE)
-
{
-
(*bta_dm_search_action[action])( (tBTA_DM_MSG*) p_msg); //为什么要搞得这么复杂?
-
}
-
else
-
{
-
break;
-
}
-
}
-
return TRUE;
-
}
这个函数指针数组看起来很复杂,但实际执行起来就是调用了bta_dm_search_action[0],
即: bta_dm_search_start
2.8 在bta/dm/bta_dm_act.c中
-
void bta_dm_search_start (tBTA_DM_MSG *p_data)
-
{
-
bta_dm_search_cb.p_search_cback = p_data->search.p_cback;
-
bta_dm_search_cb.services = p_data->search.services;
-
-
result.status = BTM_StartInquiry( (tBTM_INQ_PARMS*)&p_data->search.inq_params,
-
bta_dm_inq_results_cb,
-
(tBTM_CMPL_CB*) bta_dm_inq_cmpl_cb);
-
-
if (result.status != BTM_CMD_STARTED)
-
{
-
result.num_resp = 0;
-
bta_dm_inq_cmpl_cb ((void *)&result);
-
}
-
}
a.发送的msg是一个tBTA_DM_API_SEARCH结构体,
而tBTA_DM_API_SEARCH结构体又属于
tBTA_DM_MSG(enum)类型的search,
所以这儿就用了
p_data
->search
来代替msg,但这个msg所指的内容,还是
BTA_DmSearch所发送的msg
b. 同时BTM_StartInquiry
中的第一个参数中inq_params,也就是
btif_dm_start_discovery发送的参数
2.9 在stack/btm/btm_inq.c中
-
tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p_results_cb,
-
tBTM_CMPL_CB *p_cmpl_cb)
-
{
-
tBTM_STATUS status;
-
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
-
-
if (p_inq->inq_active || p_inq->inqfilt_active)
-
return (BTM_BUSY);
-
-
if (!BTM_IsDeviceUp())
-
return (BTM_WRONG_MODE);
-
-
if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_GENERAL_INQUIRY &&
-
(p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_LIMITED_INQUIRY)
-
return (BTM_ILLEGAL_VALUE);
-
-
p_inq->inqparms = *p_inqparms;
-
p_inq->inqparms.mode = (UINT8)(1 << (p_inqparms->mode & BTM_BR_INQUIRY_MASK));
-
p_inq->state = BTM_INQ_ACTIVE_STATE;
-
p_inq->p_inq_cmpl_cb = p_cmpl_cb;
-
p_inq->p_inq_results_cb = p_results_cb;
-
p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
-
p_inq->inq_active = (UINT8)(1 << (p_inqparms->mode & BTM_BR_INQUIRY_MASK));
-
-
switch (p_inqparms->filter_cond_type)
-
{
-
case BTM_CLR_INQUIRY_FILTER:
-
p_inq->state = BTM_INQ_SET_FILT_STATE;
-
break;
-
-
case BTM_FILTER_COND_DEVICE_CLASS:
-
case BTM_FILTER_COND_BD_ADDR:
-
p_inq->state = BTM_INQ_CLR_FILT_STATE;
-
p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
-
break;
-
-
default:
-
return (BTM_ILLEGAL_VALUE);
-
}
-
-
if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED)
-
p_inq->state = BTM_INQ_INACTIVE_STATE;
-
return (status);
-
}
3.0 与/dev/ttyS0进行通信
btm_set_inq_event_filter
-->btsnd_hcic_set_event_filter
-->btu_hcif_send_cmd
--> HCI_CMD_TO_LOWER
--> bte_main_hci_send // 发送了一个msg
--> bt_hc_worker_thread //接收者
--> hci_h4_send_msg //向/dev/ttyS2写入
-
void hci_h4_send_msg(HC_BT_HDR *p_msg)
-
{
-
bytes_to_send = p_msg->len + 1;
-
//下面就是向/dev/ttyS2写入msg
-
bytes_sent = userial_write(event,(uint8_t *) p, bytes_to_send);
-
return;
-
}
当/dev/ttyS2有数据返回时,其监听线程会从select_read中返回
在hci/src/userial.c中
-
static void *userial_read_thread(void *arg)
-
{
-
while (userial_running)
-
{
-
rx_length = select_read(userial_cb.fd, p, READ_LIMIT);
-
if (rx_length > 0)
-
{
-
p_buf->len = (uint16_t)rx_length;
-
utils_enqueue(&(userial_cb.rx_q), p_buf);
-
bthc_signal_event(HC_EVENT_RX);
-
}
-
}
-
return NULL; // Compiler friendly
-
}
select_read不仅监听,当有数据时还会读取数据,当数据读取后会返回,
并用信号HC_EVENT_RX唤醒线程bt_hc_worker_thread
在hci/src/bt_hci_bdroid.c中
-
static void *bt_hc_worker_thread(void *arg)
-
{
-
if (events & HC_EVENT_RX)
-
p_hci_if->rcv();
-
}
又会调用hci/src/hci_h4.c中的hci_h4_receive_msg
当hci_h4_receive_msg中接收完所有的msg之后
-
uint16_t hci_h4_receive_msg(void)
-
{
-
if (msg_received)
-
{
-
if ((bt_hc_cbacks) && (intercepted == FALSE))
-
bt_hc_cbacks->data_ind((TRANSAC) p_cb->p_rcv_msg, \
-
(char *) (p_cb->p_rcv_msg + 1), p_cb->p_rcv_msg->len + BT_HC_HDR_SIZE);
-
}
-
}
这个bt_hc_cbacks->data_ind就是调用main/bte_main.c中的data_ind
而main/bte_main.c中的data_ind就是发送了一个GKI_send_msg给BTU_TASK
在stack/./btu/btu_task.c中btu_task
btu_task收到了这个BT_EVT_TO_BTU_HCI_EVT,然后会调用
stack/./btu/btu_hcif.c:btu_hcif_process_event
--> btu_hcif_command_status_evt //当收到状态改变消息时会调用这个
--> btu_hcif_inquiry_rssi_result_evt //当查找到设备时会调用这个(buf中是以字符串形式存着:mac地址,类型等信息)
--> btm_process_inq_results //解析字符串,分析出bd_addr, dev_class等信息
--> bta_dm_inq_results_cb //bta/dm/bta_dm_act.c
--> BTM_InqDbRead //stack/btm/btm_inq.c 在记录的database中查看这个mac的记录是否存在
--> 回调函数bte_search_devices_evt //这个就是在刚开始
btif_dm_start_discovery时传来的回调函数
在main/../btif/src/btif_dm.c中
-
static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
-
{
-
btif_transfer_context (btif_dm_search_devices_evt , (UINT16) event, (void *)p_data, param_len,
-
(param_len > sizeof(tBTA_DM_SEARCH)) ? search_devices_copy_cb : NULL);
-
}
在./btif/src/btif_dm.c中是回调函数
-
static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
-
{
-
btif_storage_add_remote_device(&bdaddr, num_properties, properties);
-
HAL_CBACK(bt_hal_cbacks, device_found_cb, num_properties, properties);
-
}
把数据保存在cfg中,但这时候还不会写入/data/misc/bluedroid/bt_config.xml中,当与设备进行connect之后才会写入
最后调用HAL_CBACK,即调用./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中的函数,
./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp又会调用java层的方法。
然后在CachedBluetoothDevice中添加了一个设备
附一: 与上层的交互
btif_dm_cb_create_bond时,会有状态变化:由原先的BT_BOND_STATE_NONE变为BT_BOND_STATE_BONDING
此时会调用bond_state_changed,上层就会收到bond_state_changed的消息,下面详细分析一下:
1.1 在btif/src/btif_dm.c中
bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
-
static void bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr, bt_bond_state_t state)
-
{
-
HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
-
}
1.2 其中HAL_CBACK是一个宏
-
#define HAL_CBACK(P_CB, P_CBACK, ...)\
-
if (P_CB && P_CB->P_CBACK) { \
-
P_CB->P_CBACK(__VA_ARGS__); \
-
} \
-
else { \
-
ASSERTC(0, "Callback is NULL", 0); \
-
}
这儿展开后: bt_hal_cbacks
->bond_state_changed_cb
(status, bd_addr, state);
其中status=BT_STATUS_SUCCESS,说明通知上层状态改变成功
bd_addr: 要pair的设备mac地址
state: 改变后的状态BT_BOND_STATE_BONDING
1.3 bt_hal_cbacks
是如何初始化的呢?
来到bt_hal_cbacks
的初始化函数中
在btif/src/bluetooth.c中
-
static int init(bt_callbacks_t* callbacks )
-
{
-
/* store reference to user callbacks */
-
bt_hal_cbacks = callbacks;
-
}
1.4这个callbacks是如何来的呢?答案是在apk的jni层调用的
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
-
static bool initNative(JNIEnv* env, jobject obj) {
-
sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
-
if (sBluetoothInterface) {
-
sBluetoothInterface->init(&sBluetoothCallbacks);
-
return JNI_FALSE;
-
}
上面这个init就是调用bluetooth.default.so中的init,其中
sBluetoothCallbacks
的定义
-
bt_callbacks_t sBluetoothCallbacks = {
-
sizeof(sBluetoothCallbacks),
-
adapter_state_change_callback,
-
adapter_properties_callback,
-
remote_device_properties_callback,
-
device_found_callback,
-
discovery_state_changed_callback,
-
pin_request_callback,
-
ssp_request_callback,
-
bond_state_changed_callback,
-
acl_state_changed_callback,
-
callback_thread_event,
-
};
1.5
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
-
static void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
-
bt_bond_state_t state) {
-
jbyteArray addr;
-
addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
-
-
callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
-
//这儿是c调用java的方法
-
callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status, addr, (jint)state);
-
checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
-
callbackEnv->DeleteLocalRef(addr);
-
}
其中在classInitNative中被初始化:
method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V");
原来这儿是调用了java的bondStateChangeCallback这个方法。
1.6 java
在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/JniCallbacks.java中
-
void bondStateChangeCallback(int status, byte[] address, int newState) {
-
mBondStateMachine.bondStateChangeCallback(status, address, newState);
-
}
1.7
在 ./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java中
-
void bondStateChangeCallback(int status, byte[] address, int newState) {
-
BluetoothDevice device = mRemoteDevices.getDevice(address);
-
infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device + " newState: " + newState);
-
-
Message msg = obtainMessage(BONDING_STATE_CHANGE);
-
msg.obj = device;
-
-
if (newState == BOND_STATE_BONDED)
-
msg.arg1 = BluetoothDevice.BOND_BONDED;
-
else if (newState == BOND_STATE_BONDING)
-
msg.arg1 = BluetoothDevice.BOND_BONDING;
-
else
-
msg.arg1 = BluetoothDevice.BOND_NONE;
-
msg.arg2 = status;
-
-
sendMessage(msg);
-
}