BluetoothAdapter.java中有low enery(le)的一些方法,android提供了这些方法,但源码中并未找到这些方法的调用之处。本文档主要分析这类方法的执行流程,来了解下le到底做了些什么。

 

本文主要就是分析下startLeScan方法(两个重载方法)。

    public boolean startLeScan(LeScanCallback callback) {        return startLeScan(null, callback);    }    public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {         if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);                                                                                                                   synchronized(mLeScanClients) {                 if (mLeScanClients.containsKey(callback)) {                 if (DBG) Log.e(TAG, "LE Scan has already started");                                                                                                                      return false;            }            try {                //获取BluetoothGattBinder类的实例,该类的定义在GattService.java中                IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();                                                                                                               if (iGatt == null) {                                   // BLE is not supported                            return false;                              }                UUID uuid = UUID.randomUUID();                 GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids);                                                                     //重点分析该方法。作用是为本地设备进行注册,以及启动扫描                //wrapper是GattCallbackWrapper类的对象。该类注册了一些Gatt协议的回调方法                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(new ParcelUuid(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

/** Represents the standard Bluetooth GATT interface. */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 );  ......}

btgatt_client_interface_t结构体的对象:external/bluetooth/bluedroi/btif/src/btif_gatt_client.c

const btgatt_client_interface_t btgattClientInterface = {    btif_gattc_register_app,    btif_gattc_unregister_app,    btif_gattc_scan,  ......};

因此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){    ......    btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*)p_param;    if (!p_cb) return;    switch (event)    {        case BTIF_GATTC_REGISTER_APP:            btif_to_bta_uuid(&uuid, &p_cb->uuid);            //为uuid注册回调函数            BTA_GATTC_AppRegister(&uuid, bte_gattc_cback);            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;                                                                                                                                              /* register with BTA system manager */  GKI_sched_lock();  //注册Gatt客户端主事件处理函数bta_gattc_hdl_event,在bta_gatt_reg结构体中定义。    bta_sys_register(BTA_ID_GATTC, &bta_gatt_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函数。

BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg){    tBTA_GATTC_CB *p_cb = &bta_gattc_cb;    tBTA_GATTC_CLCB *p_clcb = NULL;#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_REG_EVT:                    bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);            break;        ......  }}

(b)调用bta_gattc_register函数。该函数用来注册一个客户端Gatt应用程序。

void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data){    ......    /* callback with register event */    if (p_data->api_reg.p_cback)    {        (*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事件就调用该函数处理了。

-------------------------------------------------------------------------------------------------------

 

分析回调函数bte_gattc_cback 

static void bte_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), NULL);    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){    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;        }    ......  }}

bt_gatt_callbacks对象的类型是btgatt_callbacks_t,其定义在hardware/libhardware/include/hardware/bt_gatt.h文件中。现在对bt_gatt_callbacks对象从头开始分析其来源。

 

在GattService.java::start()方法中,调用了initializeNative方法。继而调用JNI层initializeNative方法。贴出该方法。

static const btgatt_interface_t *sGattIf = NULL;static const bt_interface_t* btIf;......static void initializeNative(JNIEnv *env, jobject object) {    /* getBluetoothInterface 函数返回sBluetoothInterface对象,在android4.3 bt 扫描分析.docx中已说明该对象的来源*/    if ( (btIf = getBluetoothInterface()) == NULL) {        error("Bluetooth module is not loaded");        return;    }    ......  //(a)  // BT_PROFILE_GATT_ID的值是”gatt”    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;  //(b)  /* sGattCallbacks的定义  static const btgatt_callbacks_t sGattCallbacks = {      sizeof(btgatt_callbacks_t),      &sGattClientCallbacks,      &sGattServerCallbacks  };*/    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) 分析

static const void* get_profile_interface (const char *profile_id){    ......#if BTA_GATT_INCLUDED == TRUE     if (is_profile(profile_id, BT_PROFILE_GATT_ID))        return btif_gatt_get_interface();#endif    return NULL;}

分析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对象。

 

(b) 接下来调用sGattIf->init函数。由上可知,即为btif_gatt_init函数。

static bt_status_t btif_gatt_init( const btgatt_callbacks_t* callbacks ){  /*bt_gatt_callbacks由参数赋值,该参数是sGattCallbacks。  sGattCallbacks的定义  static const btgatt_callbacks_t sGattCallbacks = {      sizeof(btgatt_callbacks_t),      &sGattClientCallbacks,      &sGattServerCallbacks  };*/    bt_gatt_callbacks = callbacks;    BTA_GATTC_Init();    BTA_GATTS_Init();    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对象)中。

btgatt_callbacks_t结构体如下:

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,    ......};

而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;    ......        } 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方法[--->BluetoothAdapter::GattCallbackWrapper类]

        public void onClientRegistered(int status, int clientIf) {            if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status +                           " clientIf=" + clientIf);            synchronized(this) {                if (mLeHandle == -1) {                    if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled");                }                if (status == BluetoothGatt.GATT_SUCCESS) {                    mLeHandle = clientIf;                    IBluetoothGatt iGatt = null;                    try {                        BluetoothAdapter adapter = mBluetoothAdapter.get();                        if (adapter != null) {                            iGatt = adapter.getBluetoothManager().getBluetoothGatt();                            //调用startLeScan方法时,传递过来的参数为null,执行此处                            if (mScanFilter == null) {                                iGatt.startScan(mLeHandle, false);                            } else {                                ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];                                for(int i = 0; i != uuids.length; ++i) {                                    uuids[i] = new ParcelUuid(mScanFilter[i]);                                }                                iGatt.startScanWithUuids(mLeHandle, false, uuids);                            }                        } else {                            Log.e(TAG, "onClientRegistered, BluetoothAdapter null");                            mLeHandle = -1;                        }                    } catch (RemoteException e) {                        Log.e(TAG, "fail to start le scan: " + e);                        mLeHandle = -1;                    }            ......        }

接下来分析startScan方法,在GattService.java中。

    void startScan(int appIf, boolean isServer) {        ......        if (getScanClient(appIf, isServer) == null) {            if (DBG) Log.d(TAG, "startScan() - adding client=" + appIf);            mScanQueue.add(new ScanClient(appIf, isServer));        }        gattClientScanNative(appIf, true);    }

JNI层gattClientScanNative函数

static void gattClientScanNative(JNIEnv* env, jobject object, jint clientIf, jboolean start){    if (!sGattIf) return;    sGattIf->client->scan(clientIf, start);}

同之前分析register_client的步骤,分析的scan函数对应btif_gattc_scan函数。

static bt_status_t btif_gattc_scan( int client_if, bool start ){    CHECK_BTGATT_INIT();    btif_gattc_cb_t btif_cb;    btif_cb.client_if = (uint8_t) client_if;    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);}

在btgattc_handle_event函数中处理BTIF_GATTC_SCAN_START事件

        case BTIF_GATTC_SCAN_START:            btif_gattc_init_dev_cb();            // BTA_DmBleObserve发出消息,包含BTA_DM_API_BLE_OBSERVE_EVT事件            BTA_DmBleObserve(TRUE, 0, bte_scan_results_cb);            break;

调用bte_scan_results_cb函数,

static void bte_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:            ......        case BTA_DM_INQ_CMPL_EVT:            ......    btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATT_OBSERVE_EVT,                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);}

