栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

关于Android BLE 连接状态133、22 、8的问题记录

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于Android BLE 连接状态133、22 、8的问题记录

公司做了一个多连的ble应用,其他设备正常使用,但是在oppoAX7上出现了连上后过一会就断开的情况,这种情况只有在多连的时候才会出现,查了下日志发现断开的都是onClientConnectionState() - status=8 状态为8,查了好久才找到一个博主给了答案,搬运内容:

GATT_SUCCESS和GATT_FAILURE(不常见)在BluetoothGatt源码中可以找到外,其他8、22、133等status状态值不知道其意义,对于断开连接的原因就不好判断了。

下面我们从framework源码追查这几个状态

 _bluetoothGatt = device.connectGatt(_context, false, mGattCallback);

BluetoothDevice connectGatt方法将mGattCallback传入

public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                     BluetoothGattCallback callback, int transport) {
        // TODO(Bluetooth) check whether platform support BLE
        //     Do the check here or in GattServer?
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        IBluetoothManager managerService = adapter.getBluetoothManager();
        try {
            IBluetoothGatt iGatt = managerService.getBluetoothGatt();
            if (iGatt == null) {
                // BLE is not supported
                return null;
            }
            BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport);
            gatt.connect(autoConnect, callback);
            return gatt;
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    }

connect方法中创建了BluetoothGatt对象,gatt connect方法将callback导入,我们继续看BluetoothGatt源码

 boolean connect(Boolean autoConnect, BluetoothGattCallback callback) {
        if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
        synchronized(mStateLock) {
            if (mConnState != CONN_STATE_IDLE) {
                throw new IllegalStateException("Not idle");
            }
            mConnState = CONN_STATE_CONNECTING;
        }

        mAutoConnect = autoConnect;

        if (!registerApp(callback)) {
            synchronized(mStateLock) {
                mConnState = CONN_STATE_IDLE;
            }
            Log.e(TAG, "Failed to register callback");
            return false;
        }

        // The connection will continue in the onClientRegistered callback
        return true;
    }


继续看reigsterApp方法

private boolean registerApp(BluetoothGattCallback callback) {
        if (DBG) Log.d(TAG, "registerApp()");
        if (mService == null) return false;

        mCallback = callback;
        UUID uuid = UUID.randomUUID();
        if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);

        try {
            mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    }

mService是IBluetoothGatt接口的Proxy端

查找源码发现IBluetoothGatt的Stub端在GattService中实现,我们看GattService的registerClient方法

void registerClient(UUID uuid, IBluetoothGattCallback callback) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        if (DBG) Log.d(TAG, "registerClient() - UUID=" + uuid);
        mClientMap.add(uuid, callback, this);
        gattClientRegisterAppNative(uuid.getLeastSignificantBits(),
                                    uuid.getMostSignificantBits());
    }

mClientMap管理各个APP的callback对象

void onConnected(int clientIf, int connId, int status, String address)
            throws RemoteException  {
        if (DBG) Log.d(TAG, "onConnected() - clientIf=" + clientIf
            + ", connId=" + connId + ", address=" + address);

        if (status == 0) mClientMap.addConnection(clientIf, connId, address);
        ClientMap.App app = mClientMap.getById(clientIf);
        if (app != null) {
            app.callback.onClientConnectionState(status, clientIf,
                                (status==BluetoothGatt.GATT_SUCCESS), address);
        }
    }

    void onDisconnected(int clientIf, int connId, int status, String address)
            throws RemoteException {
        if (DBG) Log.d(TAG, "onDisconnected() - clientIf=" + clientIf
            + ", connId=" + connId + ", address=" + address);

        mClientMap.removeConnection(clientIf, connId);
        ClientMap.App app = mClientMap.getById(clientIf);
        if (app != null) {
            app.callback.onClientConnectionState(status, clientIf, false, address);
        }
    }

在GattService的onConnected和onDisconnected方法中我们找到了callback.onClientConnectionState的调用,那么这两个方法是谁调用的,很显然这个调用者来自jni底层

    method_onConnected   = env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
    method_onDisconnected = env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");

com_android_bluetooth_gatt.cpp中有关于这两个方法的反射调用

void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda)
{
    CHECK_CALLBACK_ENV
    char c_address[32];
    snprintf(c_address, sizeof(c_address),"%02X:%02X:%02X:%02X:%02X:%02X",
        bda->address[0], bda->address[1], bda->address[2],
        bda->address[3], bda->address[4], bda->address[5]);

    jstring address = sCallbackEnv->NewStringUTF(c_address);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected,
        clientIf, conn_id, status, address);
    sCallbackEnv->DeleteLocalRef(address);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

com_android_bluetooth_gatt的btgattc_close_cb方法中调用了onDisconnected,但是status依然是外部导入的,我们继续追。

btgattc_close_cb是BTA client callback,所以答案应该在BTA

BTA就是Bluetooth Application,所有蓝牙请求都必须进过它,我们看bta目录下的h文件,目录是system/bt/bta

最终,我们在bta_gatt_api.h中找到了status 8, 22, 133等错误

