本文主要就是分析下startLeScan方法(两个重载方法)。
public boolean startLeScan(LeScanCallback callback) { return startLeScan(null, callback); }
public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) { if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids); if (callback == null) { if (DBG) Log.e(TAG, "startLeScan: null callback"); return false; } synchronized(mLeScanClients) { if (mLeScanClients.containsKey(callback)) { if (DBG) Log.e(TAG, "LE Scan has already started"); return false; } try { IBluetoothGatt iGatt = mManagerService.getBluetoothGatt(); if (iGatt == null) { // BLE is not supported return false; } UUID uuid = UUID.randomUUID(); GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids); iGatt.registerClient(new ParcelUuid(uuid), wrapper); if (wrapper.scanStarted()) { mLeScanClients.put(callback, wrapper); return true; } } catch (RemoteException e) { Log.e(TAG,"",e); } } return false; }
下面来分析下iGatt.registerClient(newParcelUuid(uuid), wrapper);方法,路径如下:(packages/apps/Bluetooth/src/com/android/bluetooth/gatt/GattService.java::BluetoothGattBinder)
public void registerClient(ParcelUuid uuid, IBluetoothGattCallback callback) { GattService service = getService(); if (service == null) return; service.registerClient(uuid.getUuid(), callback); }
接着会调用GattService服务的同名方法
void registerClient(UUID uuid, IBluetoothGattCallback callback) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); if (DBG) Log.d(TAG, "registerClient() - UUID=" + uuid); mClientMap.add(uuid, callback); gattClientRegisterAppNative(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); }
接下来会调用jni层com_android_bluetooth_gatt.cpp文件中的gattClientRegisterAppNative方法。
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->client->register_client(&uuid); 语句
(1)sGattIf是一个静态变量,定义是static const btgatt_interface_t *sGattIf = NULL;
又是这种类型的变量。第一反应就是去找btgatt_interface_t结构体定义的头文件(一般在hardware目录),然后再搜索调用的c文件(一般在external/bluetooth/bluedroid,有时找到的c文件与头文件同名)。
btgatt_interface_t结构体的定义:hardware/libhardware/include/hardware/bt_gatt.h
typedef struct { /** Set to sizeof(btgatt_interface_t) */ size_t size; /** * Initializes the interface and provides callback routines */ bt_status_t (*init)( const btgatt_callbacks_t* callbacks ); /** Closes the interface */ void (*cleanup)( void ); /** Pointer to the GATT client interface methods.*/ const btgatt_client_interface_t* client; /** Pointer to the GATT server interface methods.*/ const btgatt_server_interface_t* server; } btgatt_interface_t;
btgatt_interface_t结构体的对象:external/bluetooth/bluedroi/btif/src/btif_gatt.c
static const btgatt_interface_t btgattInterface = { sizeof(btgattInterface), btif_gatt_init, btif_gatt_cleanup, &btgattClientInterface, &btgattServerInterface, };
回到sGattIf->client->register_client(&uuid);语句,它调用了sGattIf结构体对象中的client对象的register_client函数,那么就是btgattClientInterface对象的register_client函数。
由结构体的定义可知client对象的类型是btgatt_client_interface_t结构体。同理分析可得以下结果,
btgatt_client_interface_t结构体的定义:hardware/libhardware/include/hardware/bt_gatt_client.h
typedef struct { /** Registers a GATT client application with the stack */ bt_status_t (*register_client)( bt_uuid_t *uuid ); /** Unregister a client application from the stack */ bt_status_t (*unregister_client)(int client_if ); /** Start or stop LE device scanning */ bt_status_t (*scan)( int client_if, bool start ); /** Create a connection to a remote LE or dual-mode device */ bt_status_t (*connect)( int client_if, const bt_bdaddr_t *bd_addr, bool is_direct ); /** Disconnect a remote device or cancel a pending connection */ bt_status_t (*disconnect)( int client_if, const bt_bdaddr_t *bd_addr, int conn_id); /** Start or stop advertisements to listen for incoming connections */ bt_status_t (*listen)(int client_if, bool start); /** Clear the attribute cache for a given device */ bt_status_t (*refresh)( int client_if, const bt_bdaddr_t *bd_addr ); /** * Enumerate all GATT services on a connected device. * Optionally, the results can be filtered for a given UUID. */ bt_status_t (*search_service)(int conn_id, bt_uuid_t *filter_uuid ); /** * Enumerate included services for a given service. * Set start_incl_srvc_id to NULL to get the first included service. */ bt_status_t (*get_included_service)( int conn_id, btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *start_incl_srvc_id); /** * Enumerate characteristics for a given service. * Set start_char_id to NULL to get the first characteristic. */ bt_status_t (*get_characteristic)( int conn_id, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id); /** * Enumerate descriptors for a given characteristic. * Set start_descr_id to NULL to get the first descriptor. */ bt_status_t (*get_descriptor)( int conn_id, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *start_descr_id); /** Read a characteristic on a remote device */ bt_status_t (*read_characteristic)( int conn_id, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int auth_req ); /** Write a remote characteristic */ bt_status_t (*write_characteristic)(int conn_id, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int write_type, int len, int auth_req, char* p_value); /** Read the descriptor for a given characteristic */ bt_status_t (*read_descriptor)(int conn_id, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id, int auth_req); /** Write a remote descriptor for a given characteristic */ bt_status_t (*write_descriptor)( int conn_id, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, btgatt_gatt_id_t *descr_id, int write_type, int len, int auth_req, char* p_value); /** Execute a prepared write operation */ bt_status_t (*execute_write)(int conn_id, int execute); /** * Register to receive notifications or indications for a given * characteristic */ bt_status_t (*register_for_notification)( int client_if, const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id); /** Deregister a previous request for notifications/indications */ bt_status_t (*deregister_for_notification)( int client_if, const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id); /** Request RSSI for a given remote device */ bt_status_t (*read_remote_rssi)( int client_if, const bt_bdaddr_t *bd_addr); /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */ int (*get_device_type)( const bt_bdaddr_t *bd_addr ); /** Set the advertising data or scan response data */ bt_status_t (*set_adv_data)(int server_if, bool set_scan_rsp, bool include_name, bool include_txpower, int min_interval, int max_interval, int appearance, uint16_t manufacturer_len, char* manufacturer_data); /** Test mode interface */ bt_status_t (*test_command)( int command, btgatt_test_params_t* params); } btgatt_client_interface_t;
btgatt_client_interface_t结构体的对象:external/bluetooth/bluedroid/btif/src/btif_gatt_client.c
const btgatt_client_interface_t btgattClientInterface = { btif_gattc_register_app, btif_gattc_unregister_app, btif_gattc_scan, btif_gattc_open, btif_gattc_close, btif_gattc_listen, btif_gattc_refresh, btif_gattc_search_service, btif_gattc_get_included_service, btif_gattc_get_characteristic, btif_gattc_get_descriptor, btif_gattc_read_char, btif_gattc_write_char, btif_gattc_read_char_descr, btif_gattc_write_char_descr, btif_gattc_execute_write, btif_gattc_reg_for_notification, btif_gattc_dereg_for_notification, btif_gattc_read_remote_rssi, btif_gattc_get_device_type, btif_gattc_set_adv_data, btif_gattc_test_command };
因此client->register_client就是调用了btif_gattc_register_app方法[-->btif_gatt_client.c]。
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); }
分析btgattc_handle_event函数
static void btgattc_handle_event(uint16_t event, char* p_param) { tBTA_GATT_STATUS status; tBT_UUID uuid; tBTA_GATT_SRVC_ID srvc_id; tGATT_CHAR_PROP out_char_prop; tBTA_GATTC_CHAR_ID in_char_id; tBTA_GATTC_CHAR_ID out_char_id; tBTA_GATTC_CHAR_DESCR_ID in_char_descr_id; tBTA_GATTC_CHAR_DESCR_ID out_char_descr_id; tBTA_GATTC_INCL_SVC_ID in_incl_svc_id; tBTA_GATTC_INCL_SVC_ID out_incl_svc_id; tBTA_GATT_UNFMT descr_val; btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*)p_param; if (!p_cb) return; ALOGD("%s: Event %d", __FUNCTION__, event); switch (event) { case BTIF_GATTC_REGISTER_APP: btif_to_bta_uuid(&uuid, &p_cb->uuid); BTA_GATTC_AppRegister(&uuid, bta_gattc_cback); break; case BTIF_GATTC_UNREGISTER_APP: BTA_GATTC_AppDeregister(p_cb->client_if); break; case BTIF_GATTC_SCAN_START: btif_gattc_init_dev_cb(); BTA_DmBleObserve(TRUE, 0, bta_scan_results_cb); break; case BTIF_GATTC_SCAN_STOP: BTA_DmBleObserve(FALSE, 0, 0); break; case BTIF_GATTC_OPEN: { // Ensure device is in inquiry database int addr_type = 0; int device_type = 0; if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE && device_type != BT_DEVICE_TYPE_BREDR) BTA_DmAddBleDevice(p_cb->bd_addr.address, addr_type, device_type); // Mark background connections if (!p_cb->is_direct) BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL); // Connect! BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct); break; } case BTIF_GATTC_CLOSE: // Disconnect established connections if (p_cb->conn_id != 0) BTA_GATTC_Close(p_cb->conn_id); else BTA_GATTC_CancelOpen(p_cb->client_if, p_cb->bd_addr.address, TRUE); // Cancel pending background connections (remove from whitelist) BTA_GATTC_CancelOpen(p_cb->client_if, p_cb->bd_addr.address, FALSE); break; case BTIF_GATTC_SEARCH_SERVICE: { if (p_cb->search_all) { BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, NULL); } else { btif_to_bta_uuid(&uuid, &p_cb->uuid); BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, &uuid); } break; } case BTIF_GATTC_GET_FIRST_CHAR: { btgatt_gatt_id_t char_id; btif_to_bta_srvc_id(&srvc_id, &p_cb->srvc_id); status = BTA_GATTC_GetFirstChar(p_cb->conn_id, &srvc_id, NULL, &out_char_id, &out_char_prop); if (status == 0) bta_to_btif_gatt_id(&char_id, &out_char_id.char_id); HAL_CBACK(bt_gatt_callbacks, client->get_characteristic_cb, p_cb->conn_id, status, &p_cb->srvc_id, &char_id, out_char_prop); break; } case BTIF_GATTC_GET_NEXT_CHAR: { btgatt_gatt_id_t char_id; btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id); status = BTA_GATTC_GetNextChar(p_cb->conn_id, &in_char_id, NULL, &out_char_id, &out_char_prop); if (status == 0) bta_to_btif_gatt_id(&char_id, &out_char_id.char_id); HAL_CBACK(bt_gatt_callbacks, client->get_characteristic_cb, p_cb->conn_id, status, &p_cb->srvc_id, &char_id, out_char_prop); break; } case BTIF_GATTC_GET_FIRST_CHAR_DESCR: { btgatt_gatt_id_t descr_id; btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id); status = BTA_GATTC_GetFirstCharDescr(p_cb->conn_id, &in_char_id, NULL, &out_char_descr_id); if (status == 0) bta_to_btif_gatt_id(&descr_id, &out_char_descr_id.descr_id); HAL_CBACK(bt_gatt_callbacks, client->get_descriptor_cb, p_cb->conn_id, status, &p_cb->srvc_id, &p_cb->char_id, &descr_id); break; } case BTIF_GATTC_GET_NEXT_CHAR_DESCR: { btgatt_gatt_id_t descr_id; btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id); btif_to_bta_gatt_id(&in_char_descr_id.descr_id, &p_cb->descr_id); status = BTA_GATTC_GetNextCharDescr(p_cb->conn_id, &in_char_descr_id , NULL, &out_char_descr_id); if (status == 0) bta_to_btif_gatt_id(&descr_id, &out_char_descr_id.descr_id); HAL_CBACK(bt_gatt_callbacks, client->get_descriptor_cb, p_cb->conn_id, status, &p_cb->srvc_id, &p_cb->char_id, &descr_id); break; } case BTIF_GATTC_GET_FIRST_INCL_SERVICE: { btgatt_srvc_id_t incl_srvc_id; btif_to_bta_srvc_id(&srvc_id, &p_cb->srvc_id); status = BTA_GATTC_GetFirstIncludedService(p_cb->conn_id, &srvc_id, NULL, &out_incl_svc_id); bta_to_btif_srvc_id(&incl_srvc_id, &out_incl_svc_id.incl_svc_id); HAL_CBACK(bt_gatt_callbacks, client->get_included_service_cb, p_cb->conn_id, status, &p_cb->srvc_id, &incl_srvc_id); break; } case BTIF_GATTC_GET_NEXT_INCL_SERVICE: { btgatt_srvc_id_t incl_srvc_id; btif_to_bta_srvc_id(&in_incl_svc_id.srvc_id, &p_cb->srvc_id); btif_to_bta_srvc_id(&in_incl_svc_id.incl_svc_id, &p_cb->incl_srvc_id); status = BTA_GATTC_GetNextIncludedService(p_cb->conn_id, &in_incl_svc_id, NULL, &out_incl_svc_id); bta_to_btif_srvc_id(&incl_srvc_id, &out_incl_svc_id.incl_svc_id); HAL_CBACK(bt_gatt_callbacks, client->get_included_service_cb, p_cb->conn_id, status, &p_cb->srvc_id, &incl_srvc_id); break; } case BTIF_GATTC_READ_CHAR: btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id); BTA_GATTC_ReadCharacteristic(p_cb->conn_id, &in_char_id, p_cb->auth_req); break; case BTIF_GATTC_READ_CHAR_DESCR: btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id); btif_to_bta_gatt_id(&in_char_descr_id.descr_id, &p_cb->descr_id); BTA_GATTC_ReadCharDescr(p_cb->conn_id, &in_char_descr_id, p_cb->auth_req); break; case BTIF_GATTC_WRITE_CHAR: btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id); BTA_GATTC_WriteCharValue(p_cb->conn_id, &in_char_id, p_cb->write_type, p_cb->len, p_cb->value, p_cb->auth_req); break; case BTIF_GATTC_WRITE_CHAR_DESCR: btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id); btif_to_bta_gatt_id(&in_char_descr_id.descr_id, &p_cb->descr_id); descr_val.len = p_cb->len; descr_val.p_value = p_cb->value; BTA_GATTC_WriteCharDescr(p_cb->conn_id, &in_char_descr_id, p_cb->write_type, &descr_val, p_cb->auth_req); break; case BTIF_GATTC_EXECUTE_WRITE: BTA_GATTC_ExecuteWrite(p_cb->conn_id, p_cb->action); break; case BTIF_GATTC_REG_FOR_NOTIFICATION: btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id); status = BTA_GATTC_RegisterForNotifications(p_cb->client_if, p_cb->bd_addr.address, &in_char_id); HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb, p_cb->conn_id, 1, status, &p_cb->srvc_id, &p_cb->char_id); break; case BTIF_GATTC_DEREG_FOR_NOTIFICATION: btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id); btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id); status = BTA_GATTC_DeregisterForNotifications(p_cb->client_if, p_cb->bd_addr.address, &in_char_id); HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb, p_cb->conn_id, 0, status, &p_cb->srvc_id, &p_cb->char_id); break; case BTIF_GATTC_REFRESH: BTA_GATTC_Refresh(p_cb->bd_addr.address); break; case BTIF_GATTC_READ_RSSI: rssi_request_client_if = p_cb->client_if; BTM_ReadRSSI (p_cb->bd_addr.address, (tBTM_CMPL_CB *)btm_read_rssi_cb); break; case BTIF_GATTC_LISTEN: BTA_GATTC_Listen(p_cb->client_if, p_cb->start, NULL); break; case BTIF_GATTC_SET_ADV_DATA: { if (p_cb->start == 0) BTM_BleWriteAdvData(p_cb->adv_data.mask, &p_cb->adv_data.data); else BTM_BleWriteScanRsp(p_cb->adv_data.mask, &p_cb->adv_data.data); if (p_cb->adv_data.data.manu.p_val != NULL) GKI_freebuf(p_cb->adv_data.data.manu.p_val); break; } default: ALOGE("%s: Unknown event (%d)!", __FUNCTION__, event); break; } }
分析BTA_GATTC_AppRegister函数
void BTA_GATTC_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTC_CBACK *p_client_cb) { tBTA_GATTC_API_REG *p_buf; if (bta_sys_is_register(BTA_ID_GATTC) == FALSE) { GKI_sched_lock(); bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg); GKI_sched_unlock(); } if ((p_buf = (tBTA_GATTC_API_REG *) GKI_getbuf(sizeof(tBTA_GATTC_API_REG))) != NULL) { p_buf->hdr.event = BTA_GATTC_API_REG_EVT; if (p_app_uuid != NULL) memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID)); p_buf->p_cback = p_client_cb; bta_sys_sendmsg(p_buf); } return; }
(a) 通过bta_sys_register函数注册了bta_gatt_reg结构体中定义的客户端主事件处理函数bta_gattc_hdl_event;然后设置event为BTA_GATTC_API_REG_EV,触发bta_gattc_hdl_event函数。
static const tBTA_SYS_REG bta_gattc_reg = { bta_gattc_hdl_event, BTA_GATTC_Disable };
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg) { tBTA_GATTC_CB *p_cb = &bta_gattc_cb; tBTA_GATTC_CLCB *p_clcb = NULL; tBTA_GATTC_RCB *p_clreg; #if BTA_GATT_DEBUG == TRUE APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event)); #endif switch (p_msg->event) { case BTA_GATTC_API_DISABLE_EVT: bta_gattc_disable(p_cb); break; case BTA_GATTC_API_REG_EVT: bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg); break; case BTA_GATTC_INT_START_IF_EVT: bta_gattc_start_if(p_cb, (tBTA_GATTC_DATA *) p_msg); break; case BTA_GATTC_API_DEREG_EVT: p_clreg = bta_gattc_cl_get_regcb(((tBTA_GATTC_DATA *)p_msg)->api_dereg.client_if); bta_gattc_deregister(p_cb, p_clreg); break; case BTA_GATTC_API_OPEN_EVT: bta_gattc_process_api_open(p_cb, (tBTA_GATTC_DATA *) p_msg); break; case BTA_GATTC_API_CANCEL_OPEN_EVT: bta_gattc_process_api_open_cancel(p_cb, (tBTA_GATTC_DATA *) p_msg); break; case BTA_GATTC_API_REFRESH_EVT: bta_gattc_process_api_refresh(p_cb, (tBTA_GATTC_DATA *) p_msg); break; #if BLE_INCLUDED == TRUE case BTA_GATTC_API_LISTEN_EVT: bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg); break; #endif default: if (p_msg->event == BTA_GATTC_INT_CONN_EVT) p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg); else if (p_msg->event == BTA_GATTC_INT_DISCONN_EVT) p_clcb = bta_gattc_find_int_disconn_clcb((tBTA_GATTC_DATA *) p_msg); else p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific); if (p_clcb != NULL) { bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg); } else { APPL_TRACE_DEBUG1("Ignore unknown conn ID: %d", p_msg->layer_specific); } break; } return(TRUE); }
(b) 调用bta_gattc_register函数。该函数用来注册一个客户端Gatt应用程序。
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_DEBUG1("bta_gattc_register state %d",p_cb->state); memset(&cb_data, 0, sizeof(cb_data)); cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES; /* check if GATTC module is already enabled . Else enable */ if (p_cb->state == BTA_GATTC_STATE_DISABLED) { bta_gattc_enable (p_cb); } /* todo need to check duplicate uuid */ for (i = 0; i < BTA_GATTC_CL_MAX; i ++) { if (!p_cb->cl_rcb[i].in_use) { if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) { APPL_TRACE_ERROR0("Register with GATT stack failed."); status = BTA_GATT_ERROR; } else { 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; bta_sys_sendmsg(p_buf); status = BTA_GATT_OK; } else { GATT_Deregister(p_cb->cl_rcb[i].client_if); status = BTA_GATT_NO_RESOURCES; memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB)); } break; } } } /* 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; (*p_data->api_reg.p_cback)(BTA_GATTC_REG_EVT, (tBTA_GATTC *)&cb_data); } }
调用相关event(BTA_GATTC_REG_EVT)的回调函数。
到此,BTA_GATTC_AppRegister函数分析完毕,接下来分析BTA_GATTC_AppRegister(&uuid, bte_gattc_cback);中的参数部分。
ps:上述的回调函数就是这里的参数:bte_gattc_cback函数。那么BTA_GATTC_REG_EVT事件就调用该函数处理了。
分析回调函数bta_gattc_cback (这里很奇怪,Android4.4的代码是bte_gattc_cback,我用的代码虽然是4.4.2,但是是厂家给的,有无做修改不确定,请各自依据代码来学习开发)
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); ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status); }
分析btif_gattc_upstreams_evt函数,在该函数中会处理BTA_GATTC_REG_EVT事件。
static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) { ALOGD("%s: Event %d", __FUNCTION__, event); 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); HAL_CBACK(bt_gatt_callbacks, client->register_client_cb , p_data->reg_oper.status , p_data->reg_oper.client_if , &app_uuid ); break; } case BTA_GATTC_DEREG_EVT: break; case BTA_GATTC_READ_CHAR_EVT: { btgatt_read_params_t data; set_read_value(&data, &p_data->read); HAL_CBACK(bt_gatt_callbacks, client->read_characteristic_cb , p_data->read.conn_id, p_data->read.status, &data); break; } case BTA_GATTC_WRITE_CHAR_EVT: case BTA_GATTC_PREP_WRITE_EVT: { btgatt_write_params_t data; bta_to_btif_srvc_id(&data.srvc_id, &p_data->write.srvc_id); bta_to_btif_gatt_id(&data.char_id, &p_data->write.char_id); HAL_CBACK(bt_gatt_callbacks, client->write_characteristic_cb , p_data->write.conn_id, p_data->write.status, &data ); break; } case BTA_GATTC_EXEC_EVT: { HAL_CBACK(bt_gatt_callbacks, client->execute_write_cb , p_data->exec_cmpl.conn_id, p_data->exec_cmpl.status ); break; } case BTA_GATTC_SEARCH_CMPL_EVT: { HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb , p_data->search_cmpl.conn_id, p_data->search_cmpl.status); break; } case BTA_GATTC_SEARCH_RES_EVT: { btgatt_srvc_id_t data; bta_to_btif_srvc_id(&data, &(p_data->srvc_res.service_uuid)); HAL_CBACK(bt_gatt_callbacks, client->search_result_cb , p_data->srvc_res.conn_id, &data); break; } case BTA_GATTC_READ_DESCR_EVT: { btgatt_read_params_t data; set_read_value(&data, &p_data->read); HAL_CBACK(bt_gatt_callbacks, client->read_descriptor_cb , p_data->read.conn_id, p_data->read.status, &data); break; } case BTA_GATTC_WRITE_DESCR_EVT: { btgatt_write_params_t data; bta_to_btif_srvc_id(&data.srvc_id, &p_data->write.srvc_id); bta_to_btif_gatt_id(&data.char_id, &p_data->write.char_id); bta_to_btif_gatt_id(&data.descr_id, &p_data->write.descr_type); HAL_CBACK(bt_gatt_callbacks, client->write_descriptor_cb , p_data->write.conn_id, p_data->write.status, &data); break; } case BTA_GATTC_NOTIF_EVT: { btgatt_notify_params_t data; bdcpy(data.bda.address, p_data->notify.bda); bta_to_btif_srvc_id(&data.srvc_id, &p_data->notify.char_id.srvc_id); bta_to_btif_gatt_id(&data.char_id, &p_data->notify.char_id.char_id); memcpy(data.value, p_data->notify.value, p_data->notify.len); data.is_notify = p_data->notify.is_notify; data.len = p_data->notify.len; HAL_CBACK(bt_gatt_callbacks, client->notify_cb , p_data->notify.conn_id, &data); if (p_data->notify.is_notify == FALSE) { BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, &p_data->notify.char_id); } break; } case BTA_GATTC_OPEN_EVT: { bt_bdaddr_t bda; bdcpy(bda.address, 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, &bda); if (p_data->open.status == BTA_GATT_OK) btif_gatt_check_encrypted_link(p_data->open.remote_bda); break; } case BTA_GATTC_CLOSE_EVT: { bt_bdaddr_t bda; bdcpy(bda.address, p_data->close.remote_bda); HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id , p_data->status, p_data->close.client_if, &bda); break; } case BTA_GATTC_ACL_EVT: ALOGD("BTA_GATTC_ACL_EVT: status = %d", p_data->status); /* Ignore for now */ break; case BTA_GATTC_CANCEL_OPEN_EVT: break; case BTIF_GATT_OBSERVE_EVT: { btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param; if (!btif_gattc_find_bdaddr(p_btif_cb->bd_addr.address)) { btif_gattc_add_remote_bdaddr(p_btif_cb->bd_addr.address, p_btif_cb->addr_type); btif_gattc_update_properties(p_btif_cb); } HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb, &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value); break; } case BTIF_GATTC_RSSI_EVT: { btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param; HAL_CBACK(bt_gatt_callbacks, client->read_remote_rssi_cb, p_btif_cb->client_if, &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->status); break; } case BTA_GATTC_LISTEN_EVT: { HAL_CBACK(bt_gatt_callbacks, client->listen_cb , p_data->reg_oper.status , p_data->reg_oper.client_if ); break; } default: ALOGE("%s: Unhandled event (%d)!", __FUNCTION__, event); break; } btapp_gattc_free_req_data(event, p_data); }bt_gatt_callbacks 对象的类型是 btgatt_callbacks_t ,其定义在 hardware/libhardware/include/hardware/bt_gatt.h 文件中。现在对 bt_gatt_callbacks 对象从头开始分析其来源。
在GattService.java::start()方法中,调用了initializeNative方法。继而调用JNI层initializeNative方法。贴出该方法。
static void initializeNative(JNIEnv *env, jobject object) { if(btIf) return; if ( (btIf = getBluetoothInterface()) == NULL) { error("Bluetooth module is not loaded"); return; } if (sGattIf != NULL) { ALOGW("Cleaning up Bluetooth GATT Interface before initializing..."); sGattIf->cleanup(); sGattIf = NULL; } if (mCallbacksObj != NULL) { ALOGW("Cleaning up Bluetooth GATT callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } 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); }
(a) 分析
分析btif_gatt_get_interface函数
const btgatt_interface_t *btif_gatt_get_interface() { return &btgattInterface; }
btgattInterface对象的类型是btgatt_interface_t结构体。再贴一遍该结构体的定义,如下:
typedef struct { /** Set to sizeof(btgatt_interface_t) */ size_t size; /** * Initializes the interface and provides callback routines */ bt_status_t (*init)( const btgatt_callbacks_t* callbacks ); /** Closes the interface */ void (*cleanup)( void ); /** Pointer to the GATT client interface methods.*/ const btgatt_client_interface_t* client; /** Pointer to the GATT server interface methods.*/ const btgatt_server_interface_t* server; } btgatt_interface_t;
另,btgattInterface对象定义如下:
static const btgatt_interface_t btgattInterface = { sizeof(btgattInterface), btif_gatt_init, btif_gatt_cleanup, &btgattClientInterface, &btgattServerInterface, };
所以sGattIf 就是btgattInterface对象。
(c) 接下来调用sGattIf->init函数。由上可知,即为btif_gatt_init函数。
static bt_status_t btif_gatt_init( const btgatt_callbacks_t* callbacks ) { bt_gatt_callbacks = callbacks; return BT_STATUS_SUCCESS; }
到此为止,调用语句中bt_gatt_callbacks对象我们已经清楚了,就是sGattCallbacks对象。现在分析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 );
client对象是在btgatt_callbacks_t结构体中定义的一个变量,其初始化是在bt_gatt_callbacks对象(即sGattCallbacks对象)中。
typedef struct { /** Set to sizeof(btgatt_callbacks_t) */ size_t size; /** GATT Client callbacks */ const btgatt_client_callbacks_t* client; /** GATT Server callbacks */ const btgatt_server_callbacks_t* server; } btgatt_callbacks_t;
因此client对应的就是sGattCallbacks对象中的sGattClientCallbacks对象。sGattClientCallbacks对象定义如下(在JNI层的com_android_bluetooth_gatt.cpp文件中定义):
static const btgatt_client_callbacks_t sGattClientCallbacks = { btgattc_register_app_cb, btgattc_scan_result_cb, btgattc_open_cb, btgattc_close_cb, btgattc_search_complete_cb, btgattc_search_result_cb, btgattc_get_characteristic_cb, btgattc_get_descriptor_cb, btgattc_get_included_service_cb, btgattc_register_for_notification_cb, btgattc_notify_cb, btgattc_read_characteristic_cb, btgattc_write_characteristic_cb, btgattc_read_descriptor_cb, btgattc_write_descriptor_cb, btgattc_execute_write_cb, btgattc_remote_rssi_cb, btgattc_listen_cb };
而sGattClientCallbacks对象的类型是btgatt_client_callbacks_t结构体,如下
typedef struct { register_client_callback register_client_cb; scan_result_callback scan_result_cb; connect_callback open_cb; disconnect_callback close_cb; search_complete_callback search_complete_cb; search_result_callback search_result_cb; get_characteristic_callback get_characteristic_cb; get_descriptor_callback get_descriptor_cb; get_included_service_callback get_included_service_cb; register_for_notification_callback register_for_notification_cb; notify_callback notify_cb; read_characteristic_callback read_characteristic_cb; write_characteristic_callback write_characteristic_cb; read_descriptor_callback read_descriptor_cb; write_descriptor_callback write_descriptor_cb; execute_write_callback execute_write_cb; read_remote_rssi_callback read_remote_rssi_cb; listen_callback listen_cb; } btgatt_client_callbacks_t;
因此,client->register_client_cb就是调用了sGattClientCallbacks 对象中的btgattc_register_app_cb函数。
void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid) { CHECK_CALLBACK_ENV sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status, clientIf, UUID_PARAMS(app_uuid)); checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); }
JNI层的method_onClientRegistered 函数对应java层的onClientRegistered方法[-->GattService.java]。
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) { app.id = clientIf; app.linkToDeath(new ClientDeathRecipient(clientIf)); app.callback.onClientRegistered(status, clientIf); } }
此callback其实是GattCallbackWrapper类的对象。
分析mClientMap对象,在registerClient方法中调用了ClientMap的父类ContextMap::add方法,将GattCallbackWrapper类对象wrapper作为callback参数添加到mClientMap对象中。
onClientRegistered方法的回调我在这里有不陈述了,这个主要是可以很容易在代码中找到。
后面会继续分析bluedroid的部分。
谢谢关注。