This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nrf52 (sdk2.0 v11) alert notification and android gatt server

Hi.

I've played around with the android application (based around google gatt example, but used in gatt server -mode).

How is the example expected to be handled? In proper central mode the nrf would do the scanning and connecting and android would be the peripheral and just host the gatt server (with Alert notification service + necessary characteristics) and advertise.

However as the nrf needs to be scanned by the android device, I first connect the device via regular gatt. At this point I've already opened gatt server connection and registered callback to it. I've also created the service and added characteristics to it and added those to gatt server. I also got onServiceAdded-callsto my BluetoothGattServerCallback.

After connection call I can get onConnectionStateChanged - and onCharacteristicRead -calls to BluetoothGattServerCallback. However if I try to write to said characteristic or do notify call, I can see no response on the nrf device. I've enabled read&write&notify priviledges on the characteristics and also I have enabled all notifications from the control point characteristic.

log from terminal:

[DB]: Discovery of service with UUID 0x1811 completed with success for Connectionhandle 0
[ANS] Found supported new alert category 
[ANS] Found New Alert 
[ANS] Found supported unread alert category 
[ANS] Found Unread Alert 
[ANS] Found Ctrlpt 
hox evt  
hox ansc disco
[main] alert_ns
[ANS] ble_event
[ANS] ...default id: 51
[ANS] ble_event
[ANS] ...read rsp
[ANS] read_rsp len 5
hox evt
hox read resp
[ANS] ble_event
[ANS] ...read rsp
[ANS] read_rsp len 5
hox evt
hox read resp
[ANS] ble_event
[ANS] ...default id: 18
[ANS] ble_event
[ANS] ...default id: 58
[ANS] ble_event
[ANS] ...disconnected
hox evt
hox disco comp
[ANS] ble_event
[ANS] ...default id: 27

Android side:

 04-08 17:00:23.571 BluetoothLeService: onServiceAdded
 04-08 17:00:23.577 BluetoothGatt: onClientRegistered() - status=0 clientIf=11
 04-08 17:00:23.644 BluetoothGattServer: onServerConnectionState() - status=0 serverIf=6 device=CE:CE:67:C2:71:FE
 04-08 17:00:23.644 BluetoothLeService: onConnectionStateChage device CE:CE:67:C2:71:FE
 04-08 17:00:23.645 BluetoothGattServer: onServerConnectionState() - status=0 serverIf=7 device=CE:CE:67:C2:71:FE
 04-08 17:00:23.645 BluetoothLeService: onConnectionStateChage device CE:CE:67:C2:71:FE
 04-08 17:00:23.646 BluetoothGattServer: onServerConnectionState() - status=0 serverIf=8 device=CE:CE:67:C2:71:FE
 04-08 17:00:23.646 BluetoothLeService: onConnectionStateChage device CE:CE:67:C2:71:FE
 04-08 17:00:23.647 BluetoothGattServer: onServerConnectionState() - status=0 serverIf=9 device=CE:CE:67:C2:71:FE
 04-08 17:00:23.647 BluetoothLeService: onConnectionStateChage device CE:CE:67:C2:71:FE
 04-08 17:00:23.662 BluetoothGattServer: onServerConnectionState() - status=0 serverIf=10 device=CE:CE:67:C2:71:FE
 04-08 17:00:23.662 /BluetoothLeService: onConnectionStateChage device CE:CE:67:C2:71:FE
 04-08 17:00:23.663 BluetoothGatt: onClientConnectionState() - status=0 clientIf=11 device=CE:CE:67:C2:71:FE
 04-08 17:00:23.663 BluetoothGatt: onConnectionStateChange
 04-08 17:00:23.663 BluetoothGatt: status connected
 04-08 17:00:23.663 BluetoothGatt: discoverServices() - device: CE:CE:67:C2:71:FE
 04-08 17:00:23.671 BluetoothGatt: onSearchComplete() = Device=CE:CE:67:C2:71:FE Status=0
 04-08 17:00:23.691 Timeline: Timeline: Activity_idle id: android.os.BinderProxy@2ebcc89a time:102305919
 04-08 17:00:24.132 BluetoothLeService: onCharacteristicReadRequest UUID: 00002a47-0000-1000-8000-00805f9b34fb from device: CE:CE:67:C2:71:FE
 04-08 17:00:24.224 BluetoothLeService: onCharacteristicReadRequest UUID: 00002a48-0000-1000-8000-00805f9b34fb from device: CE:CE:67:C2:71:FE
 04-08 17:00:24.322 /BluetoothLeService: ondescriptorwriterequest UUID: 00002902-0000-1000-8000-00805f9b34fbValue: 1
 04-08 17:00:24.322 BluetoothLeService: sending nofication!

