Android BLE Gatt connection change statuses
Asked Answered
B

4

13

I have an android app to connect to a BLE device and write to it. I can successfully connect, read and write to it. As a part of testing, we are trying different disconnection scenarios.

Sometimes, if BLE device disconnects the connection, I get the connection change as disconnect with status value as 19. Also if there is any bond error, status equals 22. If I programmatically disconnect the connection, this status gives me 0. But none of these states except 0 are specified in android documentation.

Posting a sample BluetoothGattCallback

private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        Log.i(TAG, "onConnectionStateChange status: "+status+", newState: "+newState);
        /*i need to know the possible values for this status variable*/
        if(newState == BluetoothProfile.STATE_CONNECTED) {
            gatt.discoverServices();
        } else {
            gatt.close();
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        Log.i(TAG, "onServicesDiscovered service discovered");
    }
};

Does anyone face this same problem and sorted out the list of statuses. I need to know the possible values for status variable in onConnectionStateChange method

Bromine answered 12/7, 2017 at 11:34 Comment(2)
post your code..Selves
@Selves i have posted a sample code as my code is bit much lengthy and irrelevant to current situationBromine
B
34

Here is the list of codes i have

  • Programmatically disconnected - 0
  • Device went out of range - 8
  • Disconnected by device - 19
  • Issue with bond - 22
  • Device not found - 133(some phone it gives 62)

I have tested disconnect scenario's in 5.0.2, 5.1, 6.0 and 6.0.1. But only found this bond issue code in 6.0.1 android version.

Bromine answered 21/7, 2017 at 10:20 Comment(11)
how to solve issue with bond error? should we close the gatt and re-establish the connection or should we try to reconnect the existing gatt? see my problem here https://mcmap.net/q/586730/-gatt-133-exception-on-read-characteristic-and-followed-by-gatt-22/4111151Foresight
Try to delete bond and re bond again. I think this will solve the bond error.Bromine
thanks but i don't use bond i am using connect GATT method to communicate.Have you got any idea regarding this?Foresight
In my experience, error 22 will be given for bad bond error. Check if BluetoothDevice is bonded?Bromine
You will get BluetoothDevice object from BluetoothGatt object in GattCallback. BluetoothDevice device = gatt.getDevice(); int bondState = device.getBondState(); Documentation developer.android.com/reference/android/bluetooth/…Bromine
I also received status 34. What is the meaning of that? I could not find it in above mentioned URL.Myungmyxedema
@AanalMehta I haven't got status 34 yet. So have no idea on this.Bromine
@AanalMehta According to this file, 34 might mean "connection fail for LMP response timeout".Hickey
@IjasAhamedN Where did you find these error codes? I am using an SDK which is throwing error codes 13, 34, 133. I am assuming these error codes are coming from Android APIs which can be handled in the SDK itself. But, I don't know what these error codes mean and which class has them.Lora
@NikhilBansal I tried out different scenarios and figured out these error codes by myselfBromine
@IjasAhamedN I found this link where all the error codes are defined. Maybe this will help you more. Also, I found an interesting GitHub Pull Request that might be of more help. You can find it here.Lora
L
4

Sorry to bring up an old question, but here is the solution for many of the problems i've had with Bluetooth (BLE) 4.0. Sorry again for the big classes below but be sure they are needed and no method there is irrelevant or unused.

public abstract class AbstractBluetoothBroadcaster extends BroadcastReceiver {
    protected static final String LOG_TAG = BluetoothLowEnergy.LOG_TAG;

    protected BluetoothLowEnergy bluetoothLowEnergy;

    public AbstractBluetoothBroadcaster(BluetoothLowEnergy bluetoothLowEnergy, String action){
        super();
        this.bluetoothLowEnergy = bluetoothLowEnergy;

        IntentFilter intentFilterStateChange = new IntentFilter(action);
        intentFilterStateChange.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        this.bluetoothLowEnergy.getActivity().registerReceiver(this, intentFilterStateChange);
    }

