进入到android设置界面并打开蓝牙,扫描会自动开始。
下面我们从android蓝牙设置界面开始分析:
蓝牙开关按钮
BluetoothSettings.java (packages\apps\settings\src\com\android\settings\bluetooth)
public final class BluetoothSettings extends DeviceListPreferenceFragment implements Indexable
private BluetoothEnabler mBluetoothEnabler;
public void onActivityCreated(Bundle savedInstanceState)
mBluetoothEnabler = new BluetoothEnabler(activity, mSwitchBar);
mBluetoothEnabler.setupSwitchBar();
mSwitchBar.show(); // 显示蓝牙开关按钮
打开蓝牙
BluetoothEnabler.java (packages\apps\settings\src\com\android\settings\bluetooth)
onSwitchChanged()
mLocalAdapter.setBluetoothEnabled(isChecked);
打开蓝牙过程请参考我前面文章Android BlueDroid蓝牙enable过程,这里不做描述。蓝牙打开成功的状态会从协议栈回调上来,调用onBluetoothStateChanged,最终调用startScanning。
public void onBluetoothStateChanged(int bluetoothState) {
super.onBluetoothStateChanged(bluetoothState);
updateContent(bluetoothState);
}
private void updateContent(int bluetoothState) {
final PreferenceScreen preferenceScreen = getPreferenceScreen();
int messageId = 0;
switch (bluetoothState) {
case BluetoothAdapter.STATE_ON:
preferenceScreen.removeAll();
preferenceScreen.setOrderingAsAdded(true);
mDevicePreferenceMap.clear();
mPairedDevicesCategory.removeAll();
mAvailableDevicesCategory.removeAll();
if (!mInitialScanStarted) {
startScanning(); //启动扫描
mLocalAdapter.startScanning(true);
}
}
}
LocalBluetoothAdapter.java (packages\apps\settings\src\com\android\settings\bluetooth)
void startScanning(boolean force) {
if (!mAdapter.isDiscovering()) {
if (mAdapter.startDiscovery()) {
mLastScan = System.currentTimeMillis();
}
}
}
BluetoothAdapter.java (frameworks\base\core\java\android\bluetooth)
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的定义:
private IBluetooth mService;
mService通过binder调用startDiscovery。
AdapterService.java(packages\apps\bluetooth\src\com\android\bluetooth\btservice)
public class AdapterService extends Service {
boolean startDiscovery() {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
return startDiscoveryNative();
}
private static class AdapterServiceBinder extends IBluetooth.Stub {
public boolean startDiscovery() {
AdapterService service = getService();
if (service == null) return false;
return service.startDiscovery();
}
}
}
查看startDiscoveryNative的定义,可以看到它是一个native方法:
private native boolean startDiscoveryNative();
com_android_bluetooth_btservice_AdapterService.cpp (packages\apps\bluetooth\jni)
static jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
int ret = sBluetoothInterface->start_discovery();
}
查看定义
static const bt_interface_t *sBluetoothInterface = NULL;
查找sBluetoothInterface的赋值,发现它加载了一个bluetooth.defualt.so模块:
#define BT_HARDWARE_MODULE_ID "bluetooth"
#define BT_STACK_MODULE_ID "bluetooth"
#define BT_STACK_TEST_MODULE_ID "bluetooth_test"
static void classInitNative(JNIEnv* env, jclass clazz)
{
hw_module_t* module;
const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID :
BT_STACK_TEST_MODULE_ID);
// 加载btStack模块 bluetooth.defualt.so
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) {
//最终转换为btStack结构体
bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
// sBluetoothInterface 赋值
sBluetoothInterface = btStack->get_bluetooth_interface();
} else {
ALOGE("Error while opening Bluetooth library");
}
} else {
ALOGE("No Bluetooth Library found");
}
}
查看hw_get_module的定义:
Hardware.c (hardware\libhardware)
/** Base path of the hal modules */
#if defined(__LP64__)
#define HAL_LIBRARY_PATH1 "/system/lib64/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"
#else
#define HAL_LIBRARY_PATH1 "/system/lib/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
#endif
/*
* Check if a HAL with given name and subname exists, if so return 0, otherwise
* otherwise return negative. On success path will contain the path to the HAL.
*/
static int hw_module_exists(char *path, size_t path_len, const char *name,
const char *subname)
{
snprintf(path, path_len, "%s/%s.%s.so",
HAL_LIBRARY_PATH2, name, subname);
if (access(path, R_OK) == 0)
return 0;
snprintf(path, path_len, "%s/%s.%s.so",
HAL_LIBRARY_PATH1, name, subname);
if (access(path, R_OK) == 0)
return 0;
return -ENOENT;
}
int hw_get_module(const char *id, const struct hw_module_t **module)
hw_get_module_by_class(id, NULL, module);
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
char path[PATH_MAX];
char name[PATH_MAX];
strlcpy(name, class_id, PATH_MAX);
/* Nothing found, try the default */
// 查找模块 bluetooth.default.so
if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
goto found;
}
found:
return load(class_id, path, module);
void *handle;
struct hw_module_t *hmi;
handle = dlopen(path, RTLD_NOW);
/* Get the address of the struct hal_module_info. */
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
}
Bluetooth.c (external\bluetooth\bluedroid\btif\src)
我们知道BlueDroid协议栈代码编译会 生成bluetooth.defualt.so模块,代码在external\bluetooth\bluedroid目录。
static const bt_interface_t bluetoothInterface
start_discovery,
btif_dm_start_discovery();
Btif_dm.c (external\bluetooth\bluedroid\btif\src)
bt_status_t btif_dm_start_discovery(void)
inq_params.mode = BTA_DM_GENERAL_INQUIRY;
inq_params.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION; // 扫描时间10*1.28 s
inq_params.max_resps = BTIF_DM_DEFAULT_INQ_MAX_RESULTS;
inq_params.report_dup = TRUE;
inq_params.filter_type = BTA_DM_INQ_CLR;
BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
memcpy(&p_msg->inq_params, p_dm_inq, sizeof(tBTA_DM_INQ));
p_msg->services = services;
p_msg->p_cback = p_cback;
p_msg->rs_res = BTA_DM_RS_NONE;
bta_sys_sendmsg(p_msg);
btif_dm_start_discovery调用BTA_DmSearch,发送一个BTA_DM_API_SEARCH_EVT的消息,发出去的消息最后会在btu_task处理。
Bta_sys_main.c (external\bluetooth\bluedroid\bta\sys)
void bta_sys_sendmsg(void *p_msg)
{
GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);
GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
}
查看bta_sys_cb.task_id的赋值:
BTA_API void bta_sys_init(void)
bta_sys_cb.task_id = GKI_get_taskid();
bta_sys_init在btu_task中被调用,因此task_id 等于btu_task的task id,消息在btu_task中接收处理。
查看p_bta_sys_cfg->mbox的赋值:
// gki.h (external\bluetooth\bluedroid\gki\common)
/************************************************************************
** Mailbox definitions. Each task has 4 mailboxes that are used to
** send buffers to the task.
*/
#define TASK_MBOX_0 0
#define TASK_MBOX_1 1
#define TASK_MBOX_2 2
#define TASK_MBOX_3 3
#define NUM_TASK_MBOX 4
/************************************************************************
** Event definitions.
**
** There are 4 reserved events used to signal messages rcvd in task mailboxes.
** There are 4 reserved events used to signal timeout events.
** There are 8 general purpose events available for applications.
*/
#define MAX_EVENTS 16
#define TASK_MBOX_0_EVT_MASK 0x0001
#define TASK_MBOX_1_EVT_MASK 0x0002
#define TASK_MBOX_2_EVT_MASK 0x0004
#define TASK_MBOX_3_EVT_MASK 0x0008
//bta_sys.h (external\bluetooth\bluedroid\bta\sys)
/* system manager configuration structure */
typedef struct
{
UINT16 mbox_evt; /* GKI mailbox event */
UINT8 mbox; /* GKI mailbox id */
UINT8 timer; /* GKI timer id */
UINT8 trace_level; /* initial trace level */
} tBTA_SYS_CFG;
// bta_sys_cfg.c (external\bluetooth\bluedroid\bta\sys)
/* GKI task mailbox event for BTA. */
#define BTA_MBOX_EVT TASK_MBOX_2_EVT_MASK
/* GKI task mailbox for BTA. */
#define BTA_MBOX TASK_MBOX_2
const tBTA_SYS_CFG bta_sys_cfg =
{
BTA_MBOX_EVT, /* GKI mailbox event */
BTA_MBOX, /* GKI mailbox id */
BTA_TIMER, /* GKI timer id */
APPL_INITIAL_TRACE_LEVEL /* initial trace level */
};
tBTA_SYS_CFG *p_bta_sys_cfg = (tBTA_SYS_CFG *)&bta_sys_cfg;
所以p_bta_sys_cfg->mbox等于TASK_MBOX_2, EVENT_MASK(mbox)则等于TASK_MBOX_2_EVT_MASK。
btu_task.c (external\bluetooth\bluedroid\stack\btu)
/*******************************************************************************
**
** Function btu_task
**
** Description This is the main task of the Bluetooth Upper Layers unit.
** It sits in a loop waiting for messages, and dispatches them
** to the appropiate handlers.
**
** Returns should never return
**
*******************************************************************************/
BTU_API UINT32 btu_task (UINT32 param)
{
UINT16 event;
BT_HDR *p_msg;
UINT8 i;
UINT16 mask;
BOOLEAN handled;
/* Initialize the mandatory core stack control blocks
(BTU, BTM, L2CAP, and SDP)
*/
btu_init_core();
/* Initialize any optional stack components */
BTE_InitStack();
#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
bta_sys_init(); // bta init
#endif
/* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
/* Wait for, and process, events */
for (;;)
{
event = GKI_wait (0xFFFF, 0);
if (event & TASK_MBOX_0_EVT_MASK)
{
/* Process all messages in the queue */
}
if (event & TIMER_0_EVT_MASK) {
}
#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
if (event & TASK_MBOX_2_EVT_MASK)
{
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
{
bta_sys_event(p_msg);
UINT8 id;
BOOLEAN freebuf = TRUE;
//event等于BTA_DM_API_SEARCH_EVT,id等于BTA_ID_DM_SEARCH,对应的cb函数bta_dm_search_reg(在btif_task->BTA_EnableBluetooth注册)
id = (UINT8) (p_msg->event >> 8);
//调用bta_dm_search_reg的bta_dm_search_sm_execute函数
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
if (event & TIMER_1_EVT_MASK)
{
bta_sys_timer_update();
}
#endif
if (event & TIMER_3_EVT_MASK) {
}
if (event & EVENT_MASK(APPL_EVT_7))
break;
}
return(0);
}
bta_dm_main.c (external\bluetooth\bluedroid\bta\dm)
bta_dm_search_sm_execute在bta_dm_search_action函数列表中取出BTA_DM_API_SEARCH对应的函数bta_dm_search_start并调用。
/* action function list */
const tBTA_DM_ACTION bta_dm_search_action[] =
{
bta_dm_search_start, /* 0 BTA_DM_API_SEARCH */
bta_dm_search_cancel, /* 1 BTA_DM_API_SEARCH_CANCEL */
bta_dm_discover, /* 2 BTA_DM_API_DISCOVER */
bta_dm_inq_cmpl, /* 3 BTA_DM_INQUIRY_CMPL */
bta_dm_rmt_name, /* 4 BTA_DM_REMT_NAME */
bta_dm_sdp_result, /* 5 BTA_DM_SDP_RESULT */
bta_dm_search_cmpl, /* 6 BTA_DM_SEARCH_CMPL */
bta_dm_free_sdp_db, /* 7 BTA_DM_FREE_SDP_DB */
bta_dm_disc_result, /* 8 BTA_DM_DISC_RESULT */
bta_dm_search_result, /* 9 BTA_DM_SEARCH_RESULT */
bta_dm_queue_search, /* 10 BTA_DM_QUEUE_SEARCH */
bta_dm_queue_disc, /* 11 BTA_DM_QUEUE_DISC */
bta_dm_search_clear_queue, /* 12 BTA_DM_SEARCH_CLEAR_QUEUE */
bta_dm_search_cancel_cmpl, /* 13 BTA_DM_SEARCH_CANCEL_CMPL */
bta_dm_search_cancel_notify, /* 14 BTA_DM_SEARCH_CANCEL_NOTIFY */
bta_dm_search_cancel_transac_cmpl, /* 15 BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL */
bta_dm_disc_rmt_name, /* 16 BTA_DM_DISC_RMT_NAME */
bta_dm_di_disc /* 17 BTA_DM_API_DI_DISCOVER */
#if BLE_INCLUDED == TRUE
,bta_dm_close_gatt_conn
#endif
};
BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg)
{
tBTA_DM_ST_TBL state_table;
UINT8 action;
int i;
/* look up the state table for the current state */
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];
/* execute action functions */
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_act.c (external\bluetooth\bluedroid\bta\dm)
void bta_dm_search_start (tBTA_DM_MSG *p_data)
{
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);
}
Btm_inq.c (external\bluetooth\bluedroid\stack\btm)
BTM_StartInquiry函数的查询过程包括BLE和BR/EDR两种模式的查询,我们这里只关注BLE模式。p_inq->p_inq_results_cb是扫描回调指向bta_dm_inq_results_cb,扫描到广播后bta_dm_inq_results_cb将被调用。
tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
{
/* Save the inquiry parameters to be used upon the completion of setting/clearing the inquiry filter */
p_inq->inqparms = *p_inqparms;
/* Initialize the inquiry variables */
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 = p_inqparms->mode;
#if BLE_INCLUDED == TRUE
/* start LE inquiry */
status = btm_ble_start_inquiry((UINT8)(p_inqparms->mode & BTM_BLE_INQUIRY_MASK), p_inqparms->duration)) != BTM_CMD_STARTED):
return status;
#endif
/* start br/edr inquiry */
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;
}
Btm_ble_gap.c (external\bluetooth\bluedroid\stack\btm)
tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration)
{
if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
{
btm_update_scanner_filter_policy(SP_ADV_ALL);
status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
}
if (status == BTM_CMD_STARTED)
{
p_inq->inq_active |= mode;
p_ble_cb->scan_activity |= mode;
BTM_TRACE_DEBUG("btm_ble_start_inquiry inq_active = 0x%02x", p_inq->inq_active);
if (duration != 0)
{
/* 启动inquiry timer */
btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration);
}
}
}
btm_ble_start_inquiry主要做了三件事:
1)设置扫描参数: btm_update_scanner_filter_policy(SP_ADV_ALL)
2)启动扫描: btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
3)启动扫描定时器,定时器超时后在btu_task中关闭扫描:
btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration)
下面分别对这三件事进行跟踪:
Btm_ble_bgconn.c (external\bluetooth\bluedroid\stack\btm)
void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy)
{
p_inq->sfp = scan_policy;
p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
(UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
(UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
scan_policy);
}
Hciblecmds.c (external\bluetooth\bluedroid\stack\hcic)
BOOLEAN btsnd_hcic_ble_set_scan_params (UINT8 scan_type,
UINT16 scan_int, UINT16 scan_win,
UINT8 addr_type_own, UINT8 scan_filter_policy)
{
BT_HDR *p;
UINT8 *pp;
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM)) == NULL)
return (FALSE);
pp = (UINT8 *)(p + 1); // 指向 data[]
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM;
p->offset = 0;
UINT16_TO_STREAM (pp, HCI_BLE_WRITE_SCAN_PARAMS);
UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM);
UINT8_TO_STREAM (pp, scan_type);
UINT16_TO_STREAM (pp, scan_int);
UINT16_TO_STREAM (pp, scan_win);
UINT8_TO_STREAM (pp, addr_type_own);
UINT8_TO_STREAM (pp, scan_filter_policy);
/* 发送hci命令 */
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
}
Btm_ble_gap.c (external\bluetooth\bluedroid\stack\btm)
tBTM_STATUS btm_ble_start_scan (UINT8 filter_enable)
{
tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS status = BTM_CMD_STARTED;
/* start scan, disable duplicate filtering */
if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, filter_enable)) {
status = BTM_NO_RESOURCES;
btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN;
}
return status;
}
Hciblecmds.c (external\bluetooth\bluedroid\stack\hcic)
BOOLEAN btsnd_hcic_ble_set_scan_enable (UINT8 scan_enable, UINT8 duplicate)
{
BT_HDR *p;
UINT8 *pp;
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE)) == NULL)
return (FALSE);
pp = (UINT8 *)(p + 1); // 指向 data[]
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE;
p->offset = 0;
UINT16_TO_STREAM (pp, HCI_BLE_WRITE_SCAN_ENABLE);
UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE);
UINT8_TO_STREAM (pp, scan_enable);
UINT8_TO_STREAM (pp, duplicate);
/* 发送hci命令 */
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
}
void btu_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
{
BT_HDR *p_msg;
GKI_disable();
//如果btu定时器轮询停止,则重新启动计数轮询,轮询周期是1s
/* if timer list is currently empty, start periodic GKI timer */
if (btu_cb.timer_queue.p_first == NULL)
{
/* if timer starts on other than BTU task */
if (GKI_get_taskid() != BTU_TASK)
{
/* post event to start timer in BTU task */
if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL)
{
p_msg->event = BT_EVT_TO_START_TIMER;
GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
}
}
else
{
/* Start free running 1 second timer for list management */
GKI_start_timer (TIMER_0, GKI_SECS_TO_TICKS (1), TRUE);
}
}
GKI_remove_from_timer_list (&btu_cb.timer_queue, p_tle);
p_tle->event = type;
p_tle->ticks = timeout;
p_tle->ticks_initial = timeout;
//将定时器添加到GKI定时器列表
GKI_add_to_timer_list (&btu_cb.timer_queue, p_tle);
GKI_enable();
}
如果btu task的定时器队列为空,说明当前btu task的计时轮询已经停止,所以要启动btu task的计时轮询,轮询周期是1s。最后将定时器添加到GKI定时器列表。
那么定时器超时在哪里执行? 我们找到了GKI_init函数:
Gki_ulinux.c (external\bluetooth\bluedroid\gki\ulinux)
从下面的代码可以看出定时器到期执行函数为bt_alarm_cb:
void GKI_init(void)
{
pthread_mutexattr_t attr;
tGKI_OS *p_os;
memset (&gki_cb, 0, sizeof (gki_cb));
gki_buffer_init();
gki_timers_init();
alarm_service_init();
gki_cb.com.OSTicks = (UINT32) times(0);
pthread_mutexattr_init(&attr);
p_os = &gki_cb.os;
pthread_mutex_init(&p_os->GKI_mutex, &attr);
struct sigevent sigevent;
memset(&sigevent, 0, sizeof(sigevent));
sigevent.sigev_notify = SIGEV_THREAD;
sigevent.sigev_notify_function = (void (*)(union sigval))bt_alarm_cb;
sigevent.sigev_value.sival_ptr = NULL;
if (timer_create(CLOCK_REALTIME, &sigevent, &posix_timer) == -1) {
ALOGE("%s unable to create POSIX timer: %s", __func__, strerror(errno));
timer_created = false;
} else {
timer_created = true;
}
}
/** Callback from Java thread after alarm from AlarmService fires. */
static void bt_alarm_cb(void *data)
{
GKI_timer_update(ticks_taken > alarm_service.ticks_scheduled
? ticks_taken : alarm_service.ticks_scheduled);
}
Gki_time.c (external\bluetooth\bluedroid\gki\common) 25288 2017/12/14
void GKI_timer_update (INT32 ticks_since_last_update)
{
UINT8 task_id;
long next_expiration;
gki_cb.com.OSTicks += ticks_since_last_update;
gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
/* Don't allow timer interrupt nesting */
if (gki_cb.com.timer_nesting)
return;
gki_cb.com.timer_nesting = 1;
next_expiration = GKI_NO_NEW_TMRS_STARTED;
gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
GKI_disable();
/* Check for OS Task Timers */
for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
{
if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
{
gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
if (gki_cb.com.OSWaitTmr[task_id] <= 0)
{
/* Timer Expired */
gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
}
}
#if (GKI_NUM_TIMERS > 0)
/* If any timer is running, decrement */
if (gki_cb.com.OSTaskTmr0[task_id] > 0)
{
gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
{
/* Reload timer and set Timer 0 Expired event mask */
gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
GKI_send_event (task_id, TIMER_0_EVT_MASK);
}
}
/* Check to see if this timer is the next one to expire */
if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
next_expiration = gki_cb.com.OSTaskTmr0[task_id];
#endif
// 此处省略TIMER_1,TIMER_2,TIMER_3相关处理
}
/* Set the next timer experation value if there is one to start */
if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
{
gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
}
else
{
gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
}
// Set alarm service for next alarm.
alarm_service_reschedule();
GKI_enable();
gki_cb.com.timer_nesting = 0;
return;
}
如果OSTaskTmr小于0,表示定时器已经超时,这里调用GKI_send_event发送了一个event出去。
Btu_task.c (external\bluetooth\bluedroid\stack\btu)
BTU_API UINT32 btu_task (UINT32 param)
{
/* Wait for, and process, events */
for (;;)
{
event = GKI_wait (0xFFFF, 0);
if (event & TIMER_0_EVT_MASK) {
GKI_update_timer_list (&btu_cb.timer_queue, 1);
while (!GKI_timer_queue_is_empty(&btu_cb.timer_queue)) {
TIMER_LIST_ENT *p_tle = GKI_timer_getfirst(&btu_cb.timer_queue);
if (p_tle->ticks != 0)
break;
GKI_remove_from_timer_list(&btu_cb.timer_queue, p_tle);
switch (p_tle->event) {
#if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
case BTU_TTYPE_BLE_INQUIRY:
case BTU_TTYPE_BLE_GAP_LIM_DISC:
case BTU_TTYPE_BLE_GAP_FAST_ADV:
case BTU_TTYPE_BLE_OBSERVE:
btm_ble_timeout(p_tle);
break;
case BTU_TTYPE_ATT_WAIT_FOR_RSP:
gatt_rsp_timeout(p_tle);
break;
}
}
}
#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
if (event & TIMER_2_EVT_MASK)
{
btu_process_quick_timer_evt();
}
#endif
#if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
if (event & TIMER_1_EVT_MASK)
{
bta_sys_timer_update();
}
#endif
if (event & TIMER_3_EVT_MASK) {
BTM_TRACE_API("Received oneshot timer event complete");
}
}
return(0);
}
启动扫描的定时器event类型是BTU_TTYPE_BLE_INQUIRY,btm_ble_timeout被调用,最终调用btm_ble_stop_scan停止扫描。
Btm_ble_gap.c (external\bluetooth\bluedroid\stack\btm)
void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
{
switch (p_tle->event)
{
case BTU_TTYPE_BLE_INQUIRY:
btm_ble_stop_inquiry();
btm_ble_stop_scan(); // 停止扫描
break;
}
}
至此启动扫描的三件事都已跟踪完成,现在我们继续分析。
设置扫描参数和启动扫描最后都是调用btu_hcif_send_cmd发送hci命令,
下面我们就对这个函数进行跟踪。
Btu_hcif.c (external\bluetooth\bluedroid\stack\btu)
/*******************************************************************************
**
** Function btu_hcif_send_cmd
**
** Description This function is called to check if it can send commands
** to the Host Controller. It may be passed the address of
** a packet to send.
**
** Returns void
**
*******************************************************************************/
void btu_hcif_send_cmd (UINT8 controller_id, BT_HDR *p_buf)
{
tHCI_CMD_CB * p_hci_cmd_cb = &(btu_cb.hci_cmd_cb[controller_id]);
/* If there are already commands in the queue, then enqueue this command */
if ((p_buf) && (p_hci_cmd_cb->cmd_xmit_q.count))
{
GKI_enqueue (&(p_hci_cmd_cb->cmd_xmit_q), p_buf);
p_buf = NULL;
}
/* Allow for startup case, where no acks may be received */
if ( ((controller_id == LOCAL_BR_EDR_CONTROLLER_ID)
&& (p_hci_cmd_cb->cmd_window == 0)
&& (btm_cb.devcb.state == BTM_DEV_STATE_WAIT_RESET_CMPLT)) )
{
p_hci_cmd_cb->cmd_window = p_hci_cmd_cb->cmd_xmit_q.count + 1;
}
/* See if we can send anything */
while (p_hci_cmd_cb->cmd_window != 0)
{
if (!p_buf)
p_buf = (BT_HDR *)GKI_dequeue (&(p_hci_cmd_cb->cmd_xmit_q));
if (p_buf)
{
btu_hcif_store_cmd(controller_id, p_buf);
p_hci_cmd_cb->cmd_window--;
if (controller_id == LOCAL_BR_EDR_CONTROLLER_ID)
{
HCI_CMD_TO_LOWER(p_buf);
}
else
{
GKI_freebuf(p_buf);;
}
p_buf = NULL;
}
else
break;
}
if (p_buf)
GKI_enqueue (&(p_hci_cmd_cb->cmd_xmit_q), p_buf);
}
查看HCI_CMD_TO_LOWER定义:
/* Sends an HCI command received from the upper stack to the BD/EDR HCI transport. */
#ifndef HCI_CMD_TO_LOWER
#define HCI_CMD_TO_LOWER(p) bte_main_hci_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_CMD);
#endif
Bte_main.c (external\bluetooth\bluedroid\main)
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);
}
}
查看bt_hc_if的赋值:
static void bte_main_in_hw_init(void)
{
// bt_hci_bdroid.c中的 bluetoothHCLibInterface
if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \
== NULL)
{
APPL_TRACE_ERROR("!!! Failed to get BtHostControllerInterface !!!");
}
memset(&preload_retry_cb, 0, sizeof(bt_preload_retry_cb_t));
}
Bt_hci_bdroid.c (external/bluetooth/bluedroid/hci/src)
void bthc_tx(HC_BT_HDR *buf) {
pthread_mutex_lock(&hc_cb.worker_thread_lock);
if (hc_cb.worker_thread) {
if (buf)
utils_enqueue(&tx_q, buf); // 将buf放入队列tx_q,给到event_tx处理
// 构造一个work_item_t并放入thread->work_queue,
// worker_thread的线程处理函数run_thread会从thread->work_queue中取出这个item,
// 并调用回调函数event_tx
thread_post(hc_cb.worker_thread, event_tx, NULL);
}
pthread_mutex_unlock(&hc_cb.worker_thread_lock);
}
/** Transmit frame */
static int transmit_buf(TRANSAC transac, UNUSED_ATTR char *p_buf, UNUSED_ATTR int len) {
bthc_tx((HC_BT_HDR *)transac);
return BT_HC_STATUS_SUCCESS;
}
static const bt_hc_interface_t bluetoothHCLibInterface = {
sizeof(bt_hc_interface_t),
init,
set_power,
lpm,
preload,
postload,
transmit_buf,
logging,
cleanup,
tx_hc_cmd,
};
const bt_hc_interface_t *bt_hc_get_interface(void)
{
return &bluetoothHCLibInterface;
}
下面主要看下实际的发送函数event_tx:
event_tx里面有个while循环,通过utils_getnext从tx_q获取所有消息并保存到sending_msg_que,消息的个数为sending_msg_count。消息取完后跳出while,使用一个for循环取出所有要发送的消息并调用 p_hci_if->send发送出去。
注意: 如果我们已用完控制器的未用HCI命令信用(通常为1),则跳过队列中的所有HCI命令数据包。
static void event_tx(UNUSED_ATTR void *context) {
/*
* We will go through every packets in the tx queue.
* Fine to clear tx_cmd_pkts_pending.
*/
tx_cmd_pkts_pending = false;
HC_BT_HDR *sending_msg_que[64];
size_t sending_msg_count = 0;
int sending_hci_cmd_pkts_count = 0;
utils_lock();
HC_BT_HDR *p_next_msg = tx_q.p_first;
while (p_next_msg && sending_msg_count < ARRAY_SIZE(sending_msg_que))
{
// 注意: 如果我们已用完控制器的未用HCI命令信用(通常为1),
// 则跳过队列中的所有HCI命令数据包。
if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)
{
if (tx_cmd_pkts_pending ||
(sending_hci_cmd_pkts_count >= num_hci_cmd_pkts))
{
tx_cmd_pkts_pending = true;
p_next_msg = utils_getnext(p_next_msg); // 取出消息
continue;
}
sending_hci_cmd_pkts_count++; //增加消息计数sending_msg_count
}
HC_BT_HDR *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
sending_msg_que[sending_msg_count++] = p_msg;
}
utils_unlock();
for(size_t i = 0; i < sending_msg_count; i++)
p_hci_if->send(sending_msg_que[i]);
if (tx_cmd_pkts_pending)
BTHCDBG("Used up Tx Cmd credits");
}
p_hci_if在init函数中被赋值:
static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
extern tHCI_IF hci_mct_func_table;
p_hci_if = &hci_h4_func_table
Hci_h4.c (external\bluetooth\bluedroid\hci\src)
/******************************************************************************
** HCI H4 Services interface table
******************************************************************************/
const tHCI_IF hci_h4_func_table =
{
hci_h4_init,
hci_h4_cleanup,
hci_h4_send_msg,
hci_h4_send_int_cmd,
hci_h4_get_acl_data_length,
hci_h4_receive_msg
};
/*******************************************************************************
** Function hci_h4_send_msg
** Description Determine message type, set HCI H4 packet indicator, and
** send message through USERIAL driver
*******************************************************************************/
void hci_h4_send_msg(HC_BT_HDR *p_msg)
{
uint8_t type = 0;
uint16_t handle;
uint16_t bytes_to_send, lay_spec;
uint8_t *p = ((uint8_t *)(p_msg + 1)) + p_msg->offset;
uint16_t event = p_msg->event & MSG_EVT_MASK;//event类型
uint16_t sub_event = p_msg->event & MSG_SUB_EVT_MASK; // sub_event类型
uint16_t acl_pkt_size = 0, acl_data_size = 0;
uint16_t bytes_sent;
/* wake up BT device if its in sleep mode */
lpm_wake_assert();
if (event == MSG_STACK_TO_HC_HCI_ACL)
type = H4_TYPE_ACL_DATA;
else if (event == MSG_STACK_TO_HC_HCI_SCO)
type = H4_TYPE_SCO_DATA;
else if (event == MSG_STACK_TO_HC_HCI_CMD)
type = H4_TYPE_COMMAND;
if (sub_event == LOCAL_BR_EDR_CONTROLLER_ID)
{
acl_data_size = h4_cb.hc_acl_data_size;
acl_pkt_size = h4_cb.hc_acl_data_size + HCI_ACL_PREAMBLE_SIZE;
}
else
{
acl_data_size = h4_cb.hc_ble_acl_data_size;
acl_pkt_size = h4_cb.hc_ble_acl_data_size + HCI_ACL_PREAMBLE_SIZE;
}
/* Do all the first chunks */
while (p_msg->len > acl_pkt_size)
{
/* Check if sending ACL data that needs fragmenting */
if ((event == MSG_STACK_TO_HC_HCI_ACL) && (p_msg->len > acl_pkt_size))
{
bytes_to_send = acl_pkt_size + 1;
/* 通过uart发送命令/数据 */
bytes_sent = userial_write(event,(uint8_t *) p,bytes_to_send);
write(userial_cb.fd, p_data + total, len);
/* 生成btsnoop追踪消息 */
btsnoop_capture(p_msg, false);
}
}
p = ((uint8_t *)(p_msg + 1)) + p_msg->offset - 1;
*p = type;
bytes_to_send = p_msg->len + 1;
/* 通过uart发送命令/数据 */
bytes_sent = userial_write(event,(uint8_t *) p, bytes_to_send);
write(userial_cb.fd, p_data + total, len);
/* 生成btsnoop追踪消息 */
btsnoop_capture(p_msg, false);
if (bt_hc_cbacks)
{
// 回调bte_main.c中的hc_cbacks->tx_result
bt_hc_cbacks->tx_result((TRANSAC) p_msg, (char *) (p_msg + 1), \
BT_HC_TX_SUCCESS);
}
return;
}
hci_h4_send_msg主要以下工作:
1)根据消息的event得到event和sub_event
2)根据event得到hci类型,根据sub_event得到acl_data_size和acl_packet_size
3)通过uart发送消息
4)生成btsnoop追踪数据
5)回调uart写成功状态,实际命令发送状态由userial_read_thread来完成。
Userial.c (external\bluetooth\bluedroid\hci\src)
uint16_t userial_write(uint16_t msg_id, const uint8_t *p_data, uint16_t len) {
UNUSED(msg_id);
uint16_t total = 0;
while (len) {
ssize_t ret = write(userial_cb.fd, p_data + total, len);
switch (ret) {
case -1:
ALOGE("%s error writing to serial port: %s", __func__, strerror(errno));
return total;
case 0: // don't loop forever in case write returns 0.
return total;
default:
total += ret;
len -= ret;
break;
}
send_byte_total+=total;
}
return total;
}
查看userial_cb.fd的赋值:
bool userial_open(userial_port_t port) {
// Call in to the vendor-specific library to open the serial port.
int fd_array[CH_MAX];
int num_ports = vendor_send_command(BT_VND_OP_USERIAL_OPEN, &fd_array);
userial_cb.fd = fd_array[0];
userial_cb.port = port;
if (pthread_create(&userial_cb.read_thread, NULL, userial_read_thread, NULL)) {
ALOGE("%s unable to spawn read thread.", __func__);
goto error;
}
}
Vendor.c (external\bluetooth\bluedroid\hci\src)
int vendor_send_command(bt_vendor_opcode_t opcode, void *param) {
return vendor_interface->op(opcode, param);
}
VENDOR_LIBRARY_NAME = "libbt-vendor.so";
vendor_open(const uint8_t *local_bdaddr)
lib_handle = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
vendor_interface = (bt_vendor_interface_t *)dlsym(lib_handle, VENDOR_LIBRARY_SYMBOL_NAME);
dlsym根据动态链接库操作句柄与符号,返回符号对应的地址。
可以得到vendor_interface的实现代码在libbt-vendor.so这个动态链接库中。
Bt_vendor_brcm.c (hardware\broadcom\libbt\src)
全局抓取一下libbt-vendor.so,我们在hardware\broadcom\libbt下的Android.mk中找到了libbt-vendor.so的包含的源文件。
抓取一下bt_vendor_interface_t,发现在Bt_vendor_brcm.c找到了它的实现:
// Entry point of DLib
const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
sizeof(bt_vendor_interface_t),
init,
op,
case BT_VND_OP_USERIAL_OPEN:
int (*fd_array)[] = (int (*)[]) param;
int fd, idx;
fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
/* Device port name where Bluetooth controller attached */
#ifndef BLUETOOTH_UART_DEVICE_PORT // bt_vendor_brcm.h
#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyO1" // maguro
#endif
// void userial_vendor_init中赋值:
// snprintf(vnd_userial.port_name, VND_PORT_NAME_MAXLEN, "%s", BLUETOOTH_UART_DEVICE_PORT);
vnd_userial.fd = open(vnd_userial.port_name, O_RDWR);//userial_vendor.c
return vnd_userial.fd;
if (fd != -1)
{
for (idx=0; idx < CH_MAX; idx++)
(*fd_array)[idx] = fd;
retval = 1;
}
}
cleanup
};
再回到hci_h4_send_msg查看bt_hc_cbacks的赋值:
Bt_hci_bdroid.c (external\bluetooth\bluedroid\hci\src)
static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
/* store reference to user callbacks */
bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb;
static const bt_hc_interface_t bluetoothHCLibInterface = {
sizeof(bt_hc_interface_t),
init,
set_power,
lpm,
preload,
postload,
transmit_buf,
logging,
cleanup,
tx_hc_cmd,
};
bluetoothHCLibInterface的init函数在蓝牙enable的时候被调用:
Bte_main.c (external\bluetooth\bluedroid\main)
bt_hc_callbacks_t *bt_hc_cbacks = NULL;
static const bt_hc_callbacks_t hc_callbacks = {
sizeof(bt_hc_callbacks_t),
preload_cb,
postload_cb,
lpm_cb,
hostwake_ind,
alloc,
dealloc,
data_ind,
tx_result
};
static void bte_main_in_hw_init(void)
{
bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface() // Bt_hci_bdroid.c
return &bluetoothHCLibInterface;
}
bte_main_enable
bte_hci_enable
//调用bluetoothHCLibInterface的init函数,将bt_hc_cbacks赋值为hc_callbacks
int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);
bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb; // Bt_hci_bdroid.c
最终将bt_hc_cbacks赋值为hc_callbacks。
apk scan发生在蓝牙打开以后,分为经典蓝牙扫描和BLE扫描。
1)经典蓝牙扫描
private BluetoothAdapter mBluetoothAdapter;
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// 启动扫描
mBluetoothAdapter.startDiscovery();
剩下的内容和settings里面开启扫描流程相同。
扫描到的设备在JniCallbacks.java的deviceFoundCallback方法通过广播发送出来。
JniCallbacks.java (packages\apps\bluetooth\src\com\android\bluetooth\btservice)
void deviceFoundCallback(byte[] address)
mRemoteDevices.deviceFoundCallback(address);
// The device properties are already registered - we can send the intent
BluetoothDevice device = getDevice(address); // RemoteDevices.java
DeviceProperties deviceProp = getDeviceProperties(device);
Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
intent.putExtra(BluetoothDevice.EXTRA_CLASS,
new BluetoothClass(Integer.valueOf(deviceProp.mBluetoothClass)));
intent.putExtra(BluetoothDevice.EXTRA_RSSI, deviceProp.mRssi);
intent.putExtra(BluetoothDevice.EXTRA_NAME, deviceProp.mName);
mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_PERM);
应用广播接收代码:
// Broadcast Register
private SingBroadcastReceiver mReceiver;
mReceiver = new SingBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, intentFilter);
// Broadcast Receiver
class SingBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action) ){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("MainActivity", "" + device.getName() + " " + device.getAddress());
} else if (BluetoothDevice.ACTION_DISCOVERY_STARTED.equals(action)){
Log.i("MainActivity", "Discovery started.");
} else if (BluetoothDevice.ACTION_DISCOVERY_FINISHED.equals(action)){
Log.i("MainActivity", "Discovery finished.");
}
}
}
2)BLE扫描
private BluetoothAdapter mBluetoothAdapter;
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
Log.i(TAG, "mLeScanCallback device: " + device.getName() + " "+ device.getAddress());
}
};
// 启动扫描
mBluetoothAdapter.startLeScan(mLeScanCallback);
BluetoothAdapter.java (frameworks\base\core\java\android\bluetooth)
/**
* Starts a scan for Bluetooth LE devices.
* @param callback the callback LE scan results are delivered
*/
@Deprecated
public boolean startLeScan(LeScanCallback callback) {
return startLeScan(null, callback);
}
/**
* Starts a scan for Bluetooth LE devices, looking for devices that
* advertise given services.
* @param serviceUuids Array of services to look for
* @param callback the callback LE scan results are delivered
*/
@Deprecated
public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) {
if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
if (callback == null) {
if (DBG) Log.e(TAG, "startLeScan: null callback");
return false;
}
// 获得一个BluetoothLeScanner 对象
BluetoothLeScanner scanner = getBluetoothLeScanner();
if (scanner == null) {
if (DBG) Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner");
return false;
}
// 判断mLeScanClients里面是否已有当前扫描的callback,有则表示扫描已开始
synchronized(mLeScanClients) {
if (mLeScanClients.containsKey(callback)) {
if (DBG) Log.e(TAG, "LE Scan has already started");
return false;
}
try {
//获取BluetoothGatt Binder类的实例,该类的定义在GattService.java中
//GattService内部类private static class BluetoothGattBinder extends IBluetoothGatt.Stub
IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
if (iGatt == null) {
// BLE is not supported
return false;
}
// 扫描回调
ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
// Should not happen.
Log.e(TAG, "LE Scan has already started");
return;
}
// 获取扫描record
ScanRecord scanRecord = result.getScanRecord();
if (scanRecord == null) {
return;
}
if (serviceUuids != null) {
List<ParcelUuid> uuids = new ArrayList<ParcelUuid>();
for (UUID uuid : serviceUuids) {
uuids.add(new ParcelUuid(uuid));
}
List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids();
if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) {
if (DBG) Log.d(TAG, "uuids does not match");
return;
}
}
// 调用onLeScan回调至应用
callback.onLeScan(result.getDevice(), result.getRssi(),
scanRecord.getBytes());
}
};
//ScanSetting配置
ScanSettings settings = new ScanSettings.Builder()
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
//ScanFilter配置
List<ScanFilter> filters = new ArrayList<ScanFilter>();
if (serviceUuids != null && serviceUuids.length > 0) {
// Note scan filter does not support matching an UUID array so we put one
// UUID to hardware and match the whole array in callback.
ScanFilter filter = new ScanFilter.Builder().setServiceUuid(
new ParcelUuid(serviceUuids[0])).build();
filters.add(filter);
}
// 启动扫描
scanner.startScan(filters, settings, scanCallback);
// 把扫描回调放入mLeScanClients
mLeScanClients.put(callback, scanCallback);
return true;
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
return false;
}
BluetoothLeScanner.java (frameworks\base\core\java\android\bluetooth\le)
/** Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
* @param filters {@link ScanFilter}s for finding exact BLE devices.
* @param settings Settings for the scan.
* @param callback Callback used to deliver scan results.
*/
public void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback) {
startScan(filters, settings, callback, null);
}
private void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback, List<List<ResultStorageDescriptor>> resultStorages) {
// 确保蓝牙已开启
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
if (settings == null || callback == null) {
throw new IllegalArgumentException("settings or callback is null");
}
// 判断mLeScanClients里面是否已有当前扫描的callback,有则表示扫描已开始
synchronized (mLeScanClients) {
if (mLeScanClients.containsKey(callback)) {
postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
return;
}
IBluetoothGatt gatt;
try {
//获取BluetoothGatt Binder类的实例,该类的定义在GattService.java中
//GattService内部类private static class BluetoothGattBinder extends IBluetoothGatt.Stub
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
gatt = null;
}
if (gatt == null) {
postCallbackError(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
return;
}
if (!isSettingsConfigAllowedForScan(settings)) {
postCallbackError(callback,
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
return;
}
//BleScanCallbackWrapper实现了GATT接口callbacks
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
settings, callback, resultStorages);
wrapper.startRegisteration();
UUID uuid = UUID.randomUUID();
mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
mLeScanClients.put(mScanCallback, this);
}
}
GattService.java (packages\apps\bluetooth\src\com\android\bluetooth\gatt)
GattService内部类BluetoothGattBinder 继承了IBluetoothGatt.Stub.
/* Provides Bluetooth Gatt profile, as a service in the Bluetooth application*/
public class GattService extends ProfileService {
static {
classInitNative();
}
protected boolean start() {
initializeNative();
}
/* Handlers for incoming service calls */
private static class BluetoothGattBinder extends IBluetoothGatt.Stub implements IProfileServiceBinder {
public void registerClient(ParcelUuid uuid, IBluetoothGattCallback callback) {
GattService service = getService();
if (service == null) return;
service.registerClient(uuid.getUuid(), callback);
}
}
void registerClient(UUID uuid, IBluetoothGattCallback callback) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
mClientMap.add(uuid, callback);
gattClientRegisterAppNative(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits());
}
}
gattClientRegisterAppNative是一个native函数,把代码往上翻,发现GattService 静态初始化块有调用classInitNative,并在start函数中调用initializeNative。
查看packages\apps\Bluetooth下的Android.mk文件:
LOCAL_JNI_SHARED_LIBRARIES := libbluetooth_jni
它加载了动态链接库libbluetooth_jni.so,说明GattService类里面的Native函数的具体实现打包在这个动态链接库中。
进到目录packages\apps\bluetooth下,有一个jni的目录,下面有一个Android.mk,查看该文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
com_android_bluetooth_btservice_AdapterService.cpp \
com_android_bluetooth_hfp.cpp \
com_android_bluetooth_hfpclient.cpp \
com_android_bluetooth_a2dp.cpp \
com_android_bluetooth_a2dp_sink.cpp \
com_android_bluetooth_avrcp.cpp \
com_android_bluetooth_avrcp_controller.cpp \
com_android_bluetooth_hid.cpp \
com_android_bluetooth_hdp.cpp \
com_android_bluetooth_pan.cpp \
com_android_bluetooth_gatt.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libnativehelper \
libcutils \
libutils \
liblog \
libhardware
LOCAL_MULTILIB := 32
LOCAL_MODULE := libbluetooth_jni
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
可以看到这个目录的源文件将编译生成libbluetooth_jni.so。里面有不少cpp文件,从名字看和GATT相关只有一个com_android_bluetooth_gatt.cpp,我们要找的Native函数大概就在这个文件里面,不过我们还是去求证一下,我们知道JNI函数最终都是通过jniRegisterNativeMethods完成注册,将类名和Native函数对应起来。
进入packages/apps/Bluetooth/jni目录搜索:
$ grep "com/android/bluetooth/gatt/GattService" * -nR
com_android_bluetooth_gatt.cpp:1802: jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
发现类GattService对应的JNI函数确实在com_android_bluetooth_gatt.cpp注册。
Com_android_bluetooth_gatt.cpp (packages\apps\bluetooth\jni)
static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
jlong app_uuid_lsb, jlong app_uuid_msb )
{
bt_uuid_t uuid;
if (!sGattIf) return;
set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
sGattIf->client->register_client(&uuid);
}
查看sGattIf定义:
static const btgatt_interface_t *sGattIf = NULL;
查看sGattIf赋值:
#define BT_PROFILE_GATT_ID "gatt" //Bluetooth.h (hardware\libhardware\include\hardware)
static void initializeNative(JNIEnv *env, jobject object) {
if(btIf)
return;
if ( (btIf = getBluetoothInterface()) == NULL) {
error("Bluetooth module is not loaded");
return;
}
if ( (sGattIf = (btgatt_interface_t *)
btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) {
error("Failed to get Bluetooth GATT Interface");
return;
}
bt_status_t status;
if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) {
error("Failed to initialize Bluetooth GATT, status: %d", status);
sGattIf = NULL;
return;
}
mCallbacksObj = env->NewGlobalRef(object);
}
getBluetoothInterface定义在com_android_bluetooth_btservice_AdapterService.cpp中,返回sBluetoothInterface:
com_android_bluetooth_btservice_AdapterService.cpp (packages\apps\bluetooth\jni)
const bt_interface_t* getBluetoothInterface() {
return sBluetoothInterface;
}
查看sBluetoothInterface 定义:
static const bt_interface_t *sBluetoothInterface = NULL;
查找sBluetoothInterface的赋值,发现它加载了一个bluetooth.defualt.so模块:
#define BT_HARDWARE_MODULE_ID "bluetooth"
#define BT_STACK_MODULE_ID "bluetooth"
#define BT_STACK_TEST_MODULE_ID "bluetooth_test"
static void classInitNative(JNIEnv* env, jclass clazz)
{
hw_module_t* module;
const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID :
BT_STACK_TEST_MODULE_ID);
// 加载btStack模块 bluetooth.defualt.so
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) {
//最终转换为btStack结构体
bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
// sBluetoothInterface 赋值
sBluetoothInterface = btStack->get_bluetooth_interface();
} else {
ALOGE("Error while opening Bluetooth library");
}
} else {
ALOGE("No Bluetooth Library found");
}
}
bluetooth.defualt.so模块由BlueDroid协议栈代码编译会生成,代码在external\bluetooth\bluedroid目录。模块入口是Bluetooth.c。
Bluetooth.c (external\bluetooth\bluedroid\btif\src)
static const void* get_profile_interface (const char *profile_id)
{
ALOGI("get_profile_interface %s", profile_id);
/* sanity check */
if (interface_ready() == FALSE)
return NULL;
/* check for supported profile interfaces */
if (is_profile(profile_id, BT_PROFILE_HANDSFREE_ID))
return btif_hf_get_interface();
if (is_profile(profile_id, BT_PROFILE_HANDSFREE_CLIENT_ID))
return btif_hf_client_get_interface();
if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
return btif_sock_get_interface();
if (is_profile(profile_id, BT_PROFILE_PAN_ID))
return btif_pan_get_interface();
if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
return btif_av_get_src_interface();
if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID))
return btif_av_get_sink_interface();
if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
return btif_hh_get_interface();
if (is_profile(profile_id, BT_PROFILE_HEALTH_ID))
return btif_hl_get_interface();
if (is_profile(profile_id, BT_PROFILE_MAP_CLIENT_ID))
return btif_mce_get_interface();
#if ( BTA_GATT_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
if (is_profile(profile_id, BT_PROFILE_GATT_ID))
return btif_gatt_get_interface();
#endif
if (is_profile(profile_id, BT_PROFILE_AV_RC_ID))
return btif_rc_get_interface();
if (is_profile(profile_id, BT_PROFILE_AV_RC_CTRL_ID))
return btif_rc_ctrl_get_interface();
return NULL;
}
static const bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
init,
enable,
disable,
get_recv_byte,
get_send_byte,
cleanup,
get_adapter_properties,
get_adapter_property,
set_adapter_property,
get_remote_device_properties,
get_remote_device_property,
set_remote_device_property,
get_remote_service_record,
get_remote_services,
start_discovery,
cancel_discovery,
create_bond,
remove_bond,
cancel_bond,
get_connection_state,
pin_reply,
ssp_reply,
get_profile_interface,
dut_mode_configure,
dut_mode_send,
#if BLE_INCLUDED == TRUE
le_test_mode,
#else
NULL,
#endif
config_hci_snoop_log,
set_os_callouts,
read_energy_info,
};
我们再返回sGattIf赋值那里:
sGattIf = (btgatt_interface_t *)
btIf->get_profile_interface(BT_PROFILE_GATT_ID)
即调用bluetooth.c里面的bluetoothInterface->get_profile_interface(BT_PROFILE_GATT_ID), 最终返回btif_gatt_get_interface函数返回btgattInterface。
Btif_gatt.c (external\bluetooth\bluedroid\btif\src)
static const btgatt_interface_t btgattInterface = {
sizeof(btgattInterface),
btif_gatt_init,
btif_gatt_cleanup,
&btgattClientInterface,
&btgattServerInterface,
};
/*******************************************************************************
** Function btif_gatt_get_interface
** Description Get the gatt callback interface
** Returns btgatt_interface_t
*******************************************************************************/
const btgatt_interface_t *btif_gatt_get_interface()
{
return &btgattInterface;
}
再返回到gattClientRegisterAppNative函数:
static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
jlong app_uuid_lsb, jlong app_uuid_msb )
// call btgattInterface->btgattClientInterface->btif_gattc_register_app
sGattIf->client->register_client(&uuid);
则sGattIf->client->register_client(&uuid);实际调用btgattInterface->btgattClientInterface->btif_gattc_register_app(&uuid).
Btif_gatt_client.c (external\bluetooth\bluedroid\btif\src)
static bt_status_t btif_gattc_register_app(bt_uuid_t *uuid)
{
CHECK_BTGATT_INIT();
btif_gattc_cb_t btif_cb;
memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REGISTER_APP,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */
p_msg->p_cb = p_cback;
p_msg->event = event; /* callback event */
btif_sendmsg(p_msg);
GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);
btif_task
case BT_EVT_CONTEXT_SWITCH_EVT:
btif_context_switched(p_msg);
p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg;
p->p_cb(p->event, p->p_param); // 调用btgattc_handle_event
}
}
}
Btif_gatt_client.c (external\bluetooth\bluedroid\btif\src)
static void btgattc_handle_event(uint16_t event, char* p_param)
btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*) p_param;
case BTIF_GATTC_REGISTER_APP:
btif_to_bta_uuid(&uuid, &p_cb->uuid);
btif_gattc_incr_app_count();
// 给应用uuid注册应用回调函数
BTA_GATTC_AppRegister(&uuid, bta_gattc_cback);
// 注册GATT客户端event处理函数
bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
bta_sys_cb.is_reg[id] = TRUE;
// 发送一个BTA_GATTC_API_REG_EVT消息
p_buf->hdr.event = BTA_GATTC_API_REG_EVT;
memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID));
p_buf->p_cback = p_client_cb;
bta_sys_sendmsg(p_buf);
GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);
btu_task
if (event & TASK_MBOX_2_EVT_MASK)
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
bta_sys_event(p_msg);
id = (UINT8) (p_msg->event >> 8);
// 调用bta_gattc_reg->bta_gattc_hdl_event
(*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
Bta_gattc_api.c (external\bluetooth\bluedroid\bta\gatt)
/* GATT client main event handling function */
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
switch (p_msg->event)
case BTA_GATTC_API_REG_EVT:
bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
break;
Bta_gattc_act.c (external\bluetooth\bluedroid\bta\gatt)
/*******************************************************************************
** Description Register a GATT client application with BTA.
*******************************************************************************/
void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
{
tBTA_GATTC cb_data;
UINT8 i;
tBT_UUID *p_app_uuid = &p_data->api_reg.app_uuid;
tBTA_GATTC_INT_START_IF *p_buf;
tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
APPL_TRACE_DEBUG("bta_gattc_register state %d",p_cb->state);
memset(&cb_data, 0, sizeof(cb_data));
cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
bta_gattc_enable (p_cb);
/* initialize control block */
memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)
for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS; i_gatt_if++, p_reg++) {
if (!p_reg->in_use) {
memset(p_reg, 0 , sizeof(tGATT_REG));
i_gatt_if++; /* one based number */
p_reg->app_uuid128 = *p_app_uuid128;
gatt_if =
p_reg->gatt_if = (tGATT_IF)i_gatt_if;
p_reg->app_cb = *p_cb_info;
p_reg->in_use = TRUE;
break;
}
}
p_cb->cl_rcb[i].in_use = TRUE;
p_cb->cl_rcb[i].p_cback = p_data->api_reg.p_cback;
memcpy(&p_cb->cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
/* BTA use the same client interface as BTE GATT statck */
cb_data.reg_oper.client_if = p_cb->cl_rcb[i].client_if;
if ((p_buf = (tBTA_GATTC_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTC_INT_START_IF))) != NULL)
{
p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
p_buf->client_if = p_cb->cl_rcb[i].client_if;
// 发送消息至btu_task处理
bta_sys_sendmsg(p_buf);
GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);
btu_task
if (event & TASK_MBOX_2_EVT_MASK)
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
bta_sys_event(p_msg);
id = (UINT8) (p_msg->event >> 8);
// 调用bta_gattc_reg->bta_gattc_hdl_event
(*bta_sys_cb.reg[id]->evt_hdlr)(p_msg); // bta_gattc_main.c
tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
case BTA_GATTC_INT_START_IF_EVT:
bta_gattc_start_if(p_cb, (tBTA_GATTC_DATA *) p_msg);
break;
status = BTA_GATT_OK;
}
/* callback with register event */
if (p_data->api_reg.p_cback)
{
if (p_app_uuid != NULL)
memcpy(&(cb_data.reg_oper.app_uuid),p_app_uuid,sizeof(tBT_UUID));
cb_data.reg_oper.status = status;
// 调用bte_gattc_cback
(*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data);
}
}
bta_gattc_register主要工作:
1)初始化GATTC模块: 初始化GATTC控制块
2)注册应用到GATT: 保存应用的uuid,给应用分配gatt_if索引并保存,保存gatt回调bta_gattc_cl_cback,以上信息都保存至gatt_cb.cl_rcb(GATT控制块->注册控制块)
3) 保存gatt client应用信息到GATTC控制块: 同2)
4)发送BTA_GATT_OK消息
5)调用bte_gattc_cback
Btif_gatt_client.c (external\bluetooth\bluedroid\btif\src) 88028 2017/12/14
static void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
{
bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt,
(uint16_t) event, (void*) p_data, sizeof(tBTA_GATTC), btapp_gattc_req_data);
p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */
p_msg->p_cb = p_cback;
p_msg->event = event; /* callback event */
btif_sendmsg(p_msg);
GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);
btif_task
case BT_EVT_CONTEXT_SWITCH_EVT:
btif_context_switched(p_msg);
p->p_cb(p->event, p->p_param); // 调用btif_gattc_upstreams_evt
break;
}
static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
tBTA_GATTC *p_data = (tBTA_GATTC*) p_param;
switch (event)
case BTA_GATTC_REG_EVT:
bt_uuid_t app_uuid;
bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.app_uuid);
// 调用bt_gatt_callbacks->client->register_client_cb
HAL_CBACK(bt_gatt_callbacks, client->register_client_cb
, p_data->reg_oper.status
, p_data->reg_oper.client_if
, &app_uuid
);
break;
}
查看bt_gatt_callbacks定义及赋值:
Btif_gatt.c (external\bluetooth\bluedroid\btif\src)
const btgatt_callbacks_t *bt_gatt_callbacks = NULL;
查看bt_gatt_callbacks赋值:
Com_android_bluetooth_gatt.cpp (packages\apps\bluetooth\jni)
static void initializeNative(JNIEnv *env, jobject object) {
// com_android_bluetooth_btservice_AdapterService.cpp从bluetooth.defualt.so里面获得,
// 即bluetooth.c里面的bluetoothInterface。
if ( (btIf = getBluetoothInterface()) == NULL) {
error("Bluetooth module is not loaded");
return;
}
// 调用即bluetooth.c里面的bluetoothInterface->get_profile_interface(BT_PROFILE_GATT_ID), 返回btif_gatt.c里面的btgattInterface
if ( (sGattIf = (btgatt_interface_t *) btIf->get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) {
error("Failed to get Bluetooth GATT Interface");
return;
}
bt_status_t status;
// 调用btif_gatt.c里面的btgattInterface->init即btif_gatt_init函数
// 给bt_gatt_callbacks赋值为sGattCallbacks
if ( (status = sGattIf->init(&sGattCallbacks)) != BT_STATUS_SUCCESS) {
error("Failed to initialize Bluetooth GATT, status: %d", status);
sGattIf = NULL;
return;
}
}
根据上述代码得知bt_gatt_callbacks等于sGattCallbacks
查看sGattCallbacks的定义:
Com_android_bluetooth_gatt.cpp (packages\apps\bluetooth\jni)
static const btgatt_callbacks_t sGattCallbacks = {
sizeof(btgatt_callbacks_t),
&sGattClientCallbacks,
&sGattServerCallbacks
};
// 那么bt_gatt_callbacks->client->register_client_cb实际调用的是sGattCallbacks -> sGattClientCallbacks -> btgattc_register_app_cb
Com_android_bluetooth_gatt.cpp (packages\apps\bluetooth\jni)
void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid)
{
CHECK_CALLBACK_ENV
// cpp调用java函数onClientRegistered
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
clientIf, UUID_PARAMS(app_uuid));
checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
查看method_onClientRegistered赋值:
static void classInitNative(JNIEnv* env, jclass clazz)
method_onClientRegistered = env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
根据前面JNI注册过程知,JNI层的method_onClientRegistered 函数对应GattService类的onClientRegistered方法。
GattService.java (packages\apps\bluetooth\src\com\android\bluetooth\gatt)
void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb)
throws RemoteException {
UUID uuid = new UUID(uuidMsb, uuidLsb);
if (DBG) Log.d(TAG, "onClientRegistered() - UUID=" + uuid + ", clientIf=" + clientIf);
ClientMap.App app = mClientMap.getByUuid(uuid);
if (app != null) {
if (status == 0) {
app.id = clientIf;
app.linkToDeath(new ClientDeathRecipient(clientIf));
} else {
mClientMap.remove(uuid);
}
app.callback.onClientRegistered(status, clientIf);
}
}
uuid和callback在registerClient被添加到mClientMap, callback等于BleScanCallbackWrapper wrapper。
callback 注册过程跟踪:
BluetoothLeScanner.java (frameworks\base\core\java\android\bluetooth\le)
public void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback) {
startScan(filters, settings, callback, null);
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
settings, callback, resultStorages);
wrapper.startRegisteration();
UUID uuid = UUID.randomUUID();
mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
GattService service = getService();
service.registerClient(uuid.getUuid(), callback);
mClientMap.add(uuid, callback);
}
}
BleScanCallbackWrapper是BluetoothLeScanner的内部类,实现了GATT 接口的回调。
BluetoothLeScanner.java (frameworks\base\core\java\android\bluetooth\le)
public final class BluetoothLeScanner {
private class BleScanCallbackWrapper extends BluetoothGattCallbackWrapper {
public void onClientRegistered(int status, int clientIf) {
Log.d(TAG, "onClientRegistered() - status=" + status +
" clientIf=" + clientIf);
synchronized (this) {
if (status == BluetoothGatt.GATT_SUCCESS) {
mClientIf = clientIf;
try {
//mBluetoothGatt是BluetoothGatt Binder类的实例,该类的定义在GattService.java中
//GattService内部类private static class BluetoothGattBinder extends IBluetoothGatt.Stub
// 调用BluetoothGattBinder的startScan方法
mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters,
mResultStorages);
} catch (RemoteException e) {
Log.e(TAG, "fail to start le scan: " + e);
mClientIf = -1;
}
} else {
// registration failed
mClientIf = -1;
}
notifyAll();
}
}
}
GattService.java (packages\apps\bluetooth\src\com\android\bluetooth\gatt)
public void startScan(int appIf, boolean isServer, ScanSettings settings,
List<ScanFilter> filters, List storages) {
GattService service = getService();
if (service == null) return;
service.startScan(appIf, isServer, settings, filters, storages);
mScanManager.startScan(new ScanClient(appIf, isServer, settings, filters, storages));
sendMessage(MSG_START_BLE_SCAN, client);
}
ScanManager.java (packages\apps\bluetooth\src\com\android\bluetooth\gatt)
void startScan(ScanClient client) {
sendMessage(MSG_START_BLE_SCAN, client);
}
public void handleMessage(Message msg) {
ScanClient client = (ScanClient) msg.obj;
switch (msg.what) {
case MSG_START_BLE_SCAN:
handleStartScan(client);
break;
case MSG_STOP_BLE_SCAN:
handleStopScan(client);
break;
case MSG_FLUSH_BATCH_RESULTS:
handleFlushBatchResults(client);
break;
default:
// Shouldn't happen.
Log.e(TAG, "received an unkown message : " + msg.what);
}
}
void handleStartScan(ScanClient client) {
Utils.enforceAdminPermission(mService);
logd("handling starting scan");
if (!isScanSupported(client)) {
Log.e(TAG, "Scan settings not supported");
return;
}
if (mRegularScanClients.contains(client) || mBatchClients.contains(client)) {
Log.e(TAG, "Scan already started");
return;
}
// Begin scan operations.
if (isBatchClient(client)) {
mBatchClients.add(client);
mScanNative.startBatchScan(client);
} else {
mRegularScanClients.add(client);
mScanNative.startRegularScan(client);
mScanNative.configureRegularScanParams();
gattClientScanNative(true); // 调用Native函数启动扫描
}
}
我们知道JNI函数最终都是通过jniRegisterNativeMethods完成注册,将类名和Native函数对应起来。
进入packages/apps/Bluetooth/jni目录搜索:
$ grep "com/android/bluetooth/gatt/ScanManager$ScanNative" * -nR
com_android_bluetooth_gatt.cpp:1796: jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/ScanManager$ScanNative",
发现类ScanNative对应的JNI函数在com_android_bluetooth_gatt.cpp注册。
Com_android_bluetooth_gatt.cpp (packages\apps\bluetooth\jni)
static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start)
{
if (!sGattIf) return;
// btgattInterface -> btgattClientInterface -> btif_gattc_scan
sGattIf->client->scan(start);
}
Btif_gatt_client.c (external\bluetooth\bluedroid\btif\src)
static bt_status_t btif_gattc_scan( bool start )
{
CHECK_BTGATT_INIT();
btif_gattc_cb_t btif_cb;
return btif_transfer_context(btgattc_handle_event, start ? BTIF_GATTC_SCAN_START : BTIF_GATTC_SCAN_STOP,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
}
Btif_gatt_client.c (external\bluetooth\bluedroid\btif\src)
static void btgattc_handle_event(uint16_t event, char* p_param)
{
case BTIF_GATTC_SCAN_START:
btif_gattc_init_dev_cb();
BTA_DmBleObserve(TRUE, 0, bta_scan_results_cb);
p_msg->hdr.event = BTA_DM_API_BLE_OBSERVE_EVT;
p_msg->start = start;
p_msg->duration = duration;
p_msg->p_cback = p_results_cb;
bta_sys_sendmsg(p_msg);
GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);
btu_task
if (event & TASK_MBOX_2_EVT_MASK)
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
bta_sys_event(p_msg);
id = (UINT8) (p_msg->event >> 8);
// 调用bta_dm_reg->bta_dm_sm_execute
(*bta_sys_cb.reg[id]->evt_hdlr)(p_msg); // bta_gattc_main.c
//调用 bta_dm_action -> bta_dm_ble_observe
(*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg);// bta_dm_main.c
break;
break;
}
Bta_dm_act.c (external\bluetooth\bluedroid\bta\dm)
void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
{
tBTM_STATUS status;
if (p_data->ble_observe.start)
{
/*Save the callback to be called when a scan results are available */
bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)
}
Btm_ble_gap.c (external\bluetooth\bluedroid\stack\btm)
/*******************************************************************************
* Description This procedure keep the device listening for advertising
** events from a broadcast device.
*******************************************************************************/
tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration,
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
{
tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS status = BTM_WRONG_MODE;
if (start)
{
// p_obs_results_cb 等于 bta_dm_observe_results_cb, 在btm_ble_process_adv_pkt_cont被调用
btm_cb.ble_ctr_cb.p_obs_results_cb = p_results_cb;
// observe停止的时候被调用
btm_cb.ble_ctr_cb.p_obs_cmpl_cb = p_cmpl_cb;
status = BTM_CMD_STARTED;
/* scan is not started */
if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
{
p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
/* allow config scanning type */
btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
(UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
(UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
BTM_BLE_DEFAULT_SFP); /* assume observe always not using white list */
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
/* enable IRK list */
btm_ble_vendor_irk_list_known_dev (TRUE);
#endif
status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
}
if (status == BTM_CMD_STARTED)
{
btm_cb.ble_ctr_cb.scan_activity |= BTM_LE_OBSERVE_ACTIVE;
}
}
BTM_BleObserve主要工作:
1)设置btm_cb.ble_ctr_cb.p_obs_results_cb回调为bta_dm_observe_results_cb,该回调在btm_ble_process_adv_pkt_cont被调用,接收到有广播的时候btm_ble_process_adv_pkt_cont被调用。
2)设置obverse完成回调,obverser停止时被调用。
3)当scan没开启时设置扫描参数并开启扫描。
Btm_ble_gap.c (external\bluetooth\bluedroid\stack\btm)
/*******************************************************************************
** Description This function is called after random address resolution is
** done, and proceed to process adv packet.
*******************************************************************************/
static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
{
tINQ_DB_ENT *p_i;
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
tBTM_INQ_RESULTS_CB *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb;
tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
BOOLEAN update = TRUE;
UINT8 result = 0;
BTM_TRACE_WARNING("btm_ble_process_adv_pkt:evt_type=%d, bda= %0x:%0x:%0x:%0x:%0x:%0x",
evt_type, bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]);
p_i = btm_inq_db_find (bda);
// settings里面启动扫描的回调
if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT))
{
(p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
}
// apk启动扫描的回调 bta_dm_observe_results_cb
if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT))
{
(p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
}
}
1)settings 扫描回调:p_inq_results_cb扫描回调指向bta_dm_inq_results_cb,在BTM_StartInquiry时被设置。
2)apk扫描回调:p_obs_results_cb扫描回调指向bta_dm_observe_results_cb,在BTM_BleObserve时被设置。
btm_ble_process_adv_pkt_cont详细的调用流程参考: 三、Adv和Scan Resp接收
Bta_av_ssm.c (external\bluetooth\bluedroid\bta\av)
static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
{
tBTA_DM_SEARCH result;
tBTM_INQ_INFO *p_inq_info;
UINT16 service_class;
APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
result.inq_res.rssi = p_inq->rssi;
result.inq_res.ble_addr_type = p_inq->ble_addr_type;
result.inq_res.inq_result_type = p_inq->inq_result_type;
result.inq_res.device_type = p_inq->device_type;
/* application will parse EIR to find out remote device name */
result.inq_res.p_eir = p_eir;
if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL)
{
/* initialize remt_name_not_required to FALSE so that we get the name by default */
result.inq_res.remt_name_not_required = FALSE;
}
// p_scan_cback等于bta_scan_results_cb,在 BTA_DmBleObserve(TRUE, 0, bta_scan_results_cb); 时被设置
if(bta_dm_search_cb.p_scan_cback)
bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
if(p_inq_info)
{
/* application indicates if it knows the remote name, inside the callback
copy that to the inquiry data base*/
if(result.inq_res.remt_name_not_required)
p_inq_info->appl_knows_rem_name = TRUE;
}
}
Btif_gatt_client.c (external\bluetooth\bluedroid\btif\src)
static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
btif_gattc_cb_t btif_cb;
uint8_t len;
switch (event)
{
case BTA_DM_INQ_RES_EVT:
{
bdcpy(btif_cb.bd_addr.address, p_data->inq_res.bd_addr);
btif_cb.device_type = p_data->inq_res.device_type;
btif_cb.rssi = p_data->inq_res.rssi;
btif_cb.addr_type = p_data->inq_res.ble_addr_type;
btif_cb.flag = p_data->inq_res.flag;
if (p_data->inq_res.p_eir)
{
memcpy(btif_cb.value, p_data->inq_res.p_eir, 62);
if (BTA_CheckEirData(p_data->inq_res.p_eir, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE,
&len))
{
p_data->inq_res.remt_name_not_required = TRUE;
}
}
}
break;
case BTA_DM_INQ_CMPL_EVT:
{
BTIF_TRACE_DEBUG("%s BLE observe complete. Num Resp %d",
__FUNCTION__,p_data->inq_cmpl.num_resps);
return;
}
default:
BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
return;
}
// btif_gattc_upstreams_evt将被调用
btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATT_OBSERVE_EVT,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
}
static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
{
BTIF_TRACE_EVENT("%s: Event %d", __FUNCTION__, event);
tBTA_GATTC *p_data = (tBTA_GATTC*) p_param;
switch (event)
{
case BTIF_GATT_OBSERVE_EVT:
{
btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param;
uint8_t remote_name_len;
uint8_t *p_eir_remote_name=NULL;
bt_device_type_t dev_type;
bt_property_t properties;
p_eir_remote_name = BTA_CheckEirData(p_btif_cb->value,
BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
if (p_eir_remote_name == NULL)
{
p_eir_remote_name = BTA_CheckEirData(p_btif_cb->value,
BT_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
}
if ((p_btif_cb->addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name))
{
if (!btif_gattc_find_bdaddr(p_btif_cb->bd_addr.address))
{
static const char* exclude_filter[] =
{"LinkKey", "LE_KEY_PENC", "LE_KEY_PID", "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"};
btif_gattc_add_remote_bdaddr(p_btif_cb->bd_addr.address, p_btif_cb->addr_type);
btif_gattc_update_properties(p_btif_cb);
btif_config_filter_remove("Remote", exclude_filter, sizeof(exclude_filter)/sizeof(char*),
BTIF_STORAGE_MAX_ALLOWED_REMOTE_DEVICE);
}
}
if (( p_btif_cb->device_type == BT_DEVICE_TYPE_DUMO)&&
(p_btif_cb->flag & BTA_BLE_DMT_CONTROLLER_SPT) &&
(p_btif_cb->flag & BTA_BLE_DMT_HOST_SPT))
{
btif_storage_set_dmt_support_type (&(p_btif_cb->bd_addr), TRUE);
}
dev_type = p_btif_cb->device_type;
BTIF_STORAGE_FILL_PROPERTY(&properties,
BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type);
btif_storage_set_remote_device_property(&(p_btif_cb->bd_addr), &properties);
// 调用bt_gatt_callbacks->client->scan_result_cb
HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb,
&p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value);
break;
}
btapp_gattc_free_req_data(event, p_data);
}
根据前面的分析bt_gatt_callbacks等于sGattCallbacks
其定义在Com_android_bluetooth_gatt.cpp文件。
所以bt_gatt_callbacks->client->scan_result_cb实际调用的是sGattCallbacks -> sGattClientCallbacks -> btgattc_scan_result_cb
Com_android_bluetooth_gatt.cpp (packages\apps\bluetooth\jni)
void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data)
{
CHECK_CALLBACK_ENV
char c_address[32];
snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
bda->address[0], bda->address[1], bda->address[2],
bda->address[3], bda->address[4], bda->address[5]);
jstring address = sCallbackEnv->NewStringUTF(c_address);
jbyteArray jb = sCallbackEnv->NewByteArray(62);
sCallbackEnv->SetByteArrayRegion(jb, 0, 62, (jbyte *) adv_data);
// 调用JAVA函数onScanResult
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult
, address, rssi, jb);
sCallbackEnv->DeleteLocalRef(address);
sCallbackEnv->DeleteLocalRef(jb);
checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
调用JAVA函数onScanResult,对应java层文件GattService类onScanResult方法。
GattService.java (packages\apps\bluetooth\src\com\android\bluetooth\gatt)
void onScanResult(String address, int rssi, byte[] adv_data) {
if (VDBG) Log.d(TAG, "onScanResult() - address=" + address
+ ", rssi=" + rssi);
List<UUID> remoteUuids = parseUuids(adv_data);
for (ScanClient client : mScanManager.getRegularScanQueue()) {
if (client.uuids.length > 0) {
int matches = 0;
for (UUID search : client.uuids) {
for (UUID remote: remoteUuids) {
if (remote.equals(search)) {
++matches;
break; // Only count 1st match in case of duplicates
}
}
}
if (matches < client.uuids.length) continue;
}
if (!client.isServer) {
ClientMap.App app = mClientMap.getById(client.clientIf);
if (app != null) {
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter()
.getRemoteDevice(address);
ScanResult result = new ScanResult(device, ScanRecord.parseFromBytes(adv_data),
rssi, SystemClock.elapsedRealtimeNanos());
if (matchesFilters(client, result)) {
ScanSettings settings = client.settings;
// framework detects the first match, hw signal is
// used to detect the onlost
// ToDo: make scanClient+result, 1 to many when hw
// support is available
if ((settings.getCallbackType() &
ScanSettings.CALLBACK_TYPE_FIRST_MATCH) != 0) {
synchronized (mOnFoundResults) {
mOnFoundResults.put(client, result);
}
app.callback.onFoundOrLost(true, result);
}
if ((settings.getCallbackType() &
ScanSettings.CALLBACK_TYPE_ALL_MATCHES) != 0) {
app.callback.onScanResult(result);
}
}
}
}
}
}
根据前面的分析,callback在registerClient被添加到mClientMap, callback等于BleScanCallbackWrapper wrapper。
BluetoothLeScanner.java (frameworks\base\core\java\android\bluetooth\le)
public final class BluetoothLeScanner {
private class BleScanCallbackWrapper extends BluetoothGattCallbackWrapper {
public void onScanResult(final ScanResult scanResult) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
}
});
}
}
}
mScanCallback就是在BluetoothLeScanner -> startScan时示例化BleScanCallbackWrapper 传进来的ScanCallback对象,ScanCallback会回调到apk层。
至此apk扫描分析完成,下面再次把启动扫描部分代码附上,方便理解:
// 启动扫描
mBluetoothAdapter.startLeScan(mLeScanCallback);
BluetoothAdapter.java (frameworks\base\core\java\android\bluetooth)
/**
* Starts a scan for Bluetooth LE devices.
* @param callback the callback LE scan results are delivered
*/
@Deprecated
public boolean startLeScan(LeScanCallback callback) {
return startLeScan(null, callback);
}
@Deprecated
public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) {
// 获得一个BluetoothLeScanner 对象
BluetoothLeScanner scanner = getBluetoothLeScanner();
if (scanner == null) {
if (DBG) Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner");
return false;
}
// 判断mLeScanClients里面是否已有当前扫描的callback,有则表示扫描已开始
synchronized(mLeScanClients) {
if (mLeScanClients.containsKey(callback)) {
if (DBG) Log.e(TAG, "LE Scan has already started");
return false;
}
try {
//获取BluetoothGatt Binder类的实例,该类的定义在GattService.java中
//GattService内部类private static class BluetoothGattBinder extends IBluetoothGatt.Stub
IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
if (iGatt == null) {
// BLE is not supported
return false;
}
// 扫描回调
ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
// Should not happen.
Log.e(TAG, "LE Scan has already started");
return;
}
// 获取扫描record
ScanRecord scanRecord = result.getScanRecord();
if (scanRecord == null) {
return;
}
if (serviceUuids != null) {
List<ParcelUuid> uuids = new ArrayList<ParcelUuid>();
for (UUID uuid : serviceUuids) {
uuids.add(new ParcelUuid(uuid));
}
List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids();
if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) {
if (DBG) Log.d(TAG, "uuids does not match");
return;
}
}
// 调用onLeScan回调至应用
callback.onLeScan(result.getDevice(), result.getRssi(),
scanRecord.getBytes());
}
};
//ScanSetting配置
ScanSettings settings = new ScanSettings.Builder()
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
//ScanFilter配置
List<ScanFilter> filters = new ArrayList<ScanFilter>();
if (serviceUuids != null && serviceUuids.length > 0) {
// Note scan filter does not support matching an UUID array so we put one
// UUID to hardware and match the whole array in callback.
ScanFilter filter = new ScanFilter.Builder().setServiceUuid(
new ParcelUuid(serviceUuids[0])).build();
filters.add(filter);
}
// 启动扫描
scanner.startScan(filters, settings, scanCallback);
// 把扫描回调放入mLeScanClients
mLeScanClients.put(callback, scanCallback);
return true;
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
return false;
}
uart是HCI Transport层,是host和controller通信的接口,所有controller的数据都从uart传输过来。
Userial.c (external\bluetooth\bluedroid\hci\src)
static void *userial_read_thread(void *arg)
HC_BT_HDR *p_buf = NULL;
p = (uint8_t *) (p_buf + 1);
rx_length = select_read(userial_fd, p, HCI_MAX_FRAME_SIZE + 1);
utils_enqueue(&(userial_cb.rx_q), p_buf); // 将读到的数据放入rx_q队列
bthc_rx_ready();
Bt_hci_bdroid.c (external\bluetooth\bluedroid\hci\src)
void bthc_rx_ready(void) {
thread_post(hc_cb.worker_thread, event_rx, NULL); // event_rx被调用
p_hci_if->rcv(); // hci_h4_func_table->hci_h4_receive_msg
}
Hci_h4.c (external\bluetooth\bluedroid\hci\src)
uint16_t hci_h4_receive_msg(void)
if (msg_received)
{
/* generate snoop trace message */
if (p_cb->p_rcv_msg->event != MSG_HC_TO_STACK_HCI_ACL)
btsnoop_capture(p_cb->p_rcv_msg, true);
if (p_cb->p_rcv_msg->event == MSG_HC_TO_STACK_HCI_EVT)
intercepted = internal_event_intercept();
// hc_callbacks ->data_ind被调用
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);
}
Bte_main.c (external\bluetooth\bluedroid\main)
static const bt_hc_callbacks_t hc_callbacks = {
sizeof(bt_hc_callbacks_t),
preload_cb,
postload_cb,
lpm_cb,
hostwake_ind,
alloc,
dealloc,
data_ind,
tx_result
};
static int data_ind(TRANSAC transac, char *p_buf, int len)
{
BT_HDR *p_msg = (BT_HDR *) transac;
GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);
return BT_HC_STATUS_SUCCESS;
}
data_ind调用GKI_send_msg给发了一个msg给BTU_TASK。
消息的mbox是BTU_HCI_RCV_MBOX,event是BT_EVT_TO_BTU_HCI_EVT。
消息event id定义在Bt_hci_bdroid.h,如下:
#define MSG_HC_TO_STACK_HCI_ERR 0x1300 /* eq. BT_EVT_TO_BTU_HCIT_ERR */
#define MSG_HC_TO_STACK_HCI_ACL 0x1100 /* eq. BT_EVT_TO_BTU_HCI_ACL */
#define MSG_HC_TO_STACK_HCI_SCO 0x1200 /* eq. BT_EVT_TO_BTU_HCI_SCO */
#define MSG_HC_TO_STACK_HCI_EVT 0x1000 /* eq. BT_EVT_TO_BTU_HCI_EVT */
#define MSG_HC_TO_STACK_L2C_SEG_XMIT 0x1900 /* eq. BT_EVT_TO_BTU_L2C_SEG_XMIT */
#define MSG_STACK_TO_HC_HCI_ACL 0x2100 /* eq. BT_EVT_TO_LM_HCI_ACL */
#define MSG_STACK_TO_HC_HCI_SCO 0x2200 /* eq. BT_EVT_TO_LM_HCI_SCO */
#define MSG_STACK_TO_HC_HCI_CMD 0x2000 /* eq. BT_EVT_TO_LM_HCI_CMD */
Btu_task.c (external\bluetooth\bluedroid\stack\btu)
BTU_API UINT32 btu_task (UINT32 param)
{
UINT16 event;
BT_HDR *p_msg;
UINT8 i;
UINT16 mask;
BOOLEAN handled;
/* Wait for, and process, events */
for (;;)
{
event = GKI_wait (0xFFFF, 0);
if (event & TASK_MBOX_0_EVT_MASK)
{
/* Process all messages in the queue */
while ((p_msg = (BT_HDR *) GKI_read_mbox (BTU_HCI_RCV_MBOX)) != NULL)
{
switch (p_msg->event & BT_EVT_MASK)
{
case BT_EVT_TO_BTU_HCI_ACL:
/* All Acl Data goes to L2CAP */
l2c_rcv_acl_data (p_msg);
break;
case BT_EVT_TO_BTU_HCI_EVT:
btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
GKI_freebuf(p_msg);
break;
}
}
}
}
}
Btu_hcif.c (external\bluetooth\bluedroid\stack\btu)
void btu_hcif_process_event (UINT8 controller_id, BT_HDR *p_msg)
{
case HCI_INQUIRY_RESULT_EVT:
btu_hcif_inquiry_result_evt (p); // BR/EDR
break;
case HCI_BLE_EVENT:
STREAM_TO_UINT8 (ble_sub_code, p);
switch (ble_sub_code)
case HCI_BLE_ADV_PKT_RPT_EVT:
btu_ble_process_adv_pkt(p); // BLE
btm_ble_process_adv_pkt(p) //Btm_ble_gap.c (external\bluetooth\bluedroid\stack\btm)
btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p);
(p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); // 调用bta_dm_inq_results_cb
(p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);// 调用bta_dm_observe_results_cb
}
btm_ble_process_adv_pkt 地址解析,然后调用btm_ble_process_adv_pkt_cont, btm_ble_process_adv_pkt_cont查询并更新查询数据库btm_cb.btm_inq_vars.inq_db,包括设备类型,设备COD等。
p_inq->p_inq_results_cb扫描回调指向bta_dm_inq_results_cb,在BTM_StartInquiry时被设置。
Bta_dm_act.c (external\bluetooth\bluedroid\bta\dm)
bta_dm_inq_results_cb 调用bta_dm_search_cb.p_search_cback即BTA_DmSearch函数传进来的回调函数bte_search_devices_evt。
static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result); // bte_search_devices_evt
Btif_dm.c (external\bluetooth\bluedroid\btif\src)
static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
// Switches context from BTE to BTIF for DM search events
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);
p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */
p_msg->p_cb = p_cback;
p_msg->event = event; /* callback event */
btif_sendmsg(p_msg);
GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);
切换上下文至btif_task, 最终调用到btif_dm_search_devices_evt。
Btif_dm.c (external\bluetooth\bluedroid\btif\src)
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);
把收到的广播数据保存在storage中, 最后调用HAL_CBACK, 即调bt_hal_cbacks->device_found_cb。bt_hal_cbacks在bluetooth.c的bluetoothInterface->init函数中被赋值。
com_android_bluetooth_btservice_AdapterService.cpp (packages\apps\bluetooth\jni)
static bool initNative(JNIEnv* env, jobject obj)
int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
static bt_callbacks_t sBluetoothCallbacks = {
sizeof(sBluetoothCallbacks),
adapter_state_change_callback,
adapter_properties_callback,
remote_device_properties_callback,
device_found_callback,
remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val, num_properties, properties);
//java的方法deviceFoundCallback
//classInitNative -> method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
};
查看method_deviceFoundCallback的赋值:
static void classInitNative(JNIEnv* env, jclass clazz) {
jclass jniCallbackClass = env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
JniCallbacks.java (packages\apps\bluetooth\src\com\android\bluetooth\btservice)
void deviceFoundCallback(byte[] address)
mRemoteDevices.deviceFoundCallback(address);
// The device properties are already registered - we can send the intent
BluetoothDevice device = getDevice(address); // RemoteDevices.java
DeviceProperties deviceProp = getDeviceProperties(device);
Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
intent.putExtra(BluetoothDevice.EXTRA_CLASS,
new BluetoothClass(Integer.valueOf(deviceProp.mBluetoothClass)));
intent.putExtra(BluetoothDevice.EXTRA_RSSI, deviceProp.mRssi);
intent.putExtra(BluetoothDevice.EXTRA_NAME, deviceProp.mName);
mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_PERM);
BluetoothEventManager.java (packages\apps\settings\src\com\android\settings\bluetooth)
BluetoothEventManager(LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager, Context context)
addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
private class DeviceFoundHandler implements Handler {
public void onReceive(Context context, Intent intent,
BluetoothDevice device) {
short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
BluetoothClass btClass = intent.getParcelableExtra(BluetoothDevice.EXTRA_CLASS);
String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
if (cachedDevice == null) {
cachedDevice = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, device);
//更新UI, callback to UI to create Preference for new device
dispatchDeviceAdded(cachedDevice);
for (BluetoothCallback callback : mCallbacks)
callback.onDeviceAdded(cachedDevice);
}
// 缓存设备
cachedDevice.setRssi(rssi);
cachedDevice.setBtClass(btClass);
cachedDevice.setNewName(name);
cachedDevice.setVisible(true);
}
缓存的设备用于apk扫描读取,我们主要看下ui更新过程:
BluetoothCallback定义及注册回调:
private final Collection<BluetoothCallback> mCallbacks =
new ArrayList<BluetoothCallback>();
/** Register to start receiving callbacks for Bluetooth events. */
void registerCallback(BluetoothCallback callback) {
synchronized (mCallbacks) {
mCallbacks.add(callback);
}
}
DeviceListPreferenceFragment.java (packages\apps\settings\src\com\android\settings\bluetooth)
/* Parent class for settings fragments that contain a list of Bluetooth devices */
public abstract class DeviceListPreferenceFragment extends
RestrictedSettingsFragment implements BluetoothCallback {
LocalBluetoothManager mLocalManager;
public void onResume() {
super.onResume();
// call BluetoothEventManager.registerCallback
mLocalManager.getEventManager().registerCallback(this);
}
// 把设备加入蓝牙列表
public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
createDevicePreference(cachedDevice);
BluetoothDevicePreference preference = new BluetoothDevicePreference(
getActivity(), cachedDevice);
mDeviceListGroup.addPreference(preference)
}
附:扫描开启过程中回调函数注册过程:
bt_status_t btif_dm_start_discovery(void)
BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
p_msg->p_cback = p_cback; //p_cback是第三个参数即 bte_search_devices_evt
bta_sys_sendmsg(p_msg);
btu_task
bta_sys_event(p_msg)
bta_dm_search_reg->bta_dm_search_sm_execute->bta_dm_search_start(p_msg)
bta_dm_search_cb.p_search_cback = p_data->search.p_cback; // bta_dm_search_cb.p_search_cback 回调等于 bte_search_devices_evt
bta_dm_search_cb.services = p_data->search.services;
BTM_StartInquiry( (tBTM_INQ_PARMS*)&p_data->search.inq_params,
bta_dm_inq_results_cb, // p_inq->p_inq_results_cb 回调等于 bta_dm_inq_results_cb
(tBTM_CMPL_CB*) bta_dm_inq_cmpl_cb); p_inq->p_inq_cmpl_cb;回调等于 bta_dm_inq_cmpl_cb
从前面的代码中可以看到, 设置扫描参数的命令是HCI_BLE_WRITE_SCAN_PARAMS,
启动扫描的命令是HCI_BLE_WRITE_SCAN_ENABLE,查看两个宏的定义:
Hcidefs.h (external\bluetooth\bluedroid\stack\include)
HCI_GRP_BLE_CMDS表示BLE HCI命令,值为0x2000
/* BLE HCI */
#define HCI_GRP_BLE_CMDS (0x08 << 10) //0x2000
/* Commands of BLE Controller setup and configuration */
#define HCI_BLE_WRITE_SCAN_PARAMS (0x000B | HCI_GRP_BLE_CMDS)
#define HCI_BLE_WRITE_SCAN_ENABLE (0x000C | HCI_GRP_BLE_CMDS)
下面以启动扫描为例讲述BlueDroid协议栈HCI命令构建:
Hciblecmds.c (external\bluetooth\bluedroid\stack\hcic)
BOOLEAN btsnd_hcic_ble_set_scan_enable (UINT8 scan_enable, UINT8 duplicate)
{
BT_HDR *p; // 命令结构
UINT8 *pp;
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE)) == NULL)
return (FALSE);
pp = (UINT8 *)(p + 1); // 指向 data[]
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE;
p->offset = 0;
UINT16_TO_STREAM (pp, HCI_BLE_WRITE_SCAN_ENABLE);
UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE);
UINT8_TO_STREAM (pp, scan_enable);
UINT8_TO_STREAM (pp, duplicate);
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
}
查看BT_HDR结构体定义:
Bt_types.h (external\bluetooth\bluedroid\stack\include)
/* Define the header of each buffer used in the Bluetooth stack.*/
typedef struct
{
uint16_t event;
uint16_t len;
uint16_t offset;
uint16_t layer_specific;
uint8_t data[];
} BT_HDR;
#define BT_HDR_SIZE (sizeof (BT_HDR))
btsnd_hcic_ble_set_scan_enable首先为BT_HDR结构体指针p分配buf, 然后让指针pp指向BT_HDR里面的data,然后对data进行填充,函数结束后:
BT_HDR p = {
.event =0; // 未被赋值
.len = 5; // data数组的大小
.offset = 0;
.layer_specific = 0; //未被赋值
/* pp */.data[] = {HCI_BLE_WRITE_SCAN_ENABLE, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE, scan_enable, duplicate };
}
继续往下跟:
#define BT_EVT_TO_LM_HCI_CMD 0x2000 /* HCI Command */
#define BT_EVT_TO_LM_HCI_ACL 0x2100 /* HCI ACL Data */
void btu_hcif_send_cmd (UINT8 controller_id, BT_HDR *p_buf)
HCI_CMD_TO_LOWER(p_buf);
bte_main_hci_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_CMD);
UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */
p_msg->event = event; // BT_HDR 里面的event被赋值
// 调用Bt_hci_bdroid.c中的bluetoothHCLibInterface->transmit_buf
bt_hc_if->transmit_buf((TRANSAC)p_msg, (char *) (p_msg + 1), p_msg->len);
bthc_tx((HC_BT_HDR *)transac);
utils_enqueue(&tx_q, buf);//把消息放入tx_q
thread_post(hc_cb.worker_thread, event_tx, NULL); //event_tx将被执行
HC_BT_HDR *p_msg = p_next_msg;
p_next_msg = utils_getnext(p_msg);//从tx_q里面取出消息
sending_msg_que[sending_msg_count++] = p_msg;//保存到数组
for(size_t i = 0; i < sending_msg_count; i++)
p_hci_if->send(sending_msg_que[i]);//hci_h4_func_table中的hci_h4_send_msg将被调用
这里p->event在bte_main_hci_send函数中被设置成BT_EVT_TO_LM_HCI_CMD(0x2000),此时要发送的消息为:
BT_HDR p = {
.event = BT_EVT_TO_LM_HCI_CMD; // 0x2000
.len = 5; // data数组的大小
.offset = 0;
.layer_specific = 0; //未被赋值
/* pp */.data[] = {HCI_BLE_WRITE_SCAN_ENABLE, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE, scan_enable, duplicate };
}
Hci_h4.c (external\bluetooth\bluedroid\hci\src)
消息格式在这里是HC_BT_HDR,和BT_HDR结构完全一样只是名字不同。
typedef struct
{
uint16_t event;
uint16_t len;
uint16_t offset;
uint16_t layer_specific;
uint8_t data[];
} HC_BT_HDR;
/*******************************************************************************
** Function hci_h4_send_msg
** Description Determine message type, set HCI H4 packet indicator, and
** send message through USERIAL driver
*******************************************************************************/
void hci_h4_send_msg(HC_BT_HDR *p_msg)
{
uint8_t type = 0;
uint16_t handle;
uint16_t bytes_to_send, lay_spec;
uint8_t *p = ((uint8_t *)(p_msg + 1)) + p_msg->offset;
uint16_t event = p_msg->event & MSG_EVT_MASK;
uint16_t sub_event = p_msg->event & MSG_SUB_EVT_MASK;
uint16_t acl_pkt_size = 0, acl_data_size = 0;
uint16_t bytes_sent;
// 将event类型转换成HCI类型
if (event == MSG_STACK_TO_HC_HCI_ACL)
type = H4_TYPE_ACL_DATA;
else if (event == MSG_STACK_TO_HC_HCI_SCO)
type = H4_TYPE_SCO_DATA;
else if (event == MSG_STACK_TO_HC_HCI_CMD)
type = H4_TYPE_COMMAND;
if (sub_event == LOCAL_BR_EDR_CONTROLLER_ID)
{
acl_data_size = h4_cb.hc_acl_data_size;
acl_pkt_size = h4_cb.hc_acl_data_size + HCI_ACL_PREAMBLE_SIZE;
}
else
{
acl_data_size = h4_cb.hc_ble_acl_data_size;
acl_pkt_size = h4_cb.hc_ble_acl_data_size + HCI_ACL_PREAMBLE_SIZE;
}
/* Check if sending ACL data that needs fragmenting */
if ((event == MSG_STACK_TO_HC_HCI_ACL) && (p_msg->len > acl_pkt_size))
{
p = ((uint8_t *)(p_msg + 1)) + p_msg->offset - 1;
*p = type;
bytes_to_send = acl_pkt_size + 1; /* packet_size + message type */
// 通过uart发送命令/数据
bytes_sent = userial_write(event,(uint8_t *) p,bytes_to_send);
/* 生成bsnoop跟踪消息 */
btsnoop_capture(p_msg, false);
}
p = ((uint8_t *)(p_msg + 1)) + p_msg->offset - 1;
*p = type;
bytes_to_send = p_msg->len + 1;
// 通过uart发送命令/数据
bytes_sent = userial_write(event,(uint8_t *) p, bytes_to_send);
p_msg->layer_specific = lay_spec;
/* 生成bsnoop跟踪消息 */
btsnoop_capture(p_msg, false);
return;
}
hci_h4_send_msg主要以下工作:
1)根据消息的event得到event和sub_event
2)根据event得到hci类型,根据sub_event得到acl_data_size和acl_packet_size
3)通过uart发送消息:
4)生成btsnoop追踪数据
5)回调uart写成功状态,实际命令发送状态由userial_read_thread来完成。