Android BLE Gatt实现原理解析(未完)
BluetoothManagerService是Android的系统service,是在SystemServer中初始化的,如下:
public static void main(String[] args) { ............. ServerThread thr = new ServerThread(); thr.initAndLoop();}class ServerThread { public void initAndLoop() { .......... BluetoothManagerService bluetooth = null; .......... bluetooth = new BluetoothManagerService(context); ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth); .......... }}
那么这个Service是从哪里取出的呢?在BluetoothAdapter中,如下:
public static synchronized BluetoothAdapter getDefaultAdapter() { if (sAdapter == null) { IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE); if (b != null) { IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b); sAdapter = new BluetoothAdapter(managerService); } else { Log.e(TAG, "Bluetooth binder is null"); } } return sAdapter; }
我们再来看看当绑定到BluetoothManagerService时会做什么?
private class BluetoothServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName className, IBinder service) { Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) { msg.arg1 = SERVICE_IBLUETOOTH; // } else if (className.getClassName().equals(IBluetoothGatt.class.getName())) { } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { return; } msg.obj = service; mHandler.sendMessage(msg); } public void onServiceDisconnected(ComponentName className) { // Called if we unexpected disconnected. Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED); if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) { msg.arg1 = SERVICE_IBLUETOOTH; } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { return; } mHandler.sendMessage(msg); } }
在Handler中,只是将这个service转化成IBluetoothGatt的stub。
接下来我们看看BluetoothDevice.connectGatt的实现:
public BluetoothGatt connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); IBluetoothManager managerService = adapter.getBluetoothManager(); try { IBluetoothGatt iGatt = managerService.getBluetoothGatt(); BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this); gatt.connect(autoConnect, callback); return gatt; } catch (RemoteException e) {Log.e(TAG, "", e);} return null; }
这个adapter.getBluetoothManager()返回的就是BluetoothManagerService的stub,
而这个gatt.connect函数其实调用的是registerApp,如下:
boolean connect(Boolean autoConnect, BluetoothGattCallback callback) { registerApp(callback)}private boolean registerApp(BluetoothGattCallback callback) { mCallback = callback; UUID uuid = UUID.randomUUID(); mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);}
这个registerClient是在哪里实现的呢,是在GattService中,如下:
private static class BluetoothGattBinder extends IBluetoothGatt.Stub implements IProfileServiceBinder { private GattService mService; public BluetoothGattBinder(GattService svc) { mService = svc; } public void registerClient(ParcelUuid uuid, IBluetoothGattCallback callback) { mService.registerClient(uuid.getUuid(), callback); } ..........}
真正的实现如下:
void registerClient(UUID uuid, IBluetoothGattCallback callback) { mClientMap.add(uuid, callback); gattClientRegisterAppNative(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); }
这里又调到了一个native函数,实现在com_android_bluetooth_gatt.cpp中,如下:
static void gattClientRegisterAppNative(JNIEnv* env, jobject object, jlong app_uuid_lsb, jlong app_uuid_msb ){ bt_uuid_t uuid; set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb); sGattIf->client->register_client(&uuid);}
接下来我们重点看看这个sGattIf是何方神圣?
com_android:bluetooth_gatt.cpp中initializeNative中会初始化sGattIf,如下:
static void initializeNative(JNIEnv *env, jobject object) { btIf = getBluetoothInterface(); sGattIf = (btgatt_interface_t *) btIf->get_profile_interface(BT_PROFILE_GATT_ID); sGattIf->init(&sGattCallbacks); mCallbacksObj = env->NewGlobalRef(object);}
这个get_profile_interface的实现在bluetooth.c中,返回的是
static const btgatt_interface_t btgattInterface = { sizeof(btgattInterface), btif_gatt_init, btif_gatt_cleanup, &btgattClientInterface, &btgattServerInterface,};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;
可见这里对应着四个值,init,cleanup,gattClient和gattServer的接口。
我们来看看btif_gatt_init的实现:
static bt_status_t btif_gatt_init( const btgatt_callbacks_t* callbacks ){ bt_gatt_callbacks = callbacks; return BT_STATUS_SUCCESS;}
只是简单地保留回调而已。
手机端通常是作为client端,所以我们看看client端的接口,定义在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};
所以sGattIf->client->register_client(&uuid);调的其实就是btif_gattc_register_app函数,如下
// btif_gatt_client.cstatic bt_status_t btif_gattc_register_app(bt_uuid_t *uuid){ 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);}
今天先到此为止,剩下的改天再研究。
更多相关文章
- C语言函数以及函数的使用
- 【翻译】(8-补丁1)Android接口定义语言(AIDL)
- android 调用draw(canvas) 函数自动退出
- Android/Bluetooth 初始化流程
- Xposed框架之函数Hook学习
- Qt for Android 调用android原生接口分享图片或文字
- Android中的数据传递之Parcelable接口