    public void onDestroy(){
        this.bluetoothLowEnergy.getActivity().unregisterReceiver(this);
    }
}


public class BluetoothBondStateBroadcaster extends AbstractBluetoothBroadcaster {

    private BluetoothLowEnergy bluetoothLowEnergy;
    private boolean deviceBonded;

    public BluetoothBondStateBroadcaster(BluetoothLowEnergy bluetoothLowEnergy) {
        super(bluetoothLowEnergy, BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        this.bluetoothLowEnergy = bluetoothLowEnergy;
        this.deviceBonded = false;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action == null){
            return;
        }
        BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED) &&
                bluetoothDevice != null &&
                bluetoothDevice.getAddress().equals(bluetoothLowEnergy.getDeviceUUID())) {
            int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
            switch (state) {
                case BluetoothDevice.BOND_NONE:
                    Log.d(LOG_TAG, "  NOT BONDED - dev " + bluetoothDevice.getAddress());
                    this.deviceBonded = false;
                    break;
                case BluetoothDevice.BOND_BONDING:
                    Log.d(LOG_TAG, " BONDING ... - dev " + bluetoothDevice.getAddress());
                    break;
                case BluetoothDevice.BOND_BONDED:
                    Log.d(LOG_TAG, " BONDED - dev " + bluetoothDevice.getAddress());
                    deviceBonded = true;
                    bluetoothLowEnergy.onBluetoothBonded();
                    break;
                default:
                    break;
            }
        }
    }

    public void resetDeviceBonded(){
        this.deviceBonded = false;
    }

    public boolean isDeviceBonded() {
        return deviceBonded;
    }
}


public class BluetoothPairingBroadcaster extends AbstractBluetoothBroadcaster {

    private String devicePIN;

    public BluetoothPairingBroadcaster(BluetoothLowEnergy bluetoothLowEnergy){
        super(bluetoothLowEnergy, BluetoothDevice.ACTION_PAIRING_REQUEST);
        this.devicePIN = "";
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action == null){
            return;
        }
        BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        int pairingType = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
        if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST) &&
                bluetoothDevice != null &&
                bluetoothDevice.getAddress().equals(bluetoothLowEnergy.getDeviceUUID()) &&
                !getDevicePIN().isEmpty()) {
            if (pairingType == BluetoothDevice.PAIRING_VARIANT_PIN){
                bluetoothDevice.setPin(getDevicePIN().getBytes());
                Log.d(LOG_TAG," Auto-entering pin - " + getDevicePIN());
                bluetoothDevice.createBond();
                Log.d(LOG_TAG," pin entered and request sent...");
                abortBroadcast();
            }
        }
    }

    public void setDevicePIN(String pin){
        this.devicePIN = pin;
    }

    public String getDevicePIN(){
        return this.devicePIN ;
    }
}


public class BluetoothLowEnergy extends BluetoothGattCallback {

    // listener that has the methods that the application (activity)
    // will use to send / receive data, or to reflect the system state 
    // in the UI
    public interface BluetoothListener {
        /**
         * Triggered when the scanning has started successfully
         */
        void onBluetoothStartScan();

        /**
         * Triggered when the scanning stops
         * @param scanResults results of the scanning
         */
        void onBluetoothStopScan(Collection<BluetoothDevice> scanResults);

        /**
         * Triggered when the device is ready to send/receive data
         */
        void onBluetoothConnectionReady();

        /**
         * Triggered when a bluetooth msg is received
         * @param msg message received
         */
        void onBluetoothReceiveMsg(String msg);

        /**
         * Triggered whenever data is send
         * @param success true means data was sent fine to the remote device, false otherwise
         */
        void onBluetoothSend(String data, boolean success);

        /**
         * Triggered if no bluetooth is connected, and we need a connection
         * to send / receive / discover services
         */
        void onBluetoothNotConnected();

    }