在btif_gattc_upstreams_evt函数中处理BTIF_GATT_OBSERVE_EVT事件。

        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;        }

分析register_client_cb函数,在JNI层com_android_bluetooth_gatt.cpp文件中定义,分析得scan_result_cb对应函数btgattc_scan_result_cb。

void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data){    ......    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult        , address, rssi, jb);    ......}

对应java层文件GattService类onScanResult方法。

    void onScanResult(String address, int rssi, byte[] adv_data) {        for (ScanClient client : mScanQueue) {            ......            if (!client.isServer) {                ClientMap.App app = mClientMap.getById(client.appIf);                if (app != null) {                    try {                        app.callback.onScanResult(address, rssi, adv_data);                    } catch (RemoteException e) {                        Log.e(TAG, "Exception: " + e);                        mClientMap.remove(client.appIf);                        mScanQueue.remove(client);                    }                }            }        ......        }  }

callback为GattCallbackWrapper类的对象,因此调用GattCallbackWrapper类中的onScanResult方法。

        public void onScanResult(String address, int rssi, byte[] advData) {            ......            try {                BluetoothAdapter adapter = mBluetoothAdapter.get();                if (adapter == null) {                    Log.d(TAG, "onScanResult, BluetoothAdapter null");                    return;                }                mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData);            } catch (Exception ex) {                Log.w(TAG, "Unhandled exception: " + ex);            }        }

mLeScanCb对象为LeScanCallback接口的对象,不过源码中并没有类来实现该接口,故只能分析到这里了。扫描到此结束,over~~ 

 

 

-------------------------------------------------------------------------------------------------------------

贴出流程图,see see,5个步骤:

1.startLeScan(JAVA-->JNI)

-------------------------------------------------------------------------------------------------------------

2.startLeScan(蓝牙栈)

 

-------------------------------------------------------------------------------------------------------------

3.startLeScan(JNI-->JAVA)

 

-------------------------------------------------------------------------------------------------------------

4.startLeScan(蓝牙栈)

-------------------------------------------------------------------------------------------------------------

5.startLeScan(JNI-->JAVA)

 

更多相关文章

  1. Android系列之Intent传递对象的两种方法
  2. Android studio插件GsonFormat,返回json快速创建实体对象
  3. Android Studio如何使用快捷键生成get,set,tostring,构造函数
  4. 微软和亚马逊在Android方面的最新消息
  5. Android Apk反编译函数对应法则
  6. android将对象写入文件和从文件中读取对象数据
  7. Android 的一些实用的函数
  8. android binder机制及其源码解析之第二节 重要函数讲解之常用数

随机推荐

  1. 在android当中MVC模式分别代表什么?
  2. android文件选择、读取、浏览器的实现(音
  3. Super Jumper:一个2DOpenGL ES游戏
  4. android box2d运行小例子,配置eclipse【转
  5. Framework StatusBar添加(wifi,bluetooth,
  6. android 蓝牙小总结
  7. Android(安卓)ViewPager 如何判断当前页
  8. Android与iPhone的对比(水木上看到的,不清
  9. Android(安卓)8.0 以上获取设备序列号, An
  10. Android应用开发笔记(7):构建自己的Androi