Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BluetoothGattCallback returns 129 -> GATT_INTERNAL_ERROR for a Beacon, but returns 0 for phones

I call on my bluetooth adapter mBluetoothAdapter.startDiscovery(); which then returns me a list of BluetoothDevices. When I press on 1 of those devices, I do this:

   mBluetoothGatt = bluetoothDevice.connectGatt(MainActivity.this, false, mGattCallback);

Where my callback is:

   private final BluetoothGattCallback mGattCallback =
        new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                                int newState) {
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    mConnectionState = STATE_CONNECTED;
                    Log.i(TAG, "Connected to GATT server.");
                    Log.i(TAG, "Attempting to start service discovery:" +
                            mBluetoothGatt.discoverServices());
                    List<BluetoothGattService> listBGS = mBluetoothGatt.getServices();
                    Log.i("","list size: " + listBGS.size());

                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    mConnectionState = STATE_DISCONNECTED;
                    Log.i(TAG, "Disconnected from GATT server.");
                }
            }

            @Override
            // New services discovered
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    Log.w(TAG, "onServicesDiscovered GATT_SUCCESS: " + status);
                    List<BluetoothGattService> listBGS = mBluetoothGatt.getServices();
                    Log.i("","list size: " + listBGS.size());
                } else {
                    Log.w(TAG, "onServicesDiscovered received: " + status);
                }
            }

            @Override
            // Result of a characteristic read operation
            public void onCharacteristicRead(BluetoothGatt gatt,
                                             BluetoothGattCharacteristic characteristic,
                                             int status) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    Log.w(TAG, "onCharacteristicRead GATT_SUCCESS: " + status + " / char: " + characteristic);
                }
            }
        };

Now, when I try it on phones, I get STATE_CONNECTED on onConnectionStateChange , and I then call discoverServices, and I get back a GATT_SUCCESS onServicesDiscoveres. So I can take the uuids from my services. BUT when I try it on a beacon, I get back STATE_CONNECTED and when I call discoverServices, I get back an status code: 129 -> GATT_INTERNAL_ERROR Why is this happening for my beacons? Is there another way, how I can take the devices uuid? I just need the UUID to be able to do this after, for the beaconManager:

 try {
        beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", null, null, null));
    } catch (RemoteException e) {    }

EDIT

I know that the beacon should ask me for a code to pair, but it doesn't. Why? I tried adding this code:

    final IntentFilter pairingRequestFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
    pairingRequestFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY - 1);
    registerReceiver(mPairingRequestRecevier, pairingRequestFilter);

But still I don't get a request to pair and input my passkey

This is my pairingRequestReceiver:

  private final BroadcastReceiver mPairingRequestRecevier = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(intent.getAction()))
        {
            final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);

            if (type == BluetoothDevice.PAIRING_VARIANT_PIN)
            {
                device.setPin(intToByteArray(123456));
                abortBroadcast();
            }
            else
            {
                Log.e("","Unexpected pairing type: " + type);
            }
        }
    }
};
like image 249
rosu alin Avatar asked Feb 02 '18 11:02

rosu alin


1 Answers

After hours of trial and error I did manage to find a way to make it work like this: 1.I start the discovery the same, but when I select an bluetooth device, I ask to bond (pair) with it like this:

 private void pairDevice(BluetoothDevice device) {
    try {
        Method method = device.getClass().getMethod("createBond", (Class[]) null);
        method.invoke(device, (Object[]) null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

I have a ACTION_BOND_STATE_CHANGED receiver:

 private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
            final int state        = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
            final int prevState    = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);

            if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
                Log.i("","Paired");
                mBluetoothGatt = btDevice.connectGatt(MainActivity.this, false, mGattCallback);
            } else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
                Log.i("","Unpaired");
            }

        }
    }
};

Which I register like this:

         IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
    registerReceiver(mPairReceiver, intent);

And only after this, I try to connect with my BluetoothGattCallback. Hence, I can discover the services, and so on

like image 110
rosu alin Avatar answered Sep 30 '22 18:09

rosu alin