一、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)。