#define  BTA_GATT_OK                        GATT_SUCCESS
#define  BTA_GATT_INVALID_HANDLE            GATT_INVALID_HANDLE                
#define  BTA_GATT_READ_NOT_PERMIT           GATT_READ_NOT_PERMIT               
#define  BTA_GATT_WRITE_NOT_PERMIT          GATT_WRITE_NOT_PERMIT              
#define  BTA_GATT_INVALID_PDU               GATT_INVALID_PDU                   
#define  BTA_GATT_INSUF_AUTHENTICATION      GATT_INSUF_AUTHENTICATION          
#define  BTA_GATT_REQ_NOT_SUPPORTED         GATT_REQ_NOT_SUPPORTED             
#define  BTA_GATT_INVALID_OFFSET            GATT_INVALID_OFFSET                
#define  BTA_GATT_INSUF_AUTHORIZATION       GATT_INSUF_AUTHORIZATION           
#define  BTA_GATT_PREPARE_Q_FULL            GATT_PREPARE_Q_FULL                
#define  BTA_GATT_NOT_FOUND                 GATT_NOT_FOUND                     
#define  BTA_GATT_NOT_LONG                  GATT_NOT_LONG                      
#define  BTA_GATT_INSUF_KEY_SIZE            GATT_INSUF_KEY_SIZE                
#define  BTA_GATT_INVALID_ATTR_LEN          GATT_INVALID_ATTR_LEN              
#define  BTA_GATT_ERR_UNLIKELY              GATT_ERR_UNLIKELY                  
#define  BTA_GATT_INSUF_ENCRYPTION          GATT_INSUF_ENCRYPTION              
#define  BTA_GATT_UNSUPPORT_GRP_TYPE        GATT_UNSUPPORT_GRP_TYPE            
#define  BTA_GATT_INSUF_RESOURCE            GATT_INSUF_RESOURCE                


#define  BTA_GATT_NO_RESOURCES              GATT_NO_RESOURCES                  
#define  BTA_GATT_INTERNAL_ERROR            GATT_INTERNAL_ERROR                
#define  BTA_GATT_WRONG_STATE               GATT_WRONG_STATE                   
#define  BTA_GATT_DB_FULL                   GATT_DB_FULL                       
#define  BTA_GATT_BUSY                      GATT_BUSY                          
#define  BTA_GATT_ERROR                     GATT_ERROR                         
#define  BTA_GATT_CMD_STARTED               GATT_CMD_STARTED                   
#define  BTA_GATT_ILLEGAL_PARAMETER         GATT_ILLEGAL_PARAMETER             
#define  BTA_GATT_PENDING                   GATT_PENDING                       
#define  BTA_GATT_AUTH_FAIL                 GATT_AUTH_FAIL                     
#define  BTA_GATT_MORE                      GATT_MORE                          
#define  BTA_GATT_INVALID_CFG               GATT_INVALID_CFG                   
#define  BTA_GATT_SERVICE_STARTED           GATT_SERVICE_STARTED               
#define  BTA_GATT_ENCRYPED_MITM             GATT_ENCRYPED_MITM                 
#define  BTA_GATT_ENCRYPED_NO_MITM          GATT_ENCRYPED_NO_MITM              
#define  BTA_GATT_NOT_ENCRYPTED             GATT_NOT_ENCRYPTED                 
#define  BTA_GATT_CONGESTED                 GATT_CONGESTED                     

#define  BTA_GATT_DUP_REG                   0x90                               
#define  BTA_GATT_ALREADY_OPEN              0x91                               
#define  BTA_GATT_CANCEL                    0x92                               

#define BTA_GATT_CONN_UNKNOWN                   0
#define BTA_GATT_CONN_L2C_FAILURE               GATT_CONN_L2C_FAILURE         
#define BTA_GATT_CONN_TIMEOUT                   GATT_CONN_TIMEOUT             
#define BTA_GATT_CONN_TERMINATE_PEER_USER       GATT_CONN_TERMINATE_PEER_USER 
#define BTA_GATT_CONN_TERMINATE_LOCAL_HOST      GATT_CONN_TERMINATE_LOCAL_HOST
#define BTA_GATT_CONN_FAIL_ESTABLISH            GATT_CONN_FAIL_ESTABLISH      
#define BTA_GATT_CONN_LMP_TIMEOUT               GATT_CONN_LMP_TIMEOUT          
#define BTA_GATT_CONN_CANCEL                    GATT_CONN_CANCEL               
#define BTA_GATT_CONN_NONE                      0x0101                          


status 133 GATT_ERROR,这个错误是Android源码的问题

bluetooth lowenergy - Every connection request is being treated as direct connect request + android ble - Stack Overflow
 

status 22 GATT_CONN_TERMINATE_LOCAL_HOST

https://stackoverflow.com/questions/40966104/how-to-solve-the-error-onclientconnectionstate-status-22-clientif-7-in-ble?noredirect=1

status 8 GATT_CONN_TIMEOUT

参考博客地址:Android 从源码分析BLE连接错误分析_疾风细语的博客-CSDN博客

非常感谢这位大哥的分享

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/998789.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号