I checked the ans callback values from softdevice header, and they seem to be reporting non-faulty statuses (and pardon the traces I've added there).

Ideas where to go from here? There isn't really many examples on this sorf of usecase, altough the notifications from android to embedded device is quite used usecase.

  • Ok, the problem was that those descriptors needed to be unique. so 00002902 for one and second 10002902. After that the gattserver.sendresponse worked OK.

    EDIT3: one integer value interprited as hex.

    EDIT2: I think this whole problem is somehow related to character/service(?) rights. I changed the notifyCharacteristicChanged(BluetoothDevice device, BluetoothGattCharacteristic characteristic, boolean confirm) confirm-parameter to false and now I can send several notifications.

    HOWEVER if there's more than few second pause, the's timeout and connection is dropped. There seems to be ble_ans_c_new_alert_read. tx function doesn't return any errors, but after while there's ble_ans_c_on_ble_evt callback with BLE_GATTC_EVT_TIMEOUT -value.

    My New Alert -characteristic has pretty much all modes and priviledges enabled (for testing purposes). Or is this on nrf side?

    My service & characteristics &server connection code:

        mGattServer = mBluetoothManager.openGattServer(this, serverCallback);
    
        mSupportedNewAlertCategory = new BluetoothGattCharacteristic(SampleGattAttributes.UUID_SUPPORTED_NEW_ALERT_CATEGORY,
                BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
        mSupportedNewAlertCategory.setValue(new byte[]{0x1f});
        /*
        * New alert part (char & descriptor)
        * */
        clientCharacteristicConfigNa = new BluetoothGattDescriptor(SampleGattAttributes.UUID_CLIENT_CHARACTERISTIC_CONFIG_NA,
                BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE);
        clientCharacteristicConfigNa.setValue(new byte[]{1});
    
        mNewAlert = new BluetoothGattCharacteristic(SampleGattAttributes.UUID_NEW_ALERT,
                BluetoothGattCharacteristic.PROPERTY_WRITE |BluetoothGattCharacteristic.PROPERTY_INDICATE | BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_READ,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
    
        mNewAlert.addDescriptor(clientCharacteristicConfigNa);
        /*
        * Unread alert status associated with new alert
        * */
        clientCharacteristicConfigUa = new BluetoothGattDescriptor(SampleGattAttributes.UUID_CLIENT_CHARACTERISTIC_CONFIG_UA, BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE);
        clientCharacteristicConfigUa.setValue(new byte[]{1});
    
        mUnreadAlertStatus = new BluetoothGattCharacteristic(SampleGattAttributes.UUID_UNREAD_ALERT_STATUS,
                BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_INDICATE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
        mUnreadAlertStatus.addDescriptor(clientCharacteristicConfigUa);
    
        mSupportedUnreadCategory = new BluetoothGattCharacteristic(SampleGattAttributes.UUID_SUPPORTED_UNREAD_ALERT_CATEGORY,
                BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_INDICATE | BluetoothGattCharacteristic.PROPERTY_NOTIFY  | BluetoothGattCharacteristic.PROPERTY_WRITE,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
        mSupportedUnreadCategory.setValue(new byte[]{0x1f});
    
        mAlertNotificationControlPoint = new BluetoothGattCharacteristic(SampleGattAttributes.UUID_ALERT_NOTIFICATION_CONTROL_POINT,
                BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_INDICATE | BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_WRITE,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
    
        mAlertNotificationService = new BluetoothGattService(SampleGattAttributes.UUID_ALERT_NOTIFICATION_SERVICE, BluetoothGattService.SERVICE_TYPE_PRIMARY);
    
        mAlertNotificationService.addCharacteristic(mSupportedNewAlertCategory);
        mAlertNotificationService.addCharacteristic(mNewAlert);
        mAlertNotificationService.addCharacteristic(mSupportedUnreadCategory);
        mAlertNotificationService.addCharacteristic(mUnreadAlertStatus);
        mAlertNotificationService.addCharacteristic(mAlertNotificationControlPoint);
    
        mGattServer.addService(mAlertNotificationService);
    
  • Hi Matts,

    It's a little bit unclear for me on what you did on the nRF52 side. Did you do service discovery, and when you have the characteristic's handle ID, did you do a write to the CCCD to enable notification ?

    Note that there is no nCharacteristicRead event with BluetoothGattServerCallback.

    Have you called notifyCharacteristicChanged() from Android to start sending notification ?

  • Hi Hung Bui.

    The nrf side example is unchanged from the original, other than enabling traces and adding some more.

    In my app side I have a button than changes char value and calls notifyCharacteristicChanged. I can get one notification through per connection. After that I have to disconnect to get another through. The alerts I send are SMS alert, Call alert and email alert. All go trough as single notification. Also the communication is still OK, as the alert disabling (with nrf buttons) cause call to android side descriptor write callback.

    Do I have to add some notification processing to app to make it accept more notifications? A flow how these things should be handled would be nice.

  • What you described is a little bit strange, on that you receive only one notification before you need to disconnect and reconnect. Could you debug a little bit more ? Maybe check if it's the problem from the phone or from the nRF. You can use a sniffer to check if the notifications are sent but the nRF52 didn't catch it or didn't tell the application. You can run in debug mode and add a breakpoint at BLE_GATTC_EVT_HVX event to check if any event received.

  • In phone side: I just increase the new alert and unread alert counter in those two characteristics. For new alert I also change the payload type (first byte) and actual payload. The format is like the example value here: developer.bluetooth.org/.../CharacteristicViewer.aspx

    After that I just call gattserver.notifyCharacteristicChanged for both unread and new alert notification characteristics.

    In the nrf side I've added traces to all functions (special emphasis on event handlers) in ble_ans_c.c and main.c. In case of second notification i get no indications at all from any of those that something has occurred on.

    I'll try the debugger tomorrow. Could you also suggest any special points of interest on the nrf side where I could add more traces?

    I'll update the question with update log.

Related