    // custom exceptions
    public class BluetoothNotEnabledException extends Exception { }
    public class BluetoothLowEnergyNotSupported extends Exception { }
    public class BluetoothDeviceNotFound extends Exception { }

    // service and characteristic uuids that are going to be used to
    // send / receive data between central and peripheral GATTs
    private static final String SERVICE_UUID = "FFE0-";
    private static final String CHARACTERISTIC_UUID = "FFE1-";

    // timeout for bluetooth scan (in ms)
    public static final int SCAN_TIMEOUT = 5000;

    // BLE LOG TAG
    public static final String LOG_TAG = "BLUETOOTH_BLE";

    // model
    private boolean bluetoothScanning;
    private boolean bluetoothConnected;
    private Map<String, BluetoothDevice> bluetoothScanResults;

    // gui
    private Activity activity;

    // bluetooth
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothLeScanner bluetoothLeScanner;
    private ScanCallback bluetoothScanCallback;
    private BluetoothGatt bluetoothGatt;
    private BluetoothGattCharacteristic characteristic;


    public BluetoothLowEnergy(Activity activity, BluetoothListener bluetoothListener){
        this.activity = activity;
        this.bluetoothListener = bluetoothListener;

        // this keeps track of the scanning and connection states
        this.bluetoothScanning = this.bluetoothConnected = false;

        // keeps track of the scanning results
        this.bluetoothScanResults = new HashMap<>();

        // set bluetooth pairing request and bonded callback
        // these broadcasters will be responsible to detect and validate
        // the bonded state of your device
        this.pairingRequestBroadcaster = new BluetoothPairingBroadcaster(this);
        this.bondedBroadcaster = new BluetoothBondStateBroadcaster(this);

        // set the scan callback methods that will add results to 
        // this.bluetoothScanResults map
        this.bluetoothScanCallback = new ScanCallback() {
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                super.onScanResult(callbackType, result);
                addScanResult(result);
            }

            @Override
            public void onBatchScanResults(List<ScanResult> results) {
                super.onBatchScanResults(results);
                for (ScanResult result: results) {
                    addScanResult(result);
                }
            }

            @Override
            public void onScanFailed(int errorCode) {
                super.onScanFailed(errorCode);
                Log.e(LOG_TAG, "Scan Failed with code " + errorCode);
            }

            private void addScanResult(ScanResult result) {
                BluetoothDevice device = result.getDevice();
                String deviceAddress = device.getAddress();
                bluetoothScanResults.put(deviceAddress, device);
                Log.d(LOG_TAG, "Found device " + deviceAddress);
            }
        };

        // Use this to determine whether BLE is supported on the device.
        if (!this.activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            throw new BluetoothLowEnergyNotSupported();
        }
    }

    /**
     * This method should be called when the activity is destroyed
     */
    public void onDestroy(){
        this.bondedBroadcaster.onDestroy();
        this.pairingRequestBroadcaster.onDestroy();
        this.disconnect();
    }

    /**
     * This method is called when we finish pairing/bonding to the device
     */
    public void onBluetoothBonded(){
        // if we have the services already discovered, then we can 
        // send/receive data, to do so we call the bluetooth listener below
        if (servicesDiscovered){
            this.bluetoothListener.onBluetoothConnectionReady();
        // if we know we have a connection established, then we can 
        // discover services
        } else if (bluetoothConnected){
            bluetoothGatt.discoverServices();
        }
    }

    /**
     * This method is called whenever a connection is established or a disconnection happens
     */
    @Override        
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        super.onConnectionStateChange(gatt, status, newState);

        BluetoothDevice bluetoothDevice = gatt.getDevice();

        // if these conditions == true, then we have a disconnect
        if ( status == BluetoothGatt.GATT_FAILURE ||
                status != BluetoothGatt.GATT_SUCCESS ||
                newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.d(LOG_TAG, String.format(Locale.getDefault(),
                    "Disconnected from %s (%s) - status %d - state %d",
                    bluetoothDevice.getName(),
                    bluetoothDevice.getAddress(),
                    status,
                    newState
            ));
            this.disconnect();
        // if these conditions == true, then we have a successful connection
        } else if (newState == BluetoothProfile.STATE_CONNECTED) {
            bluetoothConnected = true;
            Log.d(LOG_TAG, String.format(Locale.getDefault(),
                    "Connected to %s (%s) - status %d - state %d",
                    bluetoothDevice.getName(),
                    bluetoothDevice.getAddress(),
                    status,
                    newState
            ));
            // this sleep is here to avoid TONS of problems in BLE, that occur whenever we start 
            // service discovery immediately after the connection is established 
            try {
                Thread.sleep(600);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            gatt.discoverServices();
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        if (status != BluetoothGatt.GATT_SUCCESS) {
            return;
        }
        // BEGIN - find the service and characteristic that we want (defined as a static attribute 
        // of the BluetoothLowEnergy class)
        Log.d(LOG_TAG, "Discovering services ...");
        BluetoothGattService service = null;
        for (BluetoothGattService serv: gatt.getServices()){
            Log.d(LOG_TAG, "Found service " + serv.getUuid().toString());
            if (serv.getUuid().toString().toUpperCase().contains(SERVICE_UUID)){
                service = serv;
                Log.d(LOG_TAG, "---> Selected service " + serv.getUuid().toString());
                break;
            }
        }
        if (service == null){
            return;
        }
        for (BluetoothGattCharacteristic charac: service.getCharacteristics()){
            Log.d(LOG_TAG, "Found characteristic " + charac.getUuid().toString());
            if (charac.getUuid().toString().toUpperCase().contains(CHARACTERISTIC_UUID)){
                this.characteristic = charac;
                Log.d(LOG_TAG, "---> Selected characteristic " + charac.getUuid().toString());
                break;
            }
        }
        if (this.characteristic == null){
            return;
        }
        Log.d(LOG_TAG, "Setting write and notification to the characteristic ...");
        bluetoothAdapter.cancelDiscovery();
        // END - find the service and characteristic 
        // set that we want to write to the selected characteristic and be notified if
        // it changes (the remote GATT peripheral sends data to the Android's GATT Center)
        this.characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
        gatt.setCharacteristicNotification(this.characteristic, true);
        // we finished service discovery
        this.servicesDiscovered = true;
        // if we have paired/bonded then we are ready to send/receive data            
        if (pairingRequestBroadcaster.getDevicePIN().isEmpty() || bondedBroadcaster.isDeviceBonded()) {
            this.bluetoothListener.onBluetoothConnectionReady();
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic charac, int status) {
        super.onCharacteristicRead(gatt, charac, status);
        restartDisconnectTimeout();
        if (status != BluetoothGatt.GATT_SUCCESS) {
            return;
        }
        try {
            String characValue = new String(charac.getValue(), CHARSET)
                    .replaceAll(DATA_FILTER_REGEX,"");
            Log.i(LOG_TAG, String.format(Locale.getDefault(),
                    "Characteristic Read - %s",
                    characValue
            ));
            if (charac.getUuid().equals(this.characteristic.getUuid())) {
                this.bluetoothListener.onBluetoothReceiveMsg(characValue);
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(LOG_TAG, "Characteristic Read - Failed to convert message string to byte array");
        }
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic charac, int status) {
        super.onCharacteristicWrite(gatt, charac, status);
        restartDisconnectTimeout();
        try {
            String characValue = new String(charac.getValue(), CHARSET);
            Log.i(LOG_TAG, String.format(Locale.getDefault(),
                    "Characteristic Write - SUCCESS - %s",
                    characValue
            ));
            bluetoothListener.onBluetoothSend( characValue, (status == BluetoothGatt.GATT_SUCCESS) );
        } catch (UnsupportedEncodingException e) {
            Log.e(LOG_TAG, "Characteristic Write - Failed to convert message string to byte array");
        }
    }


    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic charac) {
        super.onCharacteristicChanged(gatt, charac);
        Log.d(LOG_TAG,"Characteristic Changed");
        onCharacteristicRead(gatt, charac, BluetoothGatt.GATT_SUCCESS);
    }

    /**
     * Remove pairing/bonding of the device 
     * @param device Device to remove bonding
     */
    public static void removeBond(BluetoothDevice device){
        try {
            if (device == null){
                throw new Exception();
            }
            Method method = device.getClass().getMethod("removeBond", (Class[]) null);
            method.invoke(device, (Object[]) null);
            Log.d(LOG_TAG, "removeBond() called");
            Thread.sleep(600);
            Log.d(LOG_TAG, "removeBond() - finished method");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Clears the GATT services cache, so that new services can be discovered 
     * @param bluetoothGatt GATT Client to clear service's discovery cache
     */
    public static void refresh(BluetoothGatt bluetoothGatt){
        try {
            Method method = bluetoothGatt.getClass().getMethod("refresh", (Class[]) null);
            method.invoke(bluetoothGatt, (Object[]) null);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * Connect to the GATT Peripheral device
     * @param uuid GATT Peripheral address / mac / uuid to connect to
     * @param pin PIN to authenticate and pair to the device
     */
    public void connect(String uuid, String pin) throws BluetoothNotEnabledException, BluetoothDeviceNotFound {
        checkBluetooth();
        // do not connect twice
        if (this.isConnected()){
            return;
        }
        // get device
        BluetoothDevice device = this.bluetoothScanResults.get(uuid);
        if (device == null){
            throw new BluetoothDeviceNotFound();
        }
        this.deviceUUID = uuid;
        pairingRequestBroadcaster.setDevicePIN(pin);
        removeBond(device);
        // create connection to the bluetooth device
        bluetoothGatt = device.connectGatt(activity, false, this);
        refresh(bluetoothGatt);
    }

    /**
     * Disconnect from BLE device. This method should be called whenever we want to 
     * close the APP, or the BLE connection.
     */
    public void disconnect() {            
        Log.d(LOG_TAG, "disconnect() - executed");
        if (bluetoothGatt != null) {
            if (characteristic != null) {
                bluetoothGatt.setCharacteristicNotification(characteristic, false);
            }
            //remove device authorization/ bond/ pairing
            removeBond(bluetoothGatt);
            // disconnect now
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            Log.d(LOG_TAG, "disconnect() - bluetoothGatt disconnect happened");
        }
        bluetoothGatt = null;
        characteristic = null;
        bluetoothConnected = false;
        servicesDiscovered = false;
        // set device as not bonded anymore
        bondedBroadcaster.resetDeviceBonded();
    }

    /**
     * bluetooth nearby devices scan is on
     * @return true if scanning is on, false otherwise
     */
    public boolean isScanning(){
        return (this.bluetoothScanning);
    }

    /**
     * Check bluetooth system state (on or off)
     * @return true if system is on, false otherwise
     */
    public boolean isEnabled(){
        try {
            checkBluetooth();
            return bluetoothAdapter.isEnabled();
        } catch (BluetoothNotEnabledException e) {
            return false;
        }
    }

    /**
     * Check bluetooth connection
     * @return true if connected, false otherwise
     */
    public boolean isConnected(){
        return (this.bluetoothConnected);
    }

    /**
     * Start bluetooth scan for nearby devices
     * @param filters Scan filters that define what devices to scan for
     */
    public void startScan(List<ScanFilter> filters)
            throws BluetoothNotEnabledException{
        checkBluetooth();
        // dont run two scans simultaneously
        if (isScanning()) {
            return;
        }
        // disconnect previously connected devices
        if (isConnected()) {
            this.disconnect();
            return;
        }
        // setup bluetooth scanning settings
        ScanSettings settings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                .build();

        // start scanning
        this.bluetoothScanning = true;
        this.bluetoothScanResults.clear();
        this.bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();

        // Stops scanning after a pre-defined scan period.
        Handler bluetoothHandler = new Handler();
        bluetoothHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                stopScan();
            }
        }, SCAN_TIMEOUT);

        // start scan with default scan callback
        this.bluetoothLeScanner.startScan(filters, settings, bluetoothScanCallback);
        // we have started successfully the BLE scanning
        bluetoothListener.onBluetoothStartScan();
    }

    /**
     * Stop bluetooth scan for nearby devices
     */
    public void stopScan(){
        if (!bluetoothScanning) {
            return;
        }
        // set app scan state to false
        bluetoothScanning = false;
        if (bluetoothLeScanner != null) {
            bluetoothLeScanner.stopScan(bluetoothScanCallback);
            bluetoothLeScanner = null;
        }
        // we have stopped BLE scanning, call the user's callback
        bluetoothListener.onBluetoothStopScan(bluetoothScanResults.values());
    }

    /**
     * Send a message via bluetooth
     * @param msg message to send
     */
    public void send(String msg) {
        if (!bluetoothConnected || characteristic == null){
            bluetoothListener.onBluetoothNotConnected();
            return;
        }
        try {
            msg = msg.replaceAll(DATA_FILTER_REGEX, "") + TERMINATION_CHAR;
            Log.d(LOG_TAG, String.format(Locale.getDefault(),
                    "Sending message: %s",
                    msg));
            characteristic.setValue(msg.getBytes(CHARSET));
            bluetoothGatt.writeCharacteristic(characteristic);
        } catch (UnsupportedEncodingException e) {
            Log.e(LOG_TAG,
                "BluetoothLowEnergy.send: Failed to convert message string to byte array");
        }
    }

    public String getDeviceUUID(){
        return deviceUUID;
    }

    public Activity getActivity(){
        return activity;
    }

    /**
     * Check if bluetooth is enabled and working properly
     */
    private void checkBluetooth() throws BluetoothNotEnabledException{
        if (bluetoothAdapter == null) {
            final BluetoothManager bluetoothManager =
                    (BluetoothManager) activity.getSystemService(Context.BLUETOOTH_SERVICE);
            if (bluetoothManager == null){
                throw new BluetoothNotEnabledException();
            }
            bluetoothAdapter = bluetoothManager.getAdapter();
        }

        // Ensures Bluetooth is available on the device and it is enabled. If not,
        // displays a dialog requesting user permission to enable Bluetooth.
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            throw new BluetoothNotEnabledException();
        }
    }

}

The key methods and functions to avoid problems used above are:

  • Thread.sleep(600)
  • removeBond(device)
  • refresh(gatt)
  • gatt.disconnect()
  • gatt.close()
Louvenialouver answered 9/10, 2018 at 16:25 Comment(2)
This is an interesting code dump, but could use some explanation on how you are avoiding errors 19 and 22.Collen
Thanks for sharing. I've added a few things to my code based on it. I also noticed a couple of little things that seem redundant: status == BluetoothGatt.GATT_FAILURE and calling super on the overridden methods of BluetoothGattCallback.Hickey
T
0

In my case I got this response from bluetooth stack because the device was already bonded with my phone. I removed it from my settings and the error 22 vanished.

Tva answered 16/1, 2019 at 11:27 Comment(0)
C
0

in aosp (android source code). you can find any error in bluetooth source code, and know the meaning of status code. the file path is system/bt/stack/include/gatt_api.h

Here's the link: https://android.googlesource.com/platform/system/bt/+/ea7ab70a711e642653dd5922b83aa04a53af9e0e/stack/include/gatt_api.h but it all display by hex.

for example:

hex Decimal reason
0x08 8 connection timeout
0x13 19 connection terminate by peer user
0x16 22 connectionterminated by local host
0x22 34 connection fail for LMP response tout
0x85 133 gatt_error
Competent answered 3/9, 2021 at 9:26 Comment(1)
here localhost means server and peer means client?Fated

© 2022 - 2024 — McMap. All rights reserved.