一、bta_sys_sendmsg
void bta_sys_sendmsg(void* p_msg)
功能:在bt_main_thread线程执行bta_sys_cb.reg[id]->evt_hdlr(p_msg),其中id是p_msg->event归属的消息类别。
如何快速判断bta_sys_cb.reg[id]->evt_hdlr指向哪个函数,这分三步。
- 找到p_msg->event消息码的类别。这从对它的定义能看到。针对消息码BTA_GATTC_API_OPEN_EVT,它的消息类别是BTA_ID_GATTC,
- bta_sys_register(id, p_reg)用于把消息码处理函数赋值给bta_sys_cb.reg,找到以第一个参数是该消息码类别的调用bta_sys_register代码。这时第二个参数记为p_reg。针对BTA_GATTC_API_OPEN_EVT,赋值bta_sys_cb.reg[id]时的调用代码是bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg),第二个参数是bta_gattc_reg。
- p_reg->evt_hdlr就是我们要找到的消息处理函数。针对BTA_GATTC_API_OPEN_EVT,bta_gattc_reg.evt_hdlr是bta_gattc_hdl_event,它就要找的消息处理函数
接下让进入代码。
<aosp>/system/bt/bta/sys/bta_sys_main.cc
------
void bta_sys_sendmsg(void* p_msg) {
if (do_in_main_thread(
FROM_HERE,
base::Bind(&bta_sys_event, static_cast<BT_HDR_RIGID*>(p_msg))) !=
BT_STATUS_SUCCESS) {
LOG(ERROR) << __func__ << ": do_in_main_thread failed";
}
}
<aosp>/system/bt/bta/sys/bta_sys_main.cc
------
static void bta_sys_event(BT_HDR_RIGID* p_msg) {
uint8_t id;
bool freebuf = true;
APPL_TRACE_EVENT("%s: Event 0x%x", __func__, p_msg->event);
/* get subsystem id from event */
id = (uint8_t)(p_msg->event >> 8);
/* verify id and call subsystem event handler */
if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
} else {
LOG_INFO("Ignoring receipt of unregistered event id:%s",
BtaIdSysText(id).c_str());
}
if (freebuf) {
osi_free(p_msg);
}
}bta_sys_sendmsg做的是让在bt_main_thread线程执行bta_sys_event,内中着重调用以下这条语句。
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
要理解这个,首先说下bt协议栈定义消息码的机制,当然,这些消息码不是蓝牙标准,只是bt协议栈内部使用。
#define BTA_ID_GATTC 31 /* GATT Client */
#define BTA_SYS_EVT_START(id) ((id) << 8)
enum {
BTA_GATTC_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_GATTC),
BTA_GATTC_INT_OPEN_FAIL_EVT,
BTA_GATTC_API_CANCEL_OPEN_EVT,
BTA_GATTC_INT_CANCEL_OPEN_OK_EVT,
BTA_GATTC_API_READ_EVT,
BTA_GATTC_API_WRITE_EVT,
BTA_GATTC_API_EXEC_EVT,
BTA_GATTC_API_CFG_MTU_EVT,
BTA_GATTC_API_CLOSE_EVT,
BTA_GATTC_API_SEARCH_EVT,
...
};
<apsp>/system/bt/bta/sys/bta_sys_int.h
------
/* system manager control block */
typedef struct {
tBTA_SYS_REG* reg[BTA_ID_MAX]; /* registration structures */
bool is_reg[BTA_ID_MAX]; /* registration structures */
bool forward_hw_failures;
uint16_t sys_features; /* Bitmask of sys features */
......
} tBTA_SYS_CB;
<aosp>/system/bt/bta/sys/bta_sys.h
------
/* registration structure */
typedef struct {
tBTA_SYS_EVT_HDLR* evt_hdlr;
tBTA_SYS_DISABLE* disable;
} tBTA_SYS_REG;
<aosp>/system/bt/bta/sys/bta_sys_main.cc
------
void bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg) {
bta_sys_cb.reg[id] = (tBTA_SYS_REG*)p_reg;
bta_sys_cb.is_reg[id] = true;
}
<aosp>/system/bt/bta/gatt/bta_gattc_api.cc
------
void BTA_GATTC_AppRegister(tBTA_GATTC_CBACK* p_client_cb,
BtaAppRegisterCallback cb, bool eatt_support) {
if (!bta_sys_is_register(BTA_ID_GATTC))
bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
do_in_main_thread(
FROM_HERE, base::Bind(&bta_gattc_register, Uuid::GetRandom(), p_client_cb,
std::move(cb), eatt_support));
}
<aosp>/system/bt/bta/gatt\bta_gattc_api.cc
------
static const tBTA_SYS_REG bta_gattc_reg = {bta_gattc_hdl_event,
BTA_GATTC_Disable};- 将消息码进行分类,消息码16位,高8位是类别,低8位是该类别下的二级值。以BTA_GATTC_API_OPEN_EVT为例,它属于BTA_ID_GATTC这个类别,在该类别下,它的二级码是0。同样的,BTA_GATTC_API_SEARCH_EVT也属于BTA_ID_GATTC类别,二级值则是9。
- 既然定义了消息码,那就需要实现处理这些消息的函数,这些函数被集中放在一个全局变量:tBTA_SYS_CB bta_sys_cb,具体是当中的reg[BTA_ID_MAX]。
- reg[BTA_ID_MAX]中的一单元对应处理某一类别的消息码。举个例子,reg[BTA_ID_GATTC]对应处理BTA_ID_GATTC类别的消息码,像BTA_GATTC_API_OPEN_EVT、BTA_GATTC_API_SEARCH_EVT。
- bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg)执行着将具体消息处理函数赋值到bta_sys_cb。对不同消息类型,这赋值时机自然是不同的,具体到BTA_ID_GATTC,那就是btif_gattc_register_app时的BTA_GATTC_AppRegister。
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
结合以上规则,再看上面这条语句,对消息码BTA_GATTC_API_OPEN_EVT,那就是:freebuf = bta_gattc_hdl_event(p_msg)。
二、bta_gattc_cback、btif_gattc_upstreams_evt
void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data); 常以类似下面语句被调用,p_clreg->p_cback就是bta_gattc_cback (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
bta_gattc_cback功能:在bt_jni_thread线程执行btif_gattc_upstreams_evt(event, p_data),参数event、p_data分别是传给bta_gattc_cback的第一、第二个参数。
又因为btif_gattc_upstreams_evt主要工作是调用HAL_CBACK,这是一个宏,它的功能是用于回调bt-JNI注册到bt协议栈函数,换句话说,bta_gattc_cback用于bt协议栈把此次操作的处理结果反馈到bt-JNI。
以上是结论,接下进入分析过程。bt协议栈:connectGatt之btif_gattc_open中有写,btif_gattc_open通过调用bta_gattc_send_open_cback,把此次处理结果反馈到bt-JNI。
<aosp>/system/bt/bta/gatt/bta_gattc_utils.cc
------
void bta_gattc_send_open_cback(tBTA_GATTC_RCB* p_clreg, tGATT_STATUS status,
const RawAddress& remote_bda, uint16_t conn_id,
tBT_TRANSPORT transport, uint16_t mtu) {
tBTA_GATTC cb_data;
if (p_clreg->p_cback) {
memset(&cb_data, 0, sizeof(tBTA_GATTC));
cb_data.open.status = status;
cb_data.open.client_if = p_clreg->client_if;
cb_data.open.conn_id = conn_id;
cb_data.open.mtu = mtu;
cb_data.open.transport = transport;
cb_data.open.remote_bda = remote_bda;
(*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
}
}在bta_gattc_send_open_cback,生成cb_data结构后,以它为参数调用p_clreg->p_cback,那这个p_clcb来自哪里?
回看“图1 bta_gattc_cb”,p_clreg就是cl_rcb[BTA_GATTC_CL_MAX]数组中的某个cl_rcb。cl_rcb是全局数组的一个单元,内存分配不用管了,那它何时填充有效数据?——我们知道连接peripheral时第一个操作是btif_gattc_register_app,也就是在那时填充了cl_rcb。
<aosp>/system/bt/bta/gatt/bta_gattc_act.cc
------
/** Register a GATT client application with BTA */
void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback,
BtaAppRegisterCallback cb, bool eatt_suppport) {
...
for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i++) {
if (!bta_gattc_cb.cl_rcb[i].in_use) {
if ((bta_gattc_cb.cl_rcb[i].client_if = GATT_Register(
app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_suppport)) ==
0) {
...
} else {
bta_gattc_cb.cl_rcb[i].in_use = true;
// p_cback是传给BTA_GATTC_AppRegister的第一个参数,即bta_gattc_cback
bta_gattc_cb.cl_rcb[i].p_cback = p_cback;
...
break;
}
}
}
...
}bt协议栈:connectGatt之btif_gattc_register_app有细说bta_gattc_registe,它有4个操作,其中第二个是给bta_gattc_cb.cl_rcb[i]各字段赋值,当中有包括p_cback。右侧的参数p_cback来自哪里?——是传给BTA_GATTC_AppRegister的第一个参数,即全局变量bta_gattc_cback。深入bta_gattc_cback,看它执行了什么。
<aosp>/system/bt/btif/src/btif_gatt_client.cc
------
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,
(char*)p_data, sizeof(tBTA_GATTC), NULL);
ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}
<aosp>/system/bt/btif/src/btif_core.cc
------
bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event,
char* p_params, int param_len,
tBTIF_COPY_CBACK* p_copy_cback) {
tBTIF_CONTEXT_SWITCH_CBACK* p_msg = (tBTIF_CONTEXT_SWITCH_CBACK*)osi_malloc(
sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len);
BTIF_TRACE_VERBOSE("btif_transfer_context event %d, len %d", event,
param_len);
/* allocate and send message that will be executed in btif context */
p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */
// p_cback指向btif_gattc_upstreams_evt,它赋值给p_msg->p_cb
p_msg->p_cb = p_cback;
// event来自传给bta_gattc_cback的第一个参数,示例是BTA_GATTC_OPEN_EVT
p_msg->event = event; /* callback event */
/* check if caller has provided a copy callback to do the deep copy */
if (p_copy_cback) {
p_copy_cback(event, p_msg->p_param, p_params);
} else if (p_params) {
// 源p_params来自传给bta_gattc_cback的第二个参数p_data,示例是“&cb_data”。
memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */
}
do_in_jni_thread(base::Bind(&bt_jni_msg_ready, p_msg));
return BT_STATUS_SUCCESS;
}
static void bt_jni_msg_ready(void* context) {
tBTIF_CONTEXT_SWITCH_CBACK* p = (tBTIF_CONTEXT_SWITCH_CBACK*)context;
if (p->p_cb) p->p_cb(p->event, p->p_param);
osi_free(p);
}bta_gattc_cback以p_copy_cback==nullptr调用btif_transfer_context,结合btif_transfer_context、bt_jni_msg_ready代码,可小结bta_gattc_cback功能:在bt_jni_thread线程执行btif_gattc_upstreams_evt(event, p_data),参数event、p_data分别是传给bta_gattc_cback的第一、第二个参数。
<aosp>/system/bt/btif/src/btif_gatt_client.cc
------
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_OPEN_EVT: {
DVLOG(1) << "BTA_GATTC_OPEN_EVT " << p_data->open.remote_bda;
HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id,
p_data->open.status, p_data->open.client_if,
p_data->open.remote_bda);
if (GATT_DEF_BLE_MTU_SIZE != p_data->open.mtu && p_data->open.mtu) {
HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb,
p_data->open.conn_id, p_data->open.status, p_data->open.mtu);
}
if (p_data->open.status == GATT_SUCCESS)
btif_gatt_check_encrypted_link(p_data->open.remote_bda,
p_data->open.transport);
break;
}
case BTA_GATTC_CLOSE_EVT: {
HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id,
p_data->close.status, p_data->close.client_if,
p_data->close.remote_bda);
break;
}
...
default:
LOG_ERROR("Unhandled event (%d)!", event);
break;
}
}在btif_gattc_upstreams_evt,它的主要工作就是调用HAL_CBACK,这是一个宏,它的功能是用于回调bt-JNI注册到bt协议栈函数,换句话说,bt协议栈把此次处理结果反馈到bt-JNI。
三、HAL_CBACK
#define HAL_CBACK(P_CB, P_CBACK, ...)
HAL_CBACK是一个宏,调用时一般采用下面形式
HAL_CBACK(bt_gatt_callbacks, client->register_client_cb, status, client_id, uuid); HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id, p_data->open.status, p_data->open.client_if, p_data->open.remote_bda);
第一个参数是一个结构s,第二个参数是结构s中的一个字段,是函数f,后面则是要传给函数f的参数。如果第一个参数是bt_gatt_callbacks,第二个参数又是“client->”为前缀,那HAL_CBACK功能是执行位在bt-JNI内的、变量sGattClientCallbacks中的某个函数。在用途上,一般用于bt协议栈把此次操作结果返馈给bt-JNI。
| struct btgatt_client_callbacks_t | (bt-JNI)sGattClientCallbacks中函数 | bt协议栈操作/调用时机 |
| register_client_cb | btgattc_register_app_cb | btif_gattc_register_app |
| open_cb | btgattc_open_cb | btif_gattc_open |
| close_cb | btgattc_close_cb | |
| search_complete_cb | btgattc_search_complete_cb | btif_gattc_search_service |
| ... | ... | ... |
以“HAL_CBACK(bt_gatt_callbacks, client->register_client_cb, status, client_id, uuid)”为例,分析HAL_CBACK。
<aosp>/system/bt/btif/include/btif_common.h
------
#define HAL_CBACK(P_CB, P_CBACK, ...) \
do { \
if ((P_CB) && (P_CB)->P_CBACK) { \
BTIF_TRACE_API("%s: HAL %s->%s", __func__, #P_CB, #P_CBACK); \
(P_CB)->P_CBACK(__VA_ARGS__); \
} else { \
ASSERTC(0, "Callback is NULL", 0); \
} \
} while (0)这里展开一下,并替换其中实际的变量:
bt_gatt_callbacks->client->register_client_cb(status, client_if, uuid);
可以看到这里就是执行一个回调函数。
现在问题是bt_gatt_callbacks是谁?我们可以看到它是在btif_gatt_init初始化的:
const btgatt_callbacks_t* bt_gatt_callbacks;
<aosp>/system/bt/btif/src/btif_gatt.c
------
static bt_status_t btif_gatt_init(const btgatt_callbacks_t* callbacks) {
bt_gatt_callbacks = callbacks;
return BT_STATUS_SUCCESS;
}
<aosp>/system/bt/btif/src/btif_gatt.cc
------
static btgatt_interface_t btgattInterface = {
.size = sizeof(btgattInterface),
.init = btif_gatt_init,
.cleanup = btif_gatt_cleanup,
.client = &btgattClientInterface,
.server = &btgattServerInterface,
.scanner = nullptr, // filled in btif_gatt_get_interface
.advertiser = nullptr // filled in btif_gatt_get_interface
};也就是btif_gatt_init时候,通过参数传递进来。在分析api如何从frameworks到bt-JNI时,已经看到了初始化btgattInterface,这里的btif_gatt_init函数就赋值给了它的init成员。
通过前面的分析,bt-JNI层的sGattIf实际指向的就是这个btgattInterface对象。我们回到bt-JNI层的代码:
<aosp>/packages/apps/Bluetooth/jni/com_android_bluetooth_gatt.cpp
------
static void initializeNative(JNIEnv* env, jobject object) {
...
// 这里我们前面分析过,bt-JNI中的sGattIf指向bt协议栈中的btif_gatt_init。
sGattIf =
(btgatt_interface_t*)btIf->get_profile_interface(BT_PROFILE_GATT_ID);
if (sGattIf == NULL) {
error("Failed to get Bluetooth GATT Interface");
return;
}
// 调用了这时说的初始化方法init(...)
bt_status_t status = sGattIf->init(&sGattCallbacks);
if (status != BT_STATUS_SUCCESS) {
error("Failed to initialize Bluetooth GATT, status: %d", status);
sGattIf = NULL;
return;
}
sGattIf->advertiser->RegisterCallbacks(
JniAdvertisingCallbacks::GetInstance());
sGattIf->scanner->RegisterCallbacks(JniScanningCallbacks::GetInstance());
mCallbacksObj = env->NewGlobalRef(object);
}这里调用了sGattIf->init(...)方法,实际上就是前面的btif_gatt_init(...)函数。于是我们可以到这个结论,bt协议栈中的bt_gatt_callbacks,它指向的是bt-JNI中的sGattCallbacks对象。
<aosp>/packages/apps/Bluetooth/jni/com_android_bluetooth_gatt.cpp
------
static const btgatt_callbacks_t sGattCallbacks = {
sizeof(btgatt_callbacks_t), // => size
&sGattClientCallbacks, // => client
&sGattServerCallbacks, // => server
&sGattScannerCallbacks, // => scanner
};
<aosp>/packages/apps/Bluetooth/jni/com_android_bluetooth_gatt.cpp
------
static const btgatt_client_callbacks_t sGattClientCallbacks = {
btgattc_register_app_cb, // => register_client_cb
btgattc_open_cb, // => open_cb
btgattc_close_cb, // => close_cb
btgattc_search_complete_cb, // => search_complete_cb
...
btgattc_get_gatt_db_cb, // => get_gatt_db_cb
NULL, /* services_removed_cb */
NULL, /* services_added_cb */
btgattc_phy_updated_cb, // => phy_updated_cb
btgattc_conn_updated_cb, // => conn_updated_cb
btgattc_service_changed_cb, // => service_changed_cb
};回到上面这个例子,
bt_gatt_callbacks->client->register_client_cb(status, client_if, uuid);
等于执行bt-JNI中的btgattc_register_app_cb(status, client_if, uuid)。