1

I'm developing two app one peripheral and one central role.

Peripheral

2 characteristic :

  • one (called pippo) with write_noresponse property
  • one (called paperino) with read and notify property

y

private void addServiceToGattServer() {

        Service = new BluetoothGattService(
                UUID.fromString(CostantUUID.xxx),
                BluetoothGattService.SERVICE_TYPE_PRIMARY);

        paperino = new BluetoothGattCharacteristic(
                UUID.fromString(CostantUUID.xxx),
                BluetoothGattCharacteristic.PROPERTY_NOTIFY|BluetoothGattCharacteristic.PROPERTY_READ,BluetoothGattCharacteristic.PERMISSION_READ);


        clientCharacteristiConfiguration = new BluetoothGattDescriptor(UUID.fromString(CostantUUID.clientCharacteristiConfiguration), BluetoothGattDescriptor.PERMISSION_WRITE);
        paperino.addDescriptor(clientCharacteristiConfiguration);

        Service.addCharacteristic(paperino);


        pippo = new BluetoothGattCharacteristic(
                UUID.fromString(CostantUUID.userCommands),
                BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE ,
                BluetoothGattCharacteristic.PERMISSION_WRITE);

        ebikeService.addCharacteristic(pippo);

        mGattServer.addService(Service);
    }



@Override
        public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value)
        {
            if(responseNeeded)
              mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
                ................
                ...............
                paperino.setValue(payload);
                mGattServer.notifyCharacteristicChanged(device,paperino, false);
            }

Client side

I have abilitated the setCharacteristicNotification and wrote a descriptor for characteristic Paperino :

    bluetoothGatt.setCharacteristicNotification(characteristic, true);

    /**
     * @author I
     * I abilitate the cliatcharacteristicconfiguration descriptor
     */

    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CostantUUid.clientCharacteristiConfiguration));
    if(descriptor != null)
    {
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        bluetoothGatt.writeDescriptor(descriptor);
    }

In this way all function correctly works, but I wonder: it's really necessary to add descriptor on peripherall side and write on it from client side ?

I tried to not use it and the it doesn't work. But on the internet tutorials never tell to write descriptor...

WHat is the true ?

Furthermore if I do the first notifyCharacteristicChanged(device,paperino, false); in the onConnectionStateChange callback

@Override
    public void onConnectionStateChange(final BluetoothDevice device,
            int status, int newState) {
        super.onConnectionStateChange(device, status, newState);
        Log.d(TAG, "onConnectionStateChange status=" + status + "->"
                + newState);

        message=myHandler.obtainMessage();

if(newState == BluetoothProfile.STATE_CONNECTED)
            {
                disconnected=false;
                Bundle f=new Bundle();
                f.putString("connectionStatus", (String)(Utils.getStateDescription(newState)));
                message.setData(f);
                myHandler.sendMessage(message);
                connectedDevice=device;

                paperino.setValue(examplemsg);
                        mGattServer.notifyCharacteristicChanged(device, paperino,false);
            }

on server side the notification the "examplemessage" doesn't arrive on client side. I have to call for the first time notifyCharacteristicChanged in onDescriptorWrite...

Maybe is too early to call notifycharacteristicChanged ?

aeroxr1
  • 1,014
  • 1
  • 14
  • 36

1 Answers1

3

You have to write to the Descriptor, it's part of the Bluetooth specification. The iOS implementation abstracts that step out for you. The Android implementation however requires writing to the Descriptor manually.

I think this answer I wrote a while back still applies: Any way to implement BLE notifications in Android-L preview

Community
  • 1
  • 1
ludwigmace
  • 692
  • 4
  • 10
  • Hi !!! Thanks :) I have followed your answer to create my app ! I write this post because in many tutorial never tell to write descriptor .. and after a while the doubt is appeared in my head. For the other problem, do you have some suggestion ? I have added some code line to better explain my doubt :) – aeroxr1 May 03 '15 at 15:49
  • 1
    You're right that you're calling notifyCharacteristicChanged too early if you call it in the onConnectionStateChanged callback. By doing that, you're not giving the client a chance to write to the Descriptor which actually turns notifications on for that characteristic. Where you have it in onDescriptorWriteRequest should work just fine. – ludwigmace May 03 '15 at 16:14
  • Because I thought that I was calling notifyCharacteristicChanged too early, I have also tried to start a thread in onConnectionStateChanged which each seconds for 30 second sent a notifyCharacteristicChanged. But the final result doesn't change and the client didn't receive the notification. Why ? I'm trying to better understand the problem :) – aeroxr1 May 03 '15 at 22:38
  • 1
    The Central isn't subscribed to the Characteristic when the devices connect. The Central is only subscribed after writing to the Peripheral's Descriptor for a Characteristic, so really you should start doing stuff in the Peripheral's onDescriptorWriteRequest event. If you get disconnected and reconnect, you'll have to re-subscribe anyway, so doing anything in onConnectionStateChanged doesn't really help. – ludwigmace May 04 '15 at 02:45
  • Perfect :) Thanks ! Do you know if there are problem to receive notifycharacteristicChanged on Lollipop ? Because I have to communicate with another peripherall (not Lollipop device, but a really peripherall that notify me some data), and on kitkat there aren't problem and the communication works correctly , on Lollipop I don't receive the notification... I can't understand the problem :/ – aeroxr1 May 06 '15 at